File Comparison Report

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

richardm

04-Apr-2024

Files

Left FileRight File
File namecom_ieee8023_93a_440com_ieee8023_93a_450beta1
File pathC:\Users\richardm\OneDrive - Samtec\COM\COM\srcC:\Users\richardm\OneDrive - Samtec\COM\COM\src
Last modified26-Mar-2024 14:35:5704-Apr-2024 15:14:08

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.op.mlse

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

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

420

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

420

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

421

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

421

422

OP.COMPUTE_COM=true;

422

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

423

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

423

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

424

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

424

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

425

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

425

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

426

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

426

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

427

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

+428

427

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

428

param.use_bmax=fom_result.best_bmax.';

430

param.use_bmax=fom_result.best_bmax.';

429

%AJG021820

431

%AJG021820

430

param.use_bmin=fom_result.best_bmin.';

432

param.use_bmin=fom_result.best_bmin.';

431

% 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

432

param.current_ffegain=fom_result.best_current_ffegain;

434

param.current_ffegain=fom_result.best_current_ffegain;

433

if OP.force_pdf_bin_size

435

if OP.force_pdf_bin_size

434

param.delta_y = OP.BinSize;

436

param.delta_y = OP.BinSize;

435

else

437

else

436

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

438

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

437

end

439

end

438

% 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

439

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

441

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

440

442

441

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

443

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

442

443

PSD_results=[];

444

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

444

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

445

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

445

OP.WO_TXFFE=1;

446

OP.WO_TXFFE=1;

+447

PSD_results.w=fom_result.RxFFE;

446

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

448

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

+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

447

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

448

OP.WO_TXFFE=0;

452

OP.WO_TXFFE=0;

+453

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

454

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

455

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

456

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

449

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

450

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

458

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

+459

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

451

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

460

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

452

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

461

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

453

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

462

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

454

end

463

end

455

%% Create ISI PDF & Individual Crosstalk PDFs

464

%% Create ISI PDF & Individual Crosstalk PDFs

456

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

465

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

457

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

466

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

458

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

467

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

459

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

468

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

460

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

469

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

461

for i=1:param.number_of_s4p_files

470

for i=1:param.number_of_s4p_files

462

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

471

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

463

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

472

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

464

473

465

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

466

else

475

else

467

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

468

end

477

end

469

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

478

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

470

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

479

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

471

subplot(2,1,2);

480

subplot(2,1,2);

472

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

481

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

473

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

482

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

474

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

483

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

475

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

484

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

476

hold on; title('PDF')

485

hold on; title('PDF')

477

recolor_plots(gca);

486

recolor_plots(gca);

478

end

487

end

479

488

480

chdata(i).pdfr=pdf;

489

chdata(i).pdfr=pdf;

481

% reporting

490

% reporting

482

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

491

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

483

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

492

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

484

493

485

end

494

end

486

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

495

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

487

496

488

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

489

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

498

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

490

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

499

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

491

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

500

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

492

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

501

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

493

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

494

combined_interference_and_noise_pdf=PDF;

503

combined_interference_and_noise_pdf=PDF;

495

combined_interference_and_noise_cdf=CDF;

504

combined_interference_and_noise_cdf=CDF;

496

505

497

506

498

%% Calculate COM and other associated outputs

507

%% Calculate COM and other associated outputs

499

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

508

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

500

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

509

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

501

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

510

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

502

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

511

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

503

% 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

504

% that satisfies the relationship P(y0) = DER_0

513

% that satisfies the relationship P(y0) = DER_0

505

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

506

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

507

516

508

% begin yasuo patch 3/18/2019

517

% begin yasuo patch 3/18/2019

509

% estimate DER at threshold COM

518

% estimate DER at threshold COM

510

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

511

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

520

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

512

threshold_DER_max = max(threshold_DER_max, threshold_DER);

521

threshold_DER_max = max(threshold_DER_max, threshold_DER);

513

% end yasuo patch

522

% end yasuo patch

514

523

515

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

524

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

516

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

517

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

526

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

518

if OP.DISPLAY_WINDOW && OP.DEBUG

527

if OP.DISPLAY_WINDOW && OP.DEBUG

519

figure_name = 'Eye at DER0 estimate';

528

figure_name = 'Eye at DER0 estimate';

520

fig=findobj('Name', figure_name);

529

fig=findobj('Name', figure_name);

521

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

530

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

522

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

531

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

523

movegui(fig,'southwest')

532

movegui(fig,'southwest')

524

plot(eye_contour)

533

plot(eye_contour)

525

xlabel('UI %')

534

xlabel('UI %')

526

ylabel('V')

535

ylabel('V')

527

end

536

end

528

537

529

else

538

else

530

EW_UI=0;

539

EW_UI=0;

531

eye_contour=[];

540

eye_contour=[];

532

end

541

end

533

if OP.MLSE==0

542

if OP.MLSE==0

534

if param.T_O ~=0

543

if param.T_O ~=0

535

eye_opening=EH_T_C2M-EH_B_C2M;

544

eye_opening=EH_T_C2M-EH_B_C2M;

536

A_ni=2*A_s-eye_opening;

545

A_ni=2*A_s-eye_opening;

537

%eq 124E-4

546

%eq 124E-4

538

vec_arg=2*A_s/eye_opening;

547

vec_arg=2*A_s/eye_opening;

539

if vec_arg<eps

548

if vec_arg<eps

540

vec_arg=eps;

549

vec_arg=eps;

541

end

550

end

542

VEC_dB = 20*log10(vec_arg);

551

VEC_dB = 20*log10(vec_arg);

543

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

552

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

544

VEO_mV=eye_opening*1000;

553

VEO_mV=eye_opening*1000;

545

min_COM = min(min_COM, COM);

554

min_COM = min(min_COM, COM);

546

min_VEO_mV = min(min_VEO_mV,VEO_mV);

555

min_VEO_mV = min(min_VEO_mV,VEO_mV);

547

max_VEC_dB = max(max_VEC_dB, VEC_dB);

556

max_VEC_dB = max(max_VEC_dB, VEC_dB);

548

else

557

else

549

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

558

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

550

vec_arg=(A_s-A_ni)/A_s;

559

vec_arg=(A_s-A_ni)/A_s;

551

if vec_arg<eps

560

if vec_arg<eps

552

vec_arg=eps;

561

vec_arg=eps;

553

end

562

end

554

VEC_dB = -20*log10(vec_arg);

563

VEC_dB = -20*log10(vec_arg);

555

COM=20*log10(A_s/A_ni);

564

COM=20*log10(A_s/A_ni);

556

min_COM = min(min_COM, COM);

565

min_COM = min(min_COM, COM);

557

min_VEO_mV = min(min_VEO_mV,VEO_mV);

566

min_VEO_mV = min(min_VEO_mV,VEO_mV);

558

max_VEC_dB = max(max_VEC_dB, VEC_dB);

567

max_VEC_dB = max(max_VEC_dB, VEC_dB);

559

end

568

end

560

MLSE_results=struct;

569

MLSE_results=struct;

561

else % MLSE case added U3 option

570

else % MLSE case added U3 option

562

if OP.MLSE==1

571

if OP.MLSE==1

563

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

572

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

564

elseif OP.MLSE==2

573

elseif OP.MLSE==2

565

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

574

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

566

elseif OP.MLSE==3

575

elseif OP.MLSE==3

567

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

576

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

568

else

577

else

569

warning('unsuported MLSE option')

578

warning('unsuported MLSE option')

570

end

579

end

571

if param.T_O ~=0

580

if param.T_O ~=0

572

eye_opening=EH_T_C2M-EH_B_C2M;

581

eye_opening=EH_T_C2M-EH_B_C2M;

573

A_ni=2*A_s-eye_opening;

582

A_ni=2*A_s-eye_opening;

574

%eq 124E-4

583

%eq 124E-4

575

vec_arg=2*A_s/eye_opening;

584

vec_arg=2*A_s/eye_opening;

576

if vec_arg<eps

585

if vec_arg<eps

577

vec_arg=eps;

586

vec_arg=eps;

578

end

587

end

579

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

580

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

589

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

581

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

590

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

582

COM=MLSE_results.COM_CDF;

591

COM=MLSE_results.COM_CDF;

583

VEO_mV=eye_opening*1000;

592

VEO_mV=eye_opening*1000;

584

min_COM = min(min_COM, COM);

593

min_COM = min(min_COM, COM);

585

min_VEO_mV = min(min_VEO_mV,VEO_mV);

594

min_VEO_mV = min(min_VEO_mV,VEO_mV);

586

max_VEC_dB = max(max_VEC_dB, VEC_dB);

595

max_VEC_dB = max(max_VEC_dB, VEC_dB);

587

output_args.delta_COM=MLSE_results.delta_com_CDF;

596

output_args.delta_COM=MLSE_results.delta_com_CDF;

588

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

597

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

589

else

598

else

590

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

599

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

591

vec_arg=(A_s-A_ni)/A_s;

600

vec_arg=(A_s-A_ni)/A_s;

592

if vec_arg<eps

601

if vec_arg<eps

593

vec_arg=eps;

602

vec_arg=eps;

594

end

603

end

595

VEC_dB_orig = -20*log10(vec_arg);

604

VEC_dB_orig = -20*log10(vec_arg);

596

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

605

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

597

COM_orig=20*log10(A_s/A_ni);

606

COM_orig=20*log10(A_s/A_ni);

598

COM=MLSE_results.COM_CDF;

607

COM=MLSE_results.COM_CDF;

599

min_COM = min(min_COM, COM);

608

min_COM = min(min_COM, COM);

600

min_VEO_mV = min(min_VEO_mV,VEO_mV);

609

min_VEO_mV = min(min_VEO_mV,VEO_mV);

601

max_VEC_dB = max(max_VEC_dB, VEC_dB);

610

max_VEC_dB = max(max_VEC_dB, VEC_dB);

602

output_args.delta_COM=MLSE_results.delta_com_CDF;

611

output_args.delta_COM=MLSE_results.delta_com_CDF;

603

end

612

end

604

end

613

end

605

614

606

%% Create COM_SNR_Struct to hold the main COM outputs

615

%% Create COM_SNR_Struct to hold the main COM outputs

607

COM_SNR_Struct.A_s=A_s;

616

COM_SNR_Struct.A_s=A_s;

608

COM_SNR_Struct.A_ni=A_ni;

617

COM_SNR_Struct.A_ni=A_ni;

609

COM_SNR_Struct.threshold_DER=threshold_DER;

618

COM_SNR_Struct.threshold_DER=threshold_DER;

610

COM_SNR_Struct.EW_UI=EW_UI;

619

COM_SNR_Struct.EW_UI=EW_UI;

611

COM_SNR_Struct.COM=COM;

620

COM_SNR_Struct.COM=COM;

612

COM_SNR_Struct.VEC_dB=VEC_dB;

621

COM_SNR_Struct.VEC_dB=VEC_dB;

613

if OP.MLSE == 0

622

if OP.MLSE == 0

614

COM_SNR_Struct.COM_orig=[];

623

COM_SNR_Struct.COM_orig=[];

615

COM_SNR_Struct.VEC_dB_orig=[];

624

COM_SNR_Struct.VEC_dB_orig=[];

616

else

625

else

617

COM_SNR_Struct.COM_orig=COM_orig;

626

COM_SNR_Struct.COM_orig=COM_orig;

618

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

627

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

619

end

628

end

620

COM_SNR_Struct.VEO_mV=VEO_mV;

629

COM_SNR_Struct.VEO_mV=VEO_mV;

621

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;

622

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;

623

COM_SNR_Struct.eye_contour=eye_contour;

632

COM_SNR_Struct.eye_contour=eye_contour;

624

633

625

634

626

%% Save TD

635

%% Save TD

627

if OP.SAVE_TD

636

if OP.SAVE_TD

628

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

637

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

629

if ~OP.TDMODE

638

if ~OP.TDMODE

630

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

639

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

631

end

640

end

632

for i=1:param.number_of_s4p_files

641

for i=1:param.number_of_s4p_files

633

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

634

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

635

if ~OP.TDMODE

644

if ~OP.TDMODE

636

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

637

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

638

end

647

end

639

end

648

end

640

if OP.TDMODE

649

if OP.TDMODE

641

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

650

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

642

else

651

else

643

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

644

end

653

end

645

end

654

end

646

655

647

%% Bathtub/Contribution Plot

656

%% Bathtub/Contribution Plot

648

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

657

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

649

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

658

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

650

end

659

end

651

660

652

%% Msg management

661

%% Msg management

653

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

662

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

654

msg=[];

663

msg=[];

655

end

664

end

656

if OP.DEBUG

665

if OP.DEBUG

657

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

666

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

658

switch param.flex

667

switch param.flex

659

case 4

668

case 4

660

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

661

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

662

);

671

);

663

case 2

672

case 2

664

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

665

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

666

);

675

);

667

otherwise

676

otherwise

668

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

669

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

670

);

679

);

671

680

672

end

681

end

673

else

682

else

674

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

683

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

675

end

684

end

676

685

677

if OP.TDMODE

686

if OP.TDMODE

678

min_ERL=inf;

687

min_ERL=inf;

679

ERL=[inf inf];

688

ERL=[inf inf];

680

end

689

end

681

[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

682

691

683

692

684

%% Output Args

693

%% Output Args

685

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

694

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

686

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

695

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

687

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

696

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

688

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

697

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

689

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

690

rt=toc(t0);

699

rt=toc(t0);

691

output_args.rtmin=rt/60;

700

output_args.rtmin=rt/60;

692

701

693

if OP.BREAD_CRUMBS

702

if OP.BREAD_CRUMBS

694

output_args.OP=OP;

703

output_args.OP=OP;

695

output_args.param=param;

704

output_args.param=param;

696

output_args.chdata=chdata;

705

output_args.chdata=chdata;

697

output_args.fom_result = fom_result;

706

output_args.fom_result = fom_result;

698

output_args.PDF=PDF; % for exploration

707

output_args.PDF=PDF; % for exploration

699

output_args.CDF=CDF; % for exploration

708

output_args.CDF=CDF; % for exploration

700

output_args.MLSE_results=MLSE_results;

709

output_args.MLSE_results=MLSE_results;

701

output_args.PSD_results=PSD_results;

710

output_args.PSD_results=PSD_results;

702

end

711

end

703

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

712

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

704

713

705

%% making csv file

714

%% making csv file

706

if OP.CSV_REPORT ==1

715

if OP.CSV_REPORT ==1

707

Write_CSV(output_args,CSV_FILE);

716

Write_CSV(output_args,CSV_FILE);

708

end

717

end

709

%% making mat file

718

%% making mat file

710

if(OP.DEBUG)

719

if(OP.DEBUG)

711

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

712

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

721

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

713

end

722

end

714

if 1

723

if 1

715

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)

716

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

725

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

717

end

726

end

718

727

719

if nargout==0

728

if nargout==0

720

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

729

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

721

disp(output_args)

730

disp(output_args)

722

end

731

end

723

732

724

if OP.BREAD_CRUMBS

733

if OP.BREAD_CRUMBS

725

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

734

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

726

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

735

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

727

%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

728

try

737

try

729

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

730

catch

739

catch

731

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

740

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

732

end

741

end

733

end

742

end

734

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

735

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

744

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

736

end

745

end

737

746

738

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

739

end

748

end

740

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

741

%%

750

%%

742

751

743

if OP.RX_CALIBRATION ==1

752

if OP.RX_CALIBRATION ==1

744

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)

745

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

746

end

755

end

747

DO_ONCE=false;

756

DO_ONCE=false;

748

end

757

end

749

758

750

%% Final cleanup

759

%% Final cleanup

751

if OP.DISPLAY_WINDOW

760

if OP.DISPLAY_WINDOW

752

savefigs(param, OP);

761

savefigs(param, OP);

753

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

762

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

754

end

763

end

755

764

756

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)

757

if ~param.f_hp==0

766

if ~param.f_hp==0

758

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

759

if OP.DISPLAY_WINDOW

768

if OP.DISPLAY_WINDOW

760

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

761

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

770

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

762

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

771

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

763

end

772

end

764

else

773

else

765

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

766

if OP.DISPLAY_WINDOW

775

if OP.DISPLAY_WINDOW

767

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

768

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

777

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

769

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

778

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

770

end

779

end

771

end

780

end

772

end

781

end

773

782

774

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

783

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

775

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

776

disp(redo_cmd_str);

785

disp(redo_cmd_str);

777

if isdeployed

786

if isdeployed

778

if OP.exit_if_deployed

787

if OP.exit_if_deployed

779

quit

788

quit

780

end

789

end

781

end

790

end

782

%%

791

%%

783

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

792

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

784

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

793

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

785

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

794

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

786

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

795

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

787

796

788

FB=param.fb;

797

FB=param.fb;

789

FZ=param.CTLE_fz(fom_result.ctle);

798

FZ=param.CTLE_fz(fom_result.ctle);

790

FP1=param.CTLE_fp1(fom_result.ctle);

799

FP1=param.CTLE_fp1(fom_result.ctle);

791

FP2=param.CTLE_fp2(fom_result.ctle);

800

FP2=param.CTLE_fp2(fom_result.ctle);

792

GDC=param.ctle_gdc_values(fom_result.ctle);

801

GDC=param.ctle_gdc_values(fom_result.ctle);

793

if ~isempty(param.f_HP)

802

if ~isempty(param.f_HP)

794

FHP=param.f_HP(fom_result.best_G_high_pass);

803

FHP=param.f_HP(fom_result.best_G_high_pass);

795

end

804

end

796

if ~isempty(param.g_DC_HP_values)

805

if ~isempty(param.g_DC_HP_values)

797

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

798

end

807

end

799

if ~isempty(param.f_HP_Z)

808

if ~isempty(param.f_HP_Z)

800

FHPZ=param.f_HP_Z(fom_result.ctle);

809

FHPZ=param.f_HP_Z(fom_result.ctle);

801

end

810

end

802

if ~isempty(param.f_HP_P)

811

if ~isempty(param.f_HP_P)

803

FHPP=param.f_HP_P(fom_result.ctle);

812

FHPP=param.f_HP_P(fom_result.ctle);

804

end

813

end

805

%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

806

%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

807

%length

816

%length

808

SBR_Len=length(fom_result.sbr);

817

SBR_Len=length(fom_result.sbr);

809

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

818

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

810

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

819

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

811

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

820

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

812

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

821

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

813

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

814

end

823

end

815

for i=1:param.number_of_s4p_files

824

for i=1:param.number_of_s4p_files

816

% 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

817

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

818

if OP.INCLUDE_CTLE==1

827

if OP.INCLUDE_CTLE==1

819

switch param.CTLE_type

828

switch param.CTLE_type

820

case 'CL93'

829

case 'CL93'

821

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

822

case 'CL120d'

831

case 'CL120d'

823

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

824

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

825

case 'CL120e' % z has been adjusted for gain

834

case 'CL120e' % z has been adjusted for gain

826

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

827

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

828

end

837

end

829

else

838

else

830

eq_ir=uneq_ir;

839

eq_ir=uneq_ir;

831

end

840

end

832

chdata(i).eq_imp_response=eq_ir;

841

chdata(i).eq_imp_response=eq_ir;

833

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

834

843

835

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

844

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

836

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

837

end

846

end

838

% chdata(i).ctle_imp_response

847

% chdata(i).ctle_imp_response

839

if OP.RxFFE

848

if OP.RxFFE

840

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

849

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

841

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

842

end

851

end

843

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

844

end

853

end

845

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)

846

end

855

end

847

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)

848

857

849

% display bathtub curves in one axis per test case.

858

% display bathtub curves in one axis per test case.

850

case_number=param.package_testcase_i;

859

case_number=param.package_testcase_i;

851

if ~OP.COM_CONTRIBUTION_CURVES

860

if ~OP.COM_CONTRIBUTION_CURVES

852

figure_name = 'Voltage bathtub curves';

861

figure_name = 'Voltage bathtub curves';

853

fig=findobj('Name', figure_name);

862

fig=findobj('Name', figure_name);

854

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

863

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

855

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

864

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

856

movegui(fig,'south')

865

movegui(fig,'south')

857

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

866

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

858

plot_bathtub_curves( hax ...

867

plot_bathtub_curves( hax ...

859

, COM_SNR_Struct.A_s ...

868

, COM_SNR_Struct.A_s ...

860

, Noise_Struct.sci_pdf ...

869

, Noise_Struct.sci_pdf ...

861

, Noise_Struct.cci_pdf ...

870

, Noise_Struct.cci_pdf ...

862

, Noise_Struct.isi_and_xtalk_pdf ...

871

, Noise_Struct.isi_and_xtalk_pdf ...

863

, Noise_Struct.noise_pdf ...

872

, Noise_Struct.noise_pdf ...

864

, Noise_Struct.jitt_pdf ...

873

, Noise_Struct.jitt_pdf ...

865

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

874

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

866

, param.delta_y ...

875

, param.delta_y ...

867

);

876

);

868

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

877

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

869

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,' '],'_',' ')));

870

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

879

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

871

% show BER target line

880

% show BER target line

872

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

881

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

873

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

882

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

874

else

883

else

875

figure_name = 'COM Contributions (Rough Allocations)';

884

figure_name = 'COM Contributions (Rough Allocations)';

876

fig=findobj('Name', figure_name);

885

fig=findobj('Name', figure_name);

877

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

886

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

878

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

887

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

879

movegui(fig,'south')

888

movegui(fig,'south')

880

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

889

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

881

890

882

plot_pie_com( hax ...

891

plot_pie_com( hax ...

883

, COM_SNR_Struct.A_s ...

892

, COM_SNR_Struct.A_s ...

884

, Noise_Struct.sci_pdf ...

893

, Noise_Struct.sci_pdf ...

885

, Noise_Struct.cci_pdf ...

894

, Noise_Struct.cci_pdf ...

886

, Noise_Struct.isi_and_xtalk_pdf ...

895

, Noise_Struct.isi_and_xtalk_pdf ...

887

, Noise_Struct.noise_pdf ...

896

, Noise_Struct.noise_pdf ...

888

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

897

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

889

, param.delta_y, param...

898

, param.delta_y, param...

890

);

899

);

891

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

900

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

892

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,' '],'_',' ')));

893

end

902

end

894

903

895

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

904

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

896

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

905

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

897

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

906

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

898

end

907

end

899

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

908

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

900

909

901

if use_BT

910

if use_BT

902

a = bessel( param.BTorder );

911

a = bessel( param.BTorder );

903

acoef=fliplr( a );

912

acoef=fliplr( a );

904

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

905

else

914

else

906

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

915

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

907

end

916

end

908

917

909

918

910

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

919

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

911

920

912

%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

913

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

922

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

914

%All subsequent lines are field names in chdata

923

%All subsequent lines are field names in chdata

915

%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

916

%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

917

%

926

%

918

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

919

%#reduce

928

%#reduce

920

%sdd12_raw

929

%sdd12_raw

921

%sdd21_raw

930

%sdd21_raw

922

%sdd22_raw

931

%sdd22_raw

923

%sdd11_raw

932

%sdd11_raw

924

%

933

%

925

934

926

fid=fopen(fields_file,'r');

935

fid=fopen(fields_file,'r');

927

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

936

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

928

937

929

file_data=file_data{1};

938

file_data=file_data{1};

930

fclose(fid);

939

fclose(fid);

931

940

932

%remove blank lines

941

%remove blank lines

933

L=cellfun('length',file_data);

942

L=cellfun('length',file_data);

934

file_data=file_data(L~=0);

943

file_data=file_data(L~=0);

935

944

936

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

945

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

937

type=file_data{1};

946

type=file_data{1};

938

field_names=file_data(2:end);

947

field_names=file_data(2:end);

939

switch lower(type)

948

switch lower(type)

940

case '#reduce'

949

case '#reduce'

941

remove_fields=field_names;

950

remove_fields=field_names;

942

case '#include'

951

case '#include'

943

all_fields=fieldnames(chdata);

952

all_fields=fieldnames(chdata);

944

remove_fields=setdiff(all_fields,field_names);

953

remove_fields=setdiff(all_fields,field_names);

945

otherwise

954

otherwise

946

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

955

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

947

end

956

end

948

957

949

%remove the "remove_fields" from chdata

958

%remove the "remove_fields" from chdata

950

for j=1:length(remove_fields)

959

for j=1:length(remove_fields)

951

this_field=remove_fields{j};

960

this_field=remove_fields{j};

952

if isfield(chdata,this_field)

961

if isfield(chdata,this_field)

953

chdata=rmfield(chdata,this_field);

962

chdata=rmfield(chdata,this_field);

954

end

963

end

955

end

964

end

956

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)

957

966

958

% 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

959

% 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

960

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

961

970

962

A_s=COM_SNR_Struct.A_s;

971

A_s=COM_SNR_Struct.A_s;

963

% initialize loop with uncorrelated noise and BER

972

% initialize loop with uncorrelated noise and BER

964

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

965

974

966

% 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

967

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

976

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

968

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

977

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

969

% below target BER).

978

% below target BER).

970

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

971

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

972

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

973

if isempty(x_error_propagation)

982

if isempty(x_error_propagation)

974

p_error_propagation(1) = 1e-20;

983

p_error_propagation(1) = 1e-20;

975

else

984

else

976

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

977

end

986

end

978

987

979

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

988

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

980

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

989

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

981

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

990

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

982

if OP.use_simple_EP_model

991

if OP.use_simple_EP_model

983

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>

984

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>

985

else

994

else

986

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>

987

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>

988

end

997

end

989

998

990

% 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

991

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

992

if isempty(x_error_propagation)

1001

if isempty(x_error_propagation)

993

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

1002

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

994

else

1003

else

995

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>

996

end

1005

end

997

end

1006

end

998

1007

999

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

1008

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

1000

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

1009

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

1001

% of this event by partial sum of the PDF.

1010

% of this event by partial sum of the PDF.

1002

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

1003

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

1004

1013

1005

% probability of bursts of different lengths

1014

% probability of bursts of different lengths

1006

p_burst = cumprod(p_error_propagation);

1015

p_burst = cumprod(p_error_propagation);

1007

function H_bw=Butterworth_Filter(param,f,use_BW)

1016

function H_bw=Butterworth_Filter(param,f,use_BW)

1008

1017

1009

if use_BW

1018

if use_BW

1010

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

1011

else

1020

else

1012

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

1021

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

1013

end

1022

end

1014

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

1023

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

1015

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

1024

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

1016

CDF_ev=CDF(index);

1025

CDF_ev=CDF(index);

1017

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

1026

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

1018

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

1027

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

1019

if isempty(index)

1028

if isempty(index)

1020

CDF_inv_ev=PDF.x(end);

1029

CDF_inv_ev=PDF.x(end);

1021

else

1030

else

1022

CDF_inv_ev=PDF.x(index);

1031

CDF_inv_ev=PDF.x(index);

1023

end

1032

end

1024

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)

1025

1034

1026

1035

1027

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

1036

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

1028

Remember_keyword='Legacy';

1037

Remember_keyword='Legacy';

1029

OP.TDMODE=false;

1038

OP.TDMODE=false;

1030

OP.GET_FD=true;

1039

OP.GET_FD=true;

1031

OP.CONFIG2MAT_ONLY=false;

1040

OP.CONFIG2MAT_ONLY=false;

1032

config_file='';

1041

config_file='';

1033

num_fext=[];

1042

num_fext=[];

1034

num_next=[];

1043

num_next=[];

1035

if ~isempty(varargin)

1044

if ~isempty(varargin)

1036

if ~ischar(varargin{1})

1045

if ~ischar(varargin{1})

1037

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

1046

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

1038

end

1047

end

1039

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

1048

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

1040

if isempty(keyword_idx)

1049

if isempty(keyword_idx)

1041

%Legacy Mode

1050

%Legacy Mode

1042

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

1051

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

1043

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

1052

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

1044

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

1053

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

1045

else

1054

else

1046

%Keyword Mode

1055

%Keyword Mode

1047

my_keyword=varargin{1};

1056

my_keyword=varargin{1};

1048

Remember_keyword=my_keyword;

1057

Remember_keyword=my_keyword;

1049

varargin(1)=[];

1058

varargin(1)=[];

1050

switch my_keyword

1059

switch my_keyword

1051

1060

1052

case 'Legacy'

1061

case 'Legacy'

1053

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

1062

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

1054

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

1063

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

1055

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

1064

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

1056

case 'TD'

1065

case 'TD'

1057

OP.TDMODE=true;

1066

OP.TDMODE=true;

1058

OP.GET_FD=false;

1067

OP.GET_FD=false;

1059

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

1068

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

1060

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

1069

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

1061

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

1070

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

1062

case 'Config2Mat'

1071

case 'Config2Mat'

1063

OP.CONFIG2MAT_ONLY=true;

1072

OP.CONFIG2MAT_ONLY=true;

1064

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

1073

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

1065

end

1074

end

1066

end

1075

end

1067

end

1076

end

1068

function chdata=COM_FD_to_TD(chdata,param,OP)

1077

function chdata=COM_FD_to_TD(chdata,param,OP)

1069

1078

1070

% 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

1071

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

1072

case_number=param.package_testcase_i;

1081

case_number=param.package_testcase_i;

1073

for i=1:param.number_of_s4p_files

1082

for i=1:param.number_of_s4p_files

1074

% RIM 2-01-2023 moved to FD_Processing

1083

% RIM 2-01-2023 moved to FD_Processing

1075

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1084

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1076

% % Equation 93A-20 %%

1085

% % Equation 93A-20 %%

1077

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

1078

% f=chdata(i).faxis;

1087

% f=chdata(i).faxis;

1079

% %

1088

% %

1080

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

1089

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

1081

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

1090

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

1082

% 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

1083

% 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

1084

% 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

1085

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

1094

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

1086

% if OP.DISPLAY_WINDOW

1095

% if OP.DISPLAY_WINDOW

1087

% if i==1

1096

% if i==1

1088

% figure(300+param.package_testcase_i);

1097

% figure(300+param.package_testcase_i);

1089

% subplot(3,1,1)

1098

% subplot(3,1,1)

1090

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

1091

% try

1100

% try

1092

% legend('NumColumns',2)

1101

% legend('NumColumns',2)

1093

% legend('location','south')

1102

% legend('location','south')

1094

% catch

1103

% catch

1095

% end

1104

% end

1096

% end

1105

% end

1097

% end

1106

% end

1098

% end

1107

% end

1099

[chdata(i).uneq_imp_response, ...

1108

[chdata(i).uneq_imp_response, ...

1100

chdata(i).t, ...

1109

chdata(i).t, ...

1101

chdata(i).causality_correction_dB, ...

1110

chdata(i).causality_correction_dB, ...

1102

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

1103

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

1104

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

1105

[chdata(i).uneq_CD_imp_response, ...

1114

[chdata(i).uneq_CD_imp_response, ...

1106

chdata(i).t_DC, ...

1115

chdata(i).t_DC, ...

1107

chdata(i).causality_correction_DC_dB, ...

1116

chdata(i).causality_correction_DC_dB, ...

1108

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

1109

end

1118

end

1110

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

1119

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

1111

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

1120

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

1112

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

1121

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

1113

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

1122

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

1114

1123

1115

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

1116

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

1117

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;

1118

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

1119

% 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

1120

rss=-inf;

1129

rss=-inf;

1121

for im=1:param.samples_per_ui

1130

for im=1:param.samples_per_ui

1122

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

1123

end

1132

end

1124

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

1133

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

1125

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

1126

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

1127

end

1136

end

1128

if OP.DEBUG && OP.DISPLAY_WINDOW

1137

if OP.DEBUG && OP.DISPLAY_WINDOW

1129

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1138

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1130

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

1139

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

1131

screen_size=get(0,'ScreenSize');

1140

screen_size=get(0,'ScreenSize');

1132

pos = get(gcf, 'OuterPosition');

1141

pos = get(gcf, 'OuterPosition');

1133

set(gcf, 'OuterPosition', ...

1142

set(gcf, 'OuterPosition', ...

1134

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

1135

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

1144

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

1136

%movegui(gcf,'northeast')

1145

%movegui(gcf,'northeast')

1137

1146

1138

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

1139

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

1140

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

1141

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

1142

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

1143

end

1152

end

1144

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

1153

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

1145

% scale. thru is shown in another plot.

1154

% scale. thru is shown in another plot.

1146

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

1147

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

1156

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

1148

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

1157

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

1149

end

1158

end

1150

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

1159

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

1151

ylabel('Volts')

1160

ylabel('Volts')

1152

xlabel('seconds')

1161

xlabel('seconds')

1153

1162

1154

recolor_plots(gca);

1163

recolor_plots(gca);

1155

else

1164

else

1156

if param.ndfe~=0

1165

if param.ndfe~=0

1157

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

1158

end

1167

end

1159

end

1168

end

1160

1169

1161

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

1162

if OP.ENFORCE_CAUSALITY

1171

if OP.ENFORCE_CAUSALITY

1163

fprintf('\n');

1172

fprintf('\n');

1164

else

1173

else

1165

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

1174

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

1166

end

1175

end

1167

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

1168

1177

1169

end

1178

end

1170

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)

1171

1180

1172

1181

1173

debug_plot=0;

1182

debug_plot=0;

1174

1183

1175

1184

1176

samp_UI=param.samples_for_C2M;

1185

samp_UI=param.samples_for_C2M;

1177

half_UI=get_center_of_UI(samp_UI);

1186

half_UI=get_center_of_UI(samp_UI);

1178

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

1187

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

1179

start_sample=half_UI-T_O;

1188

start_sample=half_UI-T_O;

1180

end_sample=half_UI+T_O;

1189

end_sample=half_UI+T_O;

1181

1190

1182

1191

1183

%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

1184

%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

1185

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

1186

if pdf_range_flag

1195

if pdf_range_flag

1187

pdf_range=[start_sample end_sample];

1196

pdf_range=[start_sample end_sample];

1188

else

1197

else

1189

pdf_range=[];

1198

pdf_range=[];

1190

end

1199

end

1191

1200

1192

%pdf_full is self ISI pdf for each sample point

1201

%pdf_full is self ISI pdf for each sample point

1193

%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

1194

%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

1195

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

1196

1205

1197

1206

1198

1207

1199

if isempty(pdf_range)

1208

if isempty(pdf_range)

1200

pdf_range=1:samp_UI;

1209

pdf_range=1:samp_UI;

1201

else

1210

else

1202

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

1211

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

1203

end

1212

end

1204

1213

1205

%Test doing Level PDFs

1214

%Test doing Level PDFs

1206

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

1215

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

1207

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

1208

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

1217

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

1209

1218

1210

%add signal vector into pdf

1219

%add signal vector into pdf

1211

for n=1:param.levels

1220

for n=1:param.levels

1212

pdf_full{n}=pdf_full_1;

1221

pdf_full{n}=pdf_full_1;

1213

for j=pdf_range

1222

for j=pdf_range

1214

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

1215

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;

1216

end

1225

end

1217

end

1226

end

1218

1227

1219

1228

1220

% figure;

1229

% figure;

1221

% hold on;

1230

% hold on;

1222

%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

1223

%computed for every sample point

1232

%computed for every sample point

1224

for n=1:param.levels

1233

for n=1:param.levels

1225

for j=pdf_range

1234

for j=pdf_range

1226

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

1227

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

1228

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

1229

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

1230

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

1231

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

1232

% change from adam gregory to include crosstalk

1241

% change from adam gregory to include crosstalk

1233

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

1234

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

1235

1244

1236

%PDF to CDF

1245

%PDF to CDF

1237

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

1238

1247

1239

end

1248

end

1240

end

1249

end

1241

%hold off;

1250

%hold off;

1242

1251

1243

1252

1244

%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

1245

for n=1:param.levels

1254

for n=1:param.levels

1246

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

1255

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

1247

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

1256

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

1248

for j=pdf_range

1257

for j=pdf_range

1249

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

1250

end

1259

end

1251

end

1260

end

1252

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

1253

1262

1254

for n=1:param.levels-1

1263

for n=1:param.levels-1

1255

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

1264

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

1256

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

1265

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

1257

end

1266

end

1258

1267

1259

1268

1260

for n=1:param.levels-1

1269

for n=1:param.levels-1

1261

%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

1262

%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

1263

%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

1264

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

1273

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

1265

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

1274

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

1266

EH=EH_top-EH_bot;

1275

EH=EH_top-EH_bot;

1267

vref=EH_top/2+EH_bot/2;

1276

vref=EH_top/2+EH_bot/2;

1268

%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

1269

%the top and bottom eye contours

1278

%the top and bottom eye contours

1270

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

1271

end

1280

end

1272

1281

1273

%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

1274

eye_contour_tmp=eye_contour;

1283

eye_contour_tmp=eye_contour;

1275

eye_contour=[];

1284

eye_contour=[];

1276

for n=1:param.levels-1

1285

for n=1:param.levels-1

1277

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

1278

end

1287

end

1279

1288

1280

1289

1281

%Find VEC eye height

1290

%Find VEC eye height

1282

out_VT=[];

1291

out_VT=[];

1283

out_VB=[];

1292

out_VB=[];

1284

if param.T_O ~=0

1293

if param.T_O ~=0

1285

1294

1286

switch lower(OP.Histogram_Window_Weight)

1295

switch lower(OP.Histogram_Window_Weight)

1287

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

1296

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

1288

%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

1289

%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

1290

QL_sigma=T_O/param.QL;

1299

QL_sigma=T_O/param.QL;

1291

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

1300

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

1292

case 'triangle'

1301

case 'triangle'

1293

%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

1294

%for the weights

1303

%for the weights

1295

t_slope=1/(T_O);

1304

t_slope=1/(T_O);

1296

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

1305

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

1297

case 'rectangle'

1306

case 'rectangle'

1298

%default = rectangle. all weights = 1

1307

%default = rectangle. all weights = 1

1299

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

1308

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

1300

case 'dual_rayleigh'

1309

case 'dual_rayleigh'

1301

QL_sigma=T_O/param.QL;

1310

QL_sigma=T_O/param.QL;

1302

X=-T_O:T_O;

1311

X=-T_O:T_O;

1303

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

1304

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

1305

weights=weights/max(weights);

1314

weights=weights/max(weights);

1306

otherwise

1315

otherwise

1307

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)

1308

end

1317

end

1309

1318

1310

for n=1:param.levels

1319

for n=1:param.levels

1311

out_pdf{n}=[];

1320

out_pdf{n}=[];

1312

for j=start_sample:end_sample

1321

for j=start_sample:end_sample

1313

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1322

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1314

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

1323

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

1315

if isempty(out_pdf{n})

1324

if isempty(out_pdf{n})

1316

out_pdf{n}=target_pdf;

1325

out_pdf{n}=target_pdf;

1317

else

1326

else

1318

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

1319

end

1328

end

1320

end

1329

end

1321

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

1322

end

1331

end

1323

1332

1324

for n=1:param.levels

1333

for n=1:param.levels

1325

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

1334

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

1326

end

1335

end

1327

1336

1328

for n=1:param.levels

1337

for n=1:param.levels

1329

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

1330

end

1339

end

1331

1340

1332

for n=1:param.levels-1

1341

for n=1:param.levels-1

1333

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

1342

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

1334

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

1343

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

1335

end

1344

end

1336

1345

1337

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

1346

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

1338

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

1347

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

1339

[mineh,min_idx]=min(EH_VT);

1348

[mineh,min_idx]=min(EH_VT);

1340

out_VT=OUT_VT_L(min_idx,1);

1349

out_VT=OUT_VT_L(min_idx,1);

1341

out_VB=OUT_VT_L(min_idx,2);

1350

out_VB=OUT_VT_L(min_idx,2);

1342

1351

1343

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

1352

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

1344

% out_VT=2*CDF_Mean-A_ni_top_O;

1353

% out_VT=2*CDF_Mean-A_ni_top_O;

1345

% out_VB=-1*A_ni_bottom_O;

1354

% out_VB=-1*A_ni_bottom_O;

1346

1355

1347

if debug_plot

1356

if debug_plot

1348

figure;

1357

figure;

1349

hold on;

1358

hold on;

1350

for j=start_sample:end_sample

1359

for j=start_sample:end_sample

1351

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

1352

end

1361

end

1353

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

1362

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

1354

hold off;

1363

hold off;

1355

end

1364

end

1356

end

1365

end

1357

1366

1358

1367

1359

1368

1360

1369

1361

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)

1362

1371

1363

%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

1364

%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

1365

%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

1366

%in other places in COM

1375

%in other places in COM

1367

1376

1368

if OP.RX_CALIBRATION

1377

if OP.RX_CALIBRATION

1369

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

1370

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

1371

switch param.CTLE_type

1380

switch param.CTLE_type

1372

case 'CL93'

1381

case 'CL93'

1373

H_low2=1;

1382

H_low2=1;

1374

case 'CL120d' % this clause uses two gain indexes

1383

case 'CL120d' % this clause uses two gain indexes

1375

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

1376

case 'CL120e' % Z1 has been adjusted

1385

case 'CL120e' % Z1 has been adjusted

1377

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

1378

end

1387

end

1379

H_ctf2=H_low2.*ctle_gain2;

1388

H_ctf2=H_low2.*ctle_gain2;

1380

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

1381

else

1390

else

1382

sigma_ne=0;

1391

sigma_ne=0;

1383

end

1392

end

1384

1393

1385

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

1394

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

1386

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

1395

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

1387

if ~OP.SNR_TXwC0

1396

if ~OP.SNR_TXwC0

1388

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

1397

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

1389

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

1390

else

1399

else

1391

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

1392

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

1403

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

1393

else

1404

else

1394

NS.sigma_TX =PSD_results.tn_rms;

1405

NS.sigma_TX =PSD_results.S_tn_rms;

+1406

NS.sigma_G = PSD_results.S_G_rms;

1407

NS.sigma_rjit=PSD_results.S_rj_rms ;

1395

end

1408

end

1396

% Equation 93A-41 %%

1409

% Equation 93A-41 %%

1397

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

1398

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

+1410

1399

1411

1400

% Equation 93A-42 %%

1412

% Equation 93A-42 %%

1401

% number of sigmas needed depends on the required BER.

1413

% number of sigmas needed depends on the required BER.

1402

if param.Noise_Crest_Factor == 0

1414

if param.Noise_Crest_Factor == 0

1403

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

1415

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

1404

else

1416

else

1405

NS.ber_q=param.Noise_Crest_Factor;

1417

NS.ber_q=param.Noise_Crest_Factor;

1406

end

1418

end

1407

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

1419

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

1408

% enable overriding the Q factor of the BBN instrument.

1420

% enable overriding the Q factor of the BBN instrument.

1409

if OP.force_BBN_Q_factor

1421

if OP.force_BBN_Q_factor

1410

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

1422

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

1411

else

1423

else

1412

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

1424

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

1413

end

1425

end

1414

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

1426

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

1415

1427

1416

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

1428

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

1417

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

1429

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

1418

1430

1419

% Equation 93A-43

1431

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

1420

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

1432

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

1421

1422

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

1433

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

1423

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

1434

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

1424

1435

1425

% Implementation of 93A.1.7.3 combination procedure

1436

% Implementation of 93A.1.7.3 combination procedure

1426

% (effectively Equation 93A-44) %%

1437

% (effectively Equation 93A-44) %%

1427

1438

1428

% Self-Channel Interference is thru residual result

1439

% Self-Channel Interference is thru residual result

1429

NS.sci_pdf = chdata(1).pdfr;

1440

NS.sci_pdf = chdata(1).pdfr;

1430

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

1441

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

1431

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

1442

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

1432

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

1443

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

1433

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

1444

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

1434

if OP.RX_CALIBRATION ==0

1445

if OP.RX_CALIBRATION ==0

1435

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

1446

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

1436

% initialize to deltas

1447

% initialize to deltas

1437

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

1448

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

1438

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

1449

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

1439

% serially convolve FEXT/NEXT PDFs

1450

% serially convolve FEXT/NEXT PDFs

1440

for k=2:param.number_of_s4p_files

1451

for k=2:param.number_of_s4p_files

1441

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

1452

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

1442

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

1453

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

1443

else % ... must be FEXT

1454

else % ... must be FEXT

1444

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

1455

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

1445

end

1456

end

1446

end

1457

end

1447

1458

1448

% find "peaks" of MDNEXT/MDFEXT for reporting

1459

% find "peaks" of MDNEXT/MDFEXT for reporting

1449

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

1460

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

1450

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

1461

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

1451

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

1462

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

1452

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

1463

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

1453

1464

1454

% Combined crosstalk effect

1465

% Combined crosstalk effect

1455

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1466

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1456

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

1467

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

1457

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

1468

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

1458

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

1469

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

1459

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

1470

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

1460

% combine cci and sci

1471

% combine cci and sci

1461

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

1472

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

1462

else

1473

else

1463

% for calibration there is no cci

1474

% for calibration there is no cci

1464

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1475

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1465

end

1476

end

1466

1477

1467

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

1478

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

1468

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

1479

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

1469

1480

1470

1481

1471

% Equation 93A-45

1482

% Equation 93A-45

1472

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

1483

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

1473

PDF=combined_interference_and_noise_pdf;

1484

PDF=combined_interference_and_noise_pdf;

1474

1485

1475

% Equation 93A-37

1486

% Equation 93A-37

1476

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1487

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1477

CDF=combined_interference_and_noise_cdf;

1488

CDF=combined_interference_and_noise_cdf;

1478

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

1489

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

1479

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

1490

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

1480

1491

1481

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

1492

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

1482

%This function calculates various frequency domain metrics

1493

%This function calculates various frequency domain metrics

1483

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

1494

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

1484

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

1495

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

1485

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1496

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1486

if OP.WC_PORTZ

1497

if OP.WC_PORTZ

1487

A_thru = param.a_thru(param.Tx_rd_sel);

1498

A_thru = param.a_thru(param.Tx_rd_sel);

1488

A_fext = param.a_fext(param.Tx_rd_sel);

1499

A_fext = param.a_fext(param.Tx_rd_sel);

1489

A_next = param.a_next(param.Tx_rd_sel);

1500

A_next = param.a_next(param.Tx_rd_sel);

1490

else

1501

else

1491

A_thru = param.a_thru(package_testcase);

1502

A_thru = param.a_thru(package_testcase);

1492

A_fext = param.a_fext(package_testcase);

1503

A_fext = param.a_fext(package_testcase);

1493

A_next = param.a_next(package_testcase);

1504

A_next = param.a_next(package_testcase);

1494

end

1505

end

1495

for i=1:param.number_of_s4p_files

1506

for i=1:param.number_of_s4p_files

1496

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

1507

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

1497

chdata(i).A=A_thru;

1508

chdata(i).A=A_thru;

1498

chdata(i).Aicn=A_thru;

1509

chdata(i).Aicn=A_thru;

1499

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

1510

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

1500

chdata(i).A=A_fext;

1511

chdata(i).A=A_fext;

1501

chdata(i).Aicn=param.a_icn_fext;

1512

chdata(i).Aicn=param.a_icn_fext;

1502

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

1513

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

1503

chdata(i).A=A_next;

1514

chdata(i).A=A_next;

1504

chdata(i).Aicn=param.a_icn_next;

1515

chdata(i).Aicn=param.a_icn_next;

1505

end

1516

end

1506

end

1517

end

1507

if OP.TDMODE

1518

if OP.TDMODE

1508

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

1519

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

1509

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

1520

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

1510

end

1521

end

1511

end

1522

end

1512

if ~DO_ONCE

1523

if ~DO_ONCE

1513

return;

1524

return;

1514

end

1525

end

1515

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

1526

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

1516

output_args.fitted_IL_dB_at_Fnq = [];

1527

output_args.fitted_IL_dB_at_Fnq = [];

1517

output_args.cable__assembley_loss=[];

1528

output_args.cable__assembley_loss=[];

1518

output_args.loss_with_PCB=[];

1529

output_args.loss_with_PCB=[];

1519

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1530

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1520

output_args.IL_dB_channel_only_at_Fnq=[];

1531

output_args.IL_dB_channel_only_at_Fnq=[];

1521

output_args.VTF_loss_dB_at_Fnq=[];

1532

output_args.VTF_loss_dB_at_Fnq=[];

1522

output_args.IL_db_die_to_die_at_Fnq=[];

1533

output_args.IL_db_die_to_die_at_Fnq=[];

1523

output_args.FOM_TDILN=[];

1534

output_args.FOM_TDILN=[];

1524

output_args.TD_ILN=[];

1535

output_args.TD_ILN=[];

1525

output_args.FOM_RILN=[];

1536

output_args.FOM_RILN=[];

1526

output_args.FOM_ILD=[];

1537

output_args.FOM_ILD=[];

1527

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

1538

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

1528

if ~OP.GET_FD

1539

if ~OP.GET_FD

1529

return;

1540

return;

1530

end

1541

end

1531

case_number=param.package_testcase_i;

1542

case_number=param.package_testcase_i;

1532

f2=param.f2;

1543

f2=param.f2;

1533

f1=param.f1;

1544

f1=param.f1;

1534

MDFEXT_ICN=0; MDNEXT_ICN=0;

1545

MDFEXT_ICN=0; MDNEXT_ICN=0;

1535

for i=1:param.number_of_s4p_files

1546

for i=1:param.number_of_s4p_files

1536

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1547

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1537

% Equation 93A-20 %%

1548

% Equation 93A-20 %%

1538

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

1549

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

1539

f=chdata(i).faxis;

1550

f=chdata(i).faxis;

1540

%

1551

%

1541

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

1552

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

1542

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

1553

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

1543

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

1554

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

1544

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

1555

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

1545

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

1556

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

1546

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

1557

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

1547

if OP.DISPLAY_WINDOW

1558

if OP.DISPLAY_WINDOW

1548

if i==1

1559

if i==1

1549

figure(300+param.package_testcase_i);

1560

figure(300+param.package_testcase_i);

1550

subplot(3,1,1)

1561

subplot(3,1,1)

1551

hold on

1562

hold on

1552

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

1563

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

1553

try

1564

try

1554

legend('NumColumns',2)

1565

legend('NumColumns',2)

1555

legend('location','south')

1566

legend('location','south')

1556

catch

1567

catch

1557

end

1568

end

1558

end

1569

end

1559

end

1570

end

1560

end

1571

end

1561

end

1572

end

1562

for i=1:param.number_of_s4p_files

1573

for i=1:param.number_of_s4p_files

1563

if i == 2

1574

if i == 2

1564

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

1575

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

1565

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

1576

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

1566

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

1577

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

1567

end

1578

end

1568

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

1579

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

1569

if isempty(a)

1580

if isempty(a)

1570

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

1581

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

1571

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

1582

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

1572

else

1583

else

1573

index_f2=a(1);

1584

index_f2=a(1);

1574

end

1585

end

1575

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

1586

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

1576

if isempty(b)

1587

if isempty(b)

1577

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

1588

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

1578

index_f1=1;

1589

index_f1=1;

1579

else

1590

else

1580

index_f1=b(1);

1591

index_f1=b(1);

1581

end

1592

end

1582

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

1593

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

1583

% PWF for ICN

1594

% PWF for ICN

1584

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

1595

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

1585

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

1596

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

1586

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

1597

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

1587

end

1598

end

1588

SINC = sin(temp_angle)./temp_angle;

1599

SINC = sin(temp_angle)./temp_angle;

1589

PWF_data=SINC.^2;

1600

PWF_data=SINC.^2;

1590

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

1601

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

1591

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

1602

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

1592

fr=param.f_r*param.fb;

1603

fr=param.f_r*param.fb;

1593

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

1604

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

1594

PWF_highpass=1;

1605

PWF_highpass=1;

1595

% Equation 93A-57 %

1606

% Equation 93A-57 %

1596

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

1607

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

1597

% freq delta for integration

1608

% freq delta for integration

1598

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

1609

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

1599

% from ba spec, this is basically ICN

1610

% from ba spec, this is basically ICN

1600

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

1611

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

1601

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

1612

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

1602

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

1613

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

1603

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

1614

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

1604

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

1615

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

1605

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

1616

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

1606

chdata(i).fit_ILatNq = fit_loss;

1617

chdata(i).fit_ILatNq = fit_loss;

1607

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1618

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1608

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

1619

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

1609

chdata(i).ILatNq = IL_interp;

1620

chdata(i).ILatNq = IL_interp;

1610

if OP.include_pcb

1621

if OP.include_pcb

1611

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

1622

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

1612

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

1623

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

1613

output_args.cable__assembley_loss=cable_loss;

1624

output_args.cable__assembley_loss=cable_loss;

1614

output_args.loss_with_PCB=loss_with_PCB;

1625

output_args.loss_with_PCB=loss_with_PCB;

1615

end

1626

end

1616

Nq_loss=chdata(i).ILatNq;

1627

Nq_loss=chdata(i).ILatNq;

1617

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1628

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1618

% time domain ref RR = complex fit pulse

1629

% time domain ref RR = complex fit pulse

1619

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1630

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1620

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

1631

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

1621

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1632

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1622

FOM_ILN_complex= TD_ILN.FOM;

1633

FOM_ILN_complex= TD_ILN.FOM;

1623

end

1634

end

1624

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1635

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1625

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

1636

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

1626

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1637

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1627

FOM_ILN_complex= TD_ILN.FOM;

1638

FOM_ILN_complex= TD_ILN.FOM;

1628

end

1639

end

1629

if OP.COMPUTE_TDILN

1640

if OP.COMPUTE_TDILN

1630

output_args.FOM_TDILN=FOM_TDILN;

1641

output_args.FOM_TDILN=FOM_TDILN;

1631

output_args.TD_ILN=TD_ILN; % struct

1642

output_args.TD_ILN=TD_ILN; % struct

1632

end

1643

end

1633

if OP.COMPUTE_RILN

1644

if OP.COMPUTE_RILN

1634

% Get RIL, RILN, and TD_RILN

1645

% Get RIL, RILN, and TD_RILN

1635

[RIL_struct]= capture_RIL_RILN(chdata);

1646

[RIL_struct]= capture_RIL_RILN(chdata);

1636

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

1647

FOM_RILN=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2-1).*RIL_struct.RILN_dB(index_f1:index_f2-1)'.^2));

1637

output_args.FOM_RILN=FOM_RILN;

1648

output_args.FOM_RILN=FOM_RILN;

1638

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

1649

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

1639

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

1650

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

1640

if plot_tdomain_debug== 1

1651

if plot_tdomain_debug== 1

1641

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

1652

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

1642

ax_1= subplot(3,1,1);

1653

ax_1= subplot(3,1,1);

1643

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

1654

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

1644

hold on;

1655

hold on;

1645

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

1656

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

1646

hold on;

1657

hold on;

1647

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

1658

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

1648

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

1659

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

1649

grid on;

1660

grid on;

1650

box on;

1661

box on;

1651

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

1662

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

1652

xlabel('Time [nsec]');

1663

xlabel('Time [nsec]');

1653

ylabel('Pulse Response [mV]');

1664

ylabel('Pulse Response [mV]');

1654

1665

1655

ax_2= subplot(3,1,2);

1666

ax_2= subplot(3,1,2);

1656

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

1667

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

1657

hold on;

1668

hold on;

1658

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

1669

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

1659

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

1670

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

1660

grid on;

1671

grid on;

1661

box on;

1672

box on;

1662

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

1673

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

1663

xlabel('Time [nsec]');

1674

xlabel('Time [nsec]');

1664

ylabel('Pulse Response [mV]');

1675

ylabel('Pulse Response [mV]');

1665

ax_3= subplot(3,1,3);

1676

ax_3= subplot(3,1,3);

1666

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

1677

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

1667

hold on;

1678

hold on;

1668

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

1679

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

1669

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

1680

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

1670

grid on;

1681

grid on;

1671

box on;

1682

box on;

1672

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

1683

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

1673

xlabel('Time [nsec]');

1684

xlabel('Time [nsec]');

1674

ylabel('Pulse Response [mV]');

1685

ylabel('Pulse Response [mV]');

1675

1686

1676

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

1687

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

1677

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1688

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1678

end

1689

end

1679

%---end. plotting ILN based on ILD and RILN

1690

%---end. plotting ILN based on ILD and RILN

1680

end

1691

end

1681

% Equation 93A-56 %

1692

% Equation 93A-56 %

1682

FOM_ILD=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1693

FOM_ILD=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1683

output_args.FOM_ILD=FOM_ILD;

1694

output_args.FOM_ILD=FOM_ILD;

1684

if OP.DEBUG

1695

if OP.DEBUG

1685

if OP.DISPLAY_WINDOW

1696

if OP.DISPLAY_WINDOW

1686

figure(300+case_number);

1697

figure(300+case_number);

1687

set(gcf,'Tag','COM')

1698

set(gcf,'Tag','COM')

1688

screen_size=get(0,'ScreenSize');

1699

screen_size=get(0,'ScreenSize');

1689

pos = get(gcf, 'OuterPosition');

1700

pos = get(gcf, 'OuterPosition');

1690

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1701

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1691

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

1702

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

1692

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

1703

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

1693

subplot(3,1,1)

1704

subplot(3,1,1)

1694

title('Losses')

1705

title('Losses')

1695

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1706

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1696

hold on

1707

hold on

1697

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1708

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1698

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1709

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1699

ylim(get(gca, 'ylim'));

1710

ylim(get(gca, 'ylim'));

1700

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1711

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1701

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1712

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1702

subplot(3,1,3)

1713

subplot(3,1,3)

1703

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1714

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1704

if OP.PLOT_CM

1715

if OP.PLOT_CM

1705

if case_number ==1

1716

if case_number ==1

1706

h350=figure(350);set(gcf,'Tag','COM')

1717

h350=figure(350);set(gcf,'Tag','COM')

1707

screen_size=get(0,'ScreenSize');

1718

screen_size=get(0,'ScreenSize');

1708

pos = get(gcf, 'OuterPosition');

1719

pos = get(gcf, 'OuterPosition');

1709

set(gcf, 'OuterPosition',screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-2 -2 2 1])

1720

set(gcf, 'OuterPosition',screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-2 -2 2 1])

1710

movegui(gcf,'center');

1721

movegui(gcf,'center');

1711

htabgroup350 = uitabgroup(h350);

1722

htabgroup350 = uitabgroup(h350);

1712

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1723

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1713

hax1 = axes('Parent', htab1);

1724

hax1 = axes('Parent', htab1);

1714

set(h350,'CurrentAxes',hax1)

1725

set(h350,'CurrentAxes',hax1)

1715

hold on

1726

hold on

1716

set(gcf,'Tag','COM')

1727

set(gcf,'Tag','COM')

1717

screen_size=get(0,'ScreenSize');

1728

screen_size=get(0,'ScreenSize');

1718

pos = get(gcf, 'OuterPosition');

1729

pos = get(gcf, 'OuterPosition');

1719

title('IL & CM Losses')

1730

title('IL & CM Losses')

1720

base=strrep(chdata(i).base,'_',' ');

1731

base=strrep(chdata(i).base,'_',' ');

1721

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp', [ 'sdd21(IL) TP0-TP5 ' base])

1732

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp', [ 'sdd21(IL) TP0-TP5 ' base])

1722

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1733

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1723

ylabel('dB')

1734

ylabel('dB')

1724

xlabel('GHz')

1735

xlabel('GHz')

1725

legend show

1736

legend show

1726

legend('Location','eastoutside')

1737

legend('Location','eastoutside')

1727

hold on

1738

hold on

1728

grid on

1739

grid on

1729

if param.number_of_s4p_files > 1

1740

if param.number_of_s4p_files > 1

1730

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1741

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1731

hax2 = axes('Parent', htab2);

1742

hax2 = axes('Parent', htab2);

1732

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1743

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1733

hax3 = axes('Parent', htab3);

1744

hax3 = axes('Parent', htab3);

1734

end

1745

end

1735

1746

1736

end

1747

end

1737

end

1748

end

1738

else

1749

else

1739

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1750

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1740

end

1751

end

1741

end

1752

end

1742

else % NEXT or FEXT

1753

else % NEXT or FEXT

1743

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

1754

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

1744

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1755

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1745

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

1756

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46

1746

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1757

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1747

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

1758

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

1748

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1759

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1749

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

1760

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47

1750

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1761

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1751

end

1762

end

1752

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1763

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1753

ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));

1764

ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));

1754

output_args.ICN_mV=ICN*1000;

1765

output_args.ICN_mV=ICN*1000;

1755

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1766

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1756

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1767

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1757

if case_number ==1

1768

if case_number ==1

1758

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1769

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1759

% hax2 = axes('Parent', htab2);

1770

% hax2 = axes('Parent', htab2);

1760

set(h350,'CurrentAxes',hax2)

1771

set(h350,'CurrentAxes',hax2)

1761

hold on

1772

hold on

1762

title('CM Losses')

1773

title('CM Losses')

1763

base=strrep(chdata(i).base,'_',' ');

1774

base=strrep(chdata(i).base,'_',' ');

1764

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1775

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1765

legend('Location','eastoutside')

1776

legend('Location','eastoutside')

1766

hold on

1777

hold on

1767

grid on

1778

grid on

1768

set(h350,'CurrentAxes',hax3)

1779

set(h350,'CurrentAxes',hax3)

1769

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1780

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1770

legend('Location','eastoutside')

1781

legend('Location','eastoutside')

1771

hold on

1782

hold on

1772

grid on

1783

grid on

1773

end

1784

end

1774

end

1785

end

1775

end

1786

end

1776

end % for loop

1787

end % for loop

1777

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1788

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1778

if OP.DEBUG && OP.DISPLAY_WINDOW

1789

if OP.DEBUG && OP.DISPLAY_WINDOW

1779

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

1790

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

1780

if param.number_of_s4p_files > 1

1791

if param.number_of_s4p_files > 1

1781

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1792

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1782

subplot(3,1,1)

1793

subplot(3,1,1)

1783

hold on

1794

hold on

1784

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1795

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1785

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1796

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1786

subplot(3,1,2)

1797

subplot(3,1,2)

1787

grid on

1798

grid on

1788

ILtemp=20*log10(abs(chdata(1).sdd21f));

1799

ILtemp=20*log10(abs(chdata(1).sdd21f));

1789

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1800

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1790

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1801

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1791

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1802

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1792

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1803

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1793

hold on

1804

hold on

1794

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1805

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1795

end

1806

end

1796

subplot(3,1,1)

1807

subplot(3,1,1)

1797

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1808

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1798

grid on; legend show

1809

grid on; legend show

1799

subplot(3,1,2)

1810

subplot(3,1,2)

1800

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1811

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1801

ylim([0 80])

1812

ylim([0 80])

1802

xlim([.1 100])

1813

xlim([.1 100])

1803

grid on; %legend show

1814

grid on; %legend show

1804

subplot(3,1,3)

1815

subplot(3,1,3)

1805

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1816

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1806

ylim([-3 3])

1817

ylim([-3 3])

1807

grid on; legend show

1818

grid on; legend show

1808

end

1819

end

1809

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

1820

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

1810

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

1821

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

1811

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

1822

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

1812

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

1823

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

1813

output_args.VTF_loss_dB_at_Fnq=total_loss;

1824

output_args.VTF_loss_dB_at_Fnq=total_loss;

1814

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1825

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1815

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1826

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1816

function [ V0 ] = FFE( C , cmx,spui, V )

1827

function [ V0 ] = FFE( C , cmx,spui, V )

1817

% C FFE taps

1828

% C FFE taps

1818

% cmx number of precursors taps

1829

% cmx number of precursors taps

1819

% spui samples per ui

1830

% spui samples per ui

1820

% V input signal

1831

% V input signal

1821

%speed ups implemented:

1832

%speed ups implemented:

1822

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1833

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1823

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1834

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1824

1835

1825

V0=0;

1836

V0=0;

1826

if iscolumn(V); V=V.';end

1837

if iscolumn(V); V=V.';end

1827

for i=1:length(C)

1838

for i=1:length(C)

1828

if C(i)~=0

1839

if C(i)~=0

1829

ishift=(i-1-cmx)*spui;

1840

ishift=(i-1-cmx)*spui;

1830

V0=circshift(V',[ishift,0])*C(i)+V0;

1841

V0=circshift(V',[ishift,0])*C(i)+V0;

1831

end

1842

end

1832

end

1843

end

1833

%V0=circshift(V0,[(-cmx)*spui,0]);

1844

%V0=circshift(V0,[(-cmx)*spui,0]);

1834

% disp(max(V0));

1845

% disp(max(V0));

1835

1846

1836

1847

1837

% begin yasuo patch 12/11/2018

1848

% begin yasuo patch 12/11/2018

1838

% calculate sigma (standard deviation) value of PDF

1849

% calculate sigma (standard deviation) value of PDF

1839

function [ V0 ] = FFE_Fast( C,V_shift )

1850

function [ V0 ] = FFE_Fast( C,V_shift )

1840

% C FFE taps

1851

% C FFE taps

1841

% V input signal separated into length(C) columns with circshift already performed

1852

% V input signal separated into length(C) columns with circshift already performed

1842

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1853

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1843

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1854

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1844

% saved by pre-shifting it and remembering it across loops

1855

% saved by pre-shifting it and remembering it across loops

1845

% Another speed up: only multiply by indices of C that are not 0

1856

% Another speed up: only multiply by indices of C that are not 0

1846

1857

1847

V0=0;

1858

V0=0;

1848

for i=1:length(C)

1859

for i=1:length(C)

1849

if C(i)~=0

1860

if C(i)~=0

1850

V0=V_shift(:,i)*C(i)+V0;

1861

V0=V_shift(:,i)*C(i)+V0;

1851

end

1862

end

1852

end

1863

end

1853

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1864

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1854

1865

1855

hisi=h(isi_start:isi_end);

1866

hisi=h(isi_start:isi_end);

1856

hisi=hisi(param.N_tail_start:param.N_bmax);

1867

hisi=hisi(param.N_tail_start:param.N_bmax);

1857

bank_size = param.N_bf;

1868

bank_size = param.N_bf;

1858

num_groups = param.N_bg;

1869

num_groups = param.N_bg;

1859

1870

1860

1871

1861

%start with one by one Floating Tap

1872

%start with one by one Floating Tap

1862

num_isi=length(hisi);

1873

num_isi=length(hisi);

1863

max_isi=num_isi-bank_size+1;

1874

max_isi=num_isi-bank_size+1;

1864

valid_tap_locations=1:max_isi;

1875

valid_tap_locations=1:max_isi;

1865

all_idx=[];

1876

all_idx=[];

1866

for j=1:num_groups

1877

for j=1:num_groups

1867

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1878

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1868

for k=1:length(valid_tap_locations)

1879

for k=1:length(valid_tap_locations)

1869

this_location=valid_tap_locations(k);

1880

this_location=valid_tap_locations(k);

1870

new_idx = [all_idx this_location:this_location+bank_size-1];

1881

new_idx = [all_idx this_location:this_location+bank_size-1];

1871

new_idx=sort(new_idx);

1882

new_idx=sort(new_idx);

1872

new_idx = new_idx+param.N_tail_start-1;

1883

new_idx = new_idx+param.N_tail_start-1;

1873

%calculate FOM for each one

1884

%calculate FOM for each one

1874

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1885

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1875

end

1886

end

1876

%choose the location with best FOM

1887

%choose the location with best FOM

1877

%add it to the "all_idx" list and remove it from valid locations

1888

%add it to the "all_idx" list and remove it from valid locations

1878

[~,best_FOM_idx]=max(best_FOM);

1889

[~,best_FOM_idx]=max(best_FOM);

1879

start_tap = valid_tap_locations(best_FOM_idx);

1890

start_tap = valid_tap_locations(best_FOM_idx);

1880

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1891

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1881

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1892

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1882

remove_range(remove_range>length(valid_tap_locations))=[];

1893

remove_range(remove_range>length(valid_tap_locations))=[];

1883

valid_tap_locations(remove_range)=[];

1894

valid_tap_locations(remove_range)=[];

1884

1895

1885

%Also remove illegal taps from valid locations

1896

%Also remove illegal taps from valid locations

1886

%illegal taps are ones that would overlap with the chosen bank

1897

%illegal taps are ones that would overlap with the chosen bank

1887

bad_tap=start_tap-bank_size+1:start_tap-1;

1898

bad_tap=start_tap-bank_size+1:start_tap-1;

1888

bad_tap(bad_tap<1)=[];

1899

bad_tap(bad_tap<1)=[];

1889

for n=1:length(bad_tap)

1900

for n=1:length(bad_tap)

1890

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1901

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1891

if ~isempty(bad_tap_idx)

1902

if ~isempty(bad_tap_idx)

1892

valid_tap_locations(bad_tap_idx)=[];

1903

valid_tap_locations(bad_tap_idx)=[];

1893

end

1904

end

1894

end

1905

end

1895

end

1906

end

1896

1907

1897

%put idx back in the right location (adding N_tail_start)

1908

%put idx back in the right location (adding N_tail_start)

1898

idx = all_idx+param.N_tail_start-1;

1909

idx = all_idx+param.N_tail_start-1;

1899

idx = sort(idx);

1910

idx = sort(idx);

1900

function [ V0 ] = Fract_T_FFE( V , skew_step)

1911

function [ V0 ] = Fract_T_FFE( V , skew_step)

1901

% skew_step sub UI skew assuming param.samples_per_ui

1912

% skew_step sub UI skew assuming param.samples_per_ui

1902

% V input signal

1913

% V input signal

1903

% V0 output signal

1914

% V0 output signal

1904

% Richard Mellitz 8/17/2021

1915

% Richard Mellitz 8/17/2021

1905

V0=0;

1916

V0=0;

1906

if iscolumn(V); V=V.';end

1917

if iscolumn(V); V=V.';end

1907

ishift=skew_step;

1918

ishift=skew_step;

1908

V0=circshift(V',[ishift,0])'+V;

1919

V0=circshift(V',[ishift,0])'+V;

1909

V0=V0/2;

1920

V0=V0/2;

1910

function out=Full_Grid_Matrix(in)

1921

function out=Full_Grid_Matrix(in)

1911

1922

1912

%create a full grid matrix of input variables

1923

%create a full grid matrix of input variables

1913

%used to create the full grid of all txffe cases

1924

%used to create the full grid of all txffe cases

1914

%example:

1925

%example:

1915

%Full_Grid_Matrix({ [1 2] [100 200] })

1926

%Full_Grid_Matrix({ [1 2] [100 200] })

1916

%out =

1927

%out =

1917

% 1 100

1928

% 1 100

1918

% 1 200

1929

% 1 200

1919

% 2 100

1930

% 2 100

1920

% 2 200

1931

% 2 200

1921

%

1932

%

1922

%input can also be mixed between numeric and cell of char

1933

%input can also be mixed between numeric and cell of char

1923

%example:

1934

%example:

1924

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1935

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1925

%out =

1936

%out =

1926

% {[1]} {'A'}

1937

% {[1]} {'A'}

1927

% {[1]} {'B'}

1938

% {[1]} {'B'}

1928

% {[2]} {'A'}

1939

% {[2]} {'A'}

1929

% {[2]} {'B'}

1940

% {[2]} {'B'}

1930

1941

1931

if ~iscell(in)

1942

if ~iscell(in)

1932

error('input must be cell array of individual sweep variables');

1943

error('input must be cell array of individual sweep variables');

1933

end

1944

end

1934

1945

1935

num_columns=length(in);

1946

num_columns=length(in);

1936

num_cases=prod(cellfun('length',in));

1947

num_cases=prod(cellfun('length',in));

1937

1948

1938

cell_output=0;

1949

cell_output=0;

1939

cell_indices=cellfun(@(x) iscell(x),in);

1950

cell_indices=cellfun(@(x) iscell(x),in);

1940

if any(cell_indices)

1951

if any(cell_indices)

1941

cell_output=1;

1952

cell_output=1;

1942

end

1953

end

1943

if cell_output

1954

if cell_output

1944

for k=find(~cell_indices)

1955

for k=find(~cell_indices)

1945

in{k}=num2cell(in{k});

1956

in{k}=num2cell(in{k});

1946

end

1957

end

1947

end

1958

end

1948

1959

1949

if cell_output

1960

if cell_output

1950

out=cell(num_cases,num_columns);

1961

out=cell(num_cases,num_columns);

1951

else

1962

else

1952

out=zeros(num_cases,num_columns);

1963

out=zeros(num_cases,num_columns);

1953

end

1964

end

1954

1965

1955

%num_repetitions controls how many times each element of the column

1966

%num_repetitions controls how many times each element of the column

1956

%repeats. The first column is always just a copy of itself since every

1967

%repeats. The first column is always just a copy of itself since every

1957

%case will vary.

1968

%case will vary.

1958

num_repetitions=1;

1969

num_repetitions=1;

1959

for k=num_columns:-1:1

1970

for k=num_columns:-1:1

1960

this_column=in{k}(:);

1971

this_column=in{k}(:);

1961

%copy the column into a matrix to create the repetitions needed

1972

%copy the column into a matrix to create the repetitions needed

1962

B=repmat(this_column,[1 num_repetitions]);

1973

B=repmat(this_column,[1 num_repetitions]);

1963

%reshape into single column (actual repetitions)

1974

%reshape into single column (actual repetitions)

1964

C=reshape(B',[numel(B) 1]);

1975

C=reshape(B',[numel(B) 1]);

1965

%repeat the single column to build the entire length required

1976

%repeat the single column to build the entire length required

1966

num_repeats=num_cases/length(C);

1977

num_repeats=num_cases/length(C);

1967

D=repmat(C,[num_repeats 1]);

1978

D=repmat(C,[num_repeats 1]);

1968

out(:,k)=D;

1979

out(:,k)=D;

1969

%determine how many repetitions the next column needs

1980

%determine how many repetitions the next column needs

1970

num_repetitions=num_repetitions*length(this_column);

1981

num_repetitions=num_repetitions*length(this_column);

1971

end

1982

end

1972

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1983

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1973

% p=cpdf(type, ...)

1984

% p=cpdf(type, ...)

1974

%

1985

%

1975

% CPDF is a probability mass function for discrete distributions or an

1986

% CPDF is a probability mass function for discrete distributions or an

1976

% approxmation of a PDF for continuous distributions.

1987

% approxmation of a PDF for continuous distributions.

1977

%

1988

%

1978

% cpdf is internally normalized so that the sum of probabilities is 1

1989

% cpdf is internally normalized so that the sum of probabilities is 1

1979

% (regardless of bin size).

1990

% (regardless of bin size).

1980

1991

1981

% Internal fields:

1992

% Internal fields:

1982

% Min: *bin number* of minimum value.

1993

% Min: *bin number* of minimum value.

1983

% BinSize: size of PDF bins. Bin center is the representative value.

1994

% BinSize: size of PDF bins. Bin center is the representative value.

1984

% Vec: vector of probabilities per bin.

1995

% Vec: vector of probabilities per bin.

1985

1996

1986

pdf=EmptyPDF;

1997

pdf=EmptyPDF;

1987

1998

1988

rounded_values_div_binsize=round(values/pdf.BinSize);

1999

rounded_values_div_binsize=round(values/pdf.BinSize);

1989

%values=pdf.BinSize*rounded_values_div_binsize;

2000

%values=pdf.BinSize*rounded_values_div_binsize;

1990

2001

1991

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2002

% %speed up for small values round to 0 (because they are all much smaller than binsize)

1992

% if all(values==0)

2003

% if all(values==0)

1993

% return;

2004

% return;

1994

% end

2005

% end

1995

%

2006

%

1996

% %speed up for all values rounded to the same bin

2007

% %speed up for all values rounded to the same bin

1997

% %The output pdf is the same as the

2008

% %The output pdf is the same as the

1998

% %empty pdf, but the x value is non-zero (but still scalar)

2009

% %empty pdf, but the x value is non-zero (but still scalar)

1999

% if all(values==values(1))

2010

% if all(values==values(1))

2000

% pdf.Min=rounded_values_div_binsize(1);

2011

% pdf.Min=rounded_values_div_binsize(1);

2001

% pdf.x=values(1);

2012

% pdf.x=values(1);

2002

% return;

2013

% return;

2003

% end

2014

% end

2004

%

2015

%

2005

% %The code below requires that values is

2016

% %The code below requires that values is

2006

% %sorted. Generally this should be true, but check to be sure

2017

% %sorted. Generally this should be true, but check to be sure

2007

% if ~issorted(values)

2018

% if ~issorted(values)

2008

% [values,si]=sort(values);

2019

% [values,si]=sort(values);

2009

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2020

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2010

% probs=probs(si);

2021

% probs=probs(si);

2011

% end

2022

% end

2012

2023

2013

2024

2014

%pdf.x=values(1):pdf.BinSize:values(end);

2025

%pdf.x=values(1):pdf.BinSize:values(end);

2015

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2026

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2016

pdf.Min=rounded_values_div_binsize(1);

2027

pdf.Min=rounded_values_div_binsize(1);

2017

2028

2018

pdf.y=zeros(size(pdf.x));

2029

pdf.y=zeros(size(pdf.x));

2019

%The rounded values divided by binsize will reveal the bin number if

2030

%The rounded values divided by binsize will reveal the bin number if

2020

%pdf.Min is subtracted from it

2031

%pdf.Min is subtracted from it

2021

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2032

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2022

%Can avoid one addition by inserting the first probability

2033

%Can avoid one addition by inserting the first probability

2023

%actually helps when calling this 2 million times

2034

%actually helps when calling this 2 million times

2024

pdf.y(bin_placement(1))=probs(1);

2035

pdf.y(bin_placement(1))=probs(1);

2025

for k=2:length(values)

2036

for k=2:length(values)

2026

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2037

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2027

end

2038

end

2028

2039

2029

2040

2030

%Have already ensured that sum(pdf.y)=1

2041

%Have already ensured that sum(pdf.y)=1

2031

%pdf.y=pdf.y/sum(pdf.y);

2042

%pdf.y=pdf.y/sum(pdf.y);

2032

2043

2033

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2044

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2034

% error('PDF must be real and nonnegative');

2045

% error('PDF must be real and nonnegative');

2035

% end

2046

% end

2036

2047

2037

% pMax=pdf.Min+length(pdf.y)-1;

2048

% pMax=pdf.Min+length(pdf.y)-1;

2038

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2049

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2039

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2050

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2040

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2051

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2041

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2052

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2042

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2053

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2043

2054

2044

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2055

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2045

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2056

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2046

2057

2047

%% step 0

2058

%% step 0

2048

COM_from_matlab=20*log10(A_s/A_ni);

2059

COM_from_matlab=20*log10(A_s/A_ni);

2049

L=param.levels;

2060

L=param.levels;

2050

DER0=param.specBER;

2061

DER0=param.specBER;

2051

%% step 1 from slide 6/5

2062

%% step 1 from slide 6/5

2052

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2063

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2053

main=A_peak;

2064

main=A_peak;

2054

k_DER=qfuncinv(param.specBER);

2065

k_DER=qfuncinv(param.specBER);

2055

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2066

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2056

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2067

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2057

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2068

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2058

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2069

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2059

if A_s >= A_ni

2070

if A_s >= A_ni

2060

%% step 2 slide 10/8

2071

%% step 2 slide 10/8

2061

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2072

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2062

%% step 2 slide 10/8

2073

%% step 2 slide 10/8

2063

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2074

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2064

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2075

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2065

%% step 3 side 11/9

2076

%% step 3 side 11/9

2066

j=1:200;

2077

j=1:200;

2067

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2078

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2068

DER_MLSE_CDF=0; jj=1;

2079

DER_MLSE_CDF=0; jj=1;

2069

DER_delta = inf;

2080

DER_delta = inf;

2070

while DER_delta > .001

2081

while DER_delta > .001

2071

last_DER_MLSE_CDF=DER_MLSE_CDF;

2082

last_DER_MLSE_CDF=DER_MLSE_CDF;

2072

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;

2083

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2073

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2084

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2074

jj=jj+1;

2085

jj=jj+1;

2075

end

2086

end

2076

%% step 4 slide 12/10

2087

%% step 4 slide 12/10

2077

SNR_DFE_eqivalent=SNR_DFE*(...

2088

SNR_DFE_eqivalent=SNR_DFE*(...

2078

(L-1)*sigma_noise/main * qfuncinv(...

2089

(L-1)*sigma_noise/main * qfuncinv(...

2079

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2090

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2080

) ...

2091

) ...

2081

)^2;

2092

)^2;

2082

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2093

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2083

(L-1)/main * CDF_inv_ev(...

2094

(L-1)/main * CDF_inv_ev(...

2084

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2095

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2085

,PDF, CDF ) ...

2096

,PDF, CDF ) ...

2086

)^2;

2097

)^2;

2087

2098

2088

%% step 5 slide 13/11

2099

%% step 5 slide 13/11

2089

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2100

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2090

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2101

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2091

new_com_CDF=COM_from_matlab+delta_com_CDF;

2102

new_com_CDF=COM_from_matlab+delta_com_CDF;

2092

else

2103

else

2093

warning('MLSE not applied because there is more noise than signal')

2104

warning('MLSE not applied because there is more noise than signal')

2094

DER_MLSE=[];

2105

DER_MLSE=[];

2095

DER_MLSE_CDF=[];

2106

DER_MLSE_CDF=[];

2096

SNR_DFE_eqivalent=[];

2107

SNR_DFE_eqivalent=[];

2097

SNR_DFE_eqivalent_CDF=[];

2108

SNR_DFE_eqivalent_CDF=[];

2098

new_com_CDF=COM_from_matlab;

2109

new_com_CDF=COM_from_matlab;

2099

delta_com_CDF=0;

2110

delta_com_CDF=0;

2100

delta_com=0;

2111

delta_com=0;

2101

SNR_DFE=[];

2112

SNR_DFE=[];

2102

end

2113

end

2103

2114

+2115

%%

2116

MLSE_results.COM_from_matlab=COM_from_matlab;

2117

MLSE_results.SNR_DFE=SNR_DFE;

2118

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2119

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2120

MLSE_results.sigma_noise=sigma_noise;

2121

MLSE_results.SNR_dB=SNR_dB ;

2122

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2123

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2124

MLSE_results.COM_Gaussian=new_com_CDF;

2125

MLSE_results.COM_CDF=new_com_CDF;

2126

MLSE_results.k_DER=k_DER;

2127

MLSE_results.delta_com_CDF=delta_com_CDF;

2128

MLSE_results.delta_com_Gaussian=delta_com;

2129

2130

2131

2132

function [MLSE_results] = MLSE_U1_c(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2133

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2134

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2135

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2136

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2137

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2138

%% step 0

2139

COM_from_matlab=20*log10(A_s/A_ni);

2140

L=param.levels;

2141

DER0=param.specBER;

2142

%% step 1 from slide 6 shakiba_3dj_01_230116

2143

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2144

main=A_peak;

2145

k_DER=qfuncinv(param.specBER);

2146

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2147

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2148

% if A_s >= A_ni

2149

if 1

2150

%% step 2 slide 10 shakiba_3dj_01_230116

2151

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2152

%% step 2 slide 10 not used

2153

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2154

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2155

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2156

S_n=PSD_results.Sn_rho; % total agregate noise PSD

2157

Rn=ifft(S_n)*param.fb;

2158

Rho_row=Rn/Rn(1);

2159

Rn_len=length(Rn);

2160

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2161

for j=1:Rn_len

2162

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2163

end

2164

rho_noiseEE_row=Rho_row.*alphas_row;

2165

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2166

for j=1:Rn_len

2167

rho_noiseEE(j,j)=(1-alpha)^2;

2168

end

2169

rho_noiseEE(1,1)=1;

2170

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2171

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2172

% determine complete matrix

2173

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2174

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2175

%% shakiba_3dj_elec_01a_230504 slide 17

2176

j=1:Rn_len;

2177

DER_MLSE=[];

2178

DER_MLSE_CDF=0; jj=1;

2179

DER_MLSE_CDFold=0;

2180

DER_delta = inf;

2181

% slight modified for PAM4 DER vs SER

2182

while DER_delta > .0001 && jj<=Rn_len || jj==1

2183

last_DER_MLSE_CDF=DER_MLSE_CDF;

2184

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2185

DER_MLSE_CDF= ...

2186

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2187

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2188

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2189

jj=jj+1;

2190

end

2191

%% shakiba_3dj_elec_01a_230504 slide 19

2192

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2193

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2194

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2195

(L-1)/main * CDF_inv_ev(...

2196

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2197

,PDF, CDF ) ...

2198

)^2;

2199

%% step 5 shakiba_3dj_01_230116 slide 13

2200

delta_com=[];

2201

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2202

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2203

new_com_CDF=COM_from_matlab+delta_com_CDF;

2204

else

2205

warning('MLSE not applied because there is more noise than signal')

2206

DER_MLSE=[];

2207

DER_MLSE_CDF=[];

2208

SNR_DFE_eqivalent=[];

2209

SNR_DFE_eqivalent_CDF=[];

2210

new_com_CDF=COM_from_matlab;

2211

delta_com_CDF=0;

2212

delta_com=0;

2213

SNR_DFE=[];

2214

end

2215

SNR_DFE_eqivalent=[];

2104

%%

2216

%%

2105

MLSE_results.COM_from_matlab=COM_from_matlab;

2217

MLSE_results.COM_from_matlab=COM_from_matlab;

2106

MLSE_results.SNR_DFE=SNR_DFE;

2218

MLSE_results.SNR_DFE=SNR_DFE;

2107

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2219

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2108

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2220

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2109

MLSE_results.sigma_noise=sigma_noise;

2221

MLSE_results.sigma_noise=sigma_noise;

2110

MLSE_results.SNR_dB=SNR_dB ;

2222

MLSE_results.SNR_dB=SNR_dB ;

2111

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2223

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2112

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2224

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2113

MLSE_results.COM_Gaussian=new_com_CDF;

2225

MLSE_results.COM_Gaussian=new_com_CDF;

2114

MLSE_results.COM_CDF=new_com_CDF;

2226

MLSE_results.COM_CDF=new_com_CDF;

2115

MLSE_results.k_DER=k_DER;

2227

MLSE_results.k_DER=k_DER;

2116

MLSE_results.delta_com_CDF=delta_com_CDF;

2228

MLSE_results.delta_com_CDF=delta_com_CDF;

2117

MLSE_results.delta_com_Gaussian=delta_com;

2229

MLSE_results.delta_com_Gaussian=delta_com;

2118

2230

2119

2231

2120

2232

2121

function [MLSE_results] = MLSE_U3(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2233

function [MLSE_results] = MLSE_U3(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2122

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2234

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2123

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2235

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2124

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2236

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2125

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2237

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2126

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2238

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2127

%% step 0

2239

%% step 0

2128

COM_from_matlab=20*log10(A_s/A_ni);

2240

COM_from_matlab=20*log10(A_s/A_ni);

2129

L=param.levels;

2241

L=param.levels;

2130

DER0=param.specBER;

2242

DER0=param.specBER;

2131

%% step 1 from slide 6 shakiba_3dj_01_230116

2243

%% step 1 from slide 6 shakiba_3dj_01_230116

2132

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2244

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2133

main=A_peak;

2245

main=A_peak;

2134

k_DER=qfuncinv(param.specBER);

2246

k_DER=qfuncinv(param.specBER);

2135

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2247

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2136

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2248

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2137

% if A_s >= A_ni

2249

% if A_s >= A_ni

2138

if 1

2250

if 1

2139

%% step 2 slide 10 shakiba_3dj_01_230116

2251

%% step 2 slide 10 shakiba_3dj_01_230116

2140

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2252

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2141

%% step 2 slide 10 not used

2253

%% step 2 slide 10 not used

2142

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2254

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2143

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2255

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2144

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2256

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2145

S_n=PSD_results.S_n; % total agregate noise PSD

2257

S_n=PSD_results.S_n; % total agregate noise PSD

2146

Rn=ifft(S_n)*param.fb;

2258

Rn=ifft(S_n)*param.fb;

2147

Rho_row=Rn/Rn(1);

2259

Rho_row=Rn/Rn(1);

2148

Rn_len=length(Rn);

2260

Rn_len=length(Rn);

2149

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2261

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2150

for j=1:Rn_len

2262

for j=1:Rn_len

2151

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2263

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2152

end

2264

end

2153

rho_noiseEE_row=Rho_row.*alphas_row;

2265

rho_noiseEE_row=Rho_row.*alphas_row;

2154

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2266

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2155

for j=1:Rn_len

2267

for j=1:Rn_len

2156

rho_noiseEE(j,j)=(1-alpha)^2;

2268

rho_noiseEE(j,j)=(1-alpha)^2;

2157

end

2269

end

2158

rho_noiseEE(1,1)=1;

2270

rho_noiseEE(1,1)=1;

2159

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2271

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2160

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2272

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2161

% determine complete matrix

2273

% determine complete matrix

2162

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2274

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2163

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2275

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2164

%% shakiba_3dj_elec_01a_230504 slide 17

2276

%% shakiba_3dj_elec_01a_230504 slide 17

2165

j=1:Rn_len;

2277

j=1:Rn_len;

2166

DER_MLSE=[];

2278

DER_MLSE=[];

2167

DER_MLSE_CDF=0; jj=1;

2279

DER_MLSE_CDF=0; jj=1;

2168

DER_MLSE_CDFold=0;

2280

DER_MLSE_CDFold=0;

2169

DER_delta = inf;

2281

DER_delta = inf;

2170

% slight modified for PAM4 DER vs SER

2282

% slight modified for PAM4 DER vs SER

2171

while DER_delta > .0001 && jj<=Rn_len || jj==1

2283

while DER_delta > .0001 && jj<=Rn_len || jj==1

2172

last_DER_MLSE_CDF=DER_MLSE_CDF;

2284

last_DER_MLSE_CDF=DER_MLSE_CDF;

2173

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2285

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2174

DER_MLSE_CDF= ...

2286

DER_MLSE_CDF= ...

2175

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;

2287

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2176

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;

2288

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2177

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2289

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2178

jj=jj+1;

2290

jj=jj+1;

2179

end

2291

end

2180

%% shakiba_3dj_elec_01a_230504 slide 19

2292

%% shakiba_3dj_elec_01a_230504 slide 19

2181

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2293

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2182

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2294

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2183

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2295

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2184

(L-1)/main * CDF_inv_ev(...

2296

(L-1)/main * CDF_inv_ev(...

2185

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2297

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2186

,PDF, CDF ) ...

2298

,PDF, CDF ) ...

2187

)^2;

2299

)^2;

2188

%% step 5 shakiba_3dj_01_230116 slide 13

2300

%% step 5 shakiba_3dj_01_230116 slide 13

2189

delta_com=[];

2301

delta_com=[];

2190

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2302

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2191

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2303

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2192

new_com_CDF=COM_from_matlab+delta_com_CDF;

2304

new_com_CDF=COM_from_matlab+delta_com_CDF;

2193

else

2305

else

2194

warning('MLSE not applied because there is more noise than signal')

2306

warning('MLSE not applied because there is more noise than signal')

2195

DER_MLSE=[];

2307

DER_MLSE=[];

2196

DER_MLSE_CDF=[];

2308

DER_MLSE_CDF=[];

2197

SNR_DFE_eqivalent=[];

2309

SNR_DFE_eqivalent=[];

2198

SNR_DFE_eqivalent_CDF=[];

2310

SNR_DFE_eqivalent_CDF=[];

2199

new_com_CDF=COM_from_matlab;

2311

new_com_CDF=COM_from_matlab;

2200

delta_com_CDF=0;

2312

delta_com_CDF=0;

2201

delta_com=0;

2313

delta_com=0;

2202

SNR_DFE=[];

2314

SNR_DFE=[];

2203

end

2315

end

2204

SNR_DFE_eqivalent=[];

2316

SNR_DFE_eqivalent=[];

2205

%%

2317

%%

2206

MLSE_results.COM_from_matlab=COM_from_matlab;

2318

MLSE_results.COM_from_matlab=COM_from_matlab;

2207

MLSE_results.SNR_DFE=SNR_DFE;

2319

MLSE_results.SNR_DFE=SNR_DFE;

2208

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2320

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2209

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2321

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2210

MLSE_results.sigma_noise=sigma_noise;

2322

MLSE_results.sigma_noise=sigma_noise;

2211

MLSE_results.SNR_dB=SNR_dB ;

2323

MLSE_results.SNR_dB=SNR_dB ;

2212

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2324

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2213

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2325

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2214

MLSE_results.COM_Gaussian=new_com_CDF;

2326

MLSE_results.COM_Gaussian=new_com_CDF;

2215

MLSE_results.COM_CDF=new_com_CDF;

2327

MLSE_results.COM_CDF=new_com_CDF;

2216

MLSE_results.k_DER=k_DER;

2328

MLSE_results.k_DER=k_DER;

2217

MLSE_results.delta_com_CDF=delta_com_CDF;

2329

MLSE_results.delta_com_CDF=delta_com_CDF;

2218

MLSE_results.delta_com_Gaussian=delta_com;

2330

MLSE_results.delta_com_Gaussian=delta_com;

2219

2331

2220

2332

2221

2333

2222

function [MLSE_results] = MLSE_instu(param,alpha,A_s,A_ni,PDF,CDF)

2334

function [MLSE_results] = MLSE_instu(param,alpha,A_s,A_ni,PDF,CDF)

2223

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2335

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2224

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2336

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2225

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2337

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2226

2338

2227

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2339

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2228

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2340

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2229

2341

2230

%% step 0

2342

%% step 0

2231

COM_from_matlab=20*log10(A_s/A_ni);

2343

COM_from_matlab=20*log10(A_s/A_ni);

2232

L=param.levels;

2344

L=param.levels;

2233

DER0=param.specBER;

2345

DER0=param.specBER;

2234

%% step 1 from slide 6/5

2346

%% step 1 from slide 6/5

2235

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2347

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2236

main=A_peak;

2348

main=A_peak;

2237

k_DER=qfuncinv(param.specBER);

2349

k_DER=qfuncinv(param.specBER);

2238

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2350

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2239

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2351

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2240

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2352

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2241

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2353

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2242

if A_s >= A_ni

2354

if A_s >= A_ni

2243

%% step 2 slide 10/8

2355

%% step 2 slide 10/8

2244

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2356

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2245

%% step 2 slide 10/8

2357

%% step 2 slide 10/8

2246

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

2358

snr_dfe = @(der,PDF,CDF) -10*log10((A_s./CDF_inv_ev(der,PDF,CDF)).^2)+10*log10((L^2-1)/3*qfuncinv(der).^2) ;

2247

2359

2248

%% step 3 side 11/9

2360

%% step 3 side 11/9

2249

j=1:200;

2361

j=1:200;

2250

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2362

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2251

DER_MLSE_CDF=0; jj=1;

2363

DER_MLSE_CDF=0; jj=1;

2252

DER_delta = inf;

2364

DER_delta = inf;

2253

while DER_delta > .001

2365

while DER_delta > .001

2254

last_DER_MLSE_CDF=DER_MLSE_CDF;

2366

last_DER_MLSE_CDF=DER_MLSE_CDF;

2255

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;

2367

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2256

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2368

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2257

jj=jj+1;

2369

jj=jj+1;

2258

end

2370

end

2259

%%

2371

%%

2260

dscale=.05;

2372

dscale=.05;

2261

scale=1;

2373

scale=1;

2262

last_scale_tune=inf;

2374

last_scale_tune=inf;

2263

scale_tune=inf;

2375

scale_tune=inf;

2264

while abs(scale_tune) >= .1

2376

while abs(scale_tune) >= .1

2265

istart=-PDF.Min+1;

2377

istart=-PDF.Min+1;

2266

scale=scale-dscale;

2378

scale=scale-dscale;

2267

PDF_SCALED = scalePDF(PDF,scale);

2379

PDF_SCALED = scalePDF(PDF,scale);

2268

cdf_scaled=pdf_to_cdf(PDF_SCALED);

2380

cdf_scaled=pdf_to_cdf(PDF_SCALED);

2269

test_snr=snr_dfe(DER_MLSE_CDF,PDF_SCALED,cdf_scaled.y);

2381

test_snr=snr_dfe(DER_MLSE_CDF,PDF_SCALED,cdf_scaled.y);

2270

test_DER=2*(L-1)/L* (CDF_ev(main/(L-1),PDF_SCALED,cdf_scaled.y) );

2382

test_DER=2*(L-1)/L* (CDF_ev(main/(L-1),PDF_SCALED,cdf_scaled.y) );

2271

scale_tune=(test_DER-DER_MLSE_CDF)/DER_MLSE_CDF;

2383

scale_tune=(test_DER-DER_MLSE_CDF)/DER_MLSE_CDF;

2272

if sign(scale_tune) ~= sign(last_scale_tune)

2384

if sign(scale_tune) ~= sign(last_scale_tune)

2273

% scale=scale+dscale % back up

2385

% scale=scale+dscale % back up

2274

dscale=-dscale/2;

2386

dscale=-dscale/2;

2275

end

2387

end

2276

last_scale_tune=scale_tune;

2388

last_scale_tune=scale_tune;

2277

end

2389

end

2278

new_com_CDF=10*log10((A_s./CDF_inv_ev(DER0,PDF_SCALED,cdf_scaled.y)).^2);

2390

new_com_CDF=10*log10((A_s./CDF_inv_ev(DER0,PDF_SCALED,cdf_scaled.y)).^2);

2279

delta_com=new_com_CDF-10*log10((A_s./CDF_inv_ev(DER0,PDF,CDF)).^2);

2391

delta_com=new_com_CDF-10*log10((A_s./CDF_inv_ev(DER0,PDF,CDF)).^2);

2280

else

2392

else

2281

warning('MLSE not applied because there is more noise than signal')

2393

warning('MLSE not applied because there is more noise than signal')

2282

DER_MLSE=[];

2394

DER_MLSE=[];

2283

DER_MLSE_CDF=[];

2395

DER_MLSE_CDF=[];

2284

SNR_DFE_eqivalent=[];

2396

SNR_DFE_eqivalent=[];

2285

SNR_DFE_eqivalent_CDF=[];

2397

SNR_DFE_eqivalent_CDF=[];

2286

new_com_CDF=COM_from_matlab;

2398

new_com_CDF=COM_from_matlab;

2287

delta_com_CDF=0;

2399

delta_com_CDF=0;

2288

delta_com=0;

2400

delta_com=0;

2289

SNR_DFE=[];

2401

SNR_DFE=[];

2290

PDF_SCALED=[];

2402

PDF_SCALED=[];

2291

cdf_scaled=[];

2403

cdf_scaled=[];

2292

end

2404

end

2293

2405

2294

%%

2406

%%

2295

MLSE_results.COM_from_matlab=COM_from_matlab;

2407

MLSE_results.COM_from_matlab=COM_from_matlab;

2296

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2408

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2297

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2409

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2298

MLSE_results.sigma_noise=sigma_noise;

2410

MLSE_results.sigma_noise=sigma_noise;

2299

MLSE_results.k_DER=k_DER;

2411

MLSE_results.k_DER=k_DER;

2300

MLSE_results.COM_CDF=new_com_CDF;

2412

MLSE_results.COM_CDF=new_com_CDF;

2301

MLSE_results.delta_com_CDF=delta_com;

2413

MLSE_results.delta_com_CDF=delta_com;

2302

MLSE_results.delta_com_Gaussian=delta_com;

2414

MLSE_results.delta_com_Gaussian=delta_com;

2303

MLSE_results.PDF=PDF_SCALED;

2415

MLSE_results.PDF=PDF_SCALED;

2304

MLSE_results.CDF=cdf_scaled.y;

2416

MLSE_results.CDF=cdf_scaled.y;

2305

MLSE_results.PDF_scale=scale;

2417

MLSE_results.PDF_scale=scale;

2306

2418

2307

2419

2308

2420

2309

2421

2310

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2422

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2311

if 1

2423

if 1

2312

num_ui=param.num_ui_RXFF_noise;

2424

num_ui=param.num_ui_RXFF_noise;

2313

M=param.samples_per_ui;

2425

M=param.samples_per_ui;

2314

L=param.levels;

2426

L=param.levels;

2315

sigma_X2=(L^2-1)/(3*(L-1)^2);

2427

sigma_X2=(L^2-1)/(3*(L-1)^2);

2316

fb=param.fb;

2428

fb=param.fb;

2317

R_LM=param.R_LM;

2429

R_LM=param.R_LM;

2318

end

2430

end

2319

h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2431

h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2320

h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2432

h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2321

h=reshape(h,1,[]); % make row vectors

2433

h=reshape(h,1,[]); % make row vectors

2322

h=[ h(1:floor(length(h)/M)*M) ];

2434

h=[ h(1:floor(length(h)/M)*M) ];

2323

h= [h zeros(1,num_ui*M-length(h)) ];

2435

h= [h zeros(1,num_ui*M-length(h)) ];

2324

h=h(1:M:end);% resample

2436

h=h(1:M:end);% resample

2325

N=length(h);

2437

N=length(h);

2326

dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2438

dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2327

dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2439

dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2328

if param.N_bg == 0

2440

if param.N_bg == 0

2329

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2441

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2330

bmax=param.bmax;

2442

bmax=param.bmax;

2331

bmin=param.bmin ;

2443

bmin=param.bmin ;

2332

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

2444

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2333

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

2445

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2334

idx=[];

2446

idx=[];

2335

else

2447

else

2336

Nfloating_taps=param.N_bf*param.N_bg;

2448

Nfloating_taps=param.N_bf*param.N_bg;

2337

Nmax=param.N_bmax;

2449

Nmax=param.N_bmax;

2338

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2450

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2339

Ng=param.N_bg;

2451

Ng=param.N_bg;

2340

Nf=param.N_bf;

2452

Nf=param.N_bf;

2341

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2453

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2342

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2454

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2343

% hisi=h(dh+2:((dh-dw)+Nw));

2455

% hisi=h(dh+2:((dh-dw)+Nw));

2344

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2456

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2345

% idx=sort(idx);

2457

% idx=sort(idx);

2346

bmax=param.bmax;

2458

bmax=param.bmax;

2347

bmin=param.bmin ;

2459

bmin=param.bmin ;

2348

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

2460

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ones(1,Nfloating_taps)*param.bmaxg ];

2349

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

2461

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max -ones(1,Nfloating_taps)*param.bmaxg ];

2350

end

2462

end

2351

Nb=param.ndfe; % DFE taps

2463

Nb=param.ndfe; % DFE taps

2352

d=dw+dh; % used for index in algorithms

2464

d=dw+dh; % used for index in algorithms

2353

indx(1:N)=(1:N)-dh-1;

2465

indx(1:N)=(1:N)-dh-1;

2354

S_n=PSD_results.S_n; % total agregate noise PSD

2466

S_n=PSD_results.S_n; % total agregate noise PSD

2355

Rn=ifft(S_n)*fb;

2467

Rn=ifft(S_n)*fb;

2356

%% HH and R

2468

%% HH and R

2357

2469

2358

%Test routine finding rxffe floating taps using best FOM for each bank

2470

%Test routine finding rxffe floating taps using best FOM for each bank

2359

isi_start = dh+2;

2471

isi_start = dh+2;

2360

isi_end = (dh-dw)+Nw;

2472

isi_end = (dh-dw)+Nw;

2361

hc1=[ h zeros(1,Nw-1) ];

2473

hc1=[ h zeros(1,Nw-1) ];

2362

hr1=[ h(1) zeros(1,Nw-1)];

2474

hr1=[ h(1) zeros(1,Nw-1)];

2363

H=toeplitz(hc1,hr1);

2475

H=toeplitz(hc1,hr1);

2364

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2476

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2365

if param.N_bg ~= 0

2477

if param.N_bg ~= 0

2366

switch lower(OP.RXFFE_FLOAT_CTL)

2478

switch lower(OP.RXFFE_FLOAT_CTL)

2367

case 'isi'

2479

case 'isi'

2368

hisi=h(dh+2:((dh-dw)+Nw));

2480

hisi=h(dh+2:((dh-dw)+Nw));

2369

[idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2481

[idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2370

idx=sort(idx);

2482

idx=sort(idx);

2371

otherwise

2483

otherwise

2372

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2484

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2373

idx=sort(idx);

2485

idx=sort(idx);

2374

end

2486

end

2375

end

2487

end

2376

[sigma_e,FOM,w,idx] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx);

2488

[sigma_e,FOM,w,idx] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx);

2377

MMSE_results.sigma_e=sigma_e; %

2489

MMSE_results.sigma_e=sigma_e; %

2378

MMSE_results.FOM=FOM;

2490

MMSE_results.FOM=FOM;

2379

Craw=w/w(dw+1); % returned Rx FFE taps

2491

Craw=w/w(dw+1); % returned Rx FFE taps

2380

% re-align Cmod to floating tap locations

2492

% re-align Cmod to floating tap locations

2381

if param.N_bg ~= 0

2493

if param.N_bg ~= 0

2382

C=Craw;

2494

C=Craw;

2383

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2495

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2384

C(idx-param.N_tail_start+1+Nfix)=Craw(Nfix+(1:Nfloating_taps));

2496

C(idx-param.N_tail_start+1+Nfix)=Craw(Nfix+(1:Nfloating_taps));

2385

else

2497

else

2386

C=Craw;

2498

C=Craw;

2387

end

2499

end

2388

MMSE_results.floating_tap_locations=idx;

2500

MMSE_results.floating_tap_locations=idx;

2389

MMSE_results.C=C;

2501

MMSE_results.C=C;

2390

2502

2391

2503

2392

2504

2393

2505

2394

function [sigma_e,FOM,w,idx,Nw] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2506

function [sigma_e,FOM,w,idx,Nw] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2395

if isempty(idx)

2507

if isempty(idx)

2396

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2508

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2397

bmax=param.bmax;

2509

bmax=param.bmax;

2398

bmin=param.bmin ;

2510

bmin=param.bmin ;

2399

else

2511

else

2400

Nfloating_taps=param.N_bf*param.N_bg;

2512

Nfloating_taps=param.N_bf*param.N_bg;

2401

%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

2513

%If using the routine that finds RXFFE floating taps bank-by-bank, the number of total floating taps can be less than the final amount

2402

Nfloating_taps = length(idx);

2514

Nfloating_taps = length(idx);

2403

Nmax=param.N_bmax;

2515

Nmax=param.N_bmax;

2404

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2516

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2405

Ng=param.N_bg;

2517

Ng=param.N_bg;

2406

Nf=param.N_bf;

2518

Nf=param.N_bf;

2407

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2519

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2408

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number 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

2409

end

2521

end

2410

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2522

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2411

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2523

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2412

% hc1=[ h zeros(1,Nw-1) ];

2524

% hc1=[ h zeros(1,Nw-1) ];

2413

% hr1=[ h(1) zeros(1,Nw-1)];

2525

% hr1=[ h(1) zeros(1,Nw-1)];

2414

% H=toeplitz(hc1,hr1);

2526

% H=toeplitz(hc1,hr1);

2415

2527

2416

if param.N_bg ~= 0

2528

if param.N_bg ~= 0

2417

H=H( :,[1:Nfix idx-param.N_tail_start+1+Nfix]); % from Tobey (Pei-Rong Li 02/28/2024)

2529

H=H( :,[1:Nfix idx-param.N_tail_start+1+Nfix]); % from Tobey (Pei-Rong Li 02/28/2024)

2418

end

2530

end

2419

%% HH and R

2531

%% HH and R

2420

HH= H'*H;

2532

HH= H'*H;

2421

if param.N_bg ~= 0

2533

if param.N_bg ~= 0

2422

Rnn=Rnn( [1:Nfix idx-param.N_tail_start+1+Nfix],[1:Nfix idx-param.N_tail_start+1+Nfix]);

2534

Rnn=Rnn( [1:Nfix idx-param.N_tail_start+1+Nfix],[1:Nfix idx-param.N_tail_start+1+Nfix]);

2423

end

2535

end

2424

R=HH+Rnn/sigma_X2;

2536

R=HH+Rnn/sigma_X2;

2425

%% hb and h0

2537

%% hb and h0

2426

Hb= H(d+2:d+Nb+1,:);

2538

Hb= H(d+2:d+Nb+1,:);

2427

h0=H(d+1,:);

2539

h0=H(d+1,:);

2428

% display(floor(h0));

2540

% display(floor(h0));

2429

2541

2430

%% Ib and zb (slide 10)

2542

%% Ib and zb (slide 10)

2431

ib=eye(Nb);

2543

ib=eye(Nb);

2432

zb=zeros(1,Nb);

2544

zb=zeros(1,Nb);

2433

wbl= [ R -Hb' -h0';...

2545

wbl= [ R -Hb' -h0';...

2434

-Hb ib zb'; ...

2546

-Hb ib zb'; ...

2435

h0 zb 0]\[h0'; zb' ;1];

2547

h0 zb 0]\[h0'; zb' ;1];

2436

2548

2437

%% re-adjust Nw to number of used taps

2549

%% re-adjust Nw to number of used taps

2438

if param.N_bg ~= 0

2550

if param.N_bg ~= 0

2439

Nw=Nwft;

2551

Nw=Nwft;

2440

end

2552

end

2441

%% check equalized pulse

2553

%% check equalized pulse

2442

w=wbl(1:Nw);

2554

w=wbl(1:Nw);

2443

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2555

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2444

2556

2445

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2557

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2446

blim = min(bmax(:), max(bmin(:), b));

2558

blim = min(bmax(:), max(bmin(:), b));

2447

if (Nb > 0) && ~isequal(b, blim)

2559

if (Nb > 0) && ~isequal(b, blim)

2448

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2560

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2449

w = wl(1:Nw);

2561

w = wl(1:Nw);

2450

end

2562

end

2451

2563

2452

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2564

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2453

%so need to chop off the extra indices on wmax and wmin

2565

%so need to chop off the extra indices on wmax and wmin

2454

if length(w)<length(wmax)

2566

if length(w)<length(wmax)

2455

wmax=wmax(1:length(w));

2567

wmax=wmax(1:length(w));

2456

wmin=wmin(1:length(w));

2568

wmin=wmin(1:length(w));

2457

end

2569

end

2458

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2570

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2459

if ~isequal(w, wlim)

2571

if ~isequal(w, wlim)

2460

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2572

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2461

if Nb > 0

2573

if Nb > 0

2462

b = Hb*wlim; % Update the feedback coefficients.

2574

b = Hb*wlim; % Update the feedback coefficients.

2463

blim = min(bmax(:), max(bmin(:), b));

2575

blim = min(bmax(:), max(bmin(:), b));

2464

end

2576

end

2465

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2577

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2466

wl = wl(1:Nw);

2578

wl = wl(1:Nw);

2467

w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2579

w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2468

end

2580

end

2469

w=w(1:Nw) ;

2581

w=w(1:Nw) ;

2470

sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2582

sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2471

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2583

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2472

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

2584

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

2473

2585

2474

%not all output_args are filled here but most are

2586

%not all output_args are filled here but most are

2475

2587

2476

switch lower(OP.TDECQ)

2588

switch lower(OP.TDECQ)

2477

case { false 'none' } % should be the default

2589

case { false 'none' } % should be the default

2478

output_args.VMA=[];

2590

output_args.VMA=[];

2479

case 'vma'

2591

case 'vma'

2480

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2592

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2481

output_args.VMA=est_vma.VMA;

2593

output_args.VMA=est_vma.VMA;

2482

otherwise

2594

otherwise

2483

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2595

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2484

end

2596

end

2485

2597

2486

fileset_str=str2csv({chdata.base});

2598

fileset_str=str2csv({chdata.base});

2487

output_args.file_names=sprintf('"%s"', fileset_str);

2599

output_args.file_names=sprintf('"%s"', fileset_str);

2488

% [ahealey] Echo the termination parameters in the output arguments..

2600

% [ahealey] Echo the termination parameters in the output arguments..

2489

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2601

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2490

output_args.(odt_param{:}) = param.(odt_param{:});

2602

output_args.(odt_param{:}) = param.(odt_param{:});

2491

end

2603

end

2492

% [ahealey] End of modifications.

2604

% [ahealey] End of modifications.

2493

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2605

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2494

output_args.(pkg_params{:})= param.(pkg_params{:});

2606

output_args.(pkg_params{:})= param.(pkg_params{:});

2495

end

2607

end

2496

output_args.baud_rate_GHz=param.fb/1e9;

2608

output_args.baud_rate_GHz=param.fb/1e9;

2497

output_args.f_Nyquist_GHz = param.fb/2e9;

2609

output_args.f_Nyquist_GHz = param.fb/2e9;

2498

output_args.BER=param.specBER;

2610

output_args.BER=param.specBER;

2499

output_args.FOM = fom_result.FOM;

2611

output_args.FOM = fom_result.FOM;

2500

output_args.sigma_N=Noise_Struct.sigma_N;

2612

output_args.sigma_N=Noise_Struct.sigma_N;

2501

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2613

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2502

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2614

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2503

output_args.tail_RSS=fom_result.tail_RSS;

2615

output_args.tail_RSS=fom_result.tail_RSS;

2504

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2616

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2505

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2617

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2506

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2618

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2507

try

2619

try

2508

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2620

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2509

catch

2621

catch

2510

output_args.uneq_FIR_peak_time=[];

2622

output_args.uneq_FIR_peak_time=[];

2511

end

2623

end

2512

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2624

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2513

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2625

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2514

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2626

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2515

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2627

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2516

2628

2517

if OP.RX_CALIBRATION== 1

2629

if OP.RX_CALIBRATION== 1

2518

output_args.sigma_bn=sigma_bn;

2630

output_args.sigma_bn=sigma_bn;

2519

else

2631

else

2520

output_args.sigma_bn=[];

2632

output_args.sigma_bn=[];

2521

end

2633

end

2522

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2634

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2523

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2635

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2524

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2636

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2525

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2637

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2526

2638

2527

if OP.RX_CALIBRATION == 0

2639

if OP.RX_CALIBRATION == 0

2528

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2640

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2529

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2641

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2530

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2642

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2531

else

2643

else

2532

output_args.peak_MDXTK_interference_at_BER_mV=[];

2644

output_args.peak_MDXTK_interference_at_BER_mV=[];

2533

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2645

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2534

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2646

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2535

end

2647

end

2536

%output_args.ICN_mV=ICN*1000;

2648

%output_args.ICN_mV=ICN*1000;

2537

% output_args.ICN_test_mV=ICN_test*1000;

2649

% output_args.ICN_test_mV=ICN_test*1000;

2538

xtk=param.num_next+param.num_fext;

2650

xtk=param.num_next+param.num_fext;

2539

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2651

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2540

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2652

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2541

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2653

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2542

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2654

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2543

else

2655

else

2544

output_args.MDNEXT_ICN_92_46_mV=0;

2656

output_args.MDNEXT_ICN_92_46_mV=0;

2545

output_args.MDFEXT_ICN_92_47_mV=0;

2657

output_args.MDFEXT_ICN_92_47_mV=0;

2546

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2658

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2547

end

2659

end

2548

%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

2660

%output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(A_s/(peak_interference_at_BER/qfuncinv(param.specBER))); modified by Yasuo Hidaka, 8/7/17

2549

if 1

2661

if 1

2550

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

2662

output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(COM_SNR_Struct.A_s/(Noise_Struct.peak_interference_at_BER/sqrt(2)/erfcinv(2*param.specBER)));

2551

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2663

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2552

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2664

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2553

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2665

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2554

end

2666

end

2555

2667

2556

2668

2557

switch param.CTLE_type

2669

switch param.CTLE_type

2558

case 'CL93'

2670

case 'CL93'

2559

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2671

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2560

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2672

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2561

output_args.g_DC_HP=[];

2673

output_args.g_DC_HP=[];

2562

output_args.HP_poles_zero=[];

2674

output_args.HP_poles_zero=[];

2563

case 'CL120d'

2675

case 'CL120d'

2564

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2676

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2565

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2677

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2566

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2678

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2567

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2679

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2568

case 'CL120e'

2680

case 'CL120e'

2569

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

2681

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.f_HP_Z(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle) param.f_HP_P(fom_result.ctle)];

2570

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2682

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2571

output_args.g_DC_HP=[];

2683

output_args.g_DC_HP=[];

2572

output_args.HP_poles_zero=[];

2684

output_args.HP_poles_zero=[];

2573

end

2685

end

2574

output_args.TXLE_taps=fom_result.txffe;

2686

output_args.TXLE_taps=fom_result.txffe;

2575

if length(output_args.TXLE_taps) >= 3

2687

if length(output_args.TXLE_taps) >= 3

2576

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2688

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2577

else

2689

else

2578

output_args.Pre2Pmax=[];

2690

output_args.Pre2Pmax=[];

2579

end

2691

end

2580

output_args.DFE_taps=fom_result.DFE_taps;

2692

output_args.DFE_taps=fom_result.DFE_taps;

2581

if param.Floating_DFE || param.Floating_RXFFE

2693

if param.Floating_DFE || param.Floating_RXFFE

2582

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2694

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2583

else

2695

else

2584

output_args.floating_tap_locations=[];

2696

output_args.floating_tap_locations=[];

2585

end

2697

end

2586

2698

2587

if OP.RxFFE

2699

if OP.RxFFE

2588

output_args.RxFFE=fom_result.RxFFE;

2700

output_args.RxFFE=fom_result.RxFFE;

2589

output_args.RxFFEgain=param.current_ffegain;

2701

output_args.RxFFEgain=param.current_ffegain;

2590

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2702

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2591

output_args.RxFFE=[];

2703

output_args.RxFFE=[];

2592

output_args.RxFFEgain=[];

2704

output_args.RxFFEgain=[];

2593

end

2705

end

2594

2706

2595

output_args.itick=fom_result.itick;

2707

output_args.itick=fom_result.itick;

2596

2708

2597

% Calculation of error propagation and burst probability

2709

% Calculation of error propagation and burst probability

2598

if OP.nburst>0

2710

if OP.nburst>0

2599

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2711

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2600

output_args.error_propagation_probability = p_error_propagation;

2712

output_args.error_propagation_probability = p_error_propagation;

2601

output_args.burst_probabilities = p_burst;

2713

output_args.burst_probabilities = p_burst;

2602

else

2714

else

2603

output_args.error_propagation_probability = [];

2715

output_args.error_propagation_probability = [];

2604

output_args.burst_probabilities = [];

2716

output_args.burst_probabilities = [];

2605

end

2717

end

2606

2718

2607

2719

2608

%begin yasuo patch 12/11/2018

2720

%begin yasuo patch 12/11/2018

2609

% collect sigma values to report

2721

% collect sigma values to report

2610

% pdf2sgm() is a function to calculate sigma value from PDF

2722

% pdf2sgm() is a function to calculate sigma value from PDF

2611

% It is added at the end of this file code.

2723

% It is added at the end of this file code.

2612

% I am not sure if an equivalent function already exists.

2724

% I am not sure if an equivalent function already exists.

2613

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2725

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2614

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2726

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2615

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2727

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2616

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2728

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2617

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2729

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2618

output_args.sgm_G = Noise_Struct.sigma_G;

2730

output_args.sgm_G = Noise_Struct.sigma_G;

2619

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2731

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2620

output_args.sgm_N = Noise_Struct.sigma_N;

2732

output_args.sgm_N = Noise_Struct.sigma_N;

2621

output_args.sgm_TX = Noise_Struct.sigma_TX;

2733

output_args.sgm_TX = Noise_Struct.sigma_TX;

2622

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2734

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2623

if OP.RX_CALIBRATION == 0

2735

if OP.RX_CALIBRATION == 0

2624

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2736

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2625

else

2737

else

2626

output_args.sgm_xt=[];

2738

output_args.sgm_xt=[];

2627

end

2739

end

2628

% end yasuo patch

2740

% end yasuo patch

2629

2741

2630

% r259 putting COM, VEO and loss last in report

2742

% r259 putting COM, VEO and loss last in report

2631

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2743

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2632

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2744

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2633

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2745

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2634

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

2746

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

2635

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2747

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2636

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2748

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2637

output_args.VEO_window_mUI= param.T_O;

2749

output_args.VEO_window_mUI= param.T_O;

2638

else

2750

else

2639

output_args.EW_UI_est=[];

2751

output_args.EW_UI_est=[];

2640

output_args.eye_contour=[];

2752

output_args.eye_contour=[];

2641

output_args.VEO_window_mUI= [];

2753

output_args.VEO_window_mUI= [];

2642

end

2754

end

2643

2755

2644

if sum(param.AC_CM_RMS) ~= 0

2756

if sum(param.AC_CM_RMS) ~= 0

2645

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2757

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2646

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2758

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2647

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2759

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2648

else

2760

else

2649

output_args.sigma_ACCM_at_tp0_mV=[];

2761

output_args.sigma_ACCM_at_tp0_mV=[];

2650

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2762

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2651

end

2763

end

2652

if OP.MLSE

2764

if OP.MLSE

2653

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2765

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2654

output_args.VEC_dB_orig=COM_SNR_Struct.VEC_dB_orig;

2766

output_args.VEC_dB_orig=COM_SNR_Struct.VEC_dB_orig;

2655

end

2767

end

2656

%

2768

%

2657

output_args.COM_dB=COM_SNR_Struct.COM;

2769

output_args.COM_dB=COM_SNR_Struct.COM;

2658

% end yasuo patch

2770

% end yasuo patch

2659

% begin yasuo patch 3/18/2019

2771

% begin yasuo patch 3/18/2019

2660

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2772

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2661

% end yasuo patch

2773

% end yasuo patch

2662

function [ seq syms syms_nrz ] = PRBS13Q( )

2774

function [ seq syms syms_nrz ] = PRBS13Q( )

2663

%UNTITLED Summary of this function goes here

2775

%UNTITLED Summary of this function goes here

2664

% Detailed explanation goes here

2776

% Detailed explanation goes here

2665

2777

2666

2778

2667

taps = ([13 12 2 1]);

2779

taps = ([13 12 2 1]);

2668

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2780

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2669

[seq_nrz c] =LFSR(seed,taps);

2781

[seq_nrz c] =LFSR(seed,taps);

2670

seq_nrz=2*(seq_nrz-0.5);

2782

seq_nrz=2*(seq_nrz-0.5);

2671

seq=pam(seq_nrz);

2783

seq=pam(seq_nrz);

2672

% syms=round(2*(seq+1));

2784

% syms=round(2*(seq+1));

2673

syms((round(2*(seq+1))/2==2))=3;

2785

syms((round(2*(seq+1))/2==2))=3;

2674

syms((round(2*(seq+1))/2==1.5))=2;

2786

syms((round(2*(seq+1))/2==1.5))=2;

2675

syms((round(2*(seq+1))/2==.5))=1;

2787

syms((round(2*(seq+1))/2==.5))=1;

2676

syms((round(2*(seq+1))/2==0))=0;

2788

syms((round(2*(seq+1))/2==0))=0;

2677

2789

2678

% syms_nrz=((seq_nrz+1)/2);

2790

% syms_nrz=((seq_nrz+1)/2);

2679

2791

2680

syms_nrz=seq_nrz;

2792

syms_nrz=seq_nrz;

2681

2793

2682

2794

2683

function[seq c]=LFSR(s,t)

2795

function[seq c]=LFSR(s,t)

2684

%s=initial state of LFSR, you can choose any lenght of LFSR

2796

%s=initial state of LFSR, you can choose any lenght of LFSR

2685

%Instruction:==========

2797

%Instruction:==========

2686

%Save LFSR.m in your current directory and type following

2798

%Save LFSR.m in your current directory and type following

2687

%on Command window for simulating 5 bit LFSR with tap [5 2]

2799

%on Command window for simulating 5 bit LFSR with tap [5 2]

2688

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

2800

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

2689

%>>s=[1 1 0 0 1]

2801

%>>s=[1 1 0 0 1]

2690

%>>t=[5 2]

2802

%>>t=[5 2]

2691

%>>[seq c] =LFSR(s,t)

2803

%>>[seq c] =LFSR(s,t)

2692

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

2804

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

2693

%seq = generated sequence

2805

%seq = generated sequence

2694

%c will be matrix containing the states of LFSR raw wise

2806

%c will be matrix containing the states of LFSR raw wise

2695

%

2807

%

2696

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

2808

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

2697

%If any doubt, confusion or feedback please contact me

2809

%If any doubt, confusion or feedback please contact me

2698

% NIKESH BAJAJ

2810

% NIKESH BAJAJ

2699

% bajaj.nikkey@gmail.com (+91-9915522564)

2811

% bajaj.nikkey@gmail.com (+91-9915522564)

2700

% Asst. Professor at Lovely Profesional University

2812

% Asst. Professor at Lovely Profesional University

2701

% Masters from Aligarh Muslim University,INDIA

2813

% Masters from Aligarh Muslim University,INDIA

2702

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

2814

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

2703

n=length(s);

2815

n=length(s);

2704

c(1,:)=s;

2816

c(1,:)=s;

2705

m=length(t);

2817

m=length(t);

2706

for k=1:2^n-2;

2818

for k=1:2^n-2;

2707

b(1)=xor(s(t(1)), s(t(2)));

2819

b(1)=xor(s(t(1)), s(t(2)));

2708

if m>2;

2820

if m>2;

2709

for i=1:m-2;

2821

for i=1:m-2;

2710

b(i+1)=xor(s(t(i+2)), b(i));

2822

b(i+1)=xor(s(t(i+2)), b(i));

2711

end

2823

end

2712

end

2824

end

2713

j=1:n-1;

2825

j=1:n-1;

2714

s(n+1-j)=s(n-j);

2826

s(n+1-j)=s(n-j);

2715

s(1)=b(m-1);

2827

s(1)=b(m-1);

2716

c(k+1,:)=s;

2828

c(k+1,:)=s;

2717

end

2829

end

2718

seq=c(:,n)';

2830

seq=c(:,n)';

2719

2831

2720

function [ dataout ] = pam( data )

2832

function [ dataout ] = pam( data )

2721

% mapping data usng Grey Coding

2833

% mapping data usng Grey Coding

2722

for i=1:2:floor(length(data)/2)*2

2834

for i=1:2:floor(length(data)/2)*2

2723

if data(i:i+1)==[ -1 -1 ]

2835

if data(i:i+1)==[ -1 -1 ]

2724

dataout(ceil(i/2)) = -1;

2836

dataout(ceil(i/2)) = -1;

2725

elseif data(i:i+1)==[ -1 1 ]

2837

elseif data(i:i+1)==[ -1 1 ]

2726

dataout(ceil(i/2)) = -1/3;

2838

dataout(ceil(i/2)) = -1/3;

2727

elseif data(i:i+1)==[ 1 1 ]

2839

elseif data(i:i+1)==[ 1 1 ]

2728

dataout(ceil(i/2)) = 1/3;

2840

dataout(ceil(i/2)) = 1/3;

2729

elseif data(i:i+1)==[ 1 -1 ]

2841

elseif data(i:i+1)==[ 1 -1 ]

2730

dataout(ceil(i/2)) = 1;

2842

dataout(ceil(i/2)) = 1;

2731

end

2843

end

2732

end

2844

end

2733

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2845

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2734

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

2846

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

2735

disp('computing TD_RILN...')

2847

disp('computing TD_RILN...')

2736

sdd21=squeeze(sdd21);

2848

sdd21=squeeze(sdd21);

2737

if iscolumn(sdd21)

2849

if iscolumn(sdd21)

2738

sdd21=sdd21.';

2850

sdd21=sdd21.';

2739

end

2851

end

2740

RIL=squeeze(RIL);

2852

RIL=squeeze(RIL);

2741

if iscolumn(RIL)

2853

if iscolumn(RIL)

2742

RIL=RIL.';

2854

RIL=RIL.';

2743

end

2855

end

2744

print_for_codereview=1;

2856

print_for_codereview=1;

2745

if exist('OP','var')

2857

if exist('OP','var')

2746

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2858

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2747

2859

2748

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2860

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2749

H_bw=Butterworth_Filter(param,faxis_f2,1);

2861

H_bw=Butterworth_Filter(param,faxis_f2,1);

2750

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2862

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2751

H_tw=Tukey_Window(faxis_f2,param);

2863

H_tw=Tukey_Window(faxis_f2,param);

2752

H_tw=ones(1,length(faxis_f2) );

2864

H_tw=ones(1,length(faxis_f2) );

2753

[RILN_TD_struct.REF.FIR, ...

2865

[RILN_TD_struct.REF.FIR, ...

2754

RILN_TD_struct.REF.t, ...

2866

RILN_TD_struct.REF.t, ...

2755

RILN_TD_struct.REF.causality_correction_dB, ...

2867

RILN_TD_struct.REF.causality_correction_dB, ...

2756

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2868

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2757

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2869

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2758

[RILN_TD_struct.FIT.FIR, ...

2870

[RILN_TD_struct.FIT.FIR, ...

2759

RILN_TD_struct.FIT.t, ...

2871

RILN_TD_struct.FIT.t, ...

2760

RILN_TD_struct.FIT.causality_correction_dB, ...

2872

RILN_TD_struct.FIT.causality_correction_dB, ...

2761

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2873

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2762

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2874

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2763

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2875

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2764

NrangeUI=1000;

2876

NrangeUI=1000;

2765

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2877

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2766

range=ipeak:range_end;

2878

range=ipeak:range_end;

2767

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2879

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2768

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2880

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2769

RILN_TD_struct.FOM=-inf;

2881

RILN_TD_struct.FOM=-inf;

2770

RILN_TD_struct.FOM_PDF=-inf;

2882

RILN_TD_struct.FOM_PDF=-inf;

2771

rms_fom=-inf;

2883

rms_fom=-inf;

2772

for im=1:param.samples_per_ui

2884

for im=1:param.samples_per_ui

2773

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2885

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2774

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2886

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2775

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2887

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2776

cdf=pdf; cdf.y=cumsum(pdf.y);

2888

cdf=pdf; cdf.y=cumsum(pdf.y);

2777

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2889

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2778

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2890

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2779

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2891

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2780

if print_for_codereview % remove once all checked out

2892

if print_for_codereview % remove once all checked out

2781

h=figure(191);set(gcf,'Tag','COM');

2893

h=figure(191);set(gcf,'Tag','COM');

2782

semilogy(-cdf.x,cdf.y);

2894

semilogy(-cdf.x,cdf.y);

2783

% xlim ([0,-cdf.x(1)])

2895

% xlim ([0,-cdf.x(1)])

2784

ylim([param.specBER 1]);title ('CDF of RILN')

2896

ylim([param.specBER 1]);title ('CDF of RILN')

2785

hold on

2897

hold on

2786

end

2898

end

2787

if rms>rms_fom

2899

if rms>rms_fom

2788

rms_fom=rms;

2900

rms_fom=rms;

2789

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2901

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2790

RILN_TD_struct.PDF=pdf;

2902

RILN_TD_struct.PDF=pdf;

2791

end

2903

end

2792

end

2904

end

2793

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2905

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2794

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2906

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2795

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2907

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2796

if print_for_codereview % remove once all checked out

2908

if print_for_codereview % remove once all checked out

2797

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

2909

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

2798

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2910

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2799

hold on

2911

hold on

2800

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2912

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2801

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2913

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2802

hold off

2914

hold off

2803

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)

2915

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

2804

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

2916

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

2805

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2917

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2806

hold on

2918

hold on

2807

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2919

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2808

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2920

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2809

grid on

2921

grid on

2810

legend('show')

2922

legend('show')

2811

end

2923

end

2812

end

2924

end

2813

function is_illegal=RXFFE_Illegal(C,param,last_index)

2925

function is_illegal=RXFFE_Illegal(C,param,last_index)

2814

2926

2815

%check if RXFFE taps are illegal

2927

%check if RXFFE taps are illegal

2816

%C = RXFFE taps

2928

%C = RXFFE taps

2817

%param = COM param struct

2929

%param = COM param struct

2818

%last_index is used when computing illegality prior to Backoff. It will be set so taps

2930

%last_index is used when computing illegality prior to Backoff. It will be set so taps

2819

% in the Backoff region are not considered in the legality check.

2931

% in the Backoff region are not considered in the legality check.

2820

2932

2821

%If last index is omitted, set it to length(C)

2933

%If last index is omitted, set it to length(C)

2822

if nargin<3

2934

if nargin<3

2823

last_index=length(C);

2935

last_index=length(C);

2824

end

2936

end

2825

2937

2826

is_illegal=0;

2938

is_illegal=0;

2827

2939

2828

%Check cursor tap

2940

%Check cursor tap

2829

Ccur_i=param.RxFFE_cmx+1;

2941

Ccur_i=param.RxFFE_cmx+1;

2830

if C(Ccur_i) < param.ffe_main_cursor_min

2942

if C(Ccur_i) < param.ffe_main_cursor_min

2831

is_illegal=1;

2943

is_illegal=1;

2832

return;

2944

return;

2833

end

2945

end

2834

2946

2835

%Check postcursors

2947

%Check postcursors

2836

if param.ffe_post_tap_len ~=0

2948

if param.ffe_post_tap_len ~=0

2837

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

2949

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

2838

is_illegal=1;

2950

is_illegal=1;

2839

return;

2951

return;

2840

end

2952

end

2841

if (param.ffe_post_tap_len > 1)

2953

if (param.ffe_post_tap_len > 1)

2842

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

2954

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

2843

is_illegal=1;

2955

is_illegal=1;

2844

return;

2956

return;

2845

end

2957

end

2846

end

2958

end

2847

end

2959

end

2848

2960

2849

%Check precursors

2961

%Check precursors

2850

if param.ffe_pre_tap_len ~=0

2962

if param.ffe_pre_tap_len ~=0

2851

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

2963

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

2852

is_illegal=1;

2964

is_illegal=1;

2853

return;

2965

return;

2854

end

2966

end

2855

if (param.ffe_pre_tap_len > 1)

2967

if (param.ffe_pre_tap_len > 1)

2856

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

2968

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

2857

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

2969

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

2858

is_illegal=1;

2970

is_illegal=1;

2859

return;

2971

return;

2860

end % 11.22.2018 Yasou Hadaka

2972

end % 11.22.2018 Yasou Hadaka

2861

end

2973

end

2862

end

2974

end

2863

function S =R_series2(zref,f,R)

2975

function S =R_series2(zref,f,R)

2864

r=ones(1,length(f))*R;

2976

r=ones(1,length(f))*R;

2865

S.Parameters(1,1,:) = r./(r + 2*zref);

2977

S.Parameters(1,1,:) = r./(r + 2*zref);

2866

S.Parameters(2,2,:) = r./(r + 2*zref);

2978

S.Parameters(2,2,:) = r./(r + 2*zref);

2867

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

2979

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

2868

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

2980

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

2869

% Sm=sparameters(S.Parameters,f,zref);

2981

% Sm=sparameters(S.Parameters,f,zref);

2870

2982

2871

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

2983

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

2872

2984

2873

if use_RC

2985

if use_RC

2874

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

2986

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

2875

else

2987

else

2876

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

2988

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

2877

end

2989

end

2878

function SLD=SL(S,f,R)

2990

function SLD=SL(S,f,R)

2879

% source load impact return loss add to S21

2991

% source load impact return loss add to S21

2880

% S and SLD are the same structure

2992

% S and SLD are the same structure

2881

% S.Parameters

2993

% S.Parameters

2882

% S.Impedance

2994

% S.Impedance

2883

% S.NumPorts

2995

% S.NumPorts

2884

% S.Frequencies

2996

% S.Frequencies

2885

SLD=S; % assign the fields

2997

SLD=S; % assign the fields

2886

zref=100;

2998

zref=100;

2887

if R==0

2999

if R==0

2888

warndlg('Termination should not be set to zero');

3000

warndlg('Termination should not be set to zero');

2889

SLD=S;

3001

SLD=S;

2890

return

3002

return

2891

end

3003

end

2892

3004

2893

if R > zref

3005

if R > zref

2894

spr =R_series2(zref,f,(R-zref)); % make series sparameter

3006

spr =R_series2(zref,f,(R-zref)); % make series sparameter

2895

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

3007

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

2896

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3008

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2897

combines4p( ...

3009

combines4p( ...

2898

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3010

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2899

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3011

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2900

);

3012

);

2901

elseif R < zref

3013

elseif R < zref

2902

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

3014

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

2903

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

3015

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

2904

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3016

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2905

combines4p( ...

3017

combines4p( ...

2906

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3018

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2907

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3019

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2908

);

3020

);

2909

else

3021

else

2910

SLD=S;

3022

SLD=S;

2911

end

3023

end

2912

3024

2913

%%

3025

%%

2914

3026

2915

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

3027

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

2916

p1=param.CTLE_fp1(1);

3028

p1=param.CTLE_fp1(1);

2917

z1=param.CTLE_fz(1);

3029

z1=param.CTLE_fz(1);

2918

p2=param.CTLE_fp2(1);

3030

p2=param.CTLE_fp2(1);

2919

zlf=param.f_HP(1);

3031

zlf=param.f_HP(1);

2920

plf=param.f_HP(1);

3032

plf=param.f_HP(1);

2921

f_b=param.fb;

3033

f_b=param.fb;

2922

f_r=param.f_r;

3034

f_r=param.f_r;

2923

eta_0=param.eta_0;

3035

eta_0=param.eta_0;

2924

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

3036

H_CTF = ( 10^(G_DC/20)+ 1i*f/z1 ) .*( 10^(G_DC2/20) + 1i*f/zlf )./ ( ( 1+1i*f/p1) .* ( 1+1i*f/p2) .* ( 1+1i*f/plf));

2925

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

3037

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

2926

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

3038

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

2927

if 0

3039

if 0

2928

figure

3040

figure

2929

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

3041

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

2930

% see if it looks correct

3042

% see if it looks correct

2931

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

3043

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

2932

ylabel('dB');

3044

ylabel('dB');

2933

xlabel('GHz');

3045

xlabel('GHz');

2934

title( 'H_ctf with H_r')

3046

title( 'H_ctf with H_r')

2935

grid on

3047

grid on

2936

ylim([-30 0])

3048

ylim([-30 0])

2937

end

3049

end

2938

3050

2939

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

3051

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

2940

3052

2941

%Fill TDR data

3053

%Fill TDR data

2942

if package_testcase_i == 1

3054

if package_testcase_i == 1

2943

if OP.TDR

3055

if OP.TDR

2944

output_args.Z11est=chdata(1).TDR11.avgZport;

3056

output_args.Z11est=chdata(1).TDR11.avgZport;

2945

if ~param.FLAG.S2P

3057

if ~param.FLAG.S2P

2946

output_args.Z22est=chdata(1).TDR22.avgZport;

3058

output_args.Z22est=chdata(1).TDR22.avgZport;

2947

else

3059

else

2948

output_args.Z22est=[];

3060

output_args.Z22est=[];

2949

end

3061

end

2950

if OP.AUTO_TFX

3062

if OP.AUTO_TFX

2951

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

3063

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

2952

else

3064

else

2953

output_args.tfx_estimate=[];

3065

output_args.tfx_estimate=[];

2954

end

3066

end

2955

else

3067

else

2956

output_args.Z11est=[];

3068

output_args.Z11est=[];

2957

output_args.Z22est=[];

3069

output_args.Z22est=[];

2958

output_args.tfx_estimate=[];

3070

output_args.tfx_estimate=[];

2959

end

3071

end

2960

end

3072

end

2961

3073

2962

% Process ERL

3074

% Process ERL

2963

if package_testcase_i == 1

3075

if package_testcase_i == 1

2964

if OP.ERL

3076

if OP.ERL

2965

output_args.ERL11=chdata(1).TDR11.ERL;

3077

output_args.ERL11=chdata(1).TDR11.ERL;

2966

if ~param.FLAG.S2P

3078

if ~param.FLAG.S2P

2967

output_args.ERL22=chdata(1).TDR22.ERL;

3079

output_args.ERL22=chdata(1).TDR22.ERL;

2968

else

3080

else

2969

output_args.ERL22=[];

3081

output_args.ERL22=[];

2970

end

3082

end

2971

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

3083

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

2972

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

3084

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

2973

else

3085

else

2974

output_args.ERL11=[];

3086

output_args.ERL11=[];

2975

output_args.ERL22=[];

3087

output_args.ERL22=[];

2976

end

3088

end

2977

end

3089

end

2978

if OP.ERL

3090

if OP.ERL

2979

if OP.TDR_W_TXPKG

3091

if OP.TDR_W_TXPKG

2980

min_ERL=output_args.ERL22;

3092

min_ERL=output_args.ERL22;

2981

ERL= [ nan output_args.ERL22 ];

3093

ERL= [ nan output_args.ERL22 ];

2982

else

3094

else

2983

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

3095

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

2984

min_ERL=output_args.ERL11;

3096

min_ERL=output_args.ERL11;

2985

ERL= [ output_args.ERL11 nan ];

3097

ERL= [ output_args.ERL11 nan ];

2986

else

3098

else

2987

min_ERL=min(output_args.ERL11,output_args.ERL22);

3099

min_ERL=min(output_args.ERL11,output_args.ERL22);

2988

ERL= [ output_args.ERL11 output_args.ERL22 ];

3100

ERL= [ output_args.ERL11 output_args.ERL22 ];

2989

end

3101

end

2990

end

3102

end

2991

output_args.ERL=min_ERL;

3103

output_args.ERL=min_ERL;

2992

else

3104

else

2993

min_ERL=[];

3105

min_ERL=[];

2994

ERL= [];

3106

ERL= [];

2995

output_args.ERL=[];

3107

output_args.ERL=[];

2996

end

3108

end

2997

if OP.ERL_ONLY

3109

if OP.ERL_ONLY

2998

if OP.BREAD_CRUMBS

3110

if OP.BREAD_CRUMBS

2999

output_args.OP=OP;

3111

output_args.OP=OP;

3000

output_args.param=param;

3112

output_args.param=param;

3001

output_args.chdata=chdata;

3113

output_args.chdata=chdata;

3002

%This seems to be the intent of setting fom_result.ran=0. Add it

3114

%This seems to be the intent of setting fom_result.ran=0. Add it

3003

%to output_args so there is a fom_result field.

3115

%to output_args so there is a fom_result field.

3004

fom_result.ran=0;

3116

fom_result.ran=0;

3005

output_args.fom_result=fom_result;

3117

output_args.fom_result=fom_result;

3006

end

3118

end

3007

output_args.Z_t=param.Z_t;

3119

output_args.Z_t=param.Z_t;

3008

fileset_str=str2csv({chdata(1).base});

3120

fileset_str=str2csv({chdata(1).base});

3009

output_args.file_names=sprintf('"%s"', fileset_str);

3121

output_args.file_names=sprintf('"%s"', fileset_str);

3010

if OP.DISPLAY_WINDOW

3122

if OP.DISPLAY_WINDOW

3011

savefigs(param, OP);

3123

savefigs(param, OP);

3012

end

3124

end

3013

end

3125

end

3014

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3126

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3015

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3127

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3016

p1_ctle = -2*pi*f_p1;

3128

p1_ctle = -2*pi*f_p1;

3017

p2_ctle = -2*pi*f_p2;

3129

p2_ctle = -2*pi*f_p2;

3018

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3130

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3019

k_ctle = -p2_ctle;

3131

k_ctle = -p2_ctle;

3020

bilinear_fs = 2*fb*oversampling;

3132

bilinear_fs = 2*fb*oversampling;

3021

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3133

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3022

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3134

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3023

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3135

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3024

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3136

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3025

% allow for different pole zeros RIM 9-29-2015

3137

% allow for different pole zeros RIM 9-29-2015

3026

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3138

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3027

B_filt =k_ctle*kd*poly([zd, -1]);

3139

B_filt =k_ctle*kd*poly([zd, -1]);

3028

A_filt=poly([p1d, p2d]);

3140

A_filt=poly([p1d, p2d]);

3029

impulse_response=filter(B_filt,A_filt,ir_in);

3141

impulse_response=filter(B_filt,A_filt,ir_in);

3030

3142

3031

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3143

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3032

Over_sample=2;

3144

Over_sample=2;

3033

num_files=length(chdata);

3145

num_files=length(chdata);

3034

for i=1:num_files

3146

for i=1:num_files

3035

V=chdata(i).uneq_pulse_response;

3147

V=chdata(i).uneq_pulse_response;

3036

T=chdata(i).t;

3148

T=chdata(i).t;

3037

dt=T(2)-T(1);

3149

dt=T(2)-T(1);

3038

f=0:1/max(T):1/dt;

3150

f=0:1/max(T):1/dt;

3039

chdata(i).faxis=f;

3151

chdata(i).faxis=f;

3040

f75=find(f >= param.fb*.75,1,'first');

3152

f75=find(f >= param.fb*.75,1,'first');

3041

fnq=find(f >= param.fb*.5,1,'first');

3153

fnq=find(f >= param.fb*.5,1,'first');

3042

chdata(i).fmaxi = length(f);

3154

chdata(i).fmaxi = length(f);

3043

chdata(i).faxis = f;

3155

chdata(i).faxis = f;

3044

UI=param.ui; % unit interval

3156

UI=param.ui; % unit interval

3045

M=param.samples_per_ui; % sample per UI

3157

M=param.samples_per_ui; % sample per UI

3046

N_v=param.N_v; % number of UI for Vf determination

3158

N_v=param.N_v; % number of UI for Vf determination

3047

3159

3048

% filters

3160

% filters

3049

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

3161

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

3050

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

3162

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

3051

H_ftr=H_bw.*H_bt;

3163

H_ftr=H_bw.*H_bt;

3052

H_ftr=H_ftr(:);

3164

H_ftr=H_ftr(:);

3053

% fd of PR

3165

% fd of PR

3054

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3166

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3055

prr = prr(:);

3167

prr = prr(:);

3056

if f(1)==0, prr(1)=1; end %remove NaN

3168

if f(1)==0, prr(1)=1; end %remove NaN

3057

fd=fft(V);

3169

fd=fft(V);

3058

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3170

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3059

3171

3060

%% get Vf

3172

%% get Vf

3061

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3173

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3062

step_response=filter(V,1, shifting_vector);

3174

step_response=filter(V,1, shifting_vector);

3063

Vf=step_response(end);

3175

Vf=step_response(end);

3064

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3176

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3065

%%

3177

%%

3066

% 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

3178

% ILest=20.*log10(abs(fd(1:f75)/Vf/M/Over_sample)) - 20.*log10(abs(prr(1:f75))) - 20*log10(abs(squeeze(H_ftr(1:f75)))) ; %removing db function to avoid using sig proc toolbox

3067

% figure

3179

% figure

3068

% plot(f(1:f75),ILest)

3180

% plot(f(1:f75),ILest)

3069

3181

3070

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

3182

IL_conv=fd(1:f75)/Vf/M/Over_sample ./ prr(1:f75) ./ H_ftr(1:f75) ; %removing db function to avoid using sig proc toolbox

3071

% set same variables as get_s4p_files

3183

% set same variables as get_s4p_files

3072

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3184

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3073

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3185

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3074

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3186

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3075

zero_vector=zeros(length(IL_conv),1);

3187

zero_vector=zeros(length(IL_conv),1);

3076

for j=1:length(IL_fields)

3188

for j=1:length(IL_fields)

3077

chdata(i).(IL_fields{j})=IL_conv;

3189

chdata(i).(IL_fields{j})=IL_conv;

3078

end

3190

end

3079

for j=1:length(Zero_fields)

3191

for j=1:length(Zero_fields)

3080

chdata(i).(Zero_fields{j})=zero_vector;

3192

chdata(i).(Zero_fields{j})=zero_vector;

3081

end

3193

end

3082

3194

3083

if i==1

3195

if i==1

3084

SDDch(:,1,2)=chdata.sdd12_raw;

3196

SDDch(:,1,2)=chdata.sdd12_raw;

3085

SDDch(:,2,1)=chdata.sdd21_raw;

3197

SDDch(:,2,1)=chdata.sdd21_raw;

3086

SDDch(:,1,1)=chdata.sdd11_raw;

3198

SDDch(:,1,1)=chdata.sdd11_raw;

3087

SDDch(:,2,2)=chdata.sdd22_raw;

3199

SDDch(:,2,2)=chdata.sdd22_raw;

3088

SDDp2p= zeros(length(IL_conv),1);

3200

SDDp2p= zeros(length(IL_conv),1);

3089

end

3201

end

3090

chdata(i).TX_RL=[];

3202

chdata(i).TX_RL=[];

3091

chdata(i).TDR11=[];

3203

chdata(i).TDR11=[];

3092

chdata(i).PDTR11=[];

3204

chdata(i).PDTR11=[];

3093

chdata(i).TDR22=[];

3205

chdata(i).TDR22=[];

3094

chdata(i).PDTR22=[];

3206

chdata(i).PDTR22=[];

3095

end

3207

end

3096

3208

3097

3209

3098

function H_tw=Tukey_Window(f,param,fr,fb)

3210

function H_tw=Tukey_Window(f,param,fr,fb)

3099

% RIM 05/26/2022 added optional fr and fb

3211

% RIM 05/26/2022 added optional fr and fb

3100

% fr is the start of the raised cosine window

3212

% fr is the start of the raised cosine window

3101

% fb is the end of the raised cosine window

3213

% fb is the end of the raised cosine window

3102

if ~exist('fr','var') && ~exist('fb','var')

3214

if ~exist('fr','var') && ~exist('fb','var')

3103

fb=param.fb;

3215

fb=param.fb;

3104

fr=param.f_r*param.fb;

3216

fr=param.f_r*param.fb;

3105

end

3217

end

3106

fperiod=2*(fb-fr);

3218

fperiod=2*(fb-fr);

3107

H_tw = [ ones(1,length(f(f<fr))) ...

3219

H_tw = [ ones(1,length(f(f<fr))) ...

3108

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3220

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3109

zeros(1,length(f(f>fb)) )];

3221

zeros(1,length(f(f>fb)) )];

3110

H_tw=H_tw(1:length(f));

3222

H_tw=H_tw(1:length(f));

3111

if 0

3223

if 0

3112

plot(f/1e9,H_tw)

3224

plot(f/1e9,H_tw)

3113

end

3225

end

3114

3226

3115

3227

3116

3228

3117

%% moved output control to functions

3229

%% moved output control to functions

3118

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3230

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3119

% Author: Richard Mellitz

3231

% Author: Richard Mellitz

3120

% Date: 7/29/2022

3232

% Date: 7/29/2022

3121

% generate FD tx ffe system function

3233

% generate FD tx ffe system function

3122

% varagins...

3234

% varagins...

3123

% param - stucture

3235

% param - stucture

3124

% param.fb baud rate

3236

% param.fb baud rate

3125

% param.Tx_FFE Tx FFE coef

3237

% param.Tx_FFE Tx FFE coef

3126

% f - freq array

3238

% f - freq array

3127

% Use_Tx_FFE = flag to use or not

3239

% Use_Tx_FFE = flag to use or not

3128

% H_TxFFE is system function for Tx_FFE

3240

% H_TxFFE is system function for Tx_FFE

3129

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

3241

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

3130

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

3242

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

3131

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

3243

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

3132

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

3244

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

3133

if isempty(Use_Tx_FFE)

3245

if isempty(Use_Tx_FFE)

3134

Use_Tx_FFE=0;

3246

Use_Tx_FFE=0;

3135

end

3247

end

3136

if isempty(param)

3248

if isempty(param)

3137

param.fb=106.25e9;

3249

param.fb=106.25e9;

3138

Tx_FFE=[1 ];

3250

Tx_FFE=[1 ];

3139

else

3251

else

3140

if ~isfield(param, 'Pkg_TXFFE_preset')

3252

if ~isfield(param, 'Pkg_TXFFE_preset')

3141

Tx_FFE=[ 1 ];

3253

Tx_FFE=[ 1 ];

3142

else

3254

else

3143

Tx_FFE=param.Pkg_TXFFE_preset;

3255

Tx_FFE=param.Pkg_TXFFE_preset;

3144

end

3256

end

3145

end

3257

end

3146

if isempty(f)

3258

if isempty(f)

3147

f=0:10e6:param.fb;

3259

f=0:10e6:param.fb;

3148

end

3260

end

3149

3261

3150

3262

3151

if Use_Tx_FFE ~=0

3263

if Use_Tx_FFE ~=0

3152

[mcur,icur] = max(Tx_FFE);

3264

[mcur,icur] = max(Tx_FFE);

3153

H_TxFFE=zeros(1,length(f));

3265

H_TxFFE=zeros(1,length(f));

3154

for ii=1:length(Tx_FFE)

3266

for ii=1:length(Tx_FFE)

3155

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3267

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3156

end

3268

end

3157

else

3269

else

3158

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

3270

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

3159

end

3271

end

3160

% figure (1102320)

3272

% figure (1102320)

3161

% plot(f/1e9,db(H_TxFFE))

3273

% plot(f/1e9,db(H_TxFFE))

3162

% hold on

3274

% hold on

3163

function C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs)

3275

function C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs)

3164

cmx=param.RxFFE_cmx;

3276

cmx=param.RxFFE_cmx;

3165

cpx=param.RxFFE_cpx;

3277

cpx=param.RxFFE_cpx;

3166

% do this early on so we can reuse the old code

3278

% do this early on so we can reuse the old code

3167

% to be replaced with MMSE function from healey...

3279

% to be replaced with MMSE function from healey...

3168

if param.N_bg ~=0 % must be floating taps

3280

if param.N_bg ~=0 % must be floating taps

3169

cpx=param.N_bmax; % N_f in spreadsheet

3281

cpx=param.N_bmax; % N_f in spreadsheet

3170

end

3282

end

3171

num_taps=cmx+cpx+1;

3283

num_taps=cmx+cpx+1;

3172

ndfe=param.ndfe;

3284

ndfe=param.ndfe;

3173

spui=param.samples_per_ui;

3285

spui=param.samples_per_ui;

3174

%% Start of WIENER-HOPF MMSE EQ code

3286

%% Start of WIENER-HOPF MMSE EQ code

3175

R_n = zeros(num_taps,num_taps);

3287

R_n = zeros(num_taps,num_taps);

3176

R_xt = zeros(num_taps,num_taps);

3288

R_xt = zeros(num_taps,num_taps);

3177

3289

3178

if OP.Do_Colored_Noise

3290

if OP.Do_Colored_Noise

3179

% Form Noise Autocorrelation matrix

3291

% Form Noise Autocorrelation matrix

3180

Noise_XC = reshape (Noise_XC,1,[]);

3292

Noise_XC = reshape (Noise_XC,1,[]);

3181

len = length(Noise_XC);

3293

len = length(Noise_XC);

3182

if len < num_taps, Noise_XC = [Noise_XC,zeros(1,num_taps-len)]; end

3294

if len < num_taps, Noise_XC = [Noise_XC,zeros(1,num_taps-len)]; end

3183

Noise_XC = Noise_XC(1:num_taps);

3295

Noise_XC = Noise_XC(1:num_taps);

3184

R_n = toeplitz (Noise_XC,Noise_XC);

3296

R_n = toeplitz (Noise_XC,Noise_XC);

3185

end

3297

end

3186

%% Calculate Cross Talk Correlation matrix at T intervals.

3298

%% Calculate Cross Talk Correlation matrix at T intervals.

3187

if OP.Do_XT_Noise

3299

if OP.Do_XT_Noise

3188

% Calculate variance of Tx signal based on +/-1 outer limits

3300

% Calculate variance of Tx signal based on +/-1 outer limits

3189

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

3301

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

3190

for jj = 2:length(chdata)

3302

for jj = 2:length(chdata)

3191

if isequal(chdata(jj).type, 'FEXT') || isequal(chdata(jj).type, 'NEXT')

3303

if isequal(chdata(jj).type, 'FEXT') || isequal(chdata(jj).type, 'NEXT')

3192

if isequal(chdata(jj).type, 'FEXT')

3304

if isequal(chdata(jj).type, 'FEXT')

3193

% len = length(chdata(jj).ctle_imp_response);

3305

% len = length(chdata(jj).ctle_imp_response);

3194

% ch_imp = ifft( fft(reshape(chdata(jj).ctle_imp_response,1,[])) .* fft(reshape(upsample(txffe, param.samples_per_ui),1,[]),len) );

3306

% ch_imp = ifft( fft(reshape(chdata(jj).ctle_imp_response,1,[])) .* fft(reshape(upsample(txffe, param.samples_per_ui),1,[]),len) );

3195

ch_imp= FFE( txffe , cmx,param.samples_per_ui, chdata(jj).ctle_imp_response).';

3307

ch_imp= FFE( txffe , cmx,param.samples_per_ui, chdata(jj).ctle_imp_response).';

3196

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3308

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3197

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

3309

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

3198

ch_imp = chdata(jj).ctle_imp_response;

3310

ch_imp = chdata(jj).ctle_imp_response;

3199

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3311

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3200

end

3312

end

3201

norms = zeros(1,spui);

3313

norms = zeros(1,spui);

3202

for ii = 1:spui

3314

for ii = 1:spui

3203

norms(ii) = norm(ch_imp(ii:spui:end));

3315

norms(ii) = norm(ch_imp(ii:spui:end));

3204

end

3316

end

3205

% Pick out sampling phase with largest noise contribution

3317

% Pick out sampling phase with largest noise contribution

3206

[~,cursor] = max(norms);

3318

[~,cursor] = max(norms);

3207

sub_sample_ch = ch_imp(cursor:spui:end);

3319

sub_sample_ch = ch_imp(cursor:spui:end);

3208

xc = xcorr(sub_sample_ch,num_taps)* Tx_sigma^2;

3320

xc = xcorr(sub_sample_ch,num_taps)* Tx_sigma^2;

3209

xc = xc(num_taps+1:end);

3321

xc = xc(num_taps+1:end);

3210

xc = xc(1:num_taps);

3322

xc = xc(1:num_taps);

3211

R = toeplitz (xc,xc);

3323

R = toeplitz (xc,xc);

3212

R_xt = R_xt + R;

3324

R_xt = R_xt + R;

3213

end

3325

end

3214

end

3326

end

3215

end

3327

end

3216

%% Noise + Cross Talk contribution to R matrix

3328

%% Noise + Cross Talk contribution to R matrix

3217

R_n_xc = zeros(num_taps+ndfe);

3329

R_n_xc = zeros(num_taps+ndfe);

3218

R_n_xc(1:num_taps,1:num_taps) = R_n + R_xt ;

3330

R_n_xc(1:num_taps,1:num_taps) = R_n + R_xt ;

3219

%% For least means squares, we want to solve

3331

%% For least means squares, we want to solve

3220

%

3332

%

3221

% ro = |Ryy Ryx| * w

3333

% ro = |Ryy Ryx| * w

3222

% |Rxy Rxx|

3334

% |Rxy Rxx|

3223

% see Cioffi chapter 3, 3.7.3

3335

% see Cioffi chapter 3, 3.7.3

3224

3336

3225

himp = vsampled;

3337

himp = vsampled;

3226

RefTap = cmx+1;

3338

RefTap = cmx+1;

3227

Signal_Variance = mean ( [-1, -1/3, 1/3, 1].^2 );

3339

Signal_Variance = mean ( [-1, -1/3, 1/3, 1].^2 );

3228

Ryy.r = [1:num_taps];

3340

Ryy.r = [1:num_taps];

3229

Ryy.c = [1:num_taps];

3341

Ryy.c = [1:num_taps];

3230

Ryx.r = 1:num_taps;

3342

Ryx.r = 1:num_taps;

3231

Ryx.c = num_taps + (1:ndfe);

3343

Ryx.c = num_taps + (1:ndfe);

3232

Rxy.r = num_taps + (1:ndfe);

3344

Rxy.r = num_taps + (1:ndfe);

3233

Rxy.c = 1:num_taps;

3345

Rxy.c = 1:num_taps;

3234

Rxx.r = num_taps+(1:ndfe);

3346

Rxx.r = num_taps+(1:ndfe);

3235

Rxx.c = num_taps+(1:ndfe);

3347

Rxx.c = num_taps+(1:ndfe);

3236

himp = reshape (himp,1,[]);

3348

himp = reshape (himp,1,[]);

3237

%% ro is simply the channel response reversed in time

3349

%% ro is simply the channel response reversed in time

3238

himp_lr = fliplr(himp); % make sure himp has enough pre/post cursors, e.g. numtaps+ndfe

3350

himp_lr = fliplr(himp); % make sure himp has enough pre/post cursors, e.g. numtaps+ndfe

3239

himp_lr = [zeros(1,num_taps+ndfe), himp_lr, zeros(1,num_taps+ndfe)];

3351

himp_lr = [zeros(1,num_taps+ndfe), himp_lr, zeros(1,num_taps+ndfe)];

3240

[~,pk] = max(himp_lr);

3352

[~,pk] = max(himp_lr);

3241

r_indx = (1:num_taps) - RefTap;

3353

r_indx = (1:num_taps) - RefTap;

3242

ro = [himp_lr(pk+r_indx), zeros(1,ndfe)].';

3354

ro = [himp_lr(pk+r_indx), zeros(1,ndfe)].';

3243

ro = ro*Signal_Variance;

3355

ro = ro*Signal_Variance;

3244

%% Setup up the covariance matrix

3356

%% Setup up the covariance matrix

3245

R = zeros(num_taps+ndfe);

3357

R = zeros(num_taps+ndfe);

3246

% Form Ryy

3358

% Form Ryy

3247

% Note: important to use whole impulse response

3359

% Note: important to use whole impulse response

3248

% not just the part that spans the FFE.

3360

% not just the part that spans the FFE.

3249

[ryy,lags] = xcorr(himp,himp, num_taps-1);

3361

[ryy,lags] = xcorr(himp,himp, num_taps-1);

3250

R(Ryy.r,Ryy.c) = toeplitz (ryy(num_taps:end));

3362

R(Ryy.r,Ryy.c) = toeplitz (ryy(num_taps:end));

3251

3363

3252

% Form Rxx

3364

% Form Rxx

3253

R(Rxx.r,Rxx.c) = diag(ones(1,ndfe));

3365

R(Rxx.r,Rxx.c) = diag(ones(1,ndfe));

3254

3366

3255

% Form Ryx columns

3367

% Form Ryx columns

3256

Ryx_indxs = (1:num_taps)-1;

3368

Ryx_indxs = (1:num_taps)-1;

3257

for jj = 0:ndfe-1

3369

for jj = 0:ndfe-1

3258

% R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk+1 + Ryx_indxs -jj ).';

3370

% R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk+1 + Ryx_indxs -jj ).';

3259

R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk-cmx-1 + Ryx_indxs -jj ).';

3371

R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk-cmx-1 + Ryx_indxs -jj ).';

3260

end

3372

end

3261

% Form Rxy rows

3373

% Form Rxy rows

3262

R(Rxy.r,Rxy.c ) = R(Ryx.r,Ryx.c )';

3374

R(Rxy.r,Rxy.c ) = R(Ryx.r,Ryx.c )';

3263

3375

3264

% add in Signal Variance

3376

% add in Signal Variance

3265

R = R*Signal_Variance;

3377

R = R*Signal_Variance;

3266

Rtmp = R;

3378

Rtmp = R;

3267

% Add in Xt and colored noise terms

3379

% Add in Xt and colored noise terms

3268

R = R + R_n_xc;

3380

R = R + R_n_xc;

3269

3381

3270

% SNR = 25 dB

3382

% SNR = 25 dB

3271

SNR = OP.FFE_SNR;

3383

SNR = OP.FFE_SNR;

3272

Noise_var = max(vsampled)^2*Signal_Variance/10^(SNR/10);

3384

Noise_var = max(vsampled)^2*Signal_Variance/10^(SNR/10);

3273

R_noise = diag(ones(1,num_taps))*Noise_var;

3385

R_noise = diag(ones(1,num_taps))*Noise_var;

3274

if ~OP.Do_Colored_Noise && ~OP.Do_XT_Noise

3386

if ~OP.Do_Colored_Noise && ~OP.Do_XT_Noise

3275

R(Ryy.r,Ryy.c) = R(Ryy.r,Ryy.c) + R_noise;

3387

R(Ryy.r,Ryy.c) = R(Ryy.r,Ryy.c) + R_noise;

3276

end

3388

end

3277

3389

3278

3390

3279

%% Solve for equalizer weights

3391

%% Solve for equalizer weights

3280

w = inv(R)*ro;

3392

w = inv(R)*ro;

3281

C = w;

3393

C = w;

3282

%% Deal with 1st post Cursor DFE weight saturation

3394

%% Deal with 1st post Cursor DFE weight saturation

3283

% ro = Rw by moving "saturated" weights over to the LHS

3395

% ro = Rw by moving "saturated" weights over to the LHS

3284

DFE_h1_indx = num_taps+1;

3396

DFE_h1_indx = num_taps+1;

3285

Indx_full = 1:length(C);

3397

Indx_full = 1:length(C);

3286

ws = C;

3398

ws = C;

3287

if ndfe>0 && abs(C(DFE_h1_indx)) > param.bmax(1)

3399

if ndfe>0 && abs(C(DFE_h1_indx)) > param.bmax(1)

3288

rtmp = reshape (ro,[],1);

3400

rtmp = reshape (ro,[],1);

3289

Rtmp = R;

3401

Rtmp = R;

3290

% Move saturated DFE weights over to left hand side of equation

3402

% Move saturated DFE weights over to left hand side of equation

3291

ws = zeros (size(C));

3403

ws = zeros (size(C));

3292

ws (DFE_h1_indx) = sign(C(DFE_h1_indx))*param.bmax(1);

3404

ws (DFE_h1_indx) = sign(C(DFE_h1_indx))*param.bmax(1);

3293

rtmp = rtmp - Rtmp*ws;

3405

rtmp = rtmp - Rtmp*ws;

3294

3406

3295

% and remove the corresponding column from R

3407

% and remove the corresponding column from R

3296

Rtmp(:,DFE_h1_indx) = [];

3408

Rtmp(:,DFE_h1_indx) = [];

3297

Indx_full (DFE_h1_indx) = [];

3409

Indx_full (DFE_h1_indx) = [];

3298

% now Rtmp isn't square so have to use the R'R trick

3410

% now Rtmp isn't square so have to use the R'R trick

3299

% Probably a little dicey "theoretically" because

3411

% Probably a little dicey "theoretically" because

3300

% w = inv(R)*ro is already the mmse solution

3412

% w = inv(R)*ro is already the mmse solution

3301

% now we at doing a R'R operation, but hey

3413

% now we at doing a R'R operation, but hey

3302

% seems to work

3414

% seems to work

3303

% Alternative, since R is now over specified, more rows than

3415

% Alternative, since R is now over specified, more rows than

3304

% columns, one could try removing one of the DFE rows from the

3416

% columns, one could try removing one of the DFE rows from the

3305

% Rxy Rxx portion of the R matrix.

3417

% Rxy Rxx portion of the R matrix.

3306

3418

3307

w_partial = inv(Rtmp'*Rtmp)*(Rtmp'*rtmp);

3419

w_partial = inv(Rtmp'*Rtmp)*(Rtmp'*rtmp);

3308

ws (Indx_full,:) = w_partial;

3420

ws (Indx_full,:) = w_partial;

3309

C = ws;

3421

C = ws;

3310

end

3422

end

3311

% From Cioffi, Chapter 3

3423

% From Cioffi, Chapter 3

3312

var_ffe_dfe = Signal_Variance-ws.'*ro;

3424

var_ffe_dfe = Signal_Variance-ws.'*ro;

3313

SNR_Eq = 10*log10(Signal_Variance/var_ffe_dfe-1);

3425

SNR_Eq = 10*log10(Signal_Variance/var_ffe_dfe-1);

3314

3426

3315

%% Scale FFE gain to target output voltage

3427

%% Scale FFE gain to target output voltage

3316

Target_ouput = vsampled(ivs)*10^(param.current_ffegain/20);

3428

Target_ouput = vsampled(ivs)*10^(param.current_ffegain/20);

3317

C = C*Target_ouput;

3429

C = C*Target_ouput;

3318

C = C(1:num_taps);

3430

C = C(1:num_taps);

3319

%% End MMSE dfe code

3431

%% End MMSE dfe code

3320

function Write_CSV(output_args,csv_file)

3432

function Write_CSV(output_args,csv_file)

3321

3433

3322

items = fieldnames(output_args);

3434

items = fieldnames(output_args);

3323

item_value_strings = cell(size(items));

3435

item_value_strings = cell(size(items));

3324

for field_id=1:length(items)

3436

for field_id=1:length(items)

3325

field_name=items{field_id};

3437

field_name=items{field_id};

3326

field_value=output_args.(field_name);

3438

field_value=output_args.(field_name);

3327

if isstruct(output_args.(field_name))

3439

if isstruct(output_args.(field_name))

3328

field_value='struct';

3440

field_value='struct';

3329

end

3441

end

3330

if ischar(field_value)

3442

if ischar(field_value)

3331

item_value_strings{field_id}=field_value;

3443

item_value_strings{field_id}=field_value;

3332

elseif isempty(field_value)

3444

elseif isempty(field_value)

3333

item_value_strings{field_id}='';

3445

item_value_strings{field_id}='';

3334

elseif numel(field_value)==1

3446

elseif numel(field_value)==1

3335

item_value_strings{field_id}=num2str(field_value);

3447

item_value_strings{field_id}=num2str(field_value);

3336

else

3448

else

3337

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3449

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3338

end

3450

end

3339

end

3451

end

3340

3452

3341

header_string = str2csv(items);

3453

header_string = str2csv(items);

3342

data_string = str2csv(item_value_strings);

3454

data_string = str2csv(item_value_strings);

3343

fid = fopen(csv_file,'w');

3455

fid = fopen(csv_file,'w');

3344

fprintf(fid,'%s\n', header_string);

3456

fprintf(fid,'%s\n', header_string);

3345

fprintf(fid,'%s\n', data_string);

3457

fprintf(fid,'%s\n', data_string);

3346

fclose(fid);

3458

fclose(fid);

3347

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3459

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3348

%% Used in Clause 92 for adding board trace between TP0 and TP2

3460

%% Used in Clause 92 for adding board trace between TP0 and TP2

3349

3461

3350

switch chdata.type

3462

switch chdata.type

3351

case 'THRU'

3463

case 'THRU'

3352

z_bp_tx = param.z_bp_tx;

3464

z_bp_tx = param.z_bp_tx;

3353

z_bp_rx = param.z_bp_rx;

3465

z_bp_rx = param.z_bp_rx;

3354

case 'NEXT'

3466

case 'NEXT'

3355

z_bp_tx = param.z_bp_rx;

3467

z_bp_tx = param.z_bp_rx;

3356

z_bp_rx = param.z_bp_next;

3468

z_bp_rx = param.z_bp_next;

3357

case 'FEXT'

3469

case 'FEXT'

3358

z_bp_tx = param.z_bp_fext;

3470

z_bp_tx = param.z_bp_fext;

3359

z_bp_rx = param.z_bp_rx;

3471

z_bp_rx = param.z_bp_rx;

3360

end

3472

end

3361

% Same cap on each tx and rx three is a data stratue for bifrucation but

3473

% Same cap on each tx and rx three is a data stratue for bifrucation but

3362

% logic no implemented here RIM 06/28/2019

3474

% logic no implemented here RIM 06/28/2019

3363

zref=param.Z0;

3475

zref=param.Z0;

3364

c1=param.C_0;

3476

c1=param.C_0;

3365

c2=param.C_1;

3477

c2=param.C_1;

3366

f=chdata.faxis;

3478

f=chdata.faxis;

3367

f(f<eps)=eps;

3479

f(f<eps)=eps;

3368

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3480

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3369

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3481

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3370

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3482

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3371

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3483

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3372

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

3484

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3373

% add Tx caps

3485

% add Tx caps

3374

[s11tx, s12tx, s21tx, s22tx ]= ...

3486

[s11tx, s12tx, s21tx, s22tx ]= ...

3375

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3487

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3376

[s11tx, s12tx, s21tx, s22tx ]= ...

3488

[s11tx, s12tx, s21tx, s22tx ]= ...

3377

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3489

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3378

3490

3379

3491

3380

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3492

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3381

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3493

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3382

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3494

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3383

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3495

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3384

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

3496

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_rx);

3385

% add Rx caps

3497

% add Rx caps

3386

[s11rx, s12rx, s21rx, s22rx ]= ...

3498

[s11rx, s12rx, s21rx, s22rx ]= ...

3387

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3499

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3388

[s11rx, s12rx, s21rx, s22rx ]= ...

3500

[s11rx, s12rx, s21rx, s22rx ]= ...

3389

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3501

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3390

3502

3391

3503

3392

switch OP.include_pcb

3504

switch OP.include_pcb

3393

case 1

3505

case 1

3394

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3506

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3395

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3507

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3396

case 2

3508

case 2

3397

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3509

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3398

end

3510

end

3399

3511

3400

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3512

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3401

% Used in Clause 92 for adding board trace between TP0 and TP2

3513

% Used in Clause 92 for adding board trace between TP0 and TP2

3402

switch chdata.type

3514

switch chdata.type

3403

case 'THRU'

3515

case 'THRU'

3404

z_bp_tx = param.z_bp_tx;

3516

z_bp_tx = param.z_bp_tx;

3405

case 'NEXT'

3517

case 'NEXT'

3406

z_bp_tx = param.z_bp_next;

3518

z_bp_tx = param.z_bp_next;

3407

case 'FEXT'

3519

case 'FEXT'

3408

z_bp_tx = param.z_bp_fext;

3520

z_bp_tx = param.z_bp_fext;

3409

end

3521

end

3410

3522

3411

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

3523

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3412

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

3524

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, param.z_bp_rx);

3413

3525

3414

switch OP.include_pcb

3526

switch OP.include_pcb

3415

case 1

3527

case 1

3416

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3528

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3417

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3529

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3418

case 2

3530

case 2

3419

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3531

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3420

end

3532

end

3421

3533

3422

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3534

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3423

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3535

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3424

% applying a bank of DFE at desired location

3536

% applying a bank of DFE at desired location

3425

% hisi: waveform with cursor values;

3537

% hisi: waveform with cursor values;

3426

% idx: starting index of the bank;

3538

% idx: starting index of the bank;

3427

% tap_bk: number of taps in bank;

3539

% tap_bk: number of taps in bank;

3428

% bmaxg: maxmum coefficient in bank;

3540

% bmaxg: maxmum coefficient in bank;

3429

3541

3430

if nargin<6

3542

if nargin<6

3431

dfe_delta=0;

3543

dfe_delta=0;

3432

end

3544

end

3433

3545

3434

rng=idx:idx+tap_bk-1;

3546

rng=idx:idx+tap_bk-1;

3435

flt_curval=hisi(rng);

3547

flt_curval=hisi(rng);

3436

3548

3437

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3549

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3438

3550

3439

if dfe_delta~=0

3551

if dfe_delta~=0

3440

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3552

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3441

dfe_delta.*sign(flt_curval)*curval;

3553

dfe_delta.*sign(flt_curval)*curval;

3442

else

3554

else

3443

flt_curval_q=hisi(rng);

3555

flt_curval_q=hisi(rng);

3444

end

3556

end

3445

3557

3446

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3558

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3447

hisi(rng)= hisi(rng) - curval*tap_coef;

3559

hisi(rng)= hisi(rng) - curval*tap_coef;

3448

hisi_ref(rng)=0;

3560

hisi_ref(rng)=0;

3449

3561

3450

%AJG021820

3562

%AJG021820

3451

function [ a] = bessel( n )

3563

function [ a] = bessel( n )

3452

% bessel polynomial

3564

% bessel polynomial

3453

for ii= 0:n

3565

for ii= 0:n

3454

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3566

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3455

end

3567

end

3456

3568

3457

3569

3458

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3570

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3459

% History:

3571

% History:

3460

% 1. 14th October, 2021 (Intial release)

3572

% 1. 14th October, 2021 (Intial release)

3461

3573

3462

% Definition:

3574

% Definition:

3463

% This function captures the channel delay through the time domain using causality enforcement.

3575

% This function captures the channel delay through the time domain using causality enforcement.

3464

% Following are the steps being followed.

3576

% Following are the steps being followed.

3465

% Step 1. Cascade negative frequencies

3577

% Step 1. Cascade negative frequencies

3466

% Step 2. Extract magnitude

3578

% Step 2. Extract magnitude

3467

% Step 3. IFFT of the magnitude

3579

% Step 3. IFFT of the magnitude

3468

% Step 4. Multiply by the sign(t)

3580

% Step 4. Multiply by the sign(t)

3469

% Step 5. Calculate the phase of the 1j*causal_phase

3581

% Step 5. Calculate the phase of the 1j*causal_phase

3470

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3582

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3471

% Step 7. f-domain to t-domain pulse response

3583

% Step 7. f-domain to t-domain pulse response

3472

% Step 8. Calculate the delay

3584

% Step 8. Calculate the delay

3473

3585

3474

% Author:

3586

% Author:

3475

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3587

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3476

3588

3477

% Reference:

3589

% Reference:

3478

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

3590

% 1] "IEEE Standard for Electrical Characterization of Printed Circuit Board and Related Interconnects at Frequencies up to 50 GHz," in IEEE Std 370-2020 , vol., no., pp.1-147, 8 Jan. 2021, doi: 10.1109/IEEESTD.2021.9316329.

3479

3591

3480

% Input:

3592

% Input:

3481

% freq %frequency in hertz (odd number points)

3593

% freq %frequency in hertz (odd number points)

3482

% sdd21 %insertion loss in complex (odd number points)

3594

% sdd21 %insertion loss in complex (odd number points)

3483

% param %COM native structure passed

3595

% param %COM native structure passed

3484

% OP %COM native structure passed

3596

% OP %COM native structure passed

3485

3597

3486

% Output:

3598

% Output:

3487

% delay_sec %channel delay in seconds

3599

% delay_sec %channel delay in seconds

3488

% delay_idx %channel delay index

3600

% delay_idx %channel delay index

3489

3601

3490

if iscolumn(sdd21)

3602

if iscolumn(sdd21)

3491

sdd21= sdd21.';

3603

sdd21= sdd21.';

3492

end

3604

end

3493

if iscolumn(freq)

3605

if iscolumn(freq)

3494

freq= freq.';

3606

freq= freq.';

3495

end

3607

end

3496

3608

3497

%---start. Step 1. Cascade negative frequencies

3609

%---start. Step 1. Cascade negative frequencies

3498

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3610

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3499

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3611

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3500

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3612

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3501

%---end. Step 1. Cascade negative frequencies

3613

%---end. Step 1. Cascade negative frequencies

3502

3614

3503

%---start. Step 2. Extract magnitude

3615

%---start. Step 2. Extract magnitude

3504

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3616

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3505

%---end. Step 2. Extract magnitude

3617

%---end. Step 2. Extract magnitude

3506

3618

3507

%---start. Step 3. IFFT of the magnitude

3619

%---start. Step 3. IFFT of the magnitude

3508

sdd21_mag_time = ifft(sdd21_mag_conj);

3620

sdd21_mag_time = ifft(sdd21_mag_conj);

3509

%---end. Step 3. IFFT of the magnitude

3621

%---end. Step 3. IFFT of the magnitude

3510

3622

3511

%---start. Step 4. Multiply by the sign(t)

3623

%---start. Step 4. Multiply by the sign(t)

3512

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3624

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3513

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3625

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3514

%---end. Step 4. Multiply by the sign(t)

3626

%---end. Step 4. Multiply by the sign(t)

3515

3627

3516

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3628

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3517

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3629

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3518

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3630

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3519

3631

3520

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3632

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3521

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3633

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3522

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3634

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3523

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3635

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3524

3636

3525

%---start. Step 7. f-domain to t-domain pulse response

3637

%---start. Step 7. f-domain to t-domain pulse response

3526

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3638

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3527

%--------- Extrapolation has been already done by the COM tool

3639

%--------- Extrapolation has been already done by the COM tool

3528

freq_array= freq;

3640

freq_array= freq;

3529

time_step= param.sample_dt;

3641

time_step= param.sample_dt;

3530

fmax=1/time_step/2;

3642

fmax=1/time_step/2;

3531

freq_step=(freq_array(3)-freq_array(2))/1;

3643

freq_step=(freq_array(3)-freq_array(2))/1;

3532

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3644

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3533

3645

3534

ILin=sdd21;

3646

ILin=sdd21;

3535

IL=interp_Sparam(ILin,freq_array,fout, ...

3647

IL=interp_Sparam(ILin,freq_array,fout, ...

3536

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3648

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3537

IL_nan = find(isnan(IL));

3649

IL_nan = find(isnan(IL));

3538

for in=IL_nan

3650

for in=IL_nan

3539

IL(in)=IL(in-1);

3651

IL(in)=IL(in-1);

3540

end

3652

end

3541

IL = IL(:);

3653

IL = IL(:);

3542

% add padding for time steps

3654

% add padding for time steps

3543

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3655

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3544

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3656

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3545

clear IL IL_nan IL_symmetric

3657

clear IL IL_nan IL_symmetric

3546

3658

3547

ILin=sdd21_causality_enforced;

3659

ILin=sdd21_causality_enforced;

3548

IL=interp_Sparam(ILin,freq_array,fout, ...

3660

IL=interp_Sparam(ILin,freq_array,fout, ...

3549

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3661

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3550

IL_nan = find(isnan(IL));

3662

IL_nan = find(isnan(IL));

3551

for in=IL_nan

3663

for in=IL_nan

3552

IL(in)=IL(in-1);

3664

IL(in)=IL(in-1);

3553

end

3665

end

3554

IL = IL(:);

3666

IL = IL(:);

3555

% add padding for time steps

3667

% add padding for time steps

3556

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3668

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3557

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3669

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3558

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3670

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3559

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3671

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3560

clear IL IL_nan IL_symmetric

3672

clear IL IL_nan IL_symmetric

3561

3673

3562

clear time_step fmax freq_step freq_array

3674

clear time_step fmax freq_step freq_array

3563

3675

3564

freq_step=(fout(3)-fout(2))/1;

3676

freq_step=(fout(3)-fout(2))/1;

3565

L= length(sdd21_PR);

3677

L= length(sdd21_PR);

3566

t_base = (0:L-1)/(freq_step*L);

3678

t_base = (0:L-1)/(freq_step*L);

3567

clear fout freq_step L

3679

clear fout freq_step L

3568

%---end. Step 7. f-domain to t-domain pulse response

3680

%---end. Step 7. f-domain to t-domain pulse response

3569

3681

3570

%---start. Step 8. Calculate the delay

3682

%---start. Step 8. Calculate the delay

3571

%------start. Remove the last 5% of the waveform for noise due to IFFT

3683

%------start. Remove the last 5% of the waveform for noise due to IFFT

3572

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3684

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3573

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3685

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3574

%------end. Remove the last 5% of the waveform for noise due to IFFT

3686

%------end. Remove the last 5% of the waveform for noise due to IFFT

3575

3687

3576

%---start. calculate the difference in index between the peaks

3688

%---start. calculate the difference in index between the peaks

3577

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3689

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3578

[~, peak_y_idx] = max(sdd21_PR_reduced);

3690

[~, peak_y_idx] = max(sdd21_PR_reduced);

3579

peak_idx_difference = peak_x_idx - peak_y_idx;

3691

peak_idx_difference = peak_x_idx - peak_y_idx;

3580

%---end. calculate the difference in index between the peaks

3692

%---end. calculate the difference in index between the peaks

3581

3693

3582

if peak_idx_difference~=0

3694

if peak_idx_difference~=0

3583

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

3695

search_bounds = min(peak_x_idx, peak_y_idx);%<----one may fix it to 1e3; using minimum of the peaks in assuming the other signal has zero delay

3584

error_value = length(sdd21_causality_enforced_PR_reduced);

3696

error_value = length(sdd21_causality_enforced_PR_reduced);

3585

error_idx = 0;

3697

error_idx = 0;

3586

% i= 1;

3698

% i= 1;

3587

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3699

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3588

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3700

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3589

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3701

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3590

if (error_value > current_error)

3702

if (error_value > current_error)

3591

error_idx = shift_value;

3703

error_idx = shift_value;

3592

error_value = current_error;

3704

error_value = current_error;

3593

end

3705

end

3594

% error_idx_H(i)= error_idx;

3706

% error_idx_H(i)= error_idx;

3595

% i= i+ 1;

3707

% i= i+ 1;

3596

end

3708

end

3597

%plot(error_idx_H);

3709

%plot(error_idx_H);

3598

3710

3599

if error_idx==0

3711

if error_idx==0

3600

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3712

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3601

end

3713

end

3602

3714

3603

delay_idx = error_idx;

3715

delay_idx = error_idx;

3604

else

3716

else

3605

delay_idx= 1;

3717

delay_idx= 1;

3606

end

3718

end

3607

3719

3608

delay_sec= t_base(abs(delay_idx));

3720

delay_sec= t_base(abs(delay_idx));

3609

3721

3610

3722

3611

function [return_struct]= capture_RIL_RILN(chdata)

3723

function [return_struct]= capture_RIL_RILN(chdata)

3612

% History:

3724

% History:

3613

% 1. 12th April, 2019 (Intial release)

3725

% 1. 12th April, 2019 (Intial release)

3614

%

3726

%

3615

% 2. 11th October, 2021

3727

% 2. 11th October, 2021

3616

% - Details:

3728

% - Details:

3617

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3729

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3618

% 2] Revised the selection criteria for the solution of the quadratic

3730

% 2] Revised the selection criteria for the solution of the quadratic

3619

% equation in finding the reflection coefficient (rho).

3731

% equation in finding the reflection coefficient (rho).

3620

% - Impact:

3732

% - Impact:

3621

% => Zero impact in |RIL|, while impact on angle(RIL).

3733

% => Zero impact in |RIL|, while impact on angle(RIL).

3622

% - Previous:

3734

% - Previous:

3623

% %---start. For passive networks the reflection coefficient should be less than one

3735

% %---start. For passive networks the reflection coefficient should be less than one

3624

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3736

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3625

% rho_port2= solution_1;

3737

% rho_port2= solution_1;

3626

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3738

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3627

% rho_port2= solution_2;

3739

% rho_port2= solution_2;

3628

% else

3740

% else

3629

% rho_port2= solution_1;

3741

% rho_port2= solution_1;

3630

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3742

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3631

% end

3743

% end

3632

% %---end. For passive networks the reflection coefficient should be less than one

3744

% %---end. For passive networks the reflection coefficient should be less than one

3633

%

3745

%

3634

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

3746

% RIL= conj((1- rho_port1).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- rho_port2).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3635

% - Change:

3747

% - Change:

3636

% %---start. Given the real part of the impedance is to be positive

3748

% %---start. Given the real part of the impedance is to be positive

3637

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3749

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3638

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3750

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3639

%

3751

%

3640

% rho_port2= zeros(length(solution_1), 1);

3752

% rho_port2= zeros(length(solution_1), 1);

3641

% for solution_idx= 1:length(solution_1)

3753

% for solution_idx= 1:length(solution_1)

3642

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3754

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3643

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3755

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3644

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3756

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3645

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3757

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3646

% else

3758

% else

3647

% error('An odd case has occured. Please contact the tool developer.');

3759

% error('An odd case has occured. Please contact the tool developer.');

3648

% end

3760

% end

3649

% end

3761

% end

3650

% %---end. Given the real part of the impedance is to be positive

3762

% %---end. Given the real part of the impedance is to be positive

3651

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

3763

% RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3652

3764

3653

% Definition:

3765

% Definition:

3654

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3766

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3655

3767

3656

% Author:

3768

% Author:

3657

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3769

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3658

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3770

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3659

3771

3660

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

3772

% This function has been shared by Hansel for others to evaluate for reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter.

3661

3773

3662

% Reference:

3774

% Reference:

3663

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3775

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3664

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

3776

% 2] H. Dsilva, A. Jain, J. Sasikala and A. Kumar, "Novel Signal Integrity Application of Power Wave Scattering Matrix theory," 2019 IEEE MTT-S International Microwave and RF Conference (IMARC), 2019, pp. 1-7, doi: 10.1109/IMaRC45935.2019.9118701.

3665

3777

3666

% Input:

3778

% Input:

3667

% 1] SCH: S-matrix structure

3779

% 1] SCH: S-matrix structure

3668

% SCH.Frequencies= faxis;

3780

% SCH.Frequencies= faxis;

3669

% SCH.Parameters(1,1,:)= sdd11;

3781

% SCH.Parameters(1,1,:)= sdd11;

3670

% SCH.Parameters(2,2,:)= sdd22;

3782

% SCH.Parameters(2,2,:)= sdd22;

3671

% SCH.Parameters(1,2,:)= sdd12;

3783

% SCH.Parameters(1,2,:)= sdd12;

3672

% SCH.Parameters(2,1,:)= sdd21;

3784

% SCH.Parameters(2,1,:)= sdd21;

3673

% SCH.NumPorts= 2;

3785

% SCH.NumPorts= 2;

3674

% SCH.Impedance= 100;

3786

% SCH.Impedance= 100;

3675

3787

3676

% Output: Struct returned has the following,

3788

% Output: Struct returned has the following,

3677

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3789

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3678

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3790

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3679

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3791

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3680

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3792

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3681

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3793

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3682

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3794

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3683

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3795

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3684

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3796

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3685

% return_struct.freq %Frequency axis

3797

% return_struct.freq %Frequency axis

3686

3798

3687

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3799

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3688

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3800

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3689

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3801

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3690

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3802

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3691

SCH.Frequencies=chdata(1).faxis;

3803

SCH.Frequencies=chdata(1).faxis;

3692

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3804

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3693

SCH.NumPorts= 2;

3805

SCH.NumPorts= 2;

3694

3806

3695

%---start. allowed is only a 2-port network having a transmitter and receiver

3807

%---start. allowed is only a 2-port network having a transmitter and receiver

3696

if size(SCH.Parameters, 1)~=2

3808

if size(SCH.Parameters, 1)~=2

3697

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3809

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3698

error('Allowed is only a 2-port network having a transmitter and receiver.');

3810

error('Allowed is only a 2-port network having a transmitter and receiver.');

3699

end

3811

end

3700

%---end. allowed is only a 2-port network having a transmitter and receiver

3812

%---end. allowed is only a 2-port network having a transmitter and receiver

3701

3813

3702

%---start. do not include the DC point given sinusoidals at DC are not

3814

%---start. do not include the DC point given sinusoidals at DC are not

3703

%defined

3815

%defined

3704

if SCH.Frequencies(1)==0

3816

if SCH.Frequencies(1)==0

3705

idx_start= 2;

3817

idx_start= 2;

3706

else

3818

else

3707

idx_start= 1;

3819

idx_start= 1;

3708

end

3820

end

3709

%---end. do not include the DC point given sinusoidals at DC are not

3821

%---end. do not include the DC point given sinusoidals at DC are not

3710

%defined

3822

%defined

3711

3823

3712

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3824

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3713

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3825

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3714

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3826

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3715

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3827

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3716

3828

3717

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3829

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3718

b= 1+ Sdd22.*conj(Sdd22)+...

3830

b= 1+ Sdd22.*conj(Sdd22)+...

3719

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3831

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3720

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3832

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3721

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3833

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3722

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3834

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3723

Sdd11.*conj(Sdd11);

3835

Sdd11.*conj(Sdd11);

3724

c= -conj(Sdd22)-...

3836

c= -conj(Sdd22)-...

3725

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3837

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3726

Sdd11.*conj(Sdd11).*conj(Sdd22);

3838

Sdd11.*conj(Sdd11).*conj(Sdd22);

3727

3839

3728

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3840

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3729

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3841

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3730

3842

3731

clear a b c

3843

clear a b c

3732

3844

3733

%---start. Given the real part of the impedance is to be positive

3845

%---start. Given the real part of the impedance is to be positive

3734

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3846

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3735

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3847

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3736

3848

3737

rho_port2= zeros(length(solution_1), 1);

3849

rho_port2= zeros(length(solution_1), 1);

3738

for solution_idx= 1:length(solution_1)

3850

for solution_idx= 1:length(solution_1)

3739

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3851

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3740

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3852

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3741

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3853

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3742

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3854

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3743

else

3855

else

3744

error('An odd case has occured. Please contact the tool developer.');

3856

error('An odd case has occured. Please contact the tool developer.');

3745

end

3857

end

3746

end

3858

end

3747

%---end. Given the real part of the impedance is to be positive

3859

%---end. Given the real part of the impedance is to be positive

3748

3860

3749

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3861

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3750

3862

3751

%---start. calculate the equivalent port impedance

3863

%---start. calculate the equivalent port impedance

3752

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3864

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3753

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3865

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3754

%---end. calculate the equivalent port impedance

3866

%---end. calculate the equivalent port impedance

3755

3867

3756

3868

3757

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3869

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3758

% %to zero reflections.

3870

% %to zero reflections.

3759

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

3871

RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3760

%---end. The reflectionless insertion loss is the insertion loss corresponding

3872

%---end. The reflectionless insertion loss is the insertion loss corresponding

3761

%to zero reflections.

3873

%to zero reflections.

3762

3874

3763

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3875

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3764

RILN= RIL- Sdd21;

3876

RILN= RIL- Sdd21;

3765

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3877

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3766

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3878

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3767

3879

3768

%---start. preparing returns struct

3880

%---start. preparing returns struct

3769

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3881

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3770

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3882

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3771

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3883

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3772

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3884

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3773

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3885

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3774

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3886

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3775

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3887

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3776

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3888

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3777

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3889

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3778

%---end. preparing returns struct

3890

%---end. preparing returns struct

3779

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3891

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3780

3892

3781

3893

3782

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

3894

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

3783

3895

3784

%for the top, just find the first index at the spec BER

3896

%for the top, just find the first index at the spec BER

3785

nidx=find(cdf.y>specBER, 1, 'first');

3897

nidx=find(cdf.y>specBER, 1, 'first');

3786

noise_bottom = cdf.x(nidx);

3898

noise_bottom = cdf.x(nidx);

3787

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3899

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3788

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3900

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3789

%the true index without flipping

3901

%the true index without flipping

3790

nidx=length(cdf.y)-nidx+1;

3902

nidx=length(cdf.y)-nidx+1;

3791

noise_top = cdf.x(nidx);

3903

noise_top = cdf.x(nidx);

3792

function p=comb_fct(p1, p2)

3904

function p=comb_fct(p1, p2)

3793

if p1.BinSize ~= p2.BinSize

3905

if p1.BinSize ~= p2.BinSize

3794

error('bin size must be equal')

3906

error('bin size must be equal')

3795

end

3907

end

3796

3908

3797

p=p1;

3909

p=p1;

3798

p.BinSize=p1.BinSize;

3910

p.BinSize=p1.BinSize;

3799

%p.Min=p1.Min+p2.Min;

3911

%p.Min=p1.Min+p2.Min;

3800

p.Min=min(p1.Min,p2.Min);

3912

p.Min=min(p1.Min,p2.Min);

3801

difsz=abs(p1.Min-p2.Min);

3913

difsz=abs(p1.Min-p2.Min);

3802

lp1=length(p1.y);

3914

lp1=length(p1.y);

3803

lp2=length(p2.y);

3915

lp2=length(p2.y);

3804

if p1.Min == p.Min

3916

if p1.Min == p.Min

3805

p2.y(difsz+1:lp2+difsz)=p2.y;

3917

p2.y(difsz+1:lp2+difsz)=p2.y;

3806

p2.y(1:difsz)=0;

3918

p2.y(1:difsz)=0;

3807

p2.y(lp2+difsz+1:lp1)=0;

3919

p2.y(lp2+difsz+1:lp1)=0;

3808

elseif p2.Min == p.Min

3920

elseif p2.Min == p.Min

3809

p1.y(difsz+1:lp1+difsz)=p1.y;

3921

p1.y(difsz+1:lp1+difsz)=p1.y;

3810

p1.y(1:difsz)=0;

3922

p1.y(1:difsz)=0;

3811

p1.y(lp1+difsz+1:lp2)=0;

3923

p1.y(lp1+difsz+1:lp2)=0;

3812

end

3924

end

3813

% p.y=conv(p1.y, p2.y);

3925

% p.y=conv(p1.y, p2.y);

3814

p.y=(p1.y+p2.y);

3926

p.y=(p1.y+p2.y);

3815

% p.y=p.y/sum(p.y);

3927

% p.y=p.y/sum(p.y);

3816

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3928

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3817

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3929

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3818

3930

3819

3931

3820

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

3932

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

3821

3933

3822

if pdf1.BinSize ~= pdf2.BinSize

3934

if pdf1.BinSize ~= pdf2.BinSize

3823

error('bin size must be equal')

3935

error('bin size must be equal')

3824

end

3936

end

3825

3937

3826

x1=pdf1.x;

3938

x1=pdf1.x;

3827

y1=pdf1.y;

3939

y1=pdf1.y;

3828

x2=pdf2.x;

3940

x2=pdf2.x;

3829

y2=pdf2.y;

3941

y2=pdf2.y;

3830

%find the pdf with a larger min, force it to have the same min, and insert

3942

%find the pdf with a larger min, force it to have the same min, and insert

3831

%probability = 0

3943

%probability = 0

3832

min1=pdf1.x(1);

3944

min1=pdf1.x(1);

3833

min2=pdf2.x(1);

3945

min2=pdf2.x(1);

3834

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

3946

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

3835

if min1<min2

3947

if min1<min2

3836

x2=[pdf1.x(1:shift_amount) pdf2.x];

3948

x2=[pdf1.x(1:shift_amount) pdf2.x];

3837

y2=[zeros(1,shift_amount) pdf2.y];

3949

y2=[zeros(1,shift_amount) pdf2.y];

3838

else

3950

else

3839

x1=[pdf2.x(1:shift_amount) pdf1.x];

3951

x1=[pdf2.x(1:shift_amount) pdf1.x];

3840

y1=[zeros(1,shift_amount) pdf1.y];

3952

y1=[zeros(1,shift_amount) pdf1.y];

3841

end

3953

end

3842

%find the pdf with smaller max, force it to have the same max, and insert

3954

%find the pdf with smaller max, force it to have the same max, and insert

3843

%probability=0

3955

%probability=0

3844

L1=length(x1);

3956

L1=length(x1);

3845

L2=length(x2);

3957

L2=length(x2);

3846

Ldiff=abs(L1-L2);

3958

Ldiff=abs(L1-L2);

3847

if L1>L2

3959

if L1>L2

3848

out_x=x1;

3960

out_x=x1;

3849

y2=[y2 zeros(1,Ldiff)];

3961

y2=[y2 zeros(1,Ldiff)];

3850

else

3962

else

3851

out_x=x2;

3963

out_x=x2;

3852

y1=[y1 zeros(1,Ldiff)];

3964

y1=[y1 zeros(1,Ldiff)];

3853

end

3965

end

3854

%now the 2 pdfs have the same voltage axis, add probabilities together

3966

%now the 2 pdfs have the same voltage axis, add probabilities together

3855

%renormalization is not handled here, so the output pdf will not have sum=1

3967

%renormalization is not handled here, so the output pdf will not have sum=1

3856

%It is the responsibility of the calling function to handle renormalization

3968

%It is the responsibility of the calling function to handle renormalization

3857

%if needed

3969

%if needed

3858

out_y=y1+y2;

3970

out_y=y1+y2;

3859

out_pdf.x=out_x;

3971

out_pdf.x=out_x;

3860

out_pdf.y=out_y;

3972

out_pdf.y=out_y;

3861

out_pdf.BinSize=pdf1.BinSize;

3973

out_pdf.BinSize=pdf1.BinSize;

3862

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

3974

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

3863

3975

3864

%original method:

3976

%original method:

3865

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

3977

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

3866

% for i=1:length(s11in1)

3978

% for i=1:length(s11in1)

3867

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

3979

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

3868

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

3980

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

3869

% end

3981

% end

3870

% t1=stot(s1);

3982

% t1=stot(s1);

3871

% t2=stot(s2);

3983

% t2=stot(s2);

3872

% for i=1:length(s11in1)

3984

% for i=1:length(s11in1)

3873

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

3985

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

3874

% end

3986

% end

3875

% s3=ttos(t3);

3987

% s3=ttos(t3);

3876

% s11out=s3(1,1,:);

3988

% s11out=s3(1,1,:);

3877

% s11out=transpose(s11out(:));

3989

% s11out=transpose(s11out(:));

3878

% s12out=s3(1,2,:);

3990

% s12out=s3(1,2,:);

3879

% s12out=transpose(s12out(:));

3991

% s12out=transpose(s12out(:));

3880

% s21out=s3(2,1,:);

3992

% s21out=s3(2,1,:);

3881

% s21out=transpose(s21out(:));

3993

% s21out=transpose(s21out(:));

3882

% s22out=s3(2,2,:);

3994

% s22out=s3(2,2,:);

3883

% s22out=transpose(s22out(:));

3995

% s22out=transpose(s22out(:));

3884

3996

3885

3997

3886

%vectorized method:

3998

%vectorized method:

3887

s1(1,1,:)=s11in1;

3999

s1(1,1,:)=s11in1;

3888

s1(1,2,:)=s12in1;

4000

s1(1,2,:)=s12in1;

3889

s1(2,1,:)=s21in1;

4001

s1(2,1,:)=s21in1;

3890

s1(2,2,:)=s22in1;

4002

s1(2,2,:)=s22in1;

3891

s2(1,1,:)=s11in2;

4003

s2(1,1,:)=s11in2;

3892

s2(1,2,:)=s12in2;

4004

s2(1,2,:)=s12in2;

3893

s2(2,1,:)=s21in2;

4005

s2(2,1,:)=s21in2;

3894

s2(2,2,:)=s22in2;

4006

s2(2,2,:)=s22in2;

3895

4007

3896

4008

3897

N = (1-s1(2,2,:).*s2(1,1,:)) ;

4009

N = (1-s1(2,2,:).*s2(1,1,:)) ;

3898

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

4010

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

3899

s12out = s1(1,2,:).*s2(1,2,:)./N ;

4011

s12out = s1(1,2,:).*s2(1,2,:)./N ;

3900

s21out = s2(2,1,:).*s1(2,1,:)./N;

4012

s21out = s2(2,1,:).*s1(2,1,:)./N;

3901

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

4013

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

3902

4014

3903

s11out=transpose(squeeze(s11out));

4015

s11out=transpose(squeeze(s11out));

3904

s12out=transpose(squeeze(s12out));

4016

s12out=transpose(squeeze(s12out));

3905

s21out=transpose(squeeze(s21out));

4017

s21out=transpose(squeeze(s21out));

3906

s22out=transpose(squeeze(s22out));

4018

s22out=transpose(squeeze(s22out));

3907

function p=conv_fct(p1, p2)

4019

function p=conv_fct(p1, p2)

3908

if p1.BinSize ~= p2.BinSize

4020

if p1.BinSize ~= p2.BinSize

3909

error('bin size must be equal')

4021

error('bin size must be equal')

3910

end

4022

end

3911

4023

3912

p=p1;

4024

p=p1;

3913

%p.BinSize=p1.BinSize;

4025

%p.BinSize=p1.BinSize;

3914

%p.Min=p1.Min+p2.Min;

4026

%p.Min=p1.Min+p2.Min;

3915

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4027

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3916

p.y=conv2(p1.y, p2.y);

4028

p.y=conv2(p1.y, p2.y);

3917

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

4029

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3918

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

4030

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3919

pMax=p.Min+length(p.y)-1;

4031

pMax=p.Min+length(p.y)-1;

3920

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4032

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3921

4033

3922

4034

3923

4035

3924

4036

3925

function p=conv_fct_MeanNotZero(p1, p2)

4037

function p=conv_fct_MeanNotZero(p1, p2)

3926

4038

3927

if p1.BinSize ~= p2.BinSize

4039

if p1.BinSize ~= p2.BinSize

3928

error('bin size must be equal')

4040

error('bin size must be equal')

3929

end

4041

end

3930

4042

3931

p=p1;

4043

p=p1;

3932

%p.BinSize=p1.BinSize;

4044

%p.BinSize=p1.BinSize;

3933

%p.Min=p1.Min+p2.Min;

4045

%p.Min=p1.Min+p2.Min;

3934

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4046

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3935

p.y=conv2(p1.y, p2.y);

4047

p.y=conv2(p1.y, p2.y);

3936

4048

3937

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

4049

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

3938

%But it is faster to pre-multiply BinSize instead of multiplying the entire

4050

%But it is faster to pre-multiply BinSize instead of multiplying the entire

3939

%vector by BinSize

4051

%vector by BinSize

3940

pMax=p.Min+length(p.y)-1;

4052

pMax=p.Min+length(p.y)-1;

3941

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4053

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3942

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

4054

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

3943

4055

3944

%IN:

4056

%IN:

3945

%sbr = pulse response

4057

%sbr = pulse response

3946

%param = COM "param" struct

4058

%param = COM "param" struct

3947

%OP = COM "OP" struct

4059

%OP = COM "OP" struct

3948

%peak_search_range= a limited range to search for the peak (for speed up)

4060

%peak_search_range= a limited range to search for the peak (for speed up)

3949

% it is usually +/- 20 UI

4061

% it is usually +/- 20 UI

3950

%

4062

%

3951

%OUT:

4063

%OUT:

3952

%cursor_i = sampling location

4064

%cursor_i = sampling location

3953

%no_zero_crossing = flag that reveals if sampling is not possible.

4065

%no_zero_crossing = flag that reveals if sampling is not possible.

3954

% When this function is called in optimize_fom, it signals to quit the current case

4066

% When this function is called in optimize_fom, it signals to quit the current case

3955

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

4067

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

3956

% time consuming, so saving the peak in one spot is advantageous

4068

% time consuming, so saving the peak in one spot is advantageous

3957

%zxi = zero crossing index (returned because RXFFE uses it)

4069

%zxi = zero crossing index (returned because RXFFE uses it)

3958

4070

3959

no_zero_crossing=0;

4071

no_zero_crossing=0;

3960

%need to set cursor_i to empty in case no_zero_crossing flag is set

4072

%need to set cursor_i to empty in case no_zero_crossing flag is set

3961

cursor_i=[];

4073

cursor_i=[];

3962

4074

3963

%get peak of pulse and peak index

4075

%get peak of pulse and peak index

3964

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

4076

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

3965

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

4077

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

3966

4078

3967

4079

3968

% initial guess at cursor location (t_s) - based on approximate zero crossing

4080

% initial guess at cursor location (t_s) - based on approximate zero crossing

3969

%limit search space for speed up

4081

%limit search space for speed up

3970

search_start=sbr_peak_i-4*param.samples_per_ui;

4082

search_start=sbr_peak_i-4*param.samples_per_ui;

3971

if search_start<1

4083

if search_start<1

3972

search_start=1;

4084

search_start=1;

3973

end

4085

end

3974

%Find zero crossings

4086

%Find zero crossings

3975

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

4087

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

3976

4088

3977

%Note: the original implementation of zxi:

4089

%Note: the original implementation of zxi:

3978

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

4090

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

3979

% zxi = zxi(zxi<sbr_peak_i);

4091

% zxi = zxi(zxi<sbr_peak_i);

3980

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

4092

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

3981

% The changes to limit search space and remember max(sbr) give 10x speed up

4093

% The changes to limit search space and remember max(sbr) give 10x speed up

3982

% A test case of 25k runs, reduced from 1.2s to 0.1s

4094

% A test case of 25k runs, reduced from 1.2s to 0.1s

3983

4095

3984

4096

3985

if isempty(zxi)

4097

if isempty(zxi)

3986

%if no zero crossing, the calling program must respond (since sample point will be empty)

4098

%if no zero crossing, the calling program must respond (since sample point will be empty)

3987

no_zero_crossing=1;

4099

no_zero_crossing=1;

3988

return;

4100

return;

3989

elseif length(zxi)>1

4101

elseif length(zxi)>1

3990

%only need the last zero crossing

4102

%only need the last zero crossing

3991

zxi=zxi(end);

4103

zxi=zxi(end);

3992

end

4104

end

3993

if param.ndfe==0

4105

if param.ndfe==0

3994

max_dfe1=0;

4106

max_dfe1=0;

3995

else

4107

else

3996

max_dfe1=param.bmax(1);

4108

max_dfe1=param.bmax(1);

3997

end

4109

end

3998

% adjust cursor_i to Solve equation 93A-25 %%

4110

% adjust cursor_i to Solve equation 93A-25 %%

3999

% Muller-Mueller criterion with DFE

4111

% Muller-Mueller criterion with DFE

4000

mm_range = zxi+(0:2*param.samples_per_ui);

4112

mm_range = zxi+(0:2*param.samples_per_ui);

4001

switch OP.CDR

4113

switch OP.CDR

4002

case 'Mod-MM'

4114

case 'Mod-MM'

4003

mm_metric = ...

4115

mm_metric = ...

4004

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

4116

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

4005

otherwise % MM

4117

otherwise % MM

4006

%MM is generally: first precursor = 0

4118

%MM is generally: first precursor = 0

4007

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

4119

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

4008

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

4120

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

4009

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

4121

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

4010

%first precursor = first postcursor - max_dfe

4122

%first precursor = first postcursor - max_dfe

4011

mm_metric = ...

4123

mm_metric = ...

4012

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

4124

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

4013

end

4125

end

4014

[~, mm_cursor_offset] = min(mm_metric);

4126

[~, mm_cursor_offset] = min(mm_metric);

4015

4127

4016

%cursor_i = the sample location

4128

%cursor_i = the sample location

4017

cursor_i = zxi+mm_cursor_offset-1;

4129

cursor_i = zxi+mm_cursor_offset-1;

4018

function pdf=d_cpdf( binsize, values, probs)

4130

function pdf=d_cpdf( binsize, values, probs)

4019

% p=cpdf(type, ...)

4131

% p=cpdf(type, ...)

4020

%

4132

%

4021

% CPDF is a probability mass function for discrete distributions or an

4133

% CPDF is a probability mass function for discrete distributions or an

4022

% approxmation of a PDF for continuous distributions.

4134

% approxmation of a PDF for continuous distributions.

4023

%

4135

%

4024

% cpdf is internally normalized so that the sum of probabilities is 1

4136

% cpdf is internally normalized so that the sum of probabilities is 1

4025

% (regardless of bin size).

4137

% (regardless of bin size).

4026

4138

4027

% Internal fields:

4139

% Internal fields:

4028

% Min: *bin number* of minimum value.

4140

% Min: *bin number* of minimum value.

4029

% BinSize: size of PDF bins. Bin center is the representative value.

4141

% BinSize: size of PDF bins. Bin center is the representative value.

4030

% Vec: vector of probabilities per bin.

4142

% Vec: vector of probabilities per bin.

4031

4143

4032

%speed up for initializing empty pdf

4144

%speed up for initializing empty pdf

4033

if all(values==0)

4145

if all(values==0)

4034

pdf.BinSize=binsize;

4146

pdf.BinSize=binsize;

4035

pdf.Min=0;

4147

pdf.Min=0;

4036

pdf.y=1;

4148

pdf.y=1;

4037

pdf.x=0;

4149

pdf.x=0;

4038

return;

4150

return;

4039

end

4151

end

4040

4152

4041

if ~issorted(values)

4153

if ~issorted(values)

4042

[values,si]=sort(values);

4154

[values,si]=sort(values);

4043

probs=probs(si);

4155

probs=probs(si);

4044

end

4156

end

4045

values=binsize*round(values/binsize);

4157

values=binsize*round(values/binsize);

4046

t=(values(1):binsize:values(end));

4158

t=(values(1):binsize:values(end));

4047

pdf.Min=values(1)/binsize;

4159

pdf.Min=values(1)/binsize;

4048

pdf.y=zeros(size(t));

4160

pdf.y=zeros(size(t));

4049

for k=1:length(values)

4161

for k=1:length(values)

4050

if k==1

4162

if k==1

4051

bin=1;

4163

bin=1;

4052

elseif k==length(values)

4164

elseif k==length(values)

4053

bin=length(t);

4165

bin=length(t);

4054

else

4166

else

4055

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

4167

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

4056

end

4168

end

4057

pdf.y(bin) = pdf.y(bin)+probs(k);

4169

pdf.y(bin) = pdf.y(bin)+probs(k);

4058

end

4170

end

4059

4171

4060

pdf.BinSize=binsize;

4172

pdf.BinSize=binsize;

4061

pdf.y=pdf.y/sum(pdf.y);

4173

pdf.y=pdf.y/sum(pdf.y);

4062

if any(~isreal(pdf.y)) || any(pdf.y<0)

4174

if any(~isreal(pdf.y)) || any(pdf.y<0)

4063

error('PDF must be real and nonnegative');

4175

error('PDF must be real and nonnegative');

4064

end

4176

end

4065

support=find(pdf.y);

4177

support=find(pdf.y);

4066

pdf.y=pdf.y(support(1):support(end));

4178

pdf.y=pdf.y(support(1):support(end));

4067

pdf.Min=pdf.Min+(support(1)-1);

4179

pdf.Min=pdf.Min+(support(1)-1);

4068

pdf.x=(pdf.Min:-pdf.Min)*binsize;

4180

pdf.x=(pdf.Min:-pdf.Min)*binsize;

4069

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

4181

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

4070

4182

4071

if isrow(input)

4183

if isrow(input)

4072

max_threshold=max_threshold(:).';

4184

max_threshold=max_threshold(:).';

4073

min_threshold=min_threshold(:).';

4185

min_threshold=min_threshold(:).';

4074

else

4186

else

4075

max_threshold=max_threshold(:);

4187

max_threshold=max_threshold(:);

4076

min_threshold=min_threshold(:);

4188

min_threshold=min_threshold(:);

4077

end

4189

end

4078

4190

4079

clip_output=input;

4191

clip_output=input;

4080

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

4192

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

4081

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

4193

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

4082

4194

4083

4195

4084

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

4196

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

4085

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

4197

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

4086

if mele ==2

4198

if mele ==2

4087

param.flex=2;

4199

param.flex=2;

4088

elseif mele==4

4200

elseif mele==4

4089

param.flex=4;

4201

param.flex=4;

4090

elseif mele==1

4202

elseif mele==1

4091

param.flex=1;

4203

param.flex=1;

4092

else

4204

else

4093

error(springf('config file syntax error'))

4205

error(springf('config file syntax error'))

4094

end

4206

end

4095

4207

4096

4208

4097

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

4209

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

4098

% display bathtub curves in one axis per test case.

4210

% display bathtub curves in one axis per test case.

4099

% h=findall(0, 'Name', 'COM results');

4211

% h=findall(0, 'Name', 'COM results');

4100

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

4212

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

4101

msgtext = cell(1, length(OP.pkg_len_select));

4213

msgtext = cell(1, length(OP.pkg_len_select));

4102

msgcolor = 'g';

4214

msgcolor = 'g';

4103

else

4215

else

4104

msgtext=get(findobj(h, 'type', 'text'), 'string');

4216

msgtext=get(findobj(h, 'type', 'text'), 'string');

4105

msgcolor = get(h, 'color');

4217

msgcolor = get(h, 'color');

4106

close(h); % will be recreated

4218

close(h); % will be recreated

4107

end

4219

end

4108

msgctr=size(msgtext,1)+1;

4220

msgctr=size(msgtext,1)+1;

4109

if ~OP.ERL_ONLY

4221

if ~OP.ERL_ONLY

4110

switch OP.PHY

4222

switch OP.PHY

4111

case 'C2M'

4223

case 'C2M'

4112

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4224

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4113

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4225

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4114

msg, VEO_mV);

4226

msg, VEO_mV);

4115

else

4227

else

4116

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4228

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4117

msg, VEO_mV);

4229

msg, VEO_mV);

4118

msgcolor = 'r';

4230

msgcolor = 'r';

4119

end

4231

end

4120

4232

4121

if VEC_dB <= param.VEC_pass_threshold

4233

if VEC_dB <= param.VEC_pass_threshold

4122

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4234

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4123

(msg), VEC_dB);

4235

(msg), VEC_dB);

4124

else

4236

else

4125

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4237

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4126

(msg), VEC_dB);

4238

(msg), VEC_dB);

4127

msgcolor = 'r';

4239

msgcolor = 'r';

4128

end

4240

end

4129

case 'C2C'

4241

case 'C2C'

4130

if COM >= param.pass_threshold

4242

if COM >= param.pass_threshold

4131

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4243

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4132

% msg, COM);

4244

% msg, COM);

4133

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4245

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4134

msg, COM);

4246

msg, COM);

4135

else

4247

else

4136

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4248

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4137

% msg, COM);

4249

% msg, COM);

4138

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4250

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4139

msg, COM);

4251

msg, COM);

4140

msgcolor = 'r';

4252

msgcolor = 'r';

4141

end

4253

end

4142

% begin yasuo patch 3/18/2019

4254

% begin yasuo patch 3/18/2019

4143

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4255

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4144

% end yasuo patch

4256

% end yasuo patch

4145

case 'C2Mcom'

4257

case 'C2Mcom'

4146

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4258

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4147

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4259

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4148

msg, VEO_mV);

4260

msg, VEO_mV);

4149

else

4261

else

4150

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4262

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4151

msg, VEO_mV);

4263

msg, VEO_mV);

4152

msgcolor = 'r';

4264

msgcolor = 'r';

4153

end

4265

end

4154

4266

4155

if VEC_dB <= param.VEC_pass_threshold

4267

if VEC_dB <= param.VEC_pass_threshold

4156

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4268

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4157

(msg), VEC_dB);

4269

(msg), VEC_dB);

4158

else

4270

else

4159

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4271

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4160

(msg), VEC_dB);

4272

(msg), VEC_dB);

4161

msgcolor = 'r';

4273

msgcolor = 'r';

4162

end

4274

end

4163

if COM >= param.pass_threshold

4275

if COM >= param.pass_threshold

4164

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4276

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4165

% msg, COM);

4277

% msg, COM);

4166

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4278

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4167

msg, COM);

4279

msg, COM);

4168

else

4280

else

4169

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4281

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4170

% msg, COM);

4282

% msg, COM);

4171

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4283

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4172

msg, COM);

4284

msg, COM);

4173

msgcolor = 'r';

4285

msgcolor = 'r';

4174

end

4286

end

4175

% begin yasuo patch 3/18/2019

4287

% begin yasuo patch 3/18/2019

4176

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4288

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4177

% end yasuo patch

4289

% end yasuo patch

4178

end

4290

end

4179

end

4291

end

4180

if OP.ERL

4292

if OP.ERL

4181

if ~isempty(ERL)

4293

if ~isempty(ERL)

4182

if min_ERL >= param.ERL_pass_threshold

4294

if min_ERL >= param.ERL_pass_threshold

4183

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4295

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4184

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4296

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4185

else

4297

else

4186

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4298

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4187

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4299

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4188

msgcolor = 'r';

4300

msgcolor = 'r';

4189

end

4301

end

4190

end

4302

end

4191

end

4303

end

4192

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4304

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4193

set(h, 'color', msgcolor, 'tag', 'COM');

4305

set(h, 'color', msgcolor, 'tag', 'COM');

4194

movegui(h, 'center');

4306

movegui(h, 'center');

4195

else % no windows

4307

else % no windows

4196

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4308

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4197

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4309

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4198

if ~OP.ERL_ONLY

4310

if ~OP.ERL_ONLY

4199

switch OP.PHY

4311

switch OP.PHY

4200

case 'C2C'

4312

case 'C2C'

4201

if COM >= param.pass_threshold

4313

if COM >= param.pass_threshold

4202

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4314

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4203

else

4315

else

4204

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4316

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4205

end

4317

end

4206

% begin yasuo patch 3/18/2019

4318

% begin yasuo patch 3/18/2019

4207

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4319

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4208

% end yasuo patch

4320

% end yasuo patch

4209

case 'C2Mcom'

4321

case 'C2Mcom'

4210

if VEC_dB <= param.VEC_pass_threshold

4322

if VEC_dB <= param.VEC_pass_threshold

4211

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4323

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4212

else

4324

else

4213

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4325

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4214

end

4326

end

4215

4327

4216

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4328

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4217

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4329

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4218

else

4330

else

4219

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4331

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4220

end

4332

end

4221

if COM >= param.pass_threshold

4333

if COM >= param.pass_threshold

4222

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4334

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4223

else

4335

else

4224

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4336

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4225

end

4337

end

4226

% begin yasuo patch 3/18/2019

4338

% begin yasuo patch 3/18/2019

4227

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4339

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4228

% end yasuo patch

4340

% end yasuo patch

4229

case 'C2M'

4341

case 'C2M'

4230

if VEC_dB <= param.VEC_pass_threshold

4342

if VEC_dB <= param.VEC_pass_threshold

4231

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4343

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4232

else

4344

else

4233

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4345

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4234

end

4346

end

4235

4347

4236

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4348

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4237

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4349

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4238

else

4350

else

4239

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4351

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4240

end

4352

end

4241

end

4353

end

4242

end

4354

end

4243

if OP.ERL

4355

if OP.ERL

4244

if ~isempty(ERL)

4356

if ~isempty(ERL)

4245

if min_ERL >= param.ERL_pass_threshold

4357

if min_ERL >= param.ERL_pass_threshold

4246

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4358

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4247

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4359

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4248

else

4360

else

4249

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4361

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4250

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4362

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4251

end

4363

end

4252

end

4364

end

4253

end

4365

end

4254

end

4366

end

4255

4367

4256

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4368

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4257

4369

4258

%Left eye Width (Top Eye)

4370

%Left eye Width (Top Eye)

4259

left_top=eye_contour(half_UI:-1:1,1);

4371

left_top=eye_contour(half_UI:-1:1,1);

4260

%vref_crossing is the first point less than vref (usually first point < 0)

4372

%vref_crossing is the first point less than vref (usually first point < 0)

4261

vref_crossing=find(left_top<vref,1,'first');

4373

vref_crossing=find(left_top<vref,1,'first');

4262

if isempty(vref_crossing)

4374

if isempty(vref_crossing)

4263

%this case handles completely open eye

4375

%this case handles completely open eye

4264

L1=half_UI;

4376

L1=half_UI;

4265

elseif vref_crossing==1

4377

elseif vref_crossing==1

4266

%this case handles completely closed eye

4378

%this case handles completely closed eye

4267

L1=0;

4379

L1=0;

4268

else

4380

else

4269

%this case handles the normal eye

4381

%this case handles the normal eye

4270

%INT is a linear interpolation between the 2 points on either side of

4382

%INT is a linear interpolation between the 2 points on either side of

4271

%vref to determine where the vref crossing occurred. In systems with

4383

%vref to determine where the vref crossing occurred. In systems with

4272

%a small number of samples_per_UI, interpolation improves accuracy over

4384

%a small number of samples_per_UI, interpolation improves accuracy over

4273

%just using the integer sample point

4385

%just using the integer sample point

4274

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4386

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4275

L1=half_UI-INT;

4387

L1=half_UI-INT;

4276

end

4388

end

4277

%Left eye Width (Bottom Eye)

4389

%Left eye Width (Bottom Eye)

4278

left_bot=eye_contour(half_UI:-1:1,2);

4390

left_bot=eye_contour(half_UI:-1:1,2);

4279

vref_crossing=find(left_bot>vref,1,'first');

4391

vref_crossing=find(left_bot>vref,1,'first');

4280

if isempty(vref_crossing)

4392

if isempty(vref_crossing)

4281

L0=half_UI;

4393

L0=half_UI;

4282

elseif vref_crossing==1

4394

elseif vref_crossing==1

4283

L0=0;

4395

L0=0;

4284

else

4396

else

4285

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4397

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4286

L0=half_UI-INT;

4398

L0=half_UI-INT;

4287

end

4399

end

4288

%Right eye Width (Top Eye)

4400

%Right eye Width (Top Eye)

4289

right_top=eye_contour(half_UI:end,1);

4401

right_top=eye_contour(half_UI:end,1);

4290

vref_crossing=find(right_top<vref,1,'first');

4402

vref_crossing=find(right_top<vref,1,'first');

4291

if isempty(vref_crossing)

4403

if isempty(vref_crossing)

4292

R1=samples_per_UI-half_UI;

4404

R1=samples_per_UI-half_UI;

4293

elseif vref_crossing==1

4405

elseif vref_crossing==1

4294

R1=0;

4406

R1=0;

4295

else

4407

else

4296

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4408

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4297

R1=INT-half_UI;

4409

R1=INT-half_UI;

4298

end

4410

end

4299

%Right eye Width (Bottom Eye)

4411

%Right eye Width (Bottom Eye)

4300

right_bot=eye_contour(half_UI:end,2);

4412

right_bot=eye_contour(half_UI:end,2);

4301

vref_crossing=find(right_bot>vref,1,'first');

4413

vref_crossing=find(right_bot>vref,1,'first');

4302

if isempty(vref_crossing)

4414

if isempty(vref_crossing)

4303

R0=samples_per_UI-half_UI;

4415

R0=samples_per_UI-half_UI;

4304

elseif vref_crossing==1

4416

elseif vref_crossing==1

4305

R0=0;

4417

R0=0;

4306

else

4418

else

4307

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4419

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4308

R0=INT-half_UI;

4420

R0=INT-half_UI;

4309

end

4421

end

4310

4422

4311

%L1 = top left eye width

4423

%L1 = top left eye width

4312

%L0 = bottom left eye width

4424

%L0 = bottom left eye width

4313

%Left eye width is the minimum

4425

%Left eye width is the minimum

4314

%R1 = top right eye width

4426

%R1 = top right eye width

4315

%R0 = bottom right eye width

4427

%R0 = bottom right eye width

4316

%Right eye width is the minimum

4428

%Right eye width is the minimum

4317

Left_EW=min([L1 L0]);

4429

Left_EW=min([L1 L0]);

4318

Right_EW=min([R1 R0]);

4430

Right_EW=min([R1 R0]);

4319

4431

4320

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4432

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4321

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4433

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4322

% find the location of the DFE bank

4434

% find the location of the DFE bank

4323

% hisi: waveform with cursor values;

4435

% hisi: waveform with cursor values;

4324

% idx_st: starting index;

4436

% idx_st: starting index;

4325

% idx_en: ending index ;

4437

% idx_en: ending index ;

4326

% tap_bk: number of taps per bank;

4438

% tap_bk: number of taps per bank;

4327

% bmaxg: maximum coefficient;

4439

% bmaxg: maximum coefficient;

4328

4440

4329

hisi=hisi(:);

4441

hisi=hisi(:);

4330

len=idx_en-idx_st+1;

4442

len=idx_en-idx_st+1;

4331

h0=abs(hisi(idx_st:idx_en));

4443

h0=abs(hisi(idx_st:idx_en));

4332

h1=max(0,h0-bmaxg*curval);

4444

h1=max(0,h0-bmaxg*curval);

4333

4445

4334

%if cursor value is negative, force h1 to all zeros

4446

%if cursor value is negative, force h1 to all zeros

4335

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4447

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4336

%this makes the weakest isi the most desirable to choose so everything breaks

4448

%this makes the weakest isi the most desirable to choose so everything breaks

4337

if curval<0

4449

if curval<0

4338

h1=zeros(size(h0));

4450

h1=zeros(size(h0));

4339

end

4451

end

4340

4452

4341

h0n=zeros(len-tap_bk+1,1);

4453

h0n=zeros(len-tap_bk+1,1);

4342

h1n=h0n;

4454

h1n=h0n;

4343

4455

4344

for ii=1:tap_bk

4456

for ii=1:tap_bk

4345

h0tmp=h0(ii:ii+len-tap_bk);

4457

h0tmp=h0(ii:ii+len-tap_bk);

4346

h0n=h0n+h0tmp.^2;

4458

h0n=h0n+h0tmp.^2;

4347

h1tmp=h1(ii:ii+len-tap_bk);

4459

h1tmp=h1(ii:ii+len-tap_bk);

4348

h1n=h1n+h1tmp.^2;

4460

h1n=h1n+h1tmp.^2;

4349

end

4461

end

4350

4462

4351

ndiff=h0n-h1n;

4463

ndiff=h0n-h1n;

4352

4464

4353

min_energy = -Inf;

4465

min_energy = -Inf;

4354

4466

4355

idx=zeros(1,tap_bk*N_bg);

4467

idx=zeros(1,tap_bk*N_bg);

4356

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4468

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4357

set_next_bank=0;

4469

set_next_bank=0;

4358

%Loop through each group

4470

%Loop through each group

4359

for k=1:N_bg

4471

for k=1:N_bg

4360

%Sort to choose the strongest

4472

%Sort to choose the strongest

4361

[~,val_sort]=sort(ndiff,'descend');

4473

[~,val_sort]=sort(ndiff,'descend');

4362

if k==1

4474

if k==1

4363

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4475

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4364

if isequal(sort(val_sort(ordered_set)),ordered_set)

4476

if isequal(sort(val_sort(ordered_set)),ordered_set)

4365

idx=1:N_bg*tap_bk;

4477

idx=1:N_bg*tap_bk;

4366

break;

4478

break;

4367

end

4479

end

4368

end

4480

end

4369

if set_next_bank>0

4481

if set_next_bank>0

4370

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4482

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4371

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4483

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4372

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4484

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4373

set_next_bank=0;

4485

set_next_bank=0;

4374

ndiff(new_bank)=min_energy;

4486

ndiff(new_bank)=min_energy;

4375

bad_start=new_bank(1)-tap_bk+1;

4487

bad_start=new_bank(1)-tap_bk+1;

4376

bad_end=new_bank(1)-1;

4488

bad_end=new_bank(1)-1;

4377

if bad_end<=0

4489

if bad_end<=0

4378

badV=[];

4490

badV=[];

4379

elseif bad_start>0

4491

elseif bad_start>0

4380

badV=bad_start:bad_end;

4492

badV=bad_start:bad_end;

4381

else

4493

else

4382

badV=1:bad_end;

4494

badV=1:bad_end;

4383

end

4495

end

4384

if ~isempty(badV)

4496

if ~isempty(badV)

4385

ndiff(badV)=min_energy;

4497

ndiff(badV)=min_energy;

4386

end

4498

end

4387

continue;

4499

continue;

4388

end

4500

end

4389

%potential bank = the strongest tap group

4501

%potential bank = the strongest tap group

4390

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4502

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4391

if k==N_bg

4503

if k==N_bg

4392

%Last group: just choose the strongest

4504

%Last group: just choose the strongest

4393

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4505

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4394

break;

4506

break;

4395

end

4507

end

4396

4508

4397

do_it_again=1;

4509

do_it_again=1;

4398

first_time=1;

4510

first_time=1;

4399

num_loops=0;

4511

num_loops=0;

4400

while do_it_again

4512

while do_it_again

4401

do_it_again=0;

4513

do_it_again=0;

4402

if num_loops>length(ndiff)

4514

if num_loops>length(ndiff)

4403

break;

4515

break;

4404

end

4516

end

4405

%note badV: taps smaller and less than 1 group away

4517

%note badV: taps smaller and less than 1 group away

4406

bad_start=new_bank(1)-tap_bk+1;

4518

bad_start=new_bank(1)-tap_bk+1;

4407

bad_end=new_bank(1)-1;

4519

bad_end=new_bank(1)-1;

4408

if bad_end<=0

4520

if bad_end<=0

4409

badV=[];

4521

badV=[];

4410

elseif bad_start>0

4522

elseif bad_start>0

4411

badV=bad_start:bad_end;

4523

badV=bad_start:bad_end;

4412

else

4524

else

4413

badV=1:bad_end;

4525

badV=1:bad_end;

4414

end

4526

end

4415

for j=length(badV):-1:1

4527

for j=length(badV):-1:1

4416

if any(badV(j)-idx==0)

4528

if any(badV(j)-idx==0)

4417

badV(j)=[];

4529

badV(j)=[];

4418

end

4530

end

4419

end

4531

end

4420

%note goodV: the tap exactly 1 tap_bk smaller

4532

%note goodV: the tap exactly 1 tap_bk smaller

4421

goodV=new_bank(1)-tap_bk;

4533

goodV=new_bank(1)-tap_bk;

4422

if ~isempty(badV)

4534

if ~isempty(badV)

4423

if ~first_time

4535

if ~first_time

4424

[~,val_sort]=sort(ndiff,'descend');

4536

[~,val_sort]=sort(ndiff,'descend');

4425

end

4537

end

4426

first_time=0;

4538

first_time=0;

4427

checkV=[badV new_bank];

4539

checkV=[badV new_bank];

4428

4540

4429

badV_pos=zeros(1,length(badV));

4541

badV_pos=zeros(1,length(badV));

4430

for j=1:length(badV)

4542

for j=1:length(badV)

4431

badV_pos(j)=find(badV(j)==val_sort);

4543

badV_pos(j)=find(badV(j)==val_sort);

4432

end

4544

end

4433

4545

4434

%loop through the sorted list to find the first tap outside the group and not a member of badV

4546

%loop through the sorted list to find the first tap outside the group and not a member of badV

4435

found_goodV=0;

4547

found_goodV=0;

4436

for ii=1:length(val_sort)

4548

for ii=1:length(val_sort)

4437

if val_sort(ii)==goodV

4549

if val_sort(ii)==goodV

4438

found_goodV=1;

4550

found_goodV=1;

4439

break;

4551

break;

4440

end

4552

end

4441

if all(val_sort(ii)-checkV~=0)

4553

if all(val_sort(ii)-checkV~=0)

4442

break;

4554

break;

4443

end

4555

end

4444

end

4556

end

4445

4557

4446

if ~found_goodV && min(badV_pos)<ii

4558

if ~found_goodV && min(badV_pos)<ii

4447

%if goodV wasn't found and bad taps occur before non group members are found

4559

%if goodV wasn't found and bad taps occur before non group members are found

4448

%throw out the strongest tap and take the next strongest

4560

%throw out the strongest tap and take the next strongest

4449

do_it_again=1;

4561

do_it_again=1;

4450

ndiff(new_bank(1))=min_energy;

4562

ndiff(new_bank(1))=min_energy;

4451

%speed up: new max_val is always val_sort(2)

4563

%speed up: new max_val is always val_sort(2)

4452

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4564

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4453

end

4565

end

4454

if found_goodV

4566

if found_goodV

4455

%if goodV was found, set the next bank to goodV

4567

%if goodV was found, set the next bank to goodV

4456

set_next_bank=goodV;

4568

set_next_bank=goodV;

4457

end

4569

end

4458

end

4570

end

4459

num_loops=num_loops+1;

4571

num_loops=num_loops+1;

4460

end

4572

end

4461

%at the end, the floating taps are set to idx

4573

%at the end, the floating taps are set to idx

4462

%and ndiff has illegal values set to zero

4574

%and ndiff has illegal values set to zero

4463

ndiff(new_bank)=min_energy;

4575

ndiff(new_bank)=min_energy;

4464

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4576

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4465

if ~isempty(badV)

4577

if ~isempty(badV)

4466

ndiff(badV)=min_energy;

4578

ndiff(badV)=min_energy;

4467

end

4579

end

4468

end

4580

end

4469

4581

4470

4582

4471

idx=idx+idx_st-1;

4583

idx=idx+idx_st-1;

4472

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4584

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4473

4585

4474

% hisi = postcursor isi

4586

% hisi = postcursor isi

4475

% N_b = number of fixed dfe taps (before floating taps begin)

4587

% N_b = number of fixed dfe taps (before floating taps begin)

4476

% N_bf = number of floating taps per group

4588

% N_bf = number of floating taps per group

4477

% N_bg = nubmber of groups

4589

% N_bg = nubmber of groups

4478

% N_bmax = max tap number that can be used for floating tap

4590

% N_bmax = max tap number that can be used for floating tap

4479

% bmaxg = max tap strength for floating taps

4591

% bmaxg = max tap strength for floating taps

4480

% curval = value of the cursor

4592

% curval = value of the cursor

4481

4593

4482

4594

4483

if nargin<8, dfe_delta=0;end

4595

if nargin<8, dfe_delta=0;end

4484

4596

4485

4597

4486

tap_coef=zeros(1,length(hisi));

4598

tap_coef=zeros(1,length(hisi));

4487

b=zeros(1,length(hisi));

4599

b=zeros(1,length(hisi));

4488

4600

4489

4601

4490

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4602

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4491

4603

4492

%Apply DFE to all taps

4604

%Apply DFE to all taps

4493

flt_curval=hisi(tap_loc);

4605

flt_curval=hisi(tap_loc);

4494

if dfe_delta~=0

4606

if dfe_delta~=0

4495

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4607

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4496

dfe_delta.*sign(flt_curval)*curval;

4608

dfe_delta.*sign(flt_curval)*curval;

4497

else

4609

else

4498

flt_curval_q=hisi(tap_loc);

4610

flt_curval_q=hisi(tap_loc);

4499

end

4611

end

4500

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4612

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4501

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4613

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4502

tap_coef(tap_loc)=applied_coef;

4614

tap_coef(tap_loc)=applied_coef;

4503

4615

4504

4616

4505

4617

4506

tap_loc=sort(tap_loc,'ascend');

4618

tap_loc=sort(tap_loc,'ascend');

4507

b(tap_loc)=bmaxg;

4619

b(tap_loc)=bmaxg;

4508

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4620

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4509

% Richard Mellitz: 04/23/2019

4621

% Richard Mellitz: 04/23/2019

4510

% hisi is the isi 1 ui/sample

4622

% hisi is the isi 1 ui/sample

4511

% N_b number of fixed dfe taps

4623

% N_b number of fixed dfe taps

4512

% N_bf number of floating taps per group

4624

% N_bf number of floating taps per group

4513

% N_bg number of floating tap groups. 1 2 or 3 right now

4625

% N_bg number of floating tap groups. 1 2 or 3 right now

4514

% N_bmax number of ui for the max reach of the floating taps

4626

% N_bmax number of ui for the max reach of the floating taps

4515

% bmaxg limit for the floating taps

4627

% bmaxg limit for the floating taps

4516

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4628

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4517

%

4629

%

4518

%

4630

%

4519

% function to remove isi or add noise above bmaxg

4631

% function to remove isi or add noise above bmaxg

4520

if ~exist('COOP','var'), COOP=0;end

4632

if ~exist('COOP','var'), COOP=0;end

4521

if iscolumn(hisi); hisi=hisi.';end

4633

if iscolumn(hisi); hisi=hisi.';end

4522

hsis_in=hisi;

4634

hsis_in=hisi;

4523

% find all the reduction group taken N_bf at a time

4635

% find all the reduction group taken N_bf at a time

4524

% we are looking for the group when when remove yield the miminim isi, h, power

4636

% we are looking for the group when when remove yield the miminim isi, h, power

4525

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4637

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4526

% add on switch and loop for each potential group

4638

% add on switch and loop for each potential group

4527

switch N_bg

4639

switch N_bg

4528

case 0

4640

case 0

4529

bmax=0;

4641

bmax=0;

4530

return

4642

return

4531

case 1

4643

case 1

4532

end1=N_bmax-N_bf;

4644

end1=N_bmax-N_bf;

4533

end2=N_b+1;

4645

end2=N_b+1;

4534

end3=N_b+1;

4646

end3=N_b+1;

4535

case 2

4647

case 2

4536

end1=N_bmax-N_bf;

4648

end1=N_bmax-N_bf;

4537

end2=N_bmax-N_bf;

4649

end2=N_bmax-N_bf;

4538

end3=N_b+1;

4650

end3=N_b+1;

4539

case 3

4651

case 3

4540

end1=N_bmax-N_bf;

4652

end1=N_bmax-N_bf;

4541

end2=N_bmax-N_bf;

4653

end2=N_bmax-N_bf;

4542

end3=N_bmax-N_bf;

4654

end3=N_bmax-N_bf;

4543

end

4655

end

4544

if COOP

4656

if COOP

4545

for ig1= N_b+1:end1 % now remove the 2nd group

4657

for ig1= N_b+1:end1 % now remove the 2nd group

4546

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4658

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4547

% loop for 2rd group

4659

% loop for 2rd group

4548

for ig2= N_b+1: end2

4660

for ig2= N_b+1: end2

4549

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4661

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4550

if N_bg < 2; hcap2 =hcap; end

4662

if N_bg < 2; hcap2 =hcap; end

4551

for ig3= N_b+1: end3

4663

for ig3= N_b+1: end3

4552

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4664

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4553

if N_bg < 3 ; hcap3=hcap2 ; end

4665

if N_bg < 3 ; hcap3=hcap2 ; end

4554

sigma=norm( hcap3 );

4666

sigma=norm( hcap3 );

4555

if sigma < best_sigma

4667

if sigma < best_sigma

4556

best_sigma=sigma;

4668

best_sigma=sigma;

4557

best_ig1=ig1;

4669

best_ig1=ig1;

4558

best_ig2=ig2;

4670

best_ig2=ig2;

4559

best_ig3=ig3;

4671

best_ig3=ig3;

4560

best_hcap=hcap3;

4672

best_hcap=hcap3;

4561

end

4673

end

4562

end

4674

end

4563

end

4675

end

4564

end

4676

end

4565

else % sequentail

4677

else % sequentail

4566

for ig1= N_b+1:end1 % now remove the 1st group

4678

for ig1= N_b+1:end1 % now remove the 1st group

4567

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4679

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4568

sigma=norm( hcap );

4680

sigma=norm( hcap );

4569

if sigma < best_sigma

4681

if sigma < best_sigma

4570

best_sigma=sigma;

4682

best_sigma=sigma;

4571

best_ig1=ig1;

4683

best_ig1=ig1;

4572

best_hcap=hcap;

4684

best_hcap=hcap;

4573

end

4685

end

4574

end

4686

end

4575

% loop for 2rd group

4687

% loop for 2rd group

4576

hisi=best_hcap;

4688

hisi=best_hcap;

4577

for ig2= N_b+1: end2

4689

for ig2= N_b+1: end2

4578

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4690

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4579

sigma=norm( hcap );

4691

sigma=norm( hcap );

4580

if sigma < best_sigma

4692

if sigma < best_sigma

4581

best_sigma=sigma;

4693

best_sigma=sigma;

4582

best_ig2=ig2;

4694

best_ig2=ig2;

4583

best_hcap=hcap;

4695

best_hcap=hcap;

4584

end

4696

end

4585

end

4697

end

4586

hisi=best_hcap;

4698

hisi=best_hcap;

4587

% loop for 3rd group

4699

% loop for 3rd group

4588

for ig3= N_b+1: end3

4700

for ig3= N_b+1: end3

4589

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4701

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4590

sigma=norm( hcap );

4702

sigma=norm( hcap );

4591

if sigma < best_sigma

4703

if sigma < best_sigma

4592

best_sigma=sigma;

4704

best_sigma=sigma;

4593

best_ig3=ig3;

4705

best_ig3=ig3;

4594

best_hcap=hcap;

4706

best_hcap=hcap;

4595

end

4707

end

4596

end

4708

end

4597

4709

4598

end

4710

end

4599

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4711

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4600

switch N_bg

4712

switch N_bg

4601

case 1

4713

case 1

4602

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4714

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4603

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4715

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4604

case 2

4716

case 2

4605

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4717

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4606

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4718

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4607

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4719

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4608

case 3

4720

case 3

4609

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;

4610

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;

4611

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4723

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4612

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4724

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4613

end

4725

end

4614

floating_tap_locations=sort(floating_tap_locations);

4726

floating_tap_locations=sort(floating_tap_locations);

4615

if 0 % for code debug

4727

if 0 % for code debug

4616

close force all

4728

close force all

4617

stem(best_hcap,'disp','hcap')

4729

stem(best_hcap,'disp','hcap')

4618

hold on

4730

hold on

4619

stem(bmax,'-k','disp','bmax')

4731

stem(bmax,'-k','disp','bmax')

4620

stem(hisi,'disp','hisi')

4732

stem(hisi,'disp','hisi')

4621

hold off

4733

hold off

4622

end

4734

end

4623

4735

4624

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4736

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4625

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4737

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4626

% Vfilter is vector forced filtered sbr

4738

% Vfilter is vector forced filtered sbr

4627

% Cmod is the ffe tap co-efficient vector

4739

% Cmod is the ffe tap co-efficient vector

4628

% if C is passed, just process V with C else compute C

4740

% if C is passed, just process V with C else compute C

4629

% cmx=param.rx_cmx; number of pre cursor taps

4741

% cmx=param.rx_cmx; number of pre cursor taps

4630

% cpx=param.rx_cps; number of post cursor taps

4742

% cpx=param.rx_cps; number of post cursor taps

4631

% V=sbr; pass pulse response

4743

% V=sbr; pass pulse response

4632

% ix the sample point in the passed pulse response

4744

% ix the sample point in the passed pulse response

4633

% the sample point is recomputed by optimize_fom

4745

% the sample point is recomputed by optimize_fom

4634

% idx - return floating tap location (RIM 9-19-2023)

4746

% idx - return floating tap location (RIM 9-19-2023)

4635

% OP not used for now

4747

% OP not used for now

4636

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4748

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4637

% this allows significant speed up in optimize_fom since FFE is time consuming

4749

% this allows significant speed up in optimize_fom since FFE is time consuming

4638

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4750

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4639

% Vfiltered to be calculated

4751

% Vfiltered to be calculated

4640

% test with load('SBR_FIR_resp.mydata','-mat')

4752

% test with load('SBR_FIR_resp.mydata','-mat')

4641

idx=[];

4753

idx=[];

4642

if nargin<4

4754

if nargin<4

4643

ix=find(V==max(V),1,'first');

4755

ix=find(V==max(V),1,'first');

4644

end

4756

end

4645

if nargin<5

4757

if nargin<5

4646

C=[];

4758

C=[];

4647

end

4759

end

4648

if nargin<6

4760

if nargin<6

4649

return_V=1;

4761

return_V=1;

4650

end

4762

end

4651

cmx=param.RxFFE_cmx;

4763

cmx=param.RxFFE_cmx;

4652

cpx=param.RxFFE_cpx;

4764

cpx=param.RxFFE_cpx;

4653

% do this early on so we can reuse the old code

4765

% do this early on so we can reuse the old code

4654

if param.N_bg ~=0 % must be floating taps

4766

if param.N_bg ~=0 % must be floating taps

4655

cpx=param.N_bmax; % N_f in spreadsheet

4767

cpx=param.N_bmax; % N_f in spreadsheet

4656

end

4768

end

4657

num_taps=cmx+cpx+1;

4769

num_taps=cmx+cpx+1;

4658

cstep=param.RxFFE_stepz;

4770

cstep=param.RxFFE_stepz;

4659

ndfe=param.ndfe;

4771

ndfe=param.ndfe;

4660

spui=param.samples_per_ui;

4772

spui=param.samples_per_ui;

4661

param.current_ffegain=0;

4773

param.current_ffegain=0;

4662

if return_V && ~isempty(C)

4774

if return_V && ~isempty(C)

4663

% RIM 2-3-23 when we just want to EQ not find EQ

4775

% RIM 2-3-23 when we just want to EQ not find EQ

4664

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4776

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4665

Cmod=C;

4777

Cmod=C;

4666

return

4778

return

4667

end

4779

end

4668

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4780

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4669

if ix < length(V)

4781

if ix < length(V)

4670

if isrow(V)

4782

if isrow(V)

4671

if mod(ix,spui) == 0

4783

if mod(ix,spui) == 0

4672

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4784

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4673

else

4785

else

4674

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4786

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4675

end

4787

end

4676

4788

4677

else

4789

else

4678

if mod(ix,spui) == 0

4790

if mod(ix,spui) == 0

4679

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4791

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4680

else

4792

else

4681

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4793

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4682

end

4794

end

4683

end

4795

end

4684

else

4796

else

4685

if isrow(V)

4797

if isrow(V)

4686

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4798

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4687

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4799

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4688

else

4800

else

4689

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4801

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4690

end

4802

end

4691

else

4803

else

4692

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4804

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4693

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4805

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4694

else

4806

else

4695

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4807

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4696

end

4808

end

4697

end

4809

end

4698

end

4810

end

4699

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4811

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4700

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4812

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4701

4813

4702

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4814

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4703

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4815

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4704

% Upen Kareti suggested fix for indexing 11/04/18

4816

% Upen Kareti suggested fix for indexing 11/04/18

4705

if ix < length(V)

4817

if ix < length(V)

4706

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4818

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4707

else

4819

else

4708

ivs=find(vsampled == max(vsampled),1,'first');

4820

ivs=find(vsampled == max(vsampled),1,'first');

4709

end

4821

end

4710

4822

4711

4823

4712

%% create VV matrix of shifted UI spaced sample of the pulse response

4824

%% create VV matrix of shifted UI spaced sample of the pulse response

4713

% only consider the VV matrix that correstonds to the FFE taps

4825

% only consider the VV matrix that correstonds to the FFE taps

4714

VV=zeros(num_taps,num_taps);

4826

VV=zeros(num_taps,num_taps);

4715

for i=1:num_taps

4827

for i=1:num_taps

4716

start_idx=ivs+i-1;

4828

start_idx=ivs+i-1;

4717

end_idx=start_idx-num_taps+1;

4829

end_idx=start_idx-num_taps+1;

4718

VV(:,i)=vsampled(start_idx:-1:end_idx);

4830

VV(:,i)=vsampled(start_idx:-1:end_idx);

4719

end

4831

end

4720

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4832

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4721

%% Apply RXFFE

4833

%% Apply RXFFE

4722

if isempty(C)

4834

if isempty(C)

4723

switch upper(OP.FFE_OPT_METHOD)

4835

switch upper(OP.FFE_OPT_METHOD)

4724

case 'WIENER-HOPF'

4836

case 'WIENER-HOPF'

4725

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4837

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4726

Cmod=C(1:num_taps);

4838

Cmod=C(1:num_taps);

4727

otherwise

4839

otherwise

4728

% cmx+1 is the cursor or sample point

4840

% cmx+1 is the cursor or sample point

4729

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4841

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4730

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4842

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4731

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4843

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4732

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4844

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4733

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4845

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4734

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4846

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4735

end

4847

end

4736

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4848

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4737

if diff(size(VV))==0

4849

if diff(size(VV))==0

4738

%For square matrix, can solve C using simple inv(VV')*FV'

4850

%For square matrix, can solve C using simple inv(VV')*FV'

4739

C=VV'\FV';

4851

C=VV'\FV';

4740

else

4852

else

4741

%otherwise use the general solution with psuedo inverse

4853

%otherwise use the general solution with psuedo inverse

4742

%note: this is the same as doing pinv(VV') but pinv is far slower

4854

%note: this is the same as doing pinv(VV') but pinv is far slower

4743

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4855

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4744

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4856

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4745

end

4857

end

4746

4858

4747

Cmod=C(1:num_taps);

4859

Cmod=C(1:num_taps);

4748

end

4860

end

4749

4861

4750

4862

4751

% added for 4.2 find floating taps with either ISI or taps

4863

% added for 4.2 find floating taps with either ISI or taps

4752

switch lower(OP.RXFFE_FLOAT_CTL)

4864

switch lower(OP.RXFFE_FLOAT_CTL)

4753

case 'taps'

4865

case 'taps'

4754

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4866

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4755

otherwise

4867

otherwise

4756

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4868

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4757

end

4869

end

4758

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4870

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4759

case 'unity cursor'

4871

case 'unity cursor'

4760

Cmod=Cmod/Cmod(cmx+1);

4872

Cmod=Cmod/Cmod(cmx+1);

4761

otherwise

4873

otherwise

4762

Cmod=C;

4874

Cmod=C;

4763

end

4875

end

4764

if cstep ~= 0

4876

if cstep ~= 0

4765

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4877

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4766

end

4878

end

4767

4879

4768

if ~isempty(idx)

4880

if ~isempty(idx)

4769

idx=sort(idx);

4881

idx=sort(idx);

4770

C1=Cmod;

4882

C1=Cmod;

4771

% C1(param.N_tail_start:end)=0;

4883

% C1(param.N_tail_start:end)=0;

4772

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4884

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4773

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4885

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4774

Cmod=C1;

4886

Cmod=C1;

4775

else

4887

else

4776

% Cmod=C;

4888

% Cmod=C;

4777

end

4889

end

4778

4890

4779

% now when ussing RxFFE floating taps need to tag stems correctly and

4891

% now when ussing RxFFE floating taps need to tag stems correctly and

4780

% make sure DFEfloating tap code does not get exectuted

4892

% make sure DFEfloating tap code does not get exectuted

4781

4893

4782

%

4894

%

4783

else

4895

else

4784

Cmod=C;%just us the FFE taps, C, passed for filtering

4896

Cmod=C;%just us the FFE taps, C, passed for filtering

4785

end

4897

end

4786

%%

4898

%%

4787

%% filter the pulse response with the solved FFE

4899

%% filter the pulse response with the solved FFE

4788

% (now option to avoid this and just return Cmod for speed up)

4900

% (now option to avoid this and just return Cmod for speed up)

4789

if return_V

4901

if return_V

4790

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4902

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4791

else

4903

else

4792

Vfiltered=[];

4904

Vfiltered=[];

4793

end

4905

end

4794

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4906

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4795

% used for FD IL fitting

4907

% used for FD IL fitting

4796

% sdd21 us a complex insertion loss

4908

% sdd21 us a complex insertion loss

4797

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

4909

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

4798

sdd21=squeeze(sdd21);

4910

sdd21=squeeze(sdd21);

4799

if iscolumn(sdd21)

4911

if iscolumn(sdd21)

4800

sdd21=sdd21.';

4912

sdd21=sdd21.';

4801

end

4913

end

4802

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

4914

fmbg=[ones(length(faxis_f2),1).*transpose(abs(sdd21)) transpose(sqrt(faxis_f2)).*transpose(abs(sdd21)) transpose(faxis_f2).*transpose(abs(sdd21)) transpose(faxis_f2.^2).*transpose(abs(sdd21)) ];

4803

warning('off','MATLAB:nearlySingularMatrix');

4915

warning('off','MATLAB:nearlySingularMatrix');

4804

LGw=transpose(abs(sdd21).*db(sdd21));

4916

LGw=transpose(abs(sdd21).*db(sdd21));

4805

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4917

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4806

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4918

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4807

ILN = db(sdd21)-efit;

4919

ILN = db(sdd21)-efit;

4808

4920

4809

4921

4810

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4922

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4811

% Complex IL fitting

4923

% Complex IL fitting

4812

% sdd21 us a complex insertion loss

4924

% sdd21 us a complex insertion loss

4813

% efit and ILN are in db

4925

% efit and ILN are in db

4814

% faxix_f2 needs to be at least to fb

4926

% faxix_f2 needs to be at least to fb

4815

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

4927

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

4816

% still need to settle on voltage scaling.

4928

% still need to settle on voltage scaling.

4817

% maybe db(peak/Rss

4929

% maybe db(peak/Rss

4818

4930

4819

OP.interp_sparam_mag= 'trend_to_DC';

4931

OP.interp_sparam_mag= 'trend_to_DC';

4820

OP.interp_sparam_phase= 'interp_to_DC';

4932

OP.interp_sparam_phase= 'interp_to_DC';

4821

% OP.interp_sparam_mag= 'linear_trend_to_DC';

4933

% OP.interp_sparam_mag= 'linear_trend_to_DC';

4822

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

4934

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

4823

4935

4824

print_for_codereview=0;

4936

print_for_codereview=0;

4825

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

4937

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

4826

A_T=1;

4938

A_T=1;

4827

end

4939

end

4828

4940

4829

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

4941

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

4830

sdd21=squeeze(sdd21);

4942

sdd21=squeeze(sdd21);

4831

if iscolumn(sdd21)

4943

if iscolumn(sdd21)

4832

sdd21=sdd21.';

4944

sdd21=sdd21.';

4833

end

4945

end

4834

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

4946

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

4835

warning('off','MATLAB:nearlySingularMatrix');

4947

warning('off','MATLAB:nearlySingularMatrix');

4836

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

4948

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

4837

LGw=transpose(sdd21.*unwraplog);

4949

LGw=transpose(sdd21.*unwraplog);

4838

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4950

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4839

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4951

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4840

FIT=transpose(exp(transpose(efit_C)));

4952

FIT=transpose(exp(transpose(efit_C)));

4841

efit=db(abs(FIT));

4953

efit=db(abs(FIT));

4842

ILN = db(sdd21)-efit;

4954

ILN = db(sdd21)-efit;

4843

% time domain

4955

% time domain

4844

fprintf('computing TD_ILN (dB) ...')

4956

fprintf('computing TD_ILN (dB) ...')

4845

if exist('OP','var')

4957

if exist('OP','var')

4846

% OP.fraction_of_F_range_start_extrap_from=.95;

4958

% OP.fraction_of_F_range_start_extrap_from=.95;

4847

OP.impulse_response_truncation_threshold =1e-7;

4959

OP.impulse_response_truncation_threshold =1e-7;

4848

4960

4849

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

4961

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

4850

H_bw=Butterworth_Filter(param,faxis_f2,1);

4962

H_bw=Butterworth_Filter(param,faxis_f2,1);

4851

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

4963

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

4852

H_tw=Tukey_Window(faxis_f2,param);

4964

H_tw=Tukey_Window(faxis_f2,param);

4853

H_tw=ones(1,length(faxis_f2) );

4965

H_tw=ones(1,length(faxis_f2) );

4854

4966

4855

[TD_ILN.REF.FIR, ...

4967

[TD_ILN.REF.FIR, ...

4856

TD_ILN.REF.t, ...

4968

TD_ILN.REF.t, ...

4857

TD_ILN.REF.causality_correction_dB, ...

4969

TD_ILN.REF.causality_correction_dB, ...

4858

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4970

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4859

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

4971

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

4860

4972

4861

[TD_ILN.FIT.FIR, ...

4973

[TD_ILN.FIT.FIR, ...

4862

TD_ILN.FIT.t, ...

4974

TD_ILN.FIT.t, ...

4863

TD_ILN.FIT.causality_correction_dB, ...

4975

TD_ILN.FIT.causality_correction_dB, ...

4864

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4976

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4865

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

4977

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

4866

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

4978

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

4867

% NrangeUI=1000;

4979

% NrangeUI=1000;

4868

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

4980

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(TD_ILN.FIT.PR)-param.samples_per_ui ),length(TD_ILN.REF.PR)-param.samples_per_ui);

4869

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

4981

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

4870

range=ipeak:range_end;

4982

range=ipeak:range_end;

4871

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

4983

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

4872

TD_ILN.t=TD_ILN.FIT.t(range);

4984

TD_ILN.t=TD_ILN.FIT.t(range);

4873

TD_ILN.FOM=-inf;

4985

TD_ILN.FOM=-inf;

4874

TD_ILN.FOM_PDF=-inf;

4986

TD_ILN.FOM_PDF=-inf;

4875

rms_fom=-inf;

4987

rms_fom=-inf;

4876

for im=1:param.samples_per_ui

4988

for im=1:param.samples_per_ui

4877

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

4989

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

4878

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

4990

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

4879

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

4991

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

4880

cdf=pdf; cdf.y=cumsum(pdf.y);

4992

cdf=pdf; cdf.y=cumsum(pdf.y);

4881

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

4993

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

4882

% signal_and_isi_pdf = conv_fct(cursors, pdf);

4994

% signal_and_isi_pdf = conv_fct(cursors, pdf);

4883

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

4995

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

4884

if print_for_codereview % remove once all checked out

4996

if print_for_codereview % remove once all checked out

4885

h=figure(190);set(gcf,'Tag','COM');

4997

h=figure(190);set(gcf,'Tag','COM');

4886

semilogy(-cdf.x,cdf.y);

4998

semilogy(-cdf.x,cdf.y);

4887

% xlim ([0,-cdf.x(1)])

4999

% xlim ([0,-cdf.x(1)])

4888

ylim([param.specBER 1]);title ('CDF of ILN')

5000

ylim([param.specBER 1]);title ('CDF of ILN')

4889

hold on

5001

hold on

4890

end

5002

end

4891

if rms>rms_fom

5003

if rms>rms_fom

4892

rms_fom=rms;

5004

rms_fom=rms;

4893

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5005

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

4894

TD_ILN.PDF=pdf;

5006

TD_ILN.PDF=pdf;

4895

end

5007

end

4896

end

5008

end

4897

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

5009

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

4898

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

5010

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

4899

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

5011

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

4900

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

5012

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

4901

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

5013

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

4902

if print_for_codereview % remove once all checked out

5014

if print_for_codereview % remove once all checked out

4903

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

5015

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

4904

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

5016

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

4905

hold on

5017

hold on

4906

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

5018

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

4907

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

5019

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

4908

hold off

5020

hold off

4909

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)

5021

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',TD_ILN.SNR_ISI_FOM,TD_ILN.SNR_ISI_FOM_PDF)

4910

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

5022

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

4911

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

5023

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

4912

hold on

5024

hold on

4913

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5025

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

4914

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5026

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

4915

grid on

5027

grid on

4916

legend('show')

5028

legend('show')

4917

end

5029

end

4918

end

5030

end

4919

% display('got to end of get_ILN_cmp_td')

5031

% display('got to end of get_ILN_cmp_td')

4920

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

5032

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

+5033

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

5034

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

4921

if 1 % force indent for doc

5035

if 1 % force indent for doc

4922

num_ui=param.num_ui_RXFF_noise;

5036

num_ui=param.num_ui_RXFF_noise;

4923

M=param.samples_per_ui;

5037

M=param.samples_per_ui;

4924

L=param.levels;

5038

L=param.levels;

+5039

f_b=param.fb;

5040

SNR_TX=param.SNR_TX;

5041

dw=param.RxFFE_cmx;

5042

bmax=param.bmax;

5043

bmin=param.bmin ;

5044

Nb=param.ndfe;

4925

sigma_X2=(L^2-1)/(3*(L-1)^2);

5045

sigma_X2=(L^2-1)/(3*(L-1)^2);

4926

f_b=param.fb;

5046

eta_0=param.eta_0; %V^2/GHz

4927

T_b=1/f_b;

5047

T_b=1/f_b;

4928

delta_f = f_b/num_ui; % Units are Hz.

5048

delta_f = f_b/num_ui; % Units are Hz.

4929

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

5049

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

4930

result.fvec=fvec;

5050

result.fvec=fvec;

+5051

end

5052

if OP.COMPUTE_COM

5053

%% H_rxffe eq 178A-29 d0.2

5054

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

5055

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

5056

H_rxffe=0;

4931

SNR_TX=param.SNR_TX;

5057

for nn=1:length(result.w)

4932

eta_0=param.eta_0; %V^2/GHz

5058

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

+5059

end

5060

H_rxffe_2_of_f=abs(H_rxffe).^2;

5061

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

5062

H_rxffe_2= [real( H_rxffe_2(1)), H_rxffe_2(2:end-1), real( H_rxffe_2(end)), conj( H_rxffe_2(end-1:-1:2))];

5063

else

5064

H_rxffe_2=1;

4933

end

5065

end

+5066

4934

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

5067

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

+5068

% --->this is the point in the code may fork where we add extra rx noise

4935

%% compute S_rn healey_3dj_01_2401 slide 5

5069

%% compute S_rn ( eq 178A-15 d0.2 )

+5070

if ~OP.COMPUTE_COM

4936

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

5071

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

4937

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

5072

rxn_psd=[real(S_RN_of_f(1)), S_RN_of_f(2:end-1), real(S_RN_of_f(end)), conj(S_RN_of_f(end-1:-1:2))]; % Convert single-sided frequency response to conjugate-symmetric

4938

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

5073

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

4939

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

5074

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

4940

S_rn = sum(reshape(rxn_psd, num_ui, M).');

5075

S_rn = sum(reshape(rxn_psd, num_ui, M).');

4941

S_rn=S_rn(1:num_ui/2+1);

5076

S_rn=S_rn(1:num_ui/2+1);

4942

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

5077

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

+5078

result.S_rn=S_rn;

4943

%rxn_acf_samp = ifft(S_rn)*f_b; % Autocorrelation function. Note that the first term is rxn_rms^2.

5079

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4944

if 0 % for debug

4945

figure

4946

set(gcf, 'tag', 'COM');movegui(gcf,'northeast');

+5080

else

4947

plot(fvec(1:num_ui)/f_b,10*log10((S_rn)*1000/100) ...

5081

result.S_rn=result.S_rn.*H_rxffe_2;

4948

,'disp','Srn')

4949

xlim([0 0.5])

4950

ylim([-200 -140])

4951

set(gcf,'defaulttextinterpreter','none')

4952

xlabel('Normalized Frequency')

4953

ylabel('PSD dBm/Hz')

5082

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4954

hold on

4955

grid on

4956

title('PSD')

4957

end

5083

end

4958

result.S_rn=S_rn;

4959

result.S_rn_rms=rxn_rms;

4960

5084

4961

else % find noise for item that set have tx ffe for each loop

5085

else % find noise for item that set have tx ffe for each loop

4962

%% from healey_3dj_01_2401 slide 6

5086

%% S_xn from eq 178A-16

4963

% Crosstalk power spectral density

5087

%% Crosstalk power spectral density

+5088

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

4964

result.S_xn=0;

5089

result.S_xn=0;

4965

if length(chdata)~=1;

5090

if length(chdata)~=1

4966

for xchan=2:length(chdata)

5091

for xchan=2:length(chdata)

4967

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

5092

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

4968

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

5093

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

+5094

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

4969

% enable less UI for computation speed improvement

5095

% enable less UI for computation speed improvement

4970

%%

5096

%%

4971

if num_ui*M > length(pulse_ctle)

5097

if num_ui*M > length(pulse_ctle)

4972

pulse_ctle= [ pulse_ctle zeros(1,num_ui*M-length(pulse_ctle)) ];

5098

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

4973

else

5099

else

4974

pulse_ctle=pulse_ctle(1:num_ui*M);

4975

end

4976

cmx=find(txffe==max(txffe))-1;

4977

for i1=1:M

4978

if ~strcmp(chdata(xchan).type,'NEXT')

4979

hk(xchan).k=FFE( txffe , cmx,M, pulse_ctle )'; % need to speed up here

5100

hk(xchan).k=hk(xchan).k(1:num_ui*M);

4980

else

4981

hk(xchan).k=pulse_ctle;

4982

end

4983

end

5101

end

4984

for i1=1:M

5102

for i1=1:M

4985

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

5103

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

4986

end

5104

end

4987

iphase(xchan)=find(hxn==max(hxn));

5105

iphase(xchan)=find(hxn==max(hxn));

4988

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

5106

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

4989

result.hk(xchan).hrn= hk(xchan).hrn;

5107

result.hk(xchan).hrn= hk(xchan).hrn;

4990

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

5108

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

4991

result.S_xn=hk(xchan).S_xn+result.S_xn;

5109

result.S_xn=hk(xchan).S_xn+result.S_xn;

4992

end

5110

end

+5111

result.S_xn=result.S_xn;

5112

result.hk=hk;

5113

result.iphase=iphase;

4993

result.xn_rms = sqrt(sum(result.S_xn)* delta_f);

5114

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4994

else

5115

else % if no crosstalk, perserve structure and return 0 for S_xn

4995

result.xn_rms=0;

5116

result.S_xn=0;

+5117

result.hk=[];

4996

iphase=0;

5118

result.iphase=1;

+5119

result.S_xn_rms = 0;

5120

end

5121

else % adjust for H_rxffe when computing COM

5122

result.S_xn=result.S_xn.*H_rxffe_2;

5123

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4997

end

5124

end

4998

%% from healey_3dj_01_2401 slide 7

5125

%% S_tn from eq 178A-17

+5126

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

4999

% Transmitter noise power spectral density

5127

%% Transmitter noise power spectral density

+5128

if ~OP.COMPUTE_COM

5000

if ~OP.TDMODE

5129

if ~OP.TDMODE

5001

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

5130

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

5002

else % only use when the input was a pulse response not s-parameters

5131

else % only use when the input was a pulse response not s-parameters

5003

if isfield(chdata(1),'ctle_pulse_response')

5132

if isfield(chdata(1),'ctle_pulse_response')

5004

htn=chdata(1).ctle_pulse_response;

5133

htn=chdata(1).ctle_pulse_response;

5005

else

5134

else

5006

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

5135

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

5007

end

5136

end

5008

end

5137

end

5009

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

5138

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

5010

htn=reshape(htn,1,[]); % make row vectors

5139

htn=reshape(htn,1,[]); % make row vectors

5011

htn=[ htn(1:floor(length(htn)/M)*M) ];

5140

htn=[ htn(1:floor(length(htn)/M)*M) ];

5012

htn= [htn zeros(1,num_ui*M-length(htn)) ];

5141

htn= [htn zeros(1,num_ui*M-length(htn)) ];

5013

htn=htn(1:M:end);% resample

5142

htn=htn(1:M:end);% resample

5014

if num_ui>length(htn)

5143

if num_ui>length(htn)

5015

hext=[htn zeros(1,num_ui-length(htn))];

5144

hext=[htn zeros(1,num_ui-length(htn))];

5016

else

5145

else

5017

hext=htn(1:num_ui);

5146

hext=htn(1:num_ui);

5018

end

5147

end

5019

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

5148

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

+5149

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5150

else

5151

result.S_tn=result.S_tn.*H_rxffe_2;

5020

result.tn_rms = sqrt(sum(result.S_tn)* delta_f);

5152

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

+5153

end

5021

%% from healey_3dj_01_2401 slide 8

5154

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

+5155

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

5022

% Power spectral density of noise due to jitter

5156

%% Power spectral density of noise due to jitter

5023

%% Eq. 93A-28 %%

5157

%% Eq. 93A-28 %%

+5158

if ~OP.COMPUTE_COM

5024

sampling_offset = mod(cursor_i, M);

5159

sampling_offset = mod(cursor_i, M);

5025

%ensure we can take early sample

5160

%ensure we can take early sample

5026

if sampling_offset<=1

5161

if sampling_offset<=1

5027

sampling_offset=sampling_offset+M;

5162

sampling_offset=sampling_offset+M;

5028

end

5163

end

5029

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

5164

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

5030

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

5165

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

5031

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

5166

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

5032

else

5167

else

5033

cursors_early_sample = h(sampling_offset-1:M:end);

5168

cursors_early_sample = h(sampling_offset-1:M:end);

5034

cursors_late_sample = h(sampling_offset+1:M:end);

5169

cursors_late_sample = h(sampling_offset+1:M:end);

5035

end

5170

end

5036

% ensure lengths are equal

5171

% ensure lengths are equal

5037

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

5172

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

5038

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

5173

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

5039

h_J=reshape(h_J,1,[]); % make row vectors

5174

h_J=reshape(h_J,1,[]); % make row vectors

5040

if num_ui>length(h_J)

5175

if num_ui>length(h_J)

5041

h_J=[h_J zeros(1,num_ui-length(h_J))];

5176

h_J=[h_J zeros(1,num_ui-length(h_J))];

5042

else

5177

else

5043

h_J=h_J(1:num_ui);

5178

h_J=h_J(1:num_ui);

5044

end

5179

end

5045

result.iphase=iphase;

5046

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5180

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

+5181

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5182

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5183

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5184

else

5185

result.S_jn=result.S_jn.*H_rxffe_2;

5047

result.jn_rms = sqrt(sum(result.S_jn)* delta_f);

5186

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

+5187

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

5188

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5189

end

5190

% result.S_jn

5048

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn;

5191

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn;

+5192

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

5193

5194

%%

5195

%% Hisi to be included in MLSE rho eq 178a-28

5196

if OP.COMPUTE_COM

5197

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

5198

sampling_offset = mod(cursor_i, M);

5199

hisi=h(sampling_offset:M:end);

5200

hisi=hisi(:).';

5201

if num_ui>length(hisi)

5202

hisi=[hisi zeros(1,num_ui-length(hisi))];

5203

else

5204

hisi=hisi(1:num_ui);

5205

end

5206

cursor_n=floor(cursor_i/M)+1;

5207

for ii=1:length(hisi)

5208

if ii==cursor_n % cursor

5209

cursor=hisi(ii);

5210

hisi(ii)= 0;

5211

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

5212

ib_indx=ii-cursor_n;

5213

if hisi(ii) >= bmax(ib_indx)*cursor

5214

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

5215

elseif hisi(ii) <= bmin(ib_indx)*cursor

5216

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

5217

else

5218

hisi(ii)=0;

5219

end

5220

end

5221

end

5222

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

5223

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

5224

%%

5225

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

5226

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

5227

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

5228

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

5229

end

5049

end

5230

end

5050

function result=get_PulseR(ir,param,cb_step,ZT)

5231

function result=get_PulseR(ir,param,cb_step,ZT)

5051

%ir = impulse response

5232

%ir = impulse response

5052

%t_base=time array with equal time steps

5233

%t_base=time array with equal time steps

5053

%samp_UI = number of samples per UI for ir

5234

%samp_UI = number of samples per UI for ir

5054

5235

5055

% t for debug

5236

% t for debug

5056

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5237

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5057

5238

5058

if cb_step

5239

if cb_step

5059

Ag=1;

5240

Ag=1;

5060

dt=1/param.fb/param.samples_per_ui;

5241

dt=1/param.fb/param.samples_per_ui;

5061

edge_time=param.TR_TDR*1e-9;

5242

edge_time=param.TR_TDR*1e-9;

5062

fedge=1/edge_time;

5243

fedge=1/edge_time;

5063

tedge=0:dt:edge_time*2;

5244

tedge=0:dt:edge_time*2;

5064

%

5245

%

5065

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5246

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5066

drive_pulse=[edge ones(1,param.samples_per_ui)];

5247

drive_pulse=[edge ones(1,param.samples_per_ui)];

5067

%pulse=filter(UI_ones,1,ir);

5248

%pulse=filter(UI_ones,1,ir);

5068

% t for debug

5249

% t for debug

5069

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5250

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5070

5251

5071

pulse=filter(drive_pulse,1,ir);

5252

pulse=filter(drive_pulse,1,ir);

5072

else

5253

else

5073

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5254

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5074

end

5255

end

5075

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5256

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5076

result.PDR=PDR_response;

5257

result.PDR=PDR_response;

5077

result.pulse=pulse;

5258

result.pulse=pulse;

5078

5259

5079

5260

5080

5261

5081

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5262

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5082

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

5263

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

5083

if ~iscolumn(H), H=H.';end

5264

if ~iscolumn(H), H=H.';end

5084

if ~iscolumn(H_r), H_r=H_r.';end

5265

if ~iscolumn(H_r), H_r=H_r.';end

5085

H=H(:).*H_r;

5266

H=H(:).*H_r;

5086

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5267

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5087

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5268

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5088

5269

5089

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5270

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5090

% Complex reflection and re-reflection noise using the concept of zero'ing

5271

% Complex reflection and re-reflection noise using the concept of zero'ing

5091

% out of reflections

5272

% out of reflections

5092

% sdd21 us a complex insertion loss

5273

% sdd21 us a complex insertion loss

5093

% RIL_struct is the output of capture_RIL_RILN()

5274

% RIL_struct is the output of capture_RIL_RILN()

5094

% faxix_f2 needs to be at least to fb

5275

% faxix_f2 needs to be at least to fb

5095

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5276

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5096

% still need to settle on voltage scaling.

5277

% still need to settle on voltage scaling.

5097

% maybe db(peak/Rss

5278

% maybe db(peak/Rss

5098

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

5279

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

5099

fprintf('computing TD_RILN (dB) ...');

5280

fprintf('computing TD_RILN (dB) ...');

5100

5281

5101

OP.interp_sparam_mag= 'trend_to_DC';

5282

OP.interp_sparam_mag= 'trend_to_DC';

5102

OP.interp_sparam_phase= 'interp_to_DC';

5283

OP.interp_sparam_phase= 'interp_to_DC';

5103

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5284

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5104

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5285

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5105

5286

5106

sdd21=squeeze(sdd21);

5287

sdd21=squeeze(sdd21);

5107

if iscolumn(sdd21)

5288

if iscolumn(sdd21)

5108

sdd21=sdd21.';

5289

sdd21=sdd21.';

5109

end

5290

end

5110

RIL=squeeze(RIL_struct.RIL);

5291

RIL=squeeze(RIL_struct.RIL);

5111

if iscolumn(RIL)

5292

if iscolumn(RIL)

5112

RIL=RIL.';

5293

RIL=RIL.';

5113

end

5294

end

5114

rho_port1=squeeze(RIL_struct.rho_port1);

5295

rho_port1=squeeze(RIL_struct.rho_port1);

5115

if iscolumn(rho_port1)

5296

if iscolumn(rho_port1)

5116

rho_port1=rho_port1.';

5297

rho_port1=rho_port1.';

5117

end

5298

end

5118

rho_port2=squeeze(RIL_struct.rho_port2);

5299

rho_port2=squeeze(RIL_struct.rho_port2);

5119

if iscolumn(rho_port2)

5300

if iscolumn(rho_port2)

5120

rho_port2=rho_port2.';

5301

rho_port2=rho_port2.';

5121

end

5302

end

5122

RIL_f=squeeze(RIL_struct.freq);

5303

RIL_f=squeeze(RIL_struct.freq);

5123

if iscolumn(RIL_f)

5304

if iscolumn(RIL_f)

5124

RIL_f=RIL_f.';

5305

RIL_f=RIL_f.';

5125

end

5306

end

5126

5307

5127

%---start. Calculate the reflection and re-reflection noise

5308

%---start. Calculate the reflection and re-reflection noise

5128

number_of_echos= 1e3;

5309

number_of_echos= 1e3;

5129

fmin= 1e9;%<-------------

5310

fmin= 1e9;%<-------------

5130

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5311

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5131

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5312

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5132

for m= 1:number_of_echos

5313

for m= 1:number_of_echos

5133

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

5314

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m)).*(rho_port1.^m).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port2);

5134

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

5315

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m-1)).*(rho_port1.^(m-1)).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port1);

5135

end

5316

end

5136

5317

5137

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5318

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5138

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5319

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5139

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5320

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5140

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5321

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5141

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5322

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5142

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5323

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5143

5324

5144

% clear RIL RIL_f rho_port1 rho_port2

5325

% clear RIL RIL_f rho_port1 rho_port2

5145

% clear fmin m

5326

% clear fmin m

5146

%---end. Calculate the reflection and re-reflection noise

5327

%---end. Calculate the reflection and re-reflection noise

5147

5328

5148

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

5329

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5149

warning('off','MATLAB:nearlySingularMatrix');

5330

warning('off','MATLAB:nearlySingularMatrix');

5150

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5331

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5151

LGw=transpose(sdd21.*unwraplog);

5332

LGw=transpose(sdd21.*unwraplog);

5152

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5333

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5153

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5334

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5154

FIT=transpose(exp(transpose(efit_C)));

5335

FIT=transpose(exp(transpose(efit_C)));

5155

efit=db(abs(FIT));

5336

efit=db(abs(FIT));

5156

ILN = db(sdd21)-efit;

5337

ILN = db(sdd21)-efit;

5157

5338

5158

5339

5159

OP.impulse_response_truncation_threshold =1e-7;

5340

OP.impulse_response_truncation_threshold =1e-7;

5160

5341

5161

print_for_codereview=0;

5342

print_for_codereview=0;

5162

if exist('OP','var')

5343

if exist('OP','var')

5163

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5344

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5164

H_bw=Butterworth_Filter(param,faxis_f2,1);

5345

H_bw=Butterworth_Filter(param,faxis_f2,1);

5165

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5346

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5166

H_tw=Tukey_Window(faxis_f2,param);

5347

H_tw=Tukey_Window(faxis_f2,param);

5167

H_tw=ones(1,length(faxis_f2) );

5348

H_tw=ones(1,length(faxis_f2) );

5168

[RILN_TD_struct.REF.FIR, ...

5349

[RILN_TD_struct.REF.FIR, ...

5169

RILN_TD_struct.REF.t, ...

5350

RILN_TD_struct.REF.t, ...

5170

RILN_TD_struct.REF.causality_correction_dB, ...

5351

RILN_TD_struct.REF.causality_correction_dB, ...

5171

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5352

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5172

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5353

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5173

5354

5174

5355

5175

[RILN_TD_struct.FIT.FIR, ...

5356

[RILN_TD_struct.FIT.FIR, ...

5176

RILN_TD_struct.FIT.t, ...

5357

RILN_TD_struct.FIT.t, ...

5177

RILN_TD_struct.FIT.causality_correction_dB, ...

5358

RILN_TD_struct.FIT.causality_correction_dB, ...

5178

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5359

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5179

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5360

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5180

5361

5181

5362

5182

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5363

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5183

H_bw=Butterworth_Filter(param,RIL_f,1);

5364

H_bw=Butterworth_Filter(param,RIL_f,1);

5184

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5365

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5185

H_tw=Tukey_Window(RIL_f,param);

5366

H_tw=Tukey_Window(RIL_f,param);

5186

H_tw=ones(1,length(RIL_f) );

5367

H_tw=ones(1,length(RIL_f) );

5187

[RILN_TD_struct.RIL.FIR, ...

5368

[RILN_TD_struct.RIL.FIR, ...

5188

RILN_TD_struct.RIL.t, ...

5369

RILN_TD_struct.RIL.t, ...

5189

RILN_TD_struct.RIL.causality_correction_dB, ...

5370

RILN_TD_struct.RIL.causality_correction_dB, ...

5190

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5371

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5191

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5372

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5192

5373

5193

5374

5194

%---start. Calculate the channel delay

5375

%---start. Calculate the channel delay

5195

try

5376

try

5196

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5377

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5197

catch

5378

catch

5198

end

5379

end

5199

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5380

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5200

clear delay_sec delay_idx

5381

clear delay_sec delay_idx

5201

%---end. Calculate the channel delay

5382

%---end. Calculate the channel delay

5202

5383

5203

5384

5204

5385

5205

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5386

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5206

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5387

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5207

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5388

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5208

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5389

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5209

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5390

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5210

[RILN_TD_struct.REF_noise.FIR, ...

5391

[RILN_TD_struct.REF_noise.FIR, ...

5211

RILN_TD_struct.REF_noise.t, ...

5392

RILN_TD_struct.REF_noise.t, ...

5212

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5393

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5213

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

5394

RILN_TD_struct.REF_noise.truncation_dB] = s21_to_impulse_DC(port2_reflection_rereflection_noise.*H_bw.*H_t.*H_tw ,f_reflection_rereflection_noise, param.sample_dt, OP) ;

5214

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5395

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5215

5396

5216

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5397

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5217

% NrangeUI=1000;

5398

% NrangeUI=1000;

5218

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

5399

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(RILN_TD_struct.FIT.PR)-param.samples_per_ui ),length(RILN_TD_struct.REF.PR)-param.samples_per_ui);

5219

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5400

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5220

range=ipeak:range_end;

5401

range=ipeak:range_end;

5221

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5402

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5222

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5403

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5223

RILN_TD_struct.FOM=-inf;

5404

RILN_TD_struct.FOM=-inf;

5224

RILN_TD_struct.FOM_PDF=-inf;

5405

RILN_TD_struct.FOM_PDF=-inf;

5225

rms_fom=-inf;

5406

rms_fom=-inf;

5226

for im=1:param.samples_per_ui

5407

for im=1:param.samples_per_ui

5227

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5408

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5228

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5409

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5229

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5410

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5230

cdf=pdf; cdf.y=cumsum(pdf.y);

5411

cdf=pdf; cdf.y=cumsum(pdf.y);

5231

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5412

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5232

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5413

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5233

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5414

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5234

if print_for_codereview % remove once all checked out

5415

if print_for_codereview % remove once all checked out

5235

h=figure(190);set(gcf,'Tag','COM');

5416

h=figure(190);set(gcf,'Tag','COM');

5236

semilogy(-cdf.x,cdf.y);

5417

semilogy(-cdf.x,cdf.y);

5237

% xlim ([0,-cdf.x(1)])

5418

% xlim ([0,-cdf.x(1)])

5238

ylim([param.specBER 1]);title ('CDF of ILN')

5419

ylim([param.specBER 1]);title ('CDF of ILN')

5239

hold on

5420

hold on

5240

end

5421

end

5241

if rms>rms_fom

5422

if rms>rms_fom

5242

rms_fom=rms;

5423

rms_fom=rms;

5243

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5424

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5244

RILN_TD_struct.PDF=pdf;

5425

RILN_TD_struct.PDF=pdf;

5245

end

5426

end

5246

end

5427

end

5247

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5428

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5248

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5429

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5249

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5430

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5250

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5431

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5251

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5432

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5252

if print_for_codereview % remove once all checked out

5433

if print_for_codereview % remove once all checked out

5253

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

5434

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

5254

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5435

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5255

hold on

5436

hold on

5256

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5437

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5257

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5438

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5258

yyaxis right

5439

yyaxis right

5259

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5440

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5260

hold off

5441

hold off

5261

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)

5442

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

5262

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

5443

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

5263

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5444

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5264

hold on

5445

hold on

5265

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5446

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5266

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5447

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5267

grid on

5448

grid on

5268

legend('show')

5449

legend('show')

5269

end

5450

end

5270

end

5451

end

5271

function result=get_StepR(ir,param,cb_step,ZT)

5452

function result=get_StepR(ir,param,cb_step,ZT)

5272

%ir = impulse response

5453

%ir = impulse response

5273

%t_base=time array with equal time steps

5454

%t_base=time array with equal time steps

5274

%samp_UI = number of samples per UI for ir

5455

%samp_UI = number of samples per UI for ir

5275

% result.SBR

5456

% result.SBR

5276

% t for debug

5457

% t for debug

5277

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5458

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5278

5459

5279

if cb_step

5460

if cb_step

5280

Ag=1;

5461

Ag=1;

5281

dt=1/param.fb/param.samples_per_ui;

5462

dt=1/param.fb/param.samples_per_ui;

5282

edge_time=param.TR_TDR*1e-9;

5463

edge_time=param.TR_TDR*1e-9;

5283

fedge=1/edge_time;

5464

fedge=1/edge_time;

5284

tedge=0:dt:edge_time*2;

5465

tedge=0:dt:edge_time*2;

5285

%

5466

%

5286

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5467

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5287

drive_pulse=[edge ones(1,param.samples_per_ui)];

5468

drive_pulse=[edge ones(1,param.samples_per_ui)];

5288

%pulse=filter(UI_ones,1,ir);

5469

%pulse=filter(UI_ones,1,ir);

5289

5470

5290

pulse=filter(drive_pulse,1,ir);

5471

pulse=filter(drive_pulse,1,ir);

5291

else

5472

else

5292

pulse=cumsum(ir);

5473

pulse=cumsum(ir);

5293

end

5474

end

5294

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5475

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5295

result.ZSR=TDR_response;

5476

result.ZSR=TDR_response;

5296

result.pulse=pulse;

5477

result.pulse=pulse;

5297

5478

5298

5479

5299

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5480

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5300

% sdd is differential s-parameters structure (2 port assumed)

5481

% sdd is differential s-parameters structure (2 port assumed)

5301

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5482

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5302

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5483

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5303

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5484

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5304

% TDR_results.t starting at t=0

5485

% TDR_results.t starting at t=0

5305

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5486

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5306

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5487

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5307

% TDR_results.f frequency for filter and s parameters

5488

% TDR_results.f frequency for filter and s parameters

5308

% TDR_results.ptdr_RL reflection waveform from the pulse

5489

% TDR_results.ptdr_RL reflection waveform from the pulse

5309

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5490

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5310

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5491

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5311

% TDR_results.ERL reported effective return loss

5492

% TDR_results.ERL reported effective return loss

5312

%

5493

%

5313

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

5494

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

5314

rms =@(x) norm(x)/sqrt(length(x));

5495

rms =@(x) norm(x)/sqrt(length(x));

5315

if isfield(OP,'TDR_duration')

5496

if isfield(OP,'TDR_duration')

5316

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5497

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5317

else

5498

else

5318

TDR_duration=5;

5499

TDR_duration=5;

5319

end

5500

end

5320

if ~isfield(OP,'DISPLAY_WINDOW')

5501

if ~isfield(OP,'DISPLAY_WINDOW')

5321

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5502

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5322

end

5503

end

5323

f=sdd.Frequencies;

5504

f=sdd.Frequencies;

5324

TDR_results.f=f;

5505

TDR_results.f=f;

5325

% OP.Zt_adj=2;

5506

% OP.Zt_adj=2;

5326

if param.FLAG.S2P == 0

5507

if param.FLAG.S2P == 0

5327

5508

5328

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5509

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5329

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

5510

TDR_RL =@(Zin,Zout,s11,s12,s21,s22)(Zin.^2.*s11+Zin.^2.*s22+Zout.^2.*s11+Zout.^2.*s22+Zin.^2-Zout.^2+Zin.*Zout.*s11.*2.0-Zin.*Zout.*s22.*2.0+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21-Zout.^2.*s11.*s22+Zout.^2.*s12.*s21)./(Zin.*Zout.*2.0+Zin.^2.*s11+Zin.^2.*s22-Zout.^2.*s11-Zout.^2.*s22+Zin.^2+Zout.^2+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21+Zout.^2.*s11.*s22-Zout.^2.*s12.*s21-Zin.*Zout.*s11.*s22.*2.0+Zin.*Zout.*s12.*s21.*2.0);

5330

5511

5331

if param.RL_sel==1, other_port=2;end

5512

if param.RL_sel==1, other_port=2;end

5332

if param.RL_sel==2, other_port=1;end

5513

if param.RL_sel==2, other_port=1;end

5333

for i = 1:length(sdd.Frequencies)

5514

for i = 1:length(sdd.Frequencies)

5334

if size(sdd.Parameters,2) ==1 % for s2p files

5515

if size(sdd.Parameters,2) ==1 % for s2p files

5335

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

5516

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,1, 1 ,sdd.Parameters(param.RL_sel,param.RL_sel,i) );

5336

else

5517

else

5337

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

5518

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,sdd.Parameters( 1,2 ,i), sdd.Parameters( 2,1 ,i),sdd.Parameters( other_port,other_port ,i) );

5338

end

5519

end

5339

end

5520

end

5340

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5521

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5341

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5522

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5342

% Z_t=ZT;

5523

% Z_t=ZT;

5343

% zref=sdd.Impedance/2;

5524

% zref=sdd.Impedance/2;

5344

% if Z_t > zref

5525

% if Z_t > zref

5345

% radjust= (zref-Z_t);

5526

% radjust= (zref-Z_t);

5346

% S11adjust= radjust./(radjust + 2*zref);

5527

% S11adjust= radjust./(radjust + 2*zref);

5347

% RL=RL +S11adjust;

5528

% RL=RL +S11adjust;

5348

% elseif Z_t < zref

5529

% elseif Z_t < zref

5349

% rpad=-Z_t*zref/(Z_t-zref);

5530

% rpad=-Z_t*zref/(Z_t-zref);

5350

% S11adjust=zref/(rpad*(zref/rpad + 2));

5531

% S11adjust=zref/(rpad*(zref/rpad + 2));

5351

% RL=RL + S11adjust;

5532

% RL=RL + S11adjust;

5352

% else

5533

% else

5353

% RL=RL;

5534

% RL=RL;

5354

% end

5535

% end

5355

else

5536

else

5356

for i = 1:length(sdd.Frequencies)

5537

for i = 1:length(sdd.Frequencies)

5357

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5538

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5358

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5539

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5359

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5540

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5360

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5541

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5361

end

5542

end

5362

end

5543

end

5363

5544

5364

% end

5545

% end

5365

RL=squeeze(RL);

5546

RL=squeeze(RL);

5366

f9=f/1e9;

5547

f9=f/1e9;

5367

tr=param.TR_TDR;

5548

tr=param.TR_TDR;

5368

TDR_results.delay=500e-12 ;

5549

TDR_results.delay=500e-12 ;

5369

% determine max time from thue

5550

% determine max time from thue

5370

% if sdd.NumPorts==1

5551

% if sdd.NumPorts==1

5371

% try

5552

% try

5372

% maxtime=OP.N*param.ui;

5553

% maxtime=OP.N*param.ui;

5373

% catch

5554

% catch

5374

% maxtime=2e-9;

5555

% maxtime=2e-9;

5375

% end

5556

% end

5376

% pix=1;

5557

% pix=1;

5377

% else

5558

% else

5378

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5559

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5379

% pix=find(fir4del==max(fir4del),1);

5560

% pix=find(fir4del==max(fir4del),1);

5380

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5561

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5381

% if maxtime > tu(end); maxtime=tu(end);end

5562

% if maxtime > tu(end); maxtime=tu(end);end

5382

% endS

5563

% endS

5383

5564

5384

try

5565

try

5385

maxtime=OP.N*param.ui;

5566

maxtime=OP.N*param.ui;

5386

catch

5567

catch

5387

maxtime=2e-9;

5568

maxtime=2e-9;

5388

end

5569

end

5389

if OP.N==0

5570

if OP.N==0

5390

if sdd.NumPorts==1

5571

if sdd.NumPorts==1

5391

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5572

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5392

else

5573

else

5393

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5574

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5394

pix=find(fir4del==max(fir4del),1);

5575

pix=find(fir4del==max(fir4del),1);

5395

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5576

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5396

if maxtime > tu(end); maxtime=tu(end);end

5577

if maxtime > tu(end); maxtime=tu(end);end

5397

end

5578

end

5398

end

5579

end

5399

5580

5400

5581

5401

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5582

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5402

% (makes gausian edge somewhat causal)

5583

% (makes gausian edge somewhat causal)

5403

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

5584

H_t = exp( -2*(pi*f9*(tr)/1.6832).^2 ).*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9).*exp(-1j*2*pi*f9*tr*3);

5404

if ~isfield(OP,'cb_Guassian')

5585

if ~isfield(OP,'cb_Guassian')

5405

Use_gaussian=1;

5586

Use_gaussian=1;

5406

else

5587

else

5407

Use_gaussian=OP.cb_Guassian;

5588

Use_gaussian=OP.cb_Guassian;

5408

end

5589

end

5409

if Use_gaussian

5590

if Use_gaussian

5410

if iscolumn(H_t), H_t=H_t.'; end

5591

if iscolumn(H_t), H_t=H_t.'; end

5411

RLf=RL(:).'.*H_t;

5592

RLf=RL(:).'.*H_t;

5412

else % add extra 3x tr delay for causality

5593

else % add extra 3x tr delay for causality

5413

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5594

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5414

end

5595

end

5415

5596

5416

%Bessesl-Thomson turned off here (3rd input=0)

5597

%Bessesl-Thomson turned off here (3rd input=0)

5417

H_bt=Bessel_Thomson_Filter(param,f,0);

5598

H_bt=Bessel_Thomson_Filter(param,f,0);

5418

5599

5419

if isfield(OP,'TDR_Butterworth')

5600

if isfield(OP,'TDR_Butterworth')

5420

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

5601

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

5421

else

5602

else

5422

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

5603

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

5423

end

5604

end

5424

5605

5425

5606

5426

if param.Tukey_Window ~= 0

5607

if param.Tukey_Window ~= 0

5427

H_tw= Tukey_Window(f,param);

5608

H_tw= Tukey_Window(f,param);

5428

else

5609

else

5429

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

5610

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

5430

end

5611

end

5431

5612

5432

5613

5433

if iscolumn(H_tw), H_tw=H_tw.';end

5614

if iscolumn(H_tw), H_tw=H_tw.';end

5434

if iscolumn(H_bt), H_bt=H_bt.';end

5615

if iscolumn(H_bt), H_bt=H_bt.';end

5435

if iscolumn(H_bw), H_bw=H_bw.';end

5616

if iscolumn(H_bw), H_bw=H_bw.';end

5436

if iscolumn(RLf), RLf=RLf.';end

5617

if iscolumn(RLf), RLf=RLf.';end

5437

5618

5438

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5619

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5439

RLf=RLf.*TDR_results.Rx_filter;

5620

RLf=RLf.*TDR_results.Rx_filter;

5440

TDR_results.tx_filter=H_t;

5621

TDR_results.tx_filter=H_t;

5441

5622

5442

5623

5443

[IR, t, causality_correction_dB, truncation_dB] = ...

5624

[IR, t, causality_correction_dB, truncation_dB] = ...

5444

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5625

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5445

5626

5446

5627

5447

%

5628

%

5448

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5629

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5449

tfx=param.tfx(np); % use fixture delay for port (np)

5630

tfx=param.tfx(np); % use fixture delay for port (np)

5450

5631

5451

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5632

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5452

5633

5453

t = t-TDR_results.delay;

5634

t = t-TDR_results.delay;

5454

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5635

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5455

if isempty(tend), tend=length(t); end

5636

if isempty(tend), tend=length(t); end

5456

IR=IR(1:tend);

5637

IR=IR(1:tend);

5457

t=t(1:tend);

5638

t=t(1:tend);

5458

if isempty(tend), tend=length(t); end

5639

if isempty(tend), tend=length(t); end

5459

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5640

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5460

if isempty(tstart), tstart=1;end

5641

if isempty(tstart), tstart=1;end

5461

if isempty(tend) || tstart >= tend

5642

if isempty(tend) || tstart >= tend

5462

if isempty(tend) || tstart >= tend

5643

if isempty(tend) || tstart >= tend

5463

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5644

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5464

end

5645

end

5465

tend=length(t);

5646

tend=length(t);

5466

tstart=1;

5647

tstart=1;

5467

end

5648

end

5468

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5649

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5469

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5650

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5470

TDR_results.tdr= ch.ZSR;

5651

TDR_results.tdr= ch.ZSR;

5471

TDR_results.t = t(tstart:tend);

5652

TDR_results.t = t(tstart:tend);

5472

5653

5473

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5654

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5474

if OP.TDR || OP.PTDR % determin average impededance with

5655

if OP.TDR || OP.PTDR % determin average impededance with

5475

try

5656

try

5476

tfstart=find(t>=3*tr*1e-9,1);

5657

tfstart=find(t>=3*tr*1e-9,1);

5477

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5658

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5478

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5659

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5479

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5660

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5480

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5661

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5481

catch

5662

catch

5482

TDR_results.avgZport=0;

5663

TDR_results.avgZport=0;

5483

fit=zeros(1,1);

5664

fit=zeros(1,1);

5484

p=[0 0 0 0 ];

5665

p=[0 0 0 0 ];

5485

end

5666

end

5486

TDR_results.RL=RL;

5667

TDR_results.RL=RL;

5487

end

5668

end

5488

if OP.PTDR

5669

if OP.PTDR

5489

% param.N_bx=param.ndfe;

5670

% param.N_bx=param.ndfe;

5490

RL_equiv=-inf;

5671

RL_equiv=-inf;

5491

L=param.levels;

5672

L=param.levels;

5492

BinSize=OP.BinSize;

5673

BinSize=OP.BinSize;

5493

% param.specBER=1e-5;

5674

% param.specBER=1e-5;

5494

if OP.DISPLAY_WINDOW

5675

if OP.DISPLAY_WINDOW

5495

hwaitbar=waitbar(0);

5676

hwaitbar=waitbar(0);

5496

else

5677

else

5497

fprintf('Worst ERL searching');

5678

fprintf('Worst ERL searching');

5498

end

5679

end

5499

% adjust PTDR for NDFE

5680

% adjust PTDR for NDFE

5500

% ---------------------- 2.7 code

5681

% ---------------------- 2.7 code

5501

% ntx=find(TDR_results.t >= tfx,1,'first');

5682

% ntx=find(TDR_results.t >= tfx,1,'first');

5502

% % gatestartt=TDR_results.t(ntx);

5683

% % gatestartt=TDR_results.t(ntx);

5503

% % gatestartV=PTDR.pulse(ntx);

5684

% % gatestartV=PTDR.pulse(ntx);

5504

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5685

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5505

% tk=param.ui*1*(param.N_bx+1)+tfx;

5686

% tk=param.ui*1*(param.N_bx+1)+tfx;

5506

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

5687

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

5507

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5688

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5508

% time filter.

5689

% time filter.

5509

% ntx=find(TDR_results.t >= tfx,1,'first');

5690

% ntx=find(TDR_results.t >= tfx,1,'first');

5510

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5691

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5511

% gatestartt=TDR_results.t(ntx);

5692

% gatestartt=TDR_results.t(ntx);

5512

% gatestartV=PTDR.pulse(ntx);

5693

% gatestartV=PTDR.pulse(ntx);

5513

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5694

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5514

% tk=param.ui*1*(param.N_bx+1)+tfx;

5695

% tk=param.ui*1*(param.N_bx+1)+tfx;

5515

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5696

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5516

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5697

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5517

% [ahealey] End of modifications.

5698

% [ahealey] End of modifications.

5518

if isempty(ndfex), ndfex=length(TDR_results.t); end

5699

if isempty(ndfex), ndfex=length(TDR_results.t); end

5519

PTDR.pulse_orig=PTDR.pulse;

5700

PTDR.pulse_orig=PTDR.pulse;

5520

5701

5521

switch param.Grr

5702

switch param.Grr

5522

case 0 % pre .3cd release

5703

case 0 % pre .3cd release

5523

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5704

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5524

case 1 % .3cd release

5705

case 1 % .3cd release

5525

fctrx(1:length(PTDR.pulse_orig))=1;

5706

fctrx(1:length(PTDR.pulse_orig))=1;

5526

case 2 % .3ck working

5707

case 2 % .3ck working

5527

fctrx(1:length(PTDR.pulse_orig))=1;

5708

fctrx(1:length(PTDR.pulse_orig))=1;

5528

end

5709

end

5529

Gloss(1:length(TDR_results.t))=1;

5710

Gloss(1:length(TDR_results.t))=1;

5530

Grr(1:length(TDR_results.t))=1;

5711

Grr(1:length(TDR_results.t))=1;

5531

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5712

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5532

5713

5533

for ii=ntx:ndfex

5714

for ii=ntx:ndfex

5534

% adjust for near end loss

5715

% adjust for near end loss

5535

if param.N_bx>0 && param.beta_x~=0;

5716

if param.N_bx>0 && param.beta_x~=0;

5536

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5717

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5537

else

5718

else

5538

Gloss(ii)=1;

5719

Gloss(ii)=1;

5539

end

5720

end

5540

% ---------------------- 2.7 code

5721

% ---------------------- 2.7 code

5541

% x=(TDR_results.t(ii)-tfx)/param.ui;

5722

% x=(TDR_results.t(ii)-tfx)/param.ui;

5542

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

5723

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

5543

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5724

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5544

% rise time filter.

5725

% rise time filter.

5545

% x=(TDR_results.t(ii)-tfx)/param.ui;

5726

% x=(TDR_results.t(ii)-tfx)/param.ui;

5546

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5727

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5547

% determine how much of the return loss to use base on expected

5728

% determine how much of the return loss to use base on expected

5548

% missing reflections

5729

% missing reflections

5549

switch param.Grr

5730

switch param.Grr

5550

case 0 % pre .3cd release

5731

case 0 % pre .3cd release

5551

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5732

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5552

case 1 % .3cd release

5733

case 1 % .3cd release

5553

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5734

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5554

case 2 % .3ck working

5735

case 2 % .3ck working

5555

Grr(ii)= param.rho_x ;

5736

Grr(ii)= param.rho_x ;

5556

end

5737

end

5557

fctrx(ii)=Gloss(ii).*Grr(ii);

5738

fctrx(ii)=Gloss(ii).*Grr(ii);

5558

end

5739

end

5559

5740

5560

if isrow(fctrx), fctrx=fctrx(:);end

5741

if isrow(fctrx), fctrx=fctrx(:);end

5561

PTDR.pulse=PTDR.pulse.*fctrx;

5742

PTDR.pulse=PTDR.pulse.*fctrx;

5562

if 0

5743

if 0

5563

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5744

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5564

s1=subplot(2,1,1);

5745

s1=subplot(2,1,1);

5565

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5746

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5566

hold on

5747

hold on

5567

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5748

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5568

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5749

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5569

grid on

5750

grid on

5570

ylim([ 0 1.2])

5751

ylim([ 0 1.2])

5571

s2=subplot(2,1,2);

5752

s2=subplot(2,1,2);

5572

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5753

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5573

grid on

5754

grid on

5574

linkaxes([s1,s2],'x')

5755

linkaxes([s1,s2],'x')

5575

xlabel 'UI'

5756

xlabel 'UI'

5576

xlim ([ 1 200])

5757

xlim ([ 1 200])

5577

end

5758

end

5578

5759

5579

FAST_NOISE_CONV=0;

5760

FAST_NOISE_CONV=0;

5580

ERLRMS=rms(PTDR.pulse);

5761

ERLRMS=rms(PTDR.pulse);

5581

for ki=1:param.samples_per_ui

5762

for ki=1:param.samples_per_ui

5582

progress = ki/param.samples_per_ui;

5763

progress = ki/param.samples_per_ui;

5583

if OP.DISPLAY_WINDOW

5764

if OP.DISPLAY_WINDOW

5584

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5765

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5585

else

5766

else

5586

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5767

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5587

end

5768

end

5588

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5769

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5589

if OP.RL_norm_test

5770

if OP.RL_norm_test

5590

rl_fom=(norm(tps));

5771

rl_fom=(norm(tps));

5591

else

5772

else

5592

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5773

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5593

cdf_test=cumsum(testpdf.y);

5774

cdf_test=cumsum(testpdf.y);

5594

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5775

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5595

rl_fom=rl_test;

5776

rl_fom=rl_test;

5596

end

5777

end

5597

if rl_fom > RL_equiv

5778

if rl_fom > RL_equiv

5598

RL_equiv=rl_fom;

5779

RL_equiv=rl_fom;

5599

best_ki=ki;

5780

best_ki=ki;

5600

end

5781

end

5601

if ~OP.RL_norm_test

5782

if ~OP.RL_norm_test

5602

best_erl=rl_test;

5783

best_erl=rl_test;

5603

best_pdf=testpdf;

5784

best_pdf=testpdf;

5604

best_cdf=cdf_test;

5785

best_cdf=cdf_test;

5605

end

5786

end

5606

5787

5607

end

5788

end

5608

if OP.RL_norm_test

5789

if OP.RL_norm_test

5609

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5790

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5610

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5791

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5611

cdf_test=cumsum(testpdf.y);

5792

cdf_test=cumsum(testpdf.y);

5612

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5793

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5613

end

5794

end

5614

5795

5615

fprintf('\n');

5796

fprintf('\n');

5616

try

5797

try

5617

close(hwaitbar)

5798

close(hwaitbar)

5618

catch

5799

catch

5619

end

5800

end

5620

if ~exist('best_ki','var'),best_ki=1;end

5801

if ~exist('best_ki','var'),best_ki=1;end

5621

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5802

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5622

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5803

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5623

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5804

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5624

TDR_results.ERL=-db(best_erl);

5805

TDR_results.ERL=-db(best_erl);

5625

TDR_results.ERLRMS=-db(ERLRMS);

5806

TDR_results.ERLRMS=-db(ERLRMS);

5626

5807

5627

end

5808

end

5628

5809

5629

5810

5630

% end get TDR

5811

% end get TDR

5631

%%

5812

%%

5632

5813

5633

5814

5634

5815

5635

5816

5636

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5817

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5637

% filename parsing and acquisition

5818

% filename parsing and acquisition

5638

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

5819

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

5639

%----------put files names into chdata structure ---------

5820

%----------put files names into chdata structure ---------

5640

% The thru file has the index of 1

5821

% The thru file has the index of 1

5641

% crosstalk file are indexed from 2

5822

% crosstalk file are indexed from 2

5642

% nxi is incremented each time a file is read in so that nxi will end

5823

% nxi is incremented each time a file is read in so that nxi will end

5643

filepath=[]; % path name for file

5824

filepath=[]; % path name for file

5644

nxi=0; % file index

5825

nxi=0; % file index

5645

% get the THRU file

5826

% get the THRU file

5646

if size(file_list,2) ~= 0

5827

if size(file_list,2) ~= 0

5647

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5828

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5648

[filepath, basename, fileext]=fileparts(file_list{1});

5829

[filepath, basename, fileext]=fileparts(file_list{1});

5649

5830

5650

else

5831

else

5651

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5832

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5652

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5833

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5653

movegui(h,'northeast')

5834

movegui(h,'northeast')

5654

end

5835

end

5655

dir=fullfile(filepath, '*.csv');

5836

dir=fullfile(filepath, '*.csv');

5656

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5837

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5657

if filepath == 0

5838

if filepath == 0

5658

error('No Thru file')

5839

error('No Thru file')

5659

end

5840

end

5660

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5841

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5661

end

5842

end

5662

nxi=nxi+1;

5843

nxi=nxi+1;

5663

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5844

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5664

chdata(nxi).ext = fileext;

5845

chdata(nxi).ext = fileext;

5665

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5846

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5666

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5847

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5667

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5848

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5668

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5849

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5669

chdata(nxi).type='THRU';

5850

chdata(nxi).type='THRU';

5670

chdata(nxi).ftr=param.fb*param.f_v;

5851

chdata(nxi).ftr=param.fb*param.f_v;

5671

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5852

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5672

5853

5673

% now get FEXT file names into chdata structure

5854

% now get FEXT file names into chdata structure

5674

kxi=nxi;

5855

kxi=nxi;

5675

for nxi=kxi+1:num_fext+kxi

5856

for nxi=kxi+1:num_fext+kxi

5676

lastfilepath=filepath;

5857

lastfilepath=filepath;

5677

if size(file_list,2) ~= 0

5858

if size(file_list,2) ~= 0

5678

[filepath, basename, fileext]=fileparts(file_list{nxi});

5859

[filepath, basename, fileext]=fileparts(file_list{nxi});

5679

else

5860

else

5680

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5861

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5681

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5862

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5682

movegui(h,'northeast')

5863

movegui(h,'northeast')

5683

end

5864

end

5684

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

5865

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

5685

dir=fullfile(filepath, '*.csv');

5866

dir=fullfile(filepath, '*.csv');

5686

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5867

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5687

if filepath==0

5868

if filepath==0

5688

error('Not enough NEXT files')

5869

error('Not enough NEXT files')

5689

end

5870

end

5690

else

5871

else

5691

dir=fullfile(filepath, '*.csv');

5872

dir=fullfile(filepath, '*.csv');

5692

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5873

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5693

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5874

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5694

else

5875

else

5695

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5876

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5696

end

5877

end

5697

if filepath==0

5878

if filepath==0

5698

error('Not enough NEXT files')

5879

error('Not enough NEXT files')

5699

end

5880

end

5700

end

5881

end

5701

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5882

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5702

end

5883

end

5703

if isempty( filepath), filepath=lastfilepath; end

5884

if isempty( filepath), filepath=lastfilepath; end

5704

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5885

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5705

chdata(nxi).ext = fileext;

5886

chdata(nxi).ext = fileext;

5706

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5887

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5707

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5888

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5708

% chdata(nxi).A=param.a_fext;

5889

% chdata(nxi).A=param.a_fext;

5709

chdata(nxi).ftr=param.fb*param.f_f;

5890

chdata(nxi).ftr=param.fb*param.f_f;

5710

chdata(nxi).type='FEXT';

5891

chdata(nxi).type='FEXT';

5711

end

5892

end

5712

% now get NEXT file names into chdata structure

5893

% now get NEXT file names into chdata structure

5713

kxi=num_fext+kxi;

5894

kxi=num_fext+kxi;

5714

for nxi=kxi+1:num_next+kxi

5895

for nxi=kxi+1:num_next+kxi

5715

lastfilepath=filepath;

5896

lastfilepath=filepath;

5716

if size(file_list,2) ~= 0

5897

if size(file_list,2) ~= 0

5717

[filepath, basename, fileext]=fileparts(file_list{nxi});

5898

[filepath, basename, fileext]=fileparts(file_list{nxi});

5718

else

5899

else

5719

dir=fullfile(filepath, '*.csv');

5900

dir=fullfile(filepath, '*.csv');

5720

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5901

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5721

if filepath==0

5902

if filepath==0

5722

error('Not enough NEXT files')

5903

error('Not enough NEXT files')

5723

end

5904

end

5724

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5905

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5725

end

5906

end

5726

if isempty( filepath), filepath=lastfilepath; end

5907

if isempty( filepath), filepath=lastfilepath; end

5727

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5908

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5728

chdata(nxi).ext = fileext;

5909

chdata(nxi).ext = fileext;

5729

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5910

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5730

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5911

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5731

% chdata(nxi).A=param.A_next;

5912

% chdata(nxi).A=param.A_next;

5732

chdata(nxi).ftr=param.fb*param.f_n;

5913

chdata(nxi).ftr=param.fb*param.f_n;

5733

chdata(nxi).type='NEXT';

5914

chdata(nxi).type='NEXT';

5734

end

5915

end

5735

function half_UI=get_center_of_UI(samples_per_UI)

5916

function half_UI=get_center_of_UI(samples_per_UI)

5736

5917

5737

%half_UI reveals which value to use for the center of the UI. For eye

5918

%half_UI reveals which value to use for the center of the UI. For eye

5738

%width calculations, it is necessary to place the cursor in the center of the

5919

%width calculations, it is necessary to place the cursor in the center of the

5739

%UI window to ensure a 0 crossing on both left/right inside the window.

5920

%UI window to ensure a 0 crossing on both left/right inside the window.

5740

%This function was written in order to support even and odd samples_per_UI

5921

%This function was written in order to support even and odd samples_per_UI

5741

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

5922

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

5742

5923

5743

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

5924

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

5744

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

5925

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

5745

%the center of the UI is sample closest to 0.5

5926

%the center of the UI is sample closest to 0.5

5746

[temp_diff,half_UI]=min(abs(UI_window-0.5));

5927

[temp_diff,half_UI]=min(abs(UI_window-0.5));

5747

function results= get_cm_noise(M,PR,L,BER,OP)

5928

function results= get_cm_noise(M,PR,L,BER,OP)

5748

5929

5749

if ~exist('OP')

5930

if ~exist('OP')

5750

OP.DC_norm_test=0;

5931

OP.DC_norm_test=0;

5751

OP.DISPLAY_WINDOW=1;

5932

OP.DISPLAY_WINDOW=1;

5752

end

5933

end

5753

param.BinSize=1e-5;

5934

param.BinSize=1e-5;

5754

PR_test=-inf;

5935

PR_test=-inf;

5755

PR_fom_best=-inf;

5936

PR_fom_best=-inf;

5756

% hwaitbar=waitbar(0);

5937

% hwaitbar=waitbar(0);

5757

for ki=1:M

5938

for ki=1:M

5758

progress = ki/M;

5939

progress = ki/M;

5759

% if OP.DISPLAY_WINDOW

5940

% if OP.DISPLAY_WINDOW

5760

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

5941

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

5761

% else

5942

% else

5762

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5943

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5763

% end

5944

% end

5764

tps=PR(ki:M:end);

5945

tps=PR(ki:M:end);

5765

if OP.DC_norm_test

5946

if OP.DC_norm_test

5766

PR_fom=(norm(tps));

5947

PR_fom=(norm(tps));

5767

else

5948

else

5768

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

5949

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

5769

cdf_test=cumsum(testpdf.y);

5950

cdf_test=cumsum(testpdf.y);

5770

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

5951

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

5771

PR_fom=PRn_test;

5952

PR_fom=PRn_test;

5772

end

5953

end

5773

if PR_fom > PR_fom_best

5954

if PR_fom > PR_fom_best

5774

PR_fom_best=PR_fom;

5955

PR_fom_best=PR_fom;

5775

best_ki=ki;

5956

best_ki=ki;

5776

end

5957

end

5777

if ~OP.DC_norm_test

5958

if ~OP.DC_norm_test

5778

results.DCn=PR_fom_best;

5959

results.DCn=PR_fom_best;

5779

results.DCn_pdf=testpdf;

5960

results.DCn_pdf=testpdf;

5780

results.DCn_cdf=cdf_test;

5961

results.DCn_cdf=cdf_test;

5781

else

5962

else

5782

results.DCn=PR_fom_best;

5963

results.DCn=PR_fom_best;

5783

end

5964

end

5784

results.DCn_p2p=max(PR)-min(PR);

5965

results.DCn_p2p=max(PR)-min(PR);

5785

end

5966

end

5786

5967

5787

5968

5788

5969

5789

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

5970

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

5790

SBR=chdata.eq_pulse_response(:)'; % row vector

5971

SBR=chdata.eq_pulse_response(:)'; % row vector

5791

type=chdata.type;

5972

type=chdata.type;

5792

samp_UI=param.samples_per_ui;

5973

samp_UI=param.samples_per_ui;

5793

residual_response = SBR;

5974

residual_response = SBR;

5794

5975

5795

if isequal(type, 'THRU')

5976

if isequal(type, 'THRU')

5796

% for thru pulse response:

5977

% for thru pulse response:

5797

% remove the cursor and the DFE postcursors (up to their limit), since

5978

% remove the cursor and the DFE postcursors (up to their limit), since

5798

% we only care about the residuals.

5979

% we only care about the residuals.

5799

5980

5800

if ~param.Floating_DFE

5981

if ~param.Floating_DFE

5801

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

5982

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

5802

else

5983

else

5803

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

5984

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

5804

end

5985

end

5805

if param.dfe_delta ~= 0

5986

if param.dfe_delta ~= 0

5806

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

5987

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

5807

else

5988

else

5808

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5989

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5809

end

5990

end

5810

5991

5811

%AJG021820

5992

%AJG021820

5812

if ~param.Floating_DFE

5993

if ~param.Floating_DFE

5813

bmax_vec=residual_response(t_s)*[1,param.bmax];

5994

bmax_vec=residual_response(t_s)*[1,param.bmax];

5814

bmin_vec=residual_response(t_s)*[1,param.bmin];

5995

bmin_vec=residual_response(t_s)*[1,param.bmin];

5815

else

5996

else

5816

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

5997

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

5817

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

5998

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

5818

end

5999

end

5819

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6000

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5820

6001

5821

6002

5822

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

6003

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

5823

dfetaps=effective_cancelled_cursors/SBR(t_s);

6004

dfetaps=effective_cancelled_cursors/SBR(t_s);

5824

6005

5825

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6006

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5826

% really needed for COM, but helps debugging. May be factored out in future revisions.

6007

% really needed for COM, but helps debugging. May be factored out in future revisions.

5827

start_cancel = t_s-param.samples_per_ui/2;

6008

start_cancel = t_s-param.samples_per_ui/2;

5828

if ~param.Floating_DFE

6009

if ~param.Floating_DFE

5829

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

6010

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

5830

else

6011

else

5831

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

6012

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

5832

end

6013

end

5833

residual_response(start_cancel:end_cancel) = ...

6014

residual_response(start_cancel:end_cancel) = ...

5834

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6015

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5835

%else

6016

%else

5836

% for crosstalk pulse responses, nothing is cancelled, and all phases

6017

% for crosstalk pulse responses, nothing is cancelled, and all phases

5837

% are equally important.

6018

% are equally important.

5838

end

6019

end

5839

6020

5840

nui=round(length(residual_response)/param.samples_per_ui);

6021

nui=round(length(residual_response)/param.samples_per_ui);

5841

6022

5842

vs=zeros(nui-2, param.samples_per_ui);

6023

vs=zeros(nui-2, param.samples_per_ui);

5843

for i=1:param.samples_per_ui

6024

for i=1:param.samples_per_ui

5844

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

6025

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

5845

end

6026

end

5846

6027

5847

if OP.DISPLAY_WINDOW,

6028

if OP.DISPLAY_WINDOW,

5848

hwaitbar=waitbar(0);

6029

hwaitbar=waitbar(0);

5849

end

6030

end

5850

6031

5851

% determine which pdf to use

6032

% determine which pdf to use

5852

if isequal(type, 'THRU')

6033

if isequal(type, 'THRU')

5853

% one phase is interesting for thru

6034

% one phase is interesting for thru

5854

phases = mod(t_s,param.samples_per_ui);

6035

phases = mod(t_s,param.samples_per_ui);

5855

if phases==0, phases = param.samples_per_ui; end

6036

if phases==0, phases = param.samples_per_ui; end

5856

else

6037

else

5857

phases=1:samp_UI;

6038

phases=1:samp_UI;

5858

end

6039

end

5859

6040

5860

mxV = zeros(size(phases));

6041

mxV = zeros(size(phases));

5861

% we already found the phase in the PSD process for MMSE

6042

% we already found the phase in the PSD process for MMSE

5862

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

6043

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

5863

if isequal(type, 'THRU')

6044

if isequal(type, 'THRU')

5864

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

6045

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

5865

else

6046

else

5866

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

6047

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

5867

end

6048

end

5868

else

6049

else

5869

for k=phases

6050

for k=phases

5870

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

6051

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

5871

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6052

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

5872

progress = k/length(phases);

6053

progress = k/length(phases);

5873

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6054

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

5874

end

6055

end

5875

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

6056

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

5876

pdf=pdf_samples(pxi);

6057

pdf=pdf_samples(pxi);

5877

end

6058

end

5878

6059

5879

6060

5880

6061

5881

if OP.DISPLAY_WINDOW

6062

if OP.DISPLAY_WINDOW

5882

close(hwaitbar);

6063

close(hwaitbar);

5883

end

6064

end

5884

6065

5885

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

6066

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

5886

% Create PDF from interference vector using successive delta-set convolutions.

6067

% Create PDF from interference vector using successive delta-set convolutions.

5887

% input_vector = list of values of samples

6068

% input_vector = list of values of samples

5888

% return

6069

% return

5889

% pdf.x

6070

% pdf.x

5890

% pdf.y

6071

% pdf.y

5891

% pdf.vec

6072

% pdf.vec

5892

% pdf.bin

6073

% pdf.bin

5893

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

6074

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

5894

FAST_NOISE_CONV=0;

6075

FAST_NOISE_CONV=0;

5895

end

6076

end

5896

if max(input_vector) > BinSize

6077

if max(input_vector) > BinSize

5897

input_vector=input_vector(abs(input_vector)>BinSize);

6078

input_vector=input_vector(abs(input_vector)>BinSize);

5898

end

6079

end

5899

% for i = 1:length(input_vector)

6080

% for i = 1:length(input_vector)

5900

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

6081

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

5901

%end

6082

%end

5902

6083

5903

input_vector(abs(input_vector)<BinSize) = 0;

6084

input_vector(abs(input_vector)<BinSize) = 0;

5904

b=sign(input_vector);

6085

b=sign(input_vector);

5905

[input_vector,index]=sort(abs(input_vector),'descend');

6086

[input_vector,index]=sort(abs(input_vector),'descend');

5906

input_vector=input_vector.*b(index);

6087

input_vector=input_vector.*b(index);

5907

if FAST_NOISE_CONV

6088

if FAST_NOISE_CONV

5908

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

6089

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

5909

res_pdf= normal_dist(sig_res,5,BinSize);

6090

res_pdf= normal_dist(sig_res,5,BinSize);

5910

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

6091

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

5911

end

6092

end

5912

%% Equation 93A-39 %%

6093

%% Equation 93A-39 %%

5913

values = 2*(0:L-1)/(L-1)-1;

6094

values = 2*(0:L-1)/(L-1)-1;

5914

prob = ones(1,L)/L;

6095

prob = ones(1,L)/L;

5915

6096

5916

%% Initialize pdf to delta at 0

6097

%% Initialize pdf to delta at 0

5917

pdf=d_cpdf(BinSize, 0, 1);

6098

pdf=d_cpdf(BinSize, 0, 1);

5918

empty_pdf=pdf;

6099

empty_pdf=pdf;

5919

for k = 1:length(input_vector)

6100

for k = 1:length(input_vector)

5920

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

6101

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

5921

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

6102

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

5922

pdf=conv_fct(pdf, pdfn);

6103

pdf=conv_fct(pdf, pdfn);

5923

end

6104

end

5924

if FAST_NOISE_CONV

6105

if FAST_NOISE_CONV

5925

% pdf=conv_fct(pdf,res_pdf);

6106

% pdf=conv_fct(pdf,res_pdf);

5926

pdf=conv_fct_TEST(pdf,res_pdf);

6107

pdf=conv_fct_TEST(pdf,res_pdf);

5927

end

6108

end

5928

6109

5929

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

6110

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

5930

t_s_orig=t_s;

6111

t_s_orig=t_s;

5931

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

6112

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

5932

type=chdata.type;

6113

type=chdata.type;

5933

6114

5934

pulse_orig=chdata.eq_pulse_response(:)';

6115

pulse_orig=chdata.eq_pulse_response(:)';

5935

%build arbitrary time axis with step size = 1/samples per ui

6116

%build arbitrary time axis with step size = 1/samples per ui

5936

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

6117

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

5937

%force t_s at time =0 (makes the other things below easy)

6118

%force t_s at time =0 (makes the other things below easy)

5938

original_sample_time=old_time(t_s_orig);

6119

original_sample_time=old_time(t_s_orig);

5939

old_time=old_time-original_sample_time;

6120

old_time=old_time-original_sample_time;

5940

%build new time axis that forces time=0 to be in the axis

6121

%build new time axis that forces time=0 to be in the axis

5941

%unless the new/old samples per UI are integer ratios, time 0 will not be

6122

%unless the new/old samples per UI are integer ratios, time 0 will not be

5942

%there by default

6123

%there by default

5943

samp_UI=param.samples_for_C2M;

6124

samp_UI=param.samples_for_C2M;

5944

new_timea=[0:-1/samp_UI:min(old_time)];

6125

new_timea=[0:-1/samp_UI:min(old_time)];

5945

new_timeb=[0:1/samp_UI:max(old_time)];

6126

new_timeb=[0:1/samp_UI:max(old_time)];

5946

new_time=[fliplr(new_timea) new_timeb(2:end)];

6127

new_time=[fliplr(new_timea) new_timeb(2:end)];

5947

SBR=interp1(old_time,pulse_orig,new_time);

6128

SBR=interp1(old_time,pulse_orig,new_time);

5948

%new sample time is simply the point where new_time = 0

6129

%new sample time is simply the point where new_time = 0

5949

[tmp,t_s]=min(abs(new_time));

6130

[tmp,t_s]=min(abs(new_time));

5950

6131

5951

residual_response = SBR;

6132

residual_response = SBR;

5952

6133

5953

half_UI=get_center_of_UI(samp_UI);

6134

half_UI=get_center_of_UI(samp_UI);

5954

6135

5955

if isequal(type, 'THRU')

6136

if isequal(type, 'THRU')

5956

% for thru pulse response:

6137

% for thru pulse response:

5957

% remove the cursor and the DFE postcursors (up to their limit), since

6138

% remove the cursor and the DFE postcursors (up to their limit), since

5958

% we only care about the residuals.

6139

% we only care about the residuals.

5959

6140

5960

%AJG021820

6141

%AJG021820

5961

if ~param.Floating_DFE

6142

if ~param.Floating_DFE

5962

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

6143

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

5963

else

6144

else

5964

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

6145

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

5965

end

6146

end

5966

if param.dfe_delta ~= 0

6147

if param.dfe_delta ~= 0

5967

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

6148

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

5968

else

6149

else

5969

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

6150

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5970

end

6151

end

5971

6152

5972

if ~param.Floating_DFE

6153

if ~param.Floating_DFE

5973

bmax_vec=residual_response(t_s)*[param.bmax];

6154

bmax_vec=residual_response(t_s)*[param.bmax];

5974

bmin_vec=residual_response(t_s)*[param.bmin];

6155

bmin_vec=residual_response(t_s)*[param.bmin];

5975

else

6156

else

5976

bmax_vec=residual_response(t_s)*[param.use_bmax];

6157

bmax_vec=residual_response(t_s)*[param.use_bmax];

5977

bmin_vec=residual_response(t_s)*[param.use_bmin];

6158

bmin_vec=residual_response(t_s)*[param.use_bmin];

5978

end

6159

end

5979

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6160

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5980

6161

5981

6162

5982

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

6163

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

5983

dfetaps=effective_cancelled_cursors/SBR(t_s);

6164

dfetaps=effective_cancelled_cursors/SBR(t_s);

5984

6165

5985

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6166

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5986

% really needed for COM, but helps debugging. May be factored out in future revisions.

6167

% really needed for COM, but helps debugging. May be factored out in future revisions.

5987

6168

5988

%avoid dividing samp_UI by 2 in case it is not even

6169

%avoid dividing samp_UI by 2 in case it is not even

5989

start_cancel=t_s-half_UI+1+samp_UI;

6170

start_cancel=t_s-half_UI+1+samp_UI;

5990

%AJG021820

6171

%AJG021820

5991

if ~param.Floating_DFE

6172

if ~param.Floating_DFE

5992

end_cancel=start_cancel+param.ndfe*samp_UI-1;

6173

end_cancel=start_cancel+param.ndfe*samp_UI-1;

5993

else

6174

else

5994

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

6175

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

5995

end

6176

end

5996

residual_response(start_cancel:end_cancel) = ...

6177

residual_response(start_cancel:end_cancel) = ...

5997

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6178

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5998

%else

6179

%else

5999

% for crosstalk pulse responses, nothing is cancelled, and all phases

6180

% for crosstalk pulse responses, nothing is cancelled, and all phases

6000

% are equally important.

6181

% are equally important.

6001

6182

6002

%remove entire cursor UI

6183

%remove entire cursor UI

6003

uiv_start=start_cancel-samp_UI;

6184

uiv_start=start_cancel-samp_UI;

6004

uiv_end=uiv_start+samp_UI-1;

6185

uiv_end=uiv_start+samp_UI-1;

6005

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

6186

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

6006

residual_response(uiv_start:uiv_end)=0;

6187

residual_response(uiv_start:uiv_end)=0;

6007

end

6188

end

6008

6189

6009

nui=round(length(residual_response)/samp_UI);

6190

nui=round(length(residual_response)/samp_UI);

6010

6191

6011

6192

6012

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6193

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6013

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

6194

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

6014

%response without DFE included. (Can't include DFE for jitter calc)

6195

%response without DFE included. (Can't include DFE for jitter calc)

6015

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6196

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6016

6197

6017

% if OP.DISPLAY_WINDOW,

6198

% if OP.DISPLAY_WINDOW,

6018

% hwaitbar=waitbar(0);

6199

% hwaitbar=waitbar(0);

6019

% end

6200

% end

6020

6201

6021

% determine which pdf to use

6202

% determine which pdf to use

6022

if isequal(type, 'THRU')

6203

if isequal(type, 'THRU')

6023

% one phase is interesting for thru

6204

% one phase is interesting for thru

6024

phases = mod(t_s,samp_UI);

6205

phases = mod(t_s,samp_UI);

6025

if phases==0, phases = samp_UI; end

6206

if phases==0, phases = samp_UI; end

6026

else

6207

else

6027

phases=1:samp_UI;

6208

phases=1:samp_UI;

6028

end

6209

end

6029

6210

6030

mxV = zeros(size(phases));

6211

mxV = zeros(size(phases));

6031

6212

6032

%phases reveals the raw position in the UI window of the cursor.

6213

%phases reveals the raw position in the UI window of the cursor.

6033

%shift_amount is the amount to shift so that it aligns with half_UI

6214

%shift_amount is the amount to shift so that it aligns with half_UI

6034

shift_amount=half_UI-phases;

6215

shift_amount=half_UI-phases;

6035

%vs_shift puts the cursor at the center

6216

%vs_shift puts the cursor at the center

6036

vs_shift=circshift(vs,[0 shift_amount]);

6217

vs_shift=circshift(vs,[0 shift_amount]);

6037

L=size(vs_raw,1);

6218

L=size(vs_raw,1);

6038

%allow partial UI computation through pdf_range

6219

%allow partial UI computation through pdf_range

6039

%if pdf_range is empty, do full UI

6220

%if pdf_range is empty, do full UI

6040

if isempty(pdf_range)

6221

if isempty(pdf_range)

6041

pdf_range=1:samp_UI;

6222

pdf_range=1:samp_UI;

6042

else

6223

else

6043

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

6224

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

6044

end

6225

end

6045

h_j_full=zeros(L,samp_UI);

6226

h_j_full=zeros(L,samp_UI);

6046

for k=pdf_range

6227

for k=pdf_range

6047

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6228

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6048

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6229

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6049

%progress = k/length(phases);

6230

%progress = k/length(phases);

6050

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6231

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6051

6232

6052

%build the circshift of h_j_full into the loop to support a reduced

6233

%build the circshift of h_j_full into the loop to support a reduced

6053

%range of sampling points. circshift at the end only works if doing the

6234

%range of sampling points. circshift at the end only works if doing the

6054

%full range of sampling points. And shifting before the loop will

6235

%full range of sampling points. And shifting before the loop will

6055

%yield the wrong answer at the edges of the UI

6236

%yield the wrong answer at the edges of the UI

6056

hk=k-shift_amount;

6237

hk=k-shift_amount;

6057

if hk<1

6238

if hk<1

6058

hk=hk+samp_UI;

6239

hk=hk+samp_UI;

6059

elseif hk>samp_UI

6240

elseif hk>samp_UI

6060

hk=hk-samp_UI;

6241

hk=hk-samp_UI;

6061

end

6242

end

6062

if hk==1

6243

if hk==1

6063

%when hk=1, the early UI is the last column

6244

%when hk=1, the early UI is the last column

6064

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6245

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6065

elseif hk==samp_UI

6246

elseif hk==samp_UI

6066

%when hk=samp_UI, the late UI is the first column

6247

%when hk=samp_UI, the late UI is the first column

6067

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6248

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6068

else

6249

else

6069

%for all other cases, do the normal late=+1, early = -1

6250

%for all other cases, do the normal late=+1, early = -1

6070

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6251

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6071

end

6252

end

6072

end

6253

end

6073

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6254

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6074

% filename parsing and acquisition

6255

% filename parsing and acquisition

6075

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

6256

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

6076

%----------put files names into chdata structure ---------

6257

%----------put files names into chdata structure ---------

6077

% The thru file has the index of 1

6258

% The thru file has the index of 1

6078

% crosstalk file are indexed from 2

6259

% crosstalk file are indexed from 2

6079

% nxi is incremented each time a file is read in so that nxi will end

6260

% nxi is incremented each time a file is read in so that nxi will end

6080

filepath=[]; % path name for file

6261

filepath=[]; % path name for file

6081

nxi=0; % file index

6262

nxi=0; % file index

6082

% get the THRU file

6263

% get the THRU file

6083

if size(file_list,2) ~= 0

6264

if size(file_list,2) ~= 0

6084

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6265

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6085

[filepath, basename, fileext]=fileparts(file_list{1});

6266

[filepath, basename, fileext]=fileparts(file_list{1});

6086

6267

6087

else

6268

else

6088

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6269

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6089

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6270

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6090

movegui(h,'northeast')

6271

movegui(h,'northeast')

6091

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

6272

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

6092

end

6273

end

6093

if OP.ERL == 2

6274

if OP.ERL == 2

6094

dir=fullfile(filepath, '*.s2p');

6275

dir=fullfile(filepath, '*.s2p');

6095

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6276

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6096

if filepath == 0

6277

if filepath == 0

6097

error('No RL measurement file')

6278

error('No RL measurement file')

6098

end

6279

end

6099

else

6280

else

6100

dir=fullfile(filepath, '*.s4p');

6281

dir=fullfile(filepath, '*.s4p');

6101

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6282

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6102

if filepath == 0

6283

if filepath == 0

6103

error('No Thru file')

6284

error('No Thru file')

6104

end

6285

end

6105

end

6286

end

6106

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6287

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6107

end

6288

end

6108

nxi=nxi+1;

6289

nxi=nxi+1;

6109

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6290

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6110

chdata(nxi).ext = fileext;

6291

chdata(nxi).ext = fileext;

6111

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6292

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6112

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6293

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6113

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6294

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6114

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6295

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6115

chdata(nxi).type='THRU';

6296

chdata(nxi).type='THRU';

6116

chdata(nxi).ftr=param.fb*param.f_v;

6297

chdata(nxi).ftr=param.fb*param.f_v;

6117

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6298

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6118

6299

6119

% now get FEXT file names into chdata structure

6300

% now get FEXT file names into chdata structure

6120

kxi=nxi;

6301

kxi=nxi;

6121

for nxi=kxi+1:num_fext+kxi

6302

for nxi=kxi+1:num_fext+kxi

6122

lastfilepath=filepath;

6303

lastfilepath=filepath;

6123

if size(file_list,2) ~= 0

6304

if size(file_list,2) ~= 0

6124

[filepath, basename, fileext]=fileparts(file_list{nxi});

6305

[filepath, basename, fileext]=fileparts(file_list{nxi});

6125

else

6306

else

6126

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6307

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6127

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6308

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6128

movegui(h,'northeast')

6309

movegui(h,'northeast')

6129

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

6310

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

6130

end

6311

end

6131

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

6312

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

6132

dir=fullfile(filepath, '*.s4p');

6313

dir=fullfile(filepath, '*.s4p');

6133

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6314

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6134

if filepath==0

6315

if filepath==0

6135

error('Not enough NEXT files')

6316

error('Not enough NEXT files')

6136

end

6317

end

6137

else

6318

else

6138

dir=fullfile(filepath, '*.s4p');

6319

dir=fullfile(filepath, '*.s4p');

6139

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6320

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6140

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6321

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6141

else

6322

else

6142

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6323

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6143

end

6324

end

6144

if filepath==0

6325

if filepath==0

6145

error('Not enough NEXT files')

6326

error('Not enough NEXT files')

6146

end

6327

end

6147

end

6328

end

6148

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6329

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6149

end

6330

end

6150

if isempty( filepath), filepath=lastfilepath; end

6331

if isempty( filepath), filepath=lastfilepath; end

6151

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6332

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6152

chdata(nxi).ext = fileext;

6333

chdata(nxi).ext = fileext;

6153

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6334

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6154

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6335

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6155

% chdata(nxi).A=param.a_fext;

6336

% chdata(nxi).A=param.a_fext;

6156

chdata(nxi).ftr=param.fb*param.f_f;

6337

chdata(nxi).ftr=param.fb*param.f_f;

6157

chdata(nxi).type='FEXT';

6338

chdata(nxi).type='FEXT';

6158

end

6339

end

6159

% now get NEXT file names into chdata structure

6340

% now get NEXT file names into chdata structure

6160

kxi=num_fext+kxi;

6341

kxi=num_fext+kxi;

6161

for nxi=kxi+1:num_next+kxi

6342

for nxi=kxi+1:num_next+kxi

6162

lastfilepath=filepath;

6343

lastfilepath=filepath;

6163

if size(file_list,2) ~= 0

6344

if size(file_list,2) ~= 0

6164

[filepath, basename, fileext]=fileparts(file_list{nxi});

6345

[filepath, basename, fileext]=fileparts(file_list{nxi});

6165

else

6346

else

6166

dir=fullfile(filepath, '*.s4p');

6347

dir=fullfile(filepath, '*.s4p');

6167

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6348

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6168

if filepath==0

6349

if filepath==0

6169

error('Not enough NEXT files')

6350

error('Not enough NEXT files')

6170

end

6351

end

6171

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6352

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6172

end

6353

end

6173

if isempty( filepath), filepath=lastfilepath; end

6354

if isempty( filepath), filepath=lastfilepath; end

6174

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6355

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6175

chdata(nxi).ext = fileext;

6356

chdata(nxi).ext = fileext;

6176

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6357

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6177

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6358

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6178

% chdata(nxi).A=param.A_next;

6359

% chdata(nxi).A=param.A_next;

6179

chdata(nxi).ftr=param.fb*param.f_n;

6360

chdata(nxi).ftr=param.fb*param.f_n;

6180

chdata(nxi).type='NEXT';

6361

chdata(nxi).type='NEXT';

6181

end

6362

end

6182

6363

6183

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6364

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6184

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6365

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6185

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6366

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6186

% H_r - receiver filter, Butterworth

6367

% H_r - receiver filter, Butterworth

6187

% H_ctf - total gain of CTLE and low freq filtering

6368

% H_ctf - total gain of CTLE and low freq filtering

6188

% H_dc - the common mode channel gain

6369

% H_dc - the common mode channel gain

6189

% param.eta_0 -input referred Rx noise

6370

% param.eta_0 -input referred Rx noise

6190

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6371

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6191

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6372

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6192

%% Equation 93A-35 - independent of FFE setting %%

6373

%% Equation 93A-35 - independent of FFE setting %%

6193

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

6374

sigma_N1 = sqrt(param.eta_0*sum( abs(H_sy(2:end) .* H_r(2:end) .* H_ctf(2:end) ).^2 .* diff(chdata(1).faxis)/1e9));% eta_0 is V^2/Ghz i.e. /1

6194

if sum(param.AC_CM_RMS) ~= 0

6375

if sum(param.AC_CM_RMS) ~= 0

6195

sigma_ACCM=0;

6376

sigma_ACCM=0;

6196

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6377

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6197

for i=1:length(chdata)

6378

for i=1:length(chdata)

6198

H_dc=abs(squeeze(chdata(i).sdc21));

6379

H_dc=abs(squeeze(chdata(i).sdc21));

6199

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

6380

sigma_ACCM_acc= sqrt( 2*param.AC_CM_RMS_TX^2.*sum( abs(H_sy(2:length(f_int)) .* H_r(2:length(f_int)) .* H_ctf(2:length(f_int)).*H_dc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end) );

6200

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6381

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6201

end

6382

end

6202

sigma_N=norm([sigma_N1,sigma_ACCM]);

6383

sigma_N=norm([sigma_N1,sigma_ACCM]);

6203

else

6384

else

6204

sigma_N=sigma_N1;

6385

sigma_N=sigma_N1;

6205

end

6386

end

6206

%%

6387

%%

6207

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6388

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6208

% for Rx calibratrion only

6389

% for Rx calibratrion only

6209

% the FEXT channel for calibration basically a DC connection unlike normal

6390

% the FEXT channel for calibration basically a DC connection unlike normal

6210

% FEXT channels which are nearly open at DC channels

6391

% FEXT channels which are nearly open at DC channels

6211

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

6392

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

6212

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6393

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6213

if size(chdata,2) >= 2

6394

if size(chdata,2) >= 2

6214

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6395

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6215

else

6396

else

6216

Hnoise_channel=1;

6397

Hnoise_channel=1;

6217

end

6398

end

6218

f=chdata(2).faxis;

6399

f=chdata(2).faxis;

6219

f_hp=param.f_hp;

6400

f_hp=param.f_hp;

6220

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6401

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6221

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6402

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6222

else

6403

else

6223

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

6404

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

6224

end

6405

end

6225

%% Equation 93A-47 or 162-12

6406

%% Equation 93A-47 or 162-12

6226

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6407

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6227

6408

6228

%% Equation 93A-48 or 162-14%%

6409

%% Equation 93A-48 or 162-14%%

6229

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6410

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6230

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6411

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6231

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6412

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6232

% Modified not to double count crosstalk: John Ewen 13/12/2018

6413

% Modified not to double count crosstalk: John Ewen 13/12/2018

6233

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6414

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6234

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6415

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6235

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6416

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6236

f=chdata(1).faxis;

6417

f=chdata(1).faxis;

6237

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6418

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6238

if(f(1)==0)

6419

if(f(1)==0)

6239

temp_angle(1)=1e-20;% we don't want to divide by zero

6420

temp_angle(1)=1e-20;% we don't want to divide by zero

6240

end

6421

end

6241

PWF_tx=ones(1,length(f));

6422

PWF_tx=ones(1,length(f));

6242

if max(upsampled_txffe) > 0

6423

if max(upsampled_txffe) > 0

6243

PWF_tx=zeros(1,length(f));

6424

PWF_tx=zeros(1,length(f));

6244

[mcur,icur] = max(upsampled_txffe);

6425

[mcur,icur] = max(upsampled_txffe);

6245

if exist('phase_memory','var') && ~isempty(phase_memory)

6426

if exist('phase_memory','var') && ~isempty(phase_memory)

6246

pre_calc=1;

6427

pre_calc=1;

6247

else

6428

else

6248

pre_calc=0;

6429

pre_calc=0;

6249

end

6430

end

6250

for ii=1:length(upsampled_txffe)

6431

for ii=1:length(upsampled_txffe)

6251

if upsampled_txffe(ii)==0

6432

if upsampled_txffe(ii)==0

6252

%speed up: skip cases when txffe=0

6433

%speed up: skip cases when txffe=0

6253

continue;

6434

continue;

6254

end

6435

end

6255

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6436

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6256

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6437

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6257

% that is needed

6438

% that is needed

6258

if ii==icur

6439

if ii==icur

6259

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6440

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6260

PWF_tx = PWF_tx + upsampled_txffe(ii);

6441

PWF_tx = PWF_tx + upsampled_txffe(ii);

6261

else

6442

else

6262

if pre_calc

6443

if pre_calc

6263

%speed up: avoid vector exp calculation by externally pre-calculating it

6444

%speed up: avoid vector exp calculation by externally pre-calculating it

6264

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6445

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6265

else

6446

else

6266

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6447

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6267

end

6448

end

6268

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6449

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6269

PWF_tx = PWF_tx + transpose(term_ii(:));

6450

PWF_tx = PWF_tx + transpose(term_ii(:));

6270

end

6451

end

6271

% /Adee

6452

% /Adee

6272

end

6453

end

6273

end

6454

end

6274

PWF_rx=ones(1,length(f));

6455

PWF_rx=ones(1,length(f));

6275

if exist('C','var')

6456

if exist('C','var')

6276

PWF_rx=zeros(1,length(f));

6457

PWF_rx=zeros(1,length(f));

6277

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6458

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6278

if C(ii+param.RxFFE_cmx+1)==0

6459

if C(ii+param.RxFFE_cmx+1)==0

6279

%speed up: skip cases when rxffe=0

6460

%speed up: skip cases when rxffe=0

6280

continue;

6461

continue;

6281

end

6462

end

6282

if ii+1==0

6463

if ii+1==0

6283

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6464

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6284

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6465

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6285

else

6466

else

6286

if pre_calc

6467

if pre_calc

6287

%speed up: avoid vector exp calculation by externally pre-calculating it

6468

%speed up: avoid vector exp calculation by externally pre-calculating it

6288

%The latter columns of phase_memory hold RXFFE shift vectors

6469

%The latter columns of phase_memory hold RXFFE shift vectors

6289

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6470

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6290

term_ii=transpose(term_ii);

6471

term_ii=transpose(term_ii);

6291

else

6472

else

6292

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6473

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6293

end

6474

end

6294

PWF_rx=PWF_rx+term_ii;

6475

PWF_rx=PWF_rx+term_ii;

6295

end

6476

end

6296

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6477

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6297

end

6478

end

6298

end

6479

end

6299

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6480

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6300

for ii=2:size(chdata,2)

6481

for ii=2:size(chdata,2)

6301

SINC = sin(temp_angle)./temp_angle;

6482

SINC = sin(temp_angle)./temp_angle;

6302

PWF_data=SINC.^2;

6483

PWF_data=SINC.^2;

6303

PWF=PWF_data.*PWF_rx; % power weight function

6484

PWF=PWF_data.*PWF_rx; % power weight function

6304

PWFnext=abs(PWF);

6485

PWFnext=abs(PWF);

6305

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6486

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6306

PWFfext=abs(PWF);

6487

PWFfext=abs(PWF);

6307

if isequal(chdata(ii).type, 'FEXT')

6488

if isequal(chdata(ii).type, 'FEXT')

6308

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6489

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6309

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

6490

MDFEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFfext(1:index_f2).*abs(MDFEXT(1:index_f2)).^2)); %eq 46

6310

elseif isequal(chdata(ii).type, 'NEXT')

6491

elseif isequal(chdata(ii).type, 'NEXT')

6311

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6492

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6312

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

6493

MDNEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFnext(1:index_f2).*abs(MDNEXT(1:index_f2)).^2)); %eq 47

6313

end

6494

end

6314

end

6495

end

6315

if nargout == 1 && isequal(type,'NEXT')

6496

if nargout == 1 && isequal(type,'NEXT')

6316

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6497

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6317

elseif nargout == 1 && isequal(type,'FEXT')

6498

elseif nargout == 1 && isequal(type,'FEXT')

6318

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6499

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6319

elseif nargout == 3

6500

elseif nargout == 3

6320

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6501

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6321

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6502

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6322

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6503

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6323

end

6504

end

6324

6505

6325

function out=hrem(h,index,N_bf,bmaxg)

6506

function out=hrem(h,index,N_bf,bmaxg)

6326

6507

6327

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) ];

6508

out=[ h(1:index-1) h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) h(index+N_bf:end) ];

6328

% faster than single line function

6509

% faster than single line function

6329

% hrem =@(h,index,N_bf,bmaxg) ...

6510

% hrem =@(h,index,N_bf,bmaxg) ...

6330

% [ h(1:index-1) ...

6511

% [ h(1:index-1) ...

6331

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6512

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6332

% h(index+N_bf:end) ]...

6513

% h(index+N_bf:end) ]...

6333

% ;

6514

% ;

6334

6515

6335

%% floating DFE taps

6516

%% floating DFE taps

6336

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6517

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6337

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6518

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6338

% Sout = interp_Sparam(Sin,fin,fout)

6519

% Sout = interp_Sparam(Sin,fin,fout)

6339

%

6520

%

6340

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6521

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6341

% fout.

6522

% fout.

6342

6523

6343

if ( fin(end)<fout(end) )

6524

if ( fin(end)<fout(end) )

6344

% warning('Channel high frequencies extrapolation might be inaccurate!');

6525

% warning('Channel high frequencies extrapolation might be inaccurate!');

6345

end

6526

end

6346

6527

6347

H_mag = abs(Sin);

6528

H_mag = abs(Sin);

6348

H_mag(H_mag<eps)=eps; % handle ill cases...

6529

H_mag(H_mag<eps)=eps; % handle ill cases...

6349

H_ph = unwrap(angle(Sin));

6530

H_ph = unwrap(angle(Sin));

6350

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6531

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6351

% user ignore that.

6532

% user ignore that.

6352

if mean(diff(H_ph))>0

6533

if mean(diff(H_ph))>0

6353

if OP.DEBUG

6534

if OP.DEBUG

6354

warning('Anti-causal response found. Finer frequency step is required for this channel');

6535

warning('Anti-causal response found. Finer frequency step is required for this channel');

6355

else

6536

else

6356

error('Anti-causal response found. Finer frequency step is required for this channel');

6537

error('Anti-causal response found. Finer frequency step is required for this channel');

6357

end

6538

end

6358

end

6539

end

6359

6540

6360

%opt_interp_Sparam_mag='linear_trend_to_DC';

6541

%opt_interp_Sparam_mag='linear_trend_to_DC';

6361

switch opt_interp_Sparam_mag

6542

switch opt_interp_Sparam_mag

6362

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6543

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6363

if -iscolumn(H_mag), H_mag=H_mag.';end

6544

if -iscolumn(H_mag), H_mag=H_mag.';end

6364

if -iscolumn(fin), fin=fin.';end

6545

if -iscolumn(fin), fin=fin.';end

6365

fin_x=fin;

6546

fin_x=fin;

6366

H_mag_x=H_mag(:);

6547

H_mag_x=H_mag(:);

6367

if fin(1)>0

6548

if fin(1)>0

6368

p=polyfit(fin(1:10), H_mag(1:10), 1);

6549

p=polyfit(fin(1:10), H_mag(1:10), 1);

6369

dc_trend_val=polyval(p, 0);

6550

dc_trend_val=polyval(p, 0);

6370

fin_x=[0, fin_x];

6551

fin_x=[0, fin_x];

6371

H_mag_x = [dc_trend_val; H_mag_x];

6552

H_mag_x = [dc_trend_val; H_mag_x];

6372

end

6553

end

6373

if fin(end)<fout(end)

6554

if fin(end)<fout(end)

6374

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6555

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6375

mid_freq_ind=round(length(fin)/2);

6556

mid_freq_ind=round(length(fin)/2);

6376

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6557

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6377

warning(warn_state);

6558

warning(warn_state);

6378

hf_trend_val=polyval(p, fout(end));

6559

hf_trend_val=polyval(p, fout(end));

6379

if hf_trend_val>H_mag(end)

6560

if hf_trend_val>H_mag(end)

6380

hf_trend_val=H_mag(end);

6561

hf_trend_val=H_mag(end);

6381

hf_logtrend_val = H_mag(end);

6562

hf_logtrend_val = H_mag(end);

6382

elseif hf_trend_val<eps

6563

elseif hf_trend_val<eps

6383

hf_trend_val=eps;

6564

hf_trend_val=eps;

6384

hf_logtrend_val = realmin;

6565

hf_logtrend_val = realmin;

6385

end

6566

end

6386

fin_x=[fin_x, fout(end)];

6567

fin_x=[fin_x, fout(end)];

6387

H_mag_x = [H_mag_x; hf_trend_val];

6568

H_mag_x = [H_mag_x; hf_trend_val];

6388

end

6569

end

6389

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6570

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6390

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6571

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6391

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6572

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6392

indx = find(fout > fin(end),1,'first');

6573

indx = find(fout > fin(end),1,'first');

6393

H_mag_i(indx:end) = H_logmag_i(indx:end);

6574

H_mag_i(indx:end) = H_logmag_i(indx:end);

6394

end

6575

end

6395

case 'trend_to_DC'

6576

case 'trend_to_DC'

6396

% extrapolate to trend value at DC.

6577

% extrapolate to trend value at DC.

6397

if -iscolumn(H_mag), H_mag=H_mag.';end

6578

if -iscolumn(H_mag), H_mag=H_mag.';end

6398

if -iscolumn(fin), fin=fin.';end

6579

if -iscolumn(fin), fin=fin.';end

6399

fin_x=fin;

6580

fin_x=fin;

6400

H_mag_x=H_mag;

6581

H_mag_x=H_mag;

6401

if fin(1)>0

6582

if fin(1)>0

6402

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6583

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6403

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6584

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6404

dc_trend_val=10^polyval(p, 0);

6585

dc_trend_val=10^polyval(p, 0);

6405

fin_x=[0, fin_x];

6586

fin_x=[0, fin_x];

6406

H_mag_x = [dc_trend_val H_mag_x];

6587

H_mag_x = [dc_trend_val H_mag_x];

6407

end

6588

end

6408

if fin(end)<fout(end)

6589

if fin(end)<fout(end)

6409

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6590

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6410

mid_freq_ind=round(length(fin)/2);

6591

mid_freq_ind=round(length(fin)/2);

6411

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6592

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6412

warning(warn_state);

6593

warning(warn_state);

6413

hf_trend_val=10^polyval(p, fout(end));

6594

hf_trend_val=10^polyval(p, fout(end));

6414

if hf_trend_val>H_mag(end)

6595

if hf_trend_val>H_mag(end)

6415

hf_trend_val=H_mag(end);

6596

hf_trend_val=H_mag(end);

6416

end

6597

end

6417

fin_x=[fin_x, fout(end)];

6598

fin_x=[fin_x, fout(end)];

6418

H_mag_x = [H_mag_x hf_trend_val];

6599

H_mag_x = [H_mag_x hf_trend_val];

6419

end

6600

end

6420

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6601

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6421

case 'extrap_to_DC_or_zero'

6602

case 'extrap_to_DC_or_zero'

6422

% same as extrap_to_DC but detect AC-coupled channels and

6603

% same as extrap_to_DC but detect AC-coupled channels and

6423

% extrapolate them to 0.

6604

% extrapolate them to 0.

6424

if fin(1)>0 && 20*log10(H_mag(1))<-20

6605

if fin(1)>0 && 20*log10(H_mag(1))<-20

6425

% assume AC coupling, with 0 at DC

6606

% assume AC coupling, with 0 at DC

6426

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6607

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6427

else

6608

else

6428

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6609

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6429

end

6610

end

6430

H_mag_i(fout>fin(end)) = H_mag(end);

6611

H_mag_i(fout>fin(end)) = H_mag(end);

6431

case 'extrap_to_DC'

6612

case 'extrap_to_DC'

6432

% first extrapolate down to DC, then use highest available frequency

6613

% first extrapolate down to DC, then use highest available frequency

6433

% for higher frequencies

6614

% for higher frequencies

6434

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6615

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6435

H_mag_i(fout>fin(end)) = H_mag(end);

6616

H_mag_i(fout>fin(end)) = H_mag(end);

6436

case 'old'

6617

case 'old'

6437

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6618

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6438

otherwise

6619

otherwise

6439

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6620

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6440

end

6621

end

6441

6622

6442

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6623

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6443

6624

6444

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6625

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6445

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6626

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6446

switch opt_interp_Sparam_phase

6627

switch opt_interp_Sparam_phase

6447

case 'old'

6628

case 'old'

6448

H_ph_i = H_ph_i-H_ph_i(1);

6629

H_ph_i = H_ph_i-H_ph_i(1);

6449

case 'zero_DC'

6630

case 'zero_DC'

6450

H_ph_i(1) = 0;

6631

H_ph_i(1) = 0;

6451

case 'interp_to_DC'

6632

case 'interp_to_DC'

6452

if fin(1) ~= 0

6633

if fin(1) ~= 0

6453

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6634

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6454

end

6635

end

6455

case 'extrap_cubic_to_dc_linear_to_inf'

6636

case 'extrap_cubic_to_dc_linear_to_inf'

6456

if fin(1) ~= 0

6637

if fin(1) ~= 0

6457

% estimate low frequency group delay

6638

% estimate low frequency group delay

6458

group_delay = -diff(H_ph(:))./diff(fin(:));

6639

group_delay = -diff(H_ph(:))./diff(fin(:));

6459

low_freq_gd = group_delay(1:50);

6640

low_freq_gd = group_delay(1:50);

6460

% calculate trend, throwing away outliers

6641

% calculate trend, throwing away outliers

6461

m = median(low_freq_gd); sigma = std(low_freq_gd);

6642

m = median(low_freq_gd); sigma = std(low_freq_gd);

6462

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6643

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6463

% correct outliers in first 10 phase samples

6644

% correct outliers in first 10 phase samples

6464

for k=10:-1:1

6645

for k=10:-1:1

6465

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6646

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6466

end

6647

end

6467

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6648

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6468

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6649

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6469

% modification - trend to inf

6650

% modification - trend to inf

6470

if (1)

6651

if (1)

6471

high_freq_gd = group_delay(end-50:end);

6652

high_freq_gd = group_delay(end-50:end);

6472

% calculate trend, throwing away outliers

6653

% calculate trend, throwing away outliers

6473

m = median(high_freq_gd); sigma = std(high_freq_gd);

6654

m = median(high_freq_gd); sigma = std(high_freq_gd);

6474

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6655

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6475

hf_extrap_range = find(fout>fin(end));

6656

hf_extrap_range = find(fout>fin(end));

6476

last_data_sample = hf_extrap_range(1)-1;

6657

last_data_sample = hf_extrap_range(1)-1;

6477

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6658

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6478

% for k=hf_range

6659

% for k=hf_range

6479

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6660

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6480

% end

6661

% end

6481

end

6662

end

6482

6663

6483

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6664

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6484

H_ph_i=H_ph_cubic;

6665

H_ph_i=H_ph_cubic;

6485

H_ph_i(indx:end) = H_ph_linear(indx:end);

6666

H_ph_i(indx:end) = H_ph_linear(indx:end);

6486

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6667

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6487

end

6668

end

6488

case 'interp_and_shift_to_DC'

6669

case 'interp_and_shift_to_DC'

6489

if fin(1) ~= 0

6670

if fin(1) ~= 0

6490

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6671

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6491

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6672

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6492

end

6673

end

6493

case 'trend_and_shift_to_DC'

6674

case 'trend_and_shift_to_DC'

6494

% estimate low frequency group delay

6675

% estimate low frequency group delay

6495

group_delay = -diff(H_ph(:))./diff(fin(:));

6676

group_delay = -diff(H_ph(:))./diff(fin(:));

6496

low_freq_gd = group_delay(1:50);

6677

low_freq_gd = group_delay(1:50);

6497

% calculate trend, throwing away outliers

6678

% calculate trend, throwing away outliers

6498

m = median(low_freq_gd); sigma = std(low_freq_gd);

6679

m = median(low_freq_gd); sigma = std(low_freq_gd);

6499

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6680

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6500

fin_x=fin;

6681

fin_x=fin;

6501

H_ph_x=H_ph(:);

6682

H_ph_x=H_ph(:);

6502

if fin(1) ~= 0

6683

if fin(1) ~= 0

6503

% correct outliers in first 10 phase samples

6684

% correct outliers in first 10 phase samples

6504

for k=10:-1:1

6685

for k=10:-1:1

6505

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6686

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6506

end

6687

end

6507

6688

6508

% shift all phase data so that DC extrapolation to 0 follows trend

6689

% shift all phase data so that DC extrapolation to 0 follows trend

6509

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6690

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6510

fin_x=[0, fin_x];

6691

fin_x=[0, fin_x];

6511

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6692

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6512

end

6693

end

6513

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6694

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6514

% the last two samples, so noise can create an inverted slope and

6695

% the last two samples, so noise can create an inverted slope and

6515

% non-causal response).

6696

% non-causal response).

6516

if fout(end)>fin(end)

6697

if fout(end)>fin(end)

6517

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6698

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6518

% p=polyfit(fin_x', H_ph_x, 1);

6699

% p=polyfit(fin_x', H_ph_x, 1);

6519

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6700

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6520

% hf_phase_trend=polyval(p,max(fout));

6701

% hf_phase_trend=polyval(p,max(fout));

6521

fin_x=[fin_x, fout(end)];

6702

fin_x=[fin_x, fout(end)];

6522

H_ph_x=[H_ph_x; hf_phase_trend];

6703

H_ph_x=[H_ph_x; hf_phase_trend];

6523

end

6704

end

6524

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6705

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6525

6706

6526

otherwise

6707

otherwise

6527

error('COM:Extrap:InvalidOption', ...

6708

error('COM:Extrap:InvalidOption', ...

6528

'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"');

6709

'debug_interp_Sparam valid values are "old", "zero_DC", "interp_to_DC", "interp_and_shift_to_DC", "trend_and_shift_to_DC", "interp_cubic_to_dc_linear_to_inf"');

6529

end

6710

end

6530

H_i = H_mag_i.*exp(1j*H_ph_i);

6711

H_i = H_mag_i.*exp(1j*H_ph_i);

6531

Sout=H_i;

6712

Sout=H_i;

6532

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6713

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6533

6714

6534

%This function makes the TX or RX package. The type input must be

6715

%This function makes the TX or RX package. The type input must be

6535

%'TX' or 'RX'

6716

%'TX' or 'RX'

6536

%If the mode argument is omitted, mode='dd' is assumed. Currently

6717

%If the mode argument is omitted, mode='dd' is assumed. Currently

6537

%mode='dc' is only used when making the TX package for AC CM noise

6718

%mode='dc' is only used when making the TX package for AC CM noise

6538

%inclusion. The Rx package for 'dc' mode is still generated using

6719

%inclusion. The Rx package for 'dc' mode is still generated using

6539

%the same parameters as 'dd' mode

6720

%the same parameters as 'dd' mode

6540

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6721

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6541

%

6722

%

6542

%One instance of package block looks like this (if no elements are set to 0):

6723

%One instance of package block looks like this (if no elements are set to 0):

6543

%-------------Lcomp----------Tline---------------

6724

%-------------Lcomp----------Tline---------------

6544

% | | |

6725

% | | |

6545

% Cpad Cbump Cball

6726

% Cpad Cbump Cball

6546

% | | |

6727

% | | |

6547

%------------------------------------------------

6728

%------------------------------------------------

6548

6729

6549

if nargin<6

6730

if nargin<6

6550

%optional input "include_die"=0 allows die parameters to be forced to 0

6731

%optional input "include_die"=0 allows die parameters to be forced to 0

6551

%this includes Cpad, Lcomp, and Cbump

6732

%this includes Cpad, Lcomp, and Cbump

6552

include_die=1;

6733

include_die=1;

6553

end

6734

end

6554

if nargin<5

6735

if nargin<5

6555

mode='dd';

6736

mode='dd';

6556

end

6737

end

6557

6738

6558

6739

6559

if ~isempty(param.PKG_NAME)

6740

if ~isempty(param.PKG_NAME)

6560

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6741

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6561

%so they are swapped in depending on if Tx or Rx is set for type

6742

%so they are swapped in depending on if Tx or Rx is set for type

6562

%Note that param is not returned from this function, so the swap does not persist

6743

%Note that param is not returned from this function, so the swap does not persist

6563

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6744

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6564

if strcmpi(type,'tx')

6745

if strcmpi(type,'tx')

6565

pkg_name = param.PKG_NAME{1};

6746

pkg_name = param.PKG_NAME{1};

6566

elseif strcmpi(type,'rx')

6747

elseif strcmpi(type,'rx')

6567

pkg_name = param.PKG_NAME{2};

6748

pkg_name = param.PKG_NAME{2};

6568

else

6749

else

6569

error('Pkg type must be Tx or Rx');

6750

error('Pkg type must be Tx or Rx');

6570

end

6751

end

6571

pkg_parameter_struct = param.PKG.(pkg_name);

6752

pkg_parameter_struct = param.PKG.(pkg_name);

6572

6753

6573

6754

6574

for j=1:length(swap_fields)

6755

for j=1:length(swap_fields)

6575

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6756

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6576

end

6757

end

6577

6758

6578

end

6759

end

6579

6760

6580

C_diepad = param.C_diepad;

6761

C_diepad = param.C_diepad;

6581

C_pkg_board = param.C_pkg_board;

6762

C_pkg_board = param.C_pkg_board;

6582

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6763

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6583

L_comp = param.L_comp;

6764

L_comp = param.L_comp;

6584

C_bump = param.C_bump;

6765

C_bump = param.C_bump;

6585

if ~include_die

6766

if ~include_die

6586

%best to multiply by 0. that way vectors maintain original size

6767

%best to multiply by 0. that way vectors maintain original size

6587

C_diepad=C_diepad*0;

6768

C_diepad=C_diepad*0;

6588

L_comp=L_comp*0;

6769

L_comp=L_comp*0;

6589

C_bump=C_bump*0;

6770

C_bump=C_bump*0;

6590

end

6771

end

6591

% [ahealey] End of modifications.

6772

% [ahealey] End of modifications.

6592

% generate TX package according to channel type.

6773

% generate TX package according to channel type.

6593

[ncases, mele]=size(param.z_p_next_cases);

6774

[ncases, mele]=size(param.z_p_next_cases);

6594

6775

6595

%Syntax update for C_diepad and L_comp

6776

%Syntax update for C_diepad and L_comp

6596

%Allow a chain of values to be entered as a matrix:

6777

%Allow a chain of values to be entered as a matrix:

6597

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6778

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6598

if isvector(C_diepad)

6779

if isvector(C_diepad)

6599

Cd_Tx=C_diepad(1);

6780

Cd_Tx=C_diepad(1);

6600

Cd_Rx=C_diepad(2);

6781

Cd_Rx=C_diepad(2);

6601

L_comp_Tx=L_comp(1);

6782

L_comp_Tx=L_comp(1);

6602

L_comp_Rx=L_comp(2);

6783

L_comp_Rx=L_comp(2);

6603

num_blocks=mele;

6784

num_blocks=mele;

6604

else

6785

else

6605

Cd_Tx=C_diepad(1,:);

6786

Cd_Tx=C_diepad(1,:);

6606

Cd_Rx=C_diepad(2,:);

6787

Cd_Rx=C_diepad(2,:);

6607

L_comp_Tx=L_comp(1,:);

6788

L_comp_Tx=L_comp(1,:);

6608

L_comp_Rx=L_comp(2,:);

6789

L_comp_Rx=L_comp(2,:);

6609

num_blocks=mele+length(Cd_Tx)-1;

6790

num_blocks=mele+length(Cd_Tx)-1;

6610

end

6791

end

6611

extra_LC=length(Cd_Tx)-1;

6792

extra_LC=length(Cd_Tx)-1;

6612

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6793

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6613

insert_zeros=zeros([1 extra_LC]);

6794

insert_zeros=zeros([1 extra_LC]);

6614

6795

6615

%Updated technique of building Tx/Rx packages

6796

%Updated technique of building Tx/Rx packages

6616

%each index corresponds to the package segment

6797

%each index corresponds to the package segment

6617

switch type

6798

switch type

6618

case 'TX'

6799

case 'TX'

6619

switch mele

6800

switch mele

6620

case 1

6801

case 1

6621

Cpad=Cd_Tx;

6802

Cpad=Cd_Tx;

6622

Lcomp=L_comp_Tx;

6803

Lcomp=L_comp_Tx;

6623

Cbump=C_bump(1);

6804

Cbump=C_bump(1);

6624

Cball=C_pkg_board(1);

6805

Cball=C_pkg_board(1);

6625

Zpkg=param.pkg_Z_c(1);

6806

Zpkg=param.pkg_Z_c(1);

6626

case 4

6807

case 4

6627

Cpad=[Cd_Tx 0 0 0];

6808

Cpad=[Cd_Tx 0 0 0];

6628

Lcomp=[L_comp_Tx 0 0 0];

6809

Lcomp=[L_comp_Tx 0 0 0];

6629

Cbump=[C_bump(1) 0 0 0];

6810

Cbump=[C_bump(1) 0 0 0];

6630

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6811

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6631

Zpkg=param.pkg_Z_c(1,:);

6812

Zpkg=param.pkg_Z_c(1,:);

6632

otherwise

6813

otherwise

6633

error('package syntax error')

6814

error('package syntax error')

6634

end

6815

end

6635

switch upper(channel_type)

6816

switch upper(channel_type)

6636

case 'THRU'

6817

case 'THRU'

6637

Len=param.Pkg_len_TX;

6818

Len=param.Pkg_len_TX;

6638

case 'NEXT'

6819

case 'NEXT'

6639

Len=param.Pkg_len_NEXT;

6820

Len=param.Pkg_len_NEXT;

6640

case 'FEXT'

6821

case 'FEXT'

6641

Len=param.Pkg_len_FEXT;

6822

Len=param.Pkg_len_FEXT;

6642

end

6823

end

6643

case 'RX'

6824

case 'RX'

6644

switch mele

6825

switch mele

6645

case 1

6826

case 1

6646

Cpad=Cd_Rx;

6827

Cpad=Cd_Rx;

6647

Lcomp=L_comp_Rx;

6828

Lcomp=L_comp_Rx;

6648

Cbump=C_bump(2);

6829

Cbump=C_bump(2);

6649

Cball=C_pkg_board(2);

6830

Cball=C_pkg_board(2);

6650

Zpkg=param.pkg_Z_c(2);

6831

Zpkg=param.pkg_Z_c(2);

6651

case 4

6832

case 4

6652

Cpad=[Cd_Rx 0 0 0];

6833

Cpad=[Cd_Rx 0 0 0];

6653

Lcomp=[L_comp_Rx 0 0 0];

6834

Lcomp=[L_comp_Rx 0 0 0];

6654

Cbump=[C_bump(2) 0 0 0];

6835

Cbump=[C_bump(2) 0 0 0];

6655

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6836

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6656

Zpkg=param.pkg_Z_c(2,:);

6837

Zpkg=param.pkg_Z_c(2,:);

6657

otherwise

6838

otherwise

6658

error('package syntax error')

6839

error('package syntax error')

6659

end

6840

end

6660

switch upper(channel_type)

6841

switch upper(channel_type)

6661

case 'THRU'

6842

case 'THRU'

6662

Len=param.Pkg_len_RX;

6843

Len=param.Pkg_len_RX;

6663

case 'NEXT'

6844

case 'NEXT'

6664

Len=param.Pkg_len_RX;

6845

Len=param.Pkg_len_RX;

6665

case 'FEXT'

6846

case 'FEXT'

6666

Len=param.Pkg_len_RX;

6847

Len=param.Pkg_len_RX;

6667

end

6848

end

6668

end

6849

end

6669

6850

6670

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6851

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6671

Cball=[insert_zeros Cball];

6852

Cball=[insert_zeros Cball];

6672

Cbump=[insert_zeros Cbump];

6853

Cbump=[insert_zeros Cbump];

6673

Len=[insert_zeros Len];

6854

Len=[insert_zeros Len];

6674

Zpkg=[insert_zeros Zpkg];

6855

Zpkg=[insert_zeros Zpkg];

6675

6856

6676

% debug_string='';

6857

% debug_string='';

6677

% for j=1:length(Zpkg)

6858

% for j=1:length(Zpkg)

6678

% if Cpad(j)~=0

6859

% if Cpad(j)~=0

6679

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6860

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6680

% end

6861

% end

6681

% if Lcomp(j)~=0

6862

% if Lcomp(j)~=0

6682

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6863

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6683

% end

6864

% end

6684

% if Cbump(j)~=0

6865

% if Cbump(j)~=0

6685

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6866

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6686

% end

6867

% end

6687

% if Len(j)~=0

6868

% if Len(j)~=0

6688

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6869

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6689

% end

6870

% end

6690

% if Cball(j)~=0

6871

% if Cball(j)~=0

6691

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6872

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6692

% end

6873

% end

6693

% end

6874

% end

6694

% if length(debug_string)>2

6875

% if length(debug_string)>2

6695

% debug_string=debug_string(3:end);

6876

% debug_string=debug_string(3:end);

6696

% end

6877

% end

6697

6878

6698

% tx package

6879

% tx package

6699

pkg_param=param;

6880

pkg_param=param;

6700

if strcmpi(mode,'dc')

6881

if strcmpi(mode,'dc')

6701

% change tx package to CC mode

6882

% change tx package to CC mode

6702

pkg_param.Z0=pkg_param.Z0/2;

6883

pkg_param.Z0=pkg_param.Z0/2;

6703

Cpad=Cpad*2;

6884

Cpad=Cpad*2;

6704

Cball=Cball*2;

6885

Cball=Cball*2;

6705

Zpkg=Zpkg*2;

6886

Zpkg=Zpkg*2;

6706

Lcomp=Lcomp/2;

6887

Lcomp=Lcomp/2;

6707

Cbump=Cbump*2;

6888

Cbump=Cbump*2;

6708

end

6889

end

6709

switch num_blocks

6890

switch num_blocks

6710

case 1

6891

case 1

6711

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6892

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6712

otherwise

6893

otherwise

6713

for j=1:num_blocks

6894

for j=1:num_blocks

6714

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6895

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6715

if j==1

6896

if j==1

6716

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6897

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6717

else

6898

else

6718

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6899

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6719

end

6900

end

6720

end

6901

end

6721

end

6902

end

6722

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6903

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6723

f(f<eps)=eps;

6904

f(f<eps)=eps;

6724

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6905

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6725

%% Equation 93A-8

6906

%% Equation 93A-8

6726

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6907

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6727

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6908

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6728

6909

6729

% [ahealey] Add compensating L and shunt C (bump) when requested.

6910

% [ahealey] Add compensating L and shunt C (bump) when requested.

6730

s12pad = s21pad;

6911

s12pad = s21pad;

6731

s22pad = s11pad;

6912

s22pad = s11pad;

6732

if nargin > 6

6913

if nargin > 6

6733

lcomp = varargin{1};

6914

lcomp = varargin{1};

6734

if lcomp>0

6915

if lcomp>0

6735

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6916

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6736

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6917

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6737

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6918

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6738

s11pad, s12pad, s21pad, s22pad, ...

6919

s11pad, s12pad, s21pad, s22pad, ...

6739

s11comp, s21comp, s21comp, s11comp);

6920

s11comp, s21comp, s21comp, s11comp);

6740

end

6921

end

6741

end

6922

end

6742

if nargin > 7

6923

if nargin > 7

6743

cbump = varargin{2};

6924

cbump = varargin{2};

6744

if cbump>0

6925

if cbump>0

6745

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

6926

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

6746

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

6927

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

6747

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6928

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6748

s11pad, s12pad, s21pad, s22pad, ...

6929

s11pad, s12pad, s21pad, s22pad, ...

6749

s11bump, s21bump, s21bump, s11bump);

6930

s11bump, s21bump, s21bump, s11bump);

6750

end

6931

end

6751

end

6932

end

6752

% [ahealey] End of modifications.

6933

% [ahealey] End of modifications.

6753

6934

6754

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

6935

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

6755

% [ahealey] Symmetry cannot be assumed with more complex termination models.

6936

% [ahealey] Symmetry cannot be assumed with more complex termination models.

6756

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

6937

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

6757

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

6938

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

6758

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

6939

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

6759

s11pad, s12pad, s21pad, s22pad, ...

6940

s11pad, s12pad, s21pad, s22pad, ...

6760

S11, S21, S21, S11);

6941

S11, S21, S21, S11);

6761

% [ahealey] End of modifications.

6942

% [ahealey] End of modifications.

6762

6943

6763

%% Equation 93A-8

6944

%% Equation 93A-8

6764

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

6945

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

6765

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

6946

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

6766

[ s11out, s12out, s21out, s22out ]= ...

6947

[ s11out, s12out, s21out, s22out ]= ...

6767

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

6948

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

6768

6949

6769

function missingParameter (parameterName)

6950

function missingParameter (parameterName)

6770

error( 'error:badParameterInformation', ...

6951

error( 'error:badParameterInformation', ...

6771

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

6952

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

6772

6953

6773

function pdf = normal_dist(sigma,nsigma,binsize)

6954

function pdf = normal_dist(sigma,nsigma,binsize)

6774

pdf.BinSize=binsize;

6955

pdf.BinSize=binsize;

6775

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

6956

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

6776

pdf.x=(pdf.Min:-pdf.Min)*binsize;

6957

pdf.x=(pdf.Min:-pdf.Min)*binsize;

6777

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

6958

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

6778

pdf.y=pdf.y/sum(pdf.y);

6959

pdf.y=pdf.y/sum(pdf.y);

6779

6960

6780

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

6961

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

6781

%% input

6962

%% input

6782

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

6963

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

6783

% baud_rate - baud rate in seconds

6964

% baud_rate - baud rate in seconds

6784

% param.samples_per_ui = samples per UI of IR

6965

% param.samples_per_ui = samples per UI of IR

6785

% param.max_ctle - maximum ac to dc gain in dB

6966

% param.max_ctle - maximum ac to dc gain in dB

6786

% param.tx_ffe(1) - maximum pre cursor (positive value)

6967

% param.tx_ffe(1) - maximum pre cursor (positive value)

6787

% param.tx_ffe(2) - maximum post cursor (positive value)

6968

% param.tx_ffe(2) - maximum post cursor (positive value)

6788

% param.tx_ffe_step - sweep step size for tx pre and post taps

6969

% param.tx_ffe_step - sweep step size for tx pre and post taps

6789

% param.ndfe - number of reference dfe taps

6970

% param.ndfe - number of reference dfe taps

6790

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

6971

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

6791

% output

6972

% output

6792

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

6973

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

6793

% result.eq.ctle - index of CTLE parameters in table

6974

% result.eq.ctle - index of CTLE parameters in table

6794

% result.IR - impulse response

6975

% result.IR - impulse response

6795

% result.avail_signal - maximum signal after equalization

6976

% result.avail_signal - maximum signal after equalization

6796

% result.avail_sig_index - index in result.IR of max signal

6977

% result.avail_sig_index - index in result.IR of max signal

6797

% result.best_FOM - best raw ISI

6978

% result.best_FOM - best raw ISI

6798

6979

6799

6800

min_number_of_UI_in_response=40;

6980

min_number_of_UI_in_response=40;

6801

baud_rate=1/param.ui;

6981

baud_rate=1/param.ui;

6802

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

6982

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

6803

f=chdata(1).faxis;

6983

f=chdata(1).faxis;

6804

6984

6805

%Read user input of ts_sample_adj_range

6985

%Read user input of ts_sample_adj_range

6806

%if one value was entered, go from 0 to that value

6986

%if one value was entered, go from 0 to that value

6807

%if 2 values were entered, go from the 1st value to the 2nd value

6987

%if 2 values were entered, go from the 1st value to the 2nd value

6808

if length(param.ts_sample_adj_range)==1

6988

if length(param.ts_sample_adj_range)==1

6809

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

6989

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

6810

param.ts_sample_adj_range(1)=0;

6990

param.ts_sample_adj_range(1)=0;

6811

end

6991

end

6812

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

6992

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

6813

6993

6814

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

6994

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

6815

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

6995

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

6816

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

6996

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

6817

% need to include H_RCos in noise and when computing the system ir for thru

6997

% need to include H_RCos in noise and when computing the system ir for thru

6818

% and crosstalk

6998

% and crosstalk

6819

H_r=H_bw.*H_bt.*H_RCos;

6999

H_r=H_bw.*H_bt.*H_RCos;

6820

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

7000

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

6821

% Get f vector from 0 to Fs/2-delta_f.

7001

% Get f vector from 0 to Fs/2-delta_f.

6822

N_fft_by2 = 512;

7002

N_fft_by2 = 512;

6823

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

7003

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

6824

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

7004

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

6825

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

7005

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

6826

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

7006

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

6827

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

7007

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

6828

%%

7008

%%

6829

7009

6830

% system noise H_sy PSD

7010

% system noise H_sy PSD

6831

if OP.USE_ETA0_PSD

7011

if OP.USE_ETA0_PSD

6832

fspike=1e9;

7012

fspike=1e9;

6833

% requires communication tool box if used

7013

% requires communication tool box if used

6834

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

7014

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

6835

else

7015

else

6836

H_sy=ones(1,length(chdata(1).faxis));

7016

H_sy=ones(1,length(chdata(1).faxis));

6837

end

7017

end

6838

7018

6839

%Build txffe values dynamically

7019

%Build txffe values dynamically

6840

%any param field that is "tx_ffe_cm<X>_values" is a precursor

7020

%any param field that is "tx_ffe_cm<X>_values" is a precursor

6841

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

7021

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

6842

%where <X> is any integer

7022

%where <X> is any integer

6843

param_fields=fieldnames(param);

7023

param_fields=fieldnames(param);

6844

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

7024

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

6845

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

7025

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

6846

num_taps=num_pre+num_post;

7026

num_taps=num_pre+num_post;

6847

cur=num_pre+1;

7027

cur=num_pre+1;

6848

%txffe_cell combines all the txffe values into a single cell array

7028

%txffe_cell combines all the txffe values into a single cell array

6849

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

7029

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

6850

txffe_cell=cell(1,num_taps);

7030

txffe_cell=cell(1,num_taps);

6851

for k=num_pre:-1:1

7031

for k=num_pre:-1:1

6852

idx=num_pre-k+1;

7032

idx=num_pre-k+1;

6853

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

7033

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

6854

txffe_cell{idx}=param.(this_tx_field);

7034

txffe_cell{idx}=param.(this_tx_field);

6855

end

7035

end

6856

for k=1:num_post

7036

for k=1:num_post

6857

idx=k+num_pre;

7037

idx=k+num_pre;

6858

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

7038

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

6859

txffe_cell{idx}=param.(this_tx_field);

7039

txffe_cell{idx}=param.(this_tx_field);

6860

end

7040

end

6861

%total number of txffe runs is the product of the lengths of each tap

7041

%total number of txffe runs is the product of the lengths of each tap

6862

txffe_lengths=cellfun('length',txffe_cell);

7042

txffe_lengths=cellfun('length',txffe_cell);

6863

if isempty(txffe_cell)

7043

if isempty(txffe_cell)

6864

num_txffe_runs=1;

7044

num_txffe_runs=1;

6865

else

7045

else

6866

num_txffe_runs=prod(txffe_lengths);

7046

num_txffe_runs=prod(txffe_lengths);

6867

end

7047

end

6868

%txffe_sweep_indices are used in the LOCAL_SEARCH block

7048

%txffe_sweep_indices are used in the LOCAL_SEARCH block

6869

%any tap with length=1 can be ignored

7049

%any tap with length=1 can be ignored

6870

%Also is statistically likely that taps with greater number of values

7050

%Also is statistically likely that taps with greater number of values

6871

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

7051

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

6872

txffe_sweep_indices=find(txffe_lengths>1);

7052

txffe_sweep_indices=find(txffe_lengths>1);

6873

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

7053

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

6874

txffe_sweep_indices=txffe_sweep_indices(length_sort);

7054

txffe_sweep_indices=txffe_sweep_indices(length_sort);

6875

num_txffe_sweep_indices=length(txffe_sweep_indices);

7055

num_txffe_sweep_indices=length(txffe_sweep_indices);

6876

7056

6877

gdc_values = param.ctle_gdc_values;

7057

gdc_values = param.ctle_gdc_values;

6878

Gffe_values = param.cursor_gain;

7058

Gffe_values = param.cursor_gain;

6879

switch param.CTLE_type

7059

switch param.CTLE_type

6880

case 'CL93'

7060

case 'CL93'

6881

case 'CL120d'

7061

case 'CL120d'

6882

g_DC_HP_values =param.g_DC_HP_values;

7062

g_DC_HP_values =param.g_DC_HP_values;

6883

case 'CL120e'

7063

case 'CL120e'

6884

f_HP_Z=param.f_HP_Z;

7064

f_HP_Z=param.f_HP_Z;

6885

f_HP_P=param.f_HP_P;

7065

f_HP_P=param.f_HP_P;

6886

7066

6887

end

7067

end

6888

best_ctle = [];

7068

best_ctle = [];

6889

best_FOM = -inf;

7069

best_FOM = -inf;

6890

best_txffe = [];

7070

best_txffe = [];

6891

delta_sbr = [];

7071

delta_sbr = [];

6892

PSD_results=[];

7072

PSD_results=[];

6893

MMSE_results=[];

7073

MMSE_results=[];

6894

best_bmax=param.bmax;

7074

best_bmax=param.bmax;

6895

%AJG021820

7075

%AJG021820

6896

best_bmin=param.bmin;

7076

best_bmin=param.bmin;

6897

h_J=[];

7077

h_J=[];

6898

pxi=0;

7078

pxi=0;

6899

if OP.DISPLAY_WINDOW

7079

if OP.DISPLAY_WINDOW

6900

hwaitbar=waitbar(0);

7080

hwaitbar=waitbar(0);

6901

else

7081

else

6902

fprintf('FOM search ');

7082

fprintf('FOM search ');

6903

end

7083

end

6904

FOM=0;

7084

FOM=0;

6905

if ~OP.RxFFE

7085

if ~OP.RxFFE

6906

Gffe_values=0;

7086

Gffe_values=0;

6907

end

7087

end

6908

param.ndfe_passed=param.ndfe;

7088

param.ndfe_passed=param.ndfe;

6909

old_loops=0;

7089

old_loops=0;

6910

new_loops=0;

7090

new_loops=0;

6911

7091

6912

%GDC Qual construction

7092

%GDC Qual construction

6913

gqual= param.gqual;

7093

gqual= param.gqual;

6914

g2qual=param.g2qual;

7094

g2qual=param.g2qual;

6915

if ~strcmp(param.CTLE_type,'CL120d')

7095

if ~strcmp(param.CTLE_type,'CL120d')

6916

qual=ones(1,length(gdc_values));

7096

qual=ones(1,length(gdc_values));

6917

else

7097

else

6918

if isempty(gqual) && isempty(g2qual)

7098

if isempty(gqual) && isempty(g2qual)

6919

qual=ones(length(g_DC_HP_values),length(gdc_values));

7099

qual=ones(length(g_DC_HP_values),length(gdc_values));

6920

else

7100

else

6921

qual=zeros(length(g_DC_HP_values),length(gdc_values));

7101

qual=zeros(length(g_DC_HP_values),length(gdc_values));

6922

7102

6923

%prepare gqual and g2qual

7103

%prepare gqual and g2qual

6924

[g2qual,si]=sort(g2qual,'descend');

7104

[g2qual,si]=sort(g2qual,'descend');

6925

gqual=gqual(si,:);

7105

gqual=gqual(si,:);

6926

tmp=g2qual;

7106

tmp=g2qual;

6927

g2qual=zeros(length(tmp),2);

7107

g2qual=zeros(length(tmp),2);

6928

for kk=1:length(tmp)

7108

for kk=1:length(tmp)

6929

if kk==1

7109

if kk==1

6930

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

7110

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

6931

else

7111

else

6932

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

7112

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

6933

end

7113

end

6934

gqual(kk,:)=sort(gqual(kk,:),'descend');

7114

gqual(kk,:)=sort(gqual(kk,:),'descend');

6935

end

7115

end

6936

7116

6937

%Qual Construction

7117

%Qual Construction

6938

for jj=1:length(g_DC_HP_values)

7118

for jj=1:length(g_DC_HP_values)

6939

for ii=1:length(gdc_values)

7119

for ii=1:length(gdc_values)

6940

for kk=1:size(gqual,1)

7120

for kk=1:size(gqual,1)

6941

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

7121

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

6942

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

7122

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

6943

qual(jj,ii)=1;

7123

qual(jj,ii)=1;

6944

break;

7124

break;

6945

end

7125

end

6946

end

7126

end

6947

end

7127

end

6948

end

7128

end

6949

end

7129

end

6950

end

7130

end

6951

end

7131

end

6952

7132

6953

progress_interval=0.025;

7133

progress_interval=0.025;

6954

if do_C2M

7134

if do_C2M

6955

loop_count=[1 2];

7135

loop_count=[1 2];

6956

T_O=floor((param.T_O/1000)*param.samples_per_ui);

7136

T_O=floor((param.T_O/1000)*param.samples_per_ui);

6957

T_O=max(0,T_O);

7137

T_O=max(0,T_O);

6958

else

7138

else

6959

loop_count=1;

7139

loop_count=1;

6960

T_O=0;

7140

T_O=0;

6961

end

7141

end

6962

switch param.CTLE_type

7142

switch param.CTLE_type

6963

case 'CL93'

7143

case 'CL93'

6964

lf_indx=1;

7144

lf_indx=1;

6965

case 'CL120d'

7145

case 'CL120d'

6966

lf_indx=length(g_DC_HP_values);

7146

lf_indx=length(g_DC_HP_values);

6967

case 'CL120e'

7147

case 'CL120e'

6968

lf_indx=1;

7148

lf_indx=1;

6969

end

7149

end

6970

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

7150

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

6971

if OP.Optimize_loop_speed_up == 1

7151

if OP.Optimize_loop_speed_up == 1

6972

OP.BinSize = 1e-4;

7152

OP.BinSize = 1e-4;

6973

OP.impulse_response_truncation_threshold = 1e-3;

7153

OP.impulse_response_truncation_threshold = 1e-3;

6974

end

7154

end

6975

7155

6976

%Used to speed up FFE by only performing circshift when necessary

7156

%Used to speed up FFE by only performing circshift when necessary

6977

pulse_ctle_circshift=[];

7157

pulse_struc(1).pulse_ctle_circshift=[];

6978

ctle_response_updated=1;

7158

ctle_response_updated=1;

6979

7159

6980

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

7160

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

6981

calc_exp_phase=0;

7161

calc_exp_phase=0;

6982

7162

6983

%calculate cur index and pre/post indices outside of the loop

7163

%calculate cur index and pre/post indices outside of the loop

6984

cur_start=cur;

7164

cur_start=cur;

6985

precursor_indices=[];

7165

precursor_indices=[];

6986

postcursor_indices=[];

7166

postcursor_indices=[];

6987

auto_count_trigger=0;

7167

auto_count_trigger=0;

6988

for kv=1:num_taps

7168

for kv=1:num_taps

6989

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

7169

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

6990

%precursor values fill the beginning of the vector. Any empty precursor means

7170

%precursor values fill the beginning of the vector. Any empty precursor means

6991

%cursor position must be subtracted by 1

7171

%cursor position must be subtracted by 1

6992

if kv<cur_start

7172

if kv<cur_start

6993

cur=cur-1;

7173

cur=cur-1;

6994

end

7174

end

6995

else

7175

else

6996

%non empty value: add to precursor or postcursor indices depending on position

7176

%non empty value: add to precursor or postcursor indices depending on position

6997

%in the vector

7177

%in the vector

6998

if kv<cur_start

7178

if kv<cur_start

6999

auto_count_trigger=1;

7179

auto_count_trigger=1;

7000

precursor_indices=[precursor_indices kv];

7180

precursor_indices=[precursor_indices kv];

7001

else

7181

else

7002

auto_count_trigger=0;

7182

auto_count_trigger=0;

7003

postcursor_indices=[postcursor_indices kv];

7183

postcursor_indices=[postcursor_indices kv];

7004

end

7184

end

7005

end

7185

end

7006

end

7186

end

7007

if ~isempty(postcursor_indices)

7187

if ~isempty(postcursor_indices)

7008

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

7188

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

7009

end

7189

end

7010

7190

7011

%Calculate the full grid matrix of all txffe combinations

7191

%Calculate the full grid matrix of all txffe combinations

7012

if isempty(txffe_cell)

7192

if isempty(txffe_cell)

7013

TXFFE_grid=0;

7193

TXFFE_grid=0;

7014

FULL_tx_index_vector=1;

7194

FULL_tx_index_vector=1;

7015

else

7195

else

7016

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

7196

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

7017

%Also calculate the full grid matrix for the index used in each txffe combination

7197

%Also calculate the full grid matrix for the index used in each txffe combination

7018

%(the index is used in the LOCAL SEARCH block)

7198

%(the index is used in the LOCAL SEARCH block)

7019

for k=1:num_taps

7199

for k=1:num_taps

7020

txffe_index_cell{k}=1:txffe_lengths(k);

7200

txffe_index_cell{k}=1:txffe_lengths(k);

7021

end

7201

end

7022

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

7202

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

7023

end

7203

end

7024

7204

7025

%pre-calculate cursor to save time

7205

%pre-calculate cursor to save time

7026

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

7206

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

7027

7207

7028

%pre-calculate full txffe for each iteration to save time

7208

%pre-calculate full txffe for each iteration to save time

7029

precursor_matrix=TXFFE_grid(:,precursor_indices);

7209

precursor_matrix=TXFFE_grid(:,precursor_indices);

7030

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7210

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7031

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7211

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7032

7212

7033

if OP.TDMODE

7213

if OP.TDMODE

7034

uneq_field='uneq_pulse_response';

7214

uneq_field='uneq_pulse_response';

7035

ctle_field='ctle_pulse_response';

7215

ctle_field='ctle_pulse_response';

7036

else

7216

else

7037

uneq_field='uneq_imp_response';

7217

uneq_field='uneq_imp_response';

7038

ctle_field='ctle_imp_response';

7218

ctle_field='ctle_imp_response';

7039

end

7219

end

7040

7220

7041

%Speed up search for max(sbr)

7221

%Speed up search for max(sbr)

7042

if OP.TDMODE

7222

if OP.TDMODE

7043

[~,init_max]=max(chdata(1).uneq_pulse_response);

7223

[~,init_max]=max(chdata(1).uneq_pulse_response);

7044

else

7224

else

7045

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7225

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7046

end

7226

end

7047

UI_max_window=20;

7227

UI_max_window=20;

7048

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7228

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7049

if start_max_idx<1

7229

if start_max_idx<1

7050

start_max_idx=1;

7230

start_max_idx=1;

7051

end

7231

end

7052

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7232

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7053

if end_max_idx>length(chdata(1).(uneq_field))

7233

if end_max_idx>length(chdata(1).(uneq_field))

7054

end_max_idx=length(chdata(1).(uneq_field));

7234

end_max_idx=length(chdata(1).(uneq_field));

7055

end

7235

end

7056

7236

7057

itick_skips=0;

7237

itick_skips=0;

7058

itick_cases=0;

7238

itick_cases=0;

7059

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7239

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7060

for i=loop_count

7240

for i=loop_count

7061

7241

7062

for Gffe_index=1:length(Gffe_values)

7242

for Gffe_index=1:length(Gffe_values)

7063

param.current_ffegain=Gffe_values(Gffe_index);

7243

param.current_ffegain=Gffe_values(Gffe_index);

7064

for ctle_index=1:length(gdc_values)

7244

for ctle_index=1:length(gdc_values)

7065

g_dc = gdc_values(ctle_index);

7245

g_dc = gdc_values(ctle_index);

7066

kacdc = 10^(g_dc/20);

7246

kacdc = 10^(g_dc/20);

7067

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7247

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7068

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7248

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7069

CTLE_fz = param.CTLE_fz(ctle_index);

7249

CTLE_fz = param.CTLE_fz(ctle_index);

7070

switch param.CTLE_type

7250

switch param.CTLE_type

7071

case 'CL93'

7251

case 'CL93'

7072

%

7252

%

7073

case 'CL120d'

7253

case 'CL120d'

7074

%

7254

%

7075

case 'CL120e'

7255

case 'CL120e'

7076

HP_Z = param.f_HP_Z(ctle_index);

7256

HP_Z = param.f_HP_Z(ctle_index);

7077

HP_P = param.f_HP_P(ctle_index);

7257

HP_P = param.f_HP_P(ctle_index);

7078

end

7258

end

7079

%% HF Boost

7259

%% HF Boost

7080

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7260

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7081

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7261

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7082

%% Mid Frequency Boost

7262

%% Mid Frequency Boost

7083

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7263

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7084

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7264

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7085

for g_LP_index=1:lf_indx

7265

for g_LP_index=1:lf_indx

7086

7266

7087

%GDC Qual Check

7267

%GDC Qual Check

7088

if qual(g_LP_index,ctle_index)==0

7268

if qual(g_LP_index,ctle_index)==0

7089

pxi=pxi+num_txffe_runs;

7269

pxi=pxi+num_txffe_runs;

7090

continue;

7270

continue;

7091

end

7271

end

7092

7272

7093

switch param.CTLE_type

7273

switch param.CTLE_type

7094

case 'CL93'

7274

case 'CL93'

7095

H_low=1;

7275

H_low=1;

7096

kacde_DC_low=1;

7276

kacde_DC_low=1;

7097

case 'CL120d'

7277

case 'CL120d'

7098

g_DC_low = g_DC_HP_values(g_LP_index);

7278

g_DC_low = g_DC_HP_values(g_LP_index);

7099

f_HP=param.f_HP(g_LP_index);

7279

f_HP=param.f_HP(g_LP_index);

7100

kacde_DC_low = 10^(g_DC_low/20);

7280

kacde_DC_low = 10^(g_DC_low/20);

7101

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7281

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7102

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7282

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7103

case 'CL120e' % z1 has been adusted on read in

7283

case 'CL120e' % z1 has been adusted on read in

7104

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7284

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7105

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7285

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7106

end

7286

end

7107

H_ctf=H_low.*ctle_gain;

7287

H_ctf=H_low.*ctle_gain;

7108

switch upper(OP.FFE_OPT_METHOD)

7288

switch upper(OP.FFE_OPT_METHOD)

7109

case 'WIENER-HOPF'

7289

case 'WIENER-HOPF'

7110

%% Bill Kirkland

7290

%% Bill Kirkland

7111

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7291

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7112

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7292

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7113

% use Fourier Transform pair for correlation as we have to

7293

% use Fourier Transform pair for correlation as we have to

7114

% take ifft of H_r anyways.

7294

% take ifft of H_r anyways.

7115

% onesided and two sided responses - tricky, tricky, tricky

7295

% onesided and two sided responses - tricky, tricky, tricky

7116

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7296

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7117

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7297

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7118

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7298

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7119

7299

7120

if OP.Do_White_Noise

7300

if OP.Do_White_Noise

7121

Noise_XC = Noise_XC(1);

7301

Noise_XC = Noise_XC(1);

7122

end

7302

end

7123

otherwise

7303

otherwise

7124

Noise_XC=[];

7304

Noise_XC=[];

7125

end

7305

end

7126

7306

7127

7307

7128

7308

7129

if OP.INCLUDE_CTLE==1

7309

if OP.INCLUDE_CTLE==1

7130

for k=1:param.num_s4p_files

7310

for k=1:param.num_s4p_files

7131

ir_peak = max(abs(chdata(k).(uneq_field)));

7311

ir_peak = max(abs(chdata(k).(uneq_field)));

7132

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7312

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7133

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7313

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7134

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7314

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7135

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7315

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7136

switch param.CTLE_type

7316

switch param.CTLE_type

7137

case 'CL93'

7317

case 'CL93'

7138

case 'CL120d'

7318

case 'CL120d'

7139

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7319

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7140

case 'CL120e' % z1 has been adusted on read in

7320

case 'CL120e' % z1 has been adusted on read in

7141

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7321

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7142

end

7322

end

7143

end

7323

end

7144

%set the flag to show ctle response was updated

7324

%set the flag to show ctle response was updated

7145

ctle_response_updated=1;

7325

ctle_response_updated=1;

7146

else

7326

else

7147

for k=1:param.num_s4p_files

7327

for k=1:param.num_s4p_files

7148

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7328

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7149

end

7329

end

7150

end

7330

end

7151

for k=1:param.num_s4p_files

7331

for k=1:param.num_s4p_files

7152

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7332

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7153

end

7333

end

7154

%% Equation 93A-22 %%

7334

%% Equation 93A-22 %%

7155

% figure(1000)

7335

% figure(1000)

7156

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7336

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7157

% hold on

7337

% hold on

7158

if OP.RX_CALIBRATION

7338

if OP.RX_CALIBRATION

7159

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7339

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7160

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7340

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7161

switch param.CTLE_type

7341

switch param.CTLE_type

7162

case 'CL93'

7342

case 'CL93'

7163

H_low2=1;

7343

H_low2=1;

7164

case 'CL120d'

7344

case 'CL120d'

7165

g_DC_low = g_DC_HP_values(g_LP_index);

7345

g_DC_low = g_DC_HP_values(g_LP_index);

7166

f_HP=param.f_HP(g_LP_index);

7346

f_HP=param.f_HP(g_LP_index);

7167

kacde_DC_low = 10^(g_DC_low/20);

7347

kacde_DC_low = 10^(g_DC_low/20);

7168

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7348

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7169

case 'CL120e' % z1 has been adusted on read in

7349

case 'CL120e' % z1 has been adusted on read in

7170

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7350

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7171

end

7351

end

7172

H_ctf2=H_low2.*ctle_gain2;

7352

H_ctf2=H_low2.*ctle_gain2;

7173

end

7353

end

7174

% RIM 11-30-2020 moved to a subfunction

7354

% RIM 11-30-2020 moved to a subfunction

7175

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7355

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7176

if OP.RX_CALIBRATION

7356

if OP.RX_CALIBRATION

7177

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7357

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7178

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

7358

sigma_NEXT=sqrt(param.eta_0*sum( abs(H_sy(2:end).^2 .* H_r(2:end).*2 .* H_ctf(2:end).^2 ) .* diff(chdata(1).faxis)/1e9));% changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7179

else

7359

else

7180

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7360

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

+7361

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7181

sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7362

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7182

sigma_ne=0;

7363

sigma_ne=0;

7183

end

7364

end

7184

7365

7185

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7366

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7186

pxi=pxi+num_txffe_runs;

7367

pxi=pxi+num_txffe_runs;

7187

continue; % change per 0.3k draft 2.3

7368

continue; % change per 0.3k draft 2.3

7188

end

7369

end

7189

%%

7370

%%

7190

PSD_results=[];

7371

PSD_results=[];

7191

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7372

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7192

OP.WO_TXFFE=1;

7373

OP.WO_TXFFE=1;

7193

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7374

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7194

end

7375

end

7195

%TXFFE Loop

7376

%TXFFE Loop

7196

%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

7377

%Originally this was a separate for loop for each tap, but it is now all contained in the TXFFE_grid matrix to use a single modular loop

7197

for TK=1:size(TXFFE_grid,1)

7378

for TK=1:size(TXFFE_grid,1)

7198

7379

7199

pxi=pxi+1;

7380

pxi=pxi+1;

7200

progress = pxi/runs;

7381

progress = pxi/runs;

7201

if OP.DISPLAY_WINDOW

7382

if OP.DISPLAY_WINDOW

7202

if ~mod(pxi,floor(runs*progress_interval))

7383

if ~mod(pxi,floor(runs*progress_interval))

7203

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7384

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7204

end

7385

end

7205

else

7386

else

7206

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7387

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7207

end

7388

end

7208

7389

7209

%get the cursor for this iteration

7390

%get the cursor for this iteration

7210

txffe_cur=txffe_cursor_vector(TK);

7391

txffe_cur=txffe_cursor_vector(TK);

7211

7392

7212

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7393

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7213

if txffe_cur<param.tx_ffe_c0_min

7394

if txffe_cur<param.tx_ffe_c0_min

7214

continue;

7395

continue;

7215

end

7396

end

7216

old_loops=old_loops+1;

7397

old_loops=old_loops+1;

7217

7398

7218

%get the index used for each tap on this iteration

7399

%get the index used for each tap on this iteration

7219

%this is needed for the LOCAL SEARCH block

7400

%this is needed for the LOCAL SEARCH block

7220

tx_index_vector=FULL_tx_index_vector(TK,:);

7401

tx_index_vector=FULL_tx_index_vector(TK,:);

7221

7402

7222

%Original LOCAL SEARCH Block:

7403

%Original LOCAL SEARCH Block:

7223

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7404

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7224

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7405

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7225

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7406

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7226

% % skip configurations more than

7407

% % skip configurations more than

7227

% % 2 steps away from current "best" point on any grid direction

7408

% % 2 steps away from current "best" point on any grid direction

7228

% % Matt Brown 11/19/2021 for cp2 and cp3

7409

% % Matt Brown 11/19/2021 for cp2 and cp3

7229

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7410

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7230

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7411

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7231

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7412

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7232

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7413

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7233

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7414

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7234

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7415

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7235

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7416

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7236

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7417

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7237

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7418

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7238

%

7419

%

7239

% continue;

7420

% continue;

7240

% end

7421

% end

7241

7422

7242

%Modular LOCAL_SEARCH block:

7423

%Modular LOCAL_SEARCH block:

7243

% speedup "local search" heuristic - Adee Ran 03-17-2020

7424

% speedup "local search" heuristic - Adee Ran 03-17-2020

7244

% skip configurations more than 2 steps away from current "best" point on any grid direction

7425

% skip configurations more than 2 steps away from current "best" point on any grid direction

7245

skip_it=0;

7426

skip_it=0;

7246

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7427

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7247

%instead of looping across all taps, only loop across

7428

%instead of looping across all taps, only loop across

7248

%those with length>1 (txffe_sweep_indices).

7429

%those with length>1 (txffe_sweep_indices).

7249

%It saves time since this block is encountered so often

7430

%It saves time since this block is encountered so often

7250

for kj=1:num_txffe_sweep_indices

7431

for kj=1:num_txffe_sweep_indices

7251

kv=txffe_sweep_indices(kj);

7432

kv=txffe_sweep_indices(kj);

7252

if kv==1

7433

if kv==1

7253

previous_loop_val=g_LP_index;

7434

previous_loop_val=g_LP_index;

7254

else

7435

else

7255

previous_loop_val=tx_index_vector(kv-1);

7436

previous_loop_val=tx_index_vector(kv-1);

7256

end

7437

end

7257

if previous_loop_val>1

7438

if previous_loop_val>1

7258

best_index_this_tap=best_txffe_index(kv);

7439

best_index_this_tap=best_txffe_index(kv);

7259

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7440

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7260

skip_it=1;

7441

skip_it=1;

7261

break;

7442

break;

7262

end

7443

end

7263

end

7444

end

7264

end

7445

end

7265

7446

7266

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7447

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7267

skip_it=1;

7448

skip_it=1;

7268

end

7449

end

7269

end

7450

end

7270

if skip_it

7451

if skip_it

7271

continue;

7452

continue;

7272

end

7453

end

7273

%End Modular LOCAL SEARCH block

7454

%End Modular LOCAL SEARCH block

7274

7455

7275

new_loops=new_loops+1;

7456

new_loops=new_loops+1;

7276

7457

7277

%fetch txffe for this iteration

7458

%fetch txffe for this iteration

7278

txffe=txffe_matrix(TK,:);

7459

txffe=txffe_matrix(TK,:);

7279

7460

7280

%The phase shift exponentials used in get_xtlk_noise are independent of

7461

%The phase shift exponentials used in get_xtlk_noise are independent of

7281

%everything except number of taps and cursor position

7462

%everything except number of taps and cursor position

7282

%So it can be calculated 1 time here to avoid thousands of re-calcs

7463

%So it can be calculated 1 time here to avoid thousands of re-calcs

7283

if ~calc_exp_phase

7464

if ~calc_exp_phase

7284

calc_exp_phase=1;

7465

calc_exp_phase=1;

7285

for k=1:length(txffe)

7466

for k=1:length(txffe)

7286

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7467

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7287

end

7468

end

7288

if OP.RxFFE

7469

if OP.RxFFE

7289

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7470

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7290

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7471

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7291

end

7472

end

7292

phase_memory=[phase_memory phase_memoryRXFFE];

7473

phase_memory=[phase_memory phase_memoryRXFFE];

7293

end

7474

end

7294

end

7475

end

7295

7476

7296

%% Unequalized Pulse Reponse & circshift for FFE

7477

%% Unequalized Pulse Reponse & circshift for FFE

7297

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7478

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7298

%in the pre-shifted matrix

7479

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7299

if ctle_response_updated

7480

if ctle_response_updated

7300

ctle_response_updated=0;

7481

ctle_response_updated=0;

7301

num_pre=cur-1;

7482

num_pre=cur-1;

7302

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7483

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7303

%Calculating here reduces number of convolutions by thousands

7484

%Calculating here reduces number of convolutions by thousands

+7485

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7486

ich=1;

7487

else

7488

ich=param.num_s4p_files;

7489

end

7490

for ii=1:ich

7304

if OP.TDMODE

7491

if OP.TDMODE

7305

pulse_ctle=chdata(1).(ctle_field)(:);

7492

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7306

else

7493

else

7307

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7494

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7308

%"conv2" is faster than filter. Just need to chop off extra points at the end

7495

%"conv2" is faster than filter. Just need to chop off extra points at the end

7309

pulse_ctle=conv2(chdata(1).(ctle_field)(:),ones(param.samples_per_ui, 1));

7496

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7310

pulse_ctle=pulse_ctle(1:end-param.samples_per_ui+1);

7497

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7311

end

7498

end

7312

for k=1:length(txffe)

7499

for k=1:length(txffe)

7313

pulse_ctle_circshift(:,k)=circshift(pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7500

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

+7501

end

7314

end

7502

end

7315

end

7503

end

7316

7504

7317

%% Apply TXFFE to pre-shifted pulse response

7505

%% Apply TXFFE to pre-shifted pulse response

7318

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7506

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7319

sbr=FFE_Fast(txffe,pulse_ctle_circshift);

7507

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7320

sbr_from_txffe=sbr;

7508

sbr_from_txffe=sbr;

+7509

for ii=1:ich

7321

sbr1=sbr;

7510

% this is sbr when ii=1; to be used in get_PSDs

+7511

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7512

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7513

else

7514

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7515

end

7516

end

7322

7517

7323

7324

%% Find Sample Location

7518

%% Find Sample Location

7325

% If RXFFE is included, the sample location will be found again below

7519

% If RXFFE is included, the sample location will be found again below

7326

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7520

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7327

if param.ts_anchor==0

7521

if param.ts_anchor==0

7328

%keep MM

7522

%keep MM

7329

elseif param.ts_anchor==1

7523

elseif param.ts_anchor==1

7330

%peak sample

7524

%peak sample

7331

cursor_i=sbr_peak_i;

7525

cursor_i=sbr_peak_i;

7332

no_zero_crossing=0;

7526

no_zero_crossing=0;

7333

elseif param.ts_anchor==2

7527

elseif param.ts_anchor==2

7334

%max DV

7528

%max DV

7335

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7529

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7336

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7530

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7337

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7531

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7338

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7532

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7339

no_zero_crossing=0;

7533

no_zero_crossing=0;

7340

else

7534

else

7341

error('ts_anchor parameter must be 0, 1, or 2');

7535

error('ts_anchor parameter must be 0, 1, or 2');

7342

end

7536

end

7343

if no_zero_crossing

7537

if no_zero_crossing

7344

continue;

7538

continue;

7345

end

7539

end

7346

raw_cursor_i=cursor_i;

7540

raw_cursor_i=cursor_i;

7347

7541

7348

%%%%%%%%%%

7542

%%%%%%%%%%

7349

%%%%%%%%%%

7543

%%%%%%%%%%

7350

%%%%%%%%%%

7544

%%%%%%%%%%

7351

%NEW ITICK LOOP (not indenting everything yet)

7545

%NEW ITICK LOOP (not indenting everything yet)

7352

[~,si]=sort(abs(full_sample_range));

7546

[~,si]=sort(abs(full_sample_range));

7353

best_positive_itick_FOM=-inf;

7547

best_positive_itick_FOM=-inf;

7354

best_negative_itick_FOM=-inf;

7548

best_negative_itick_FOM=-inf;

7355

best_positive_itick_in_loop=[];

7549

best_positive_itick_in_loop=[];

7356

best_negative_itick_in_loop=[];

7550

best_negative_itick_in_loop=[];

7357

best_itick_FOM=-inf;

7551

best_itick_FOM=-inf;

7358

best_itick_in_cluster=[];

7552

best_itick_in_cluster=[];

7359

best_cluster=[];

7553

best_cluster=[];

7360

7554

7361

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7555

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7362

%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)

7556

%middle_search: start from itick=0 and work outwards in negative and positive direction. stop searching when FOM starts to go down (using LOCAL SEARCH)

7363

box_search=0;

7557

box_search=0;

7364

middle_search=1;

7558

middle_search=1;% should set 0 so all Ts sample points are used

7365

7559

7366

if box_search

7560

if box_search

7367

box_size=5;

7561

box_size=5;

7368

box_mid=floor(box_size/2);

7562

box_mid=floor(box_size/2);

7369

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7563

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7370

CL=length(cluster);

7564

CL=length(cluster);

7371

loop_range=1:CL+box_mid*2;

7565

loop_range=1:CL+box_mid*2;

7372

elseif middle_search

7566

elseif middle_search

7373

loop_range=si;

7567

loop_range=si;

7374

else

7568

else

7375

loop_range=1:length(full_sample_range);

7569

loop_range=1:length(full_sample_range);

7376

end

7570

end

7377

7571

7378

for itickn=loop_range

7572

for itickn=loop_range

7379

if box_search

7573

if box_search

7380

if itickn<=CL

7574

if itickn<=CL

7381

itick=cluster(itickn);

7575

itick=cluster(itickn);

7382

else

7576

else

7383

if itickn==CL+1

7577

if itickn==CL+1

7384

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7578

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7385

end

7579

end

7386

if isempty(best_cluster)

7580

if isempty(best_cluster)

7387

continue;

7581

continue;

7388

end

7582

end

7389

itick=best_cluster(itickn-CL);

7583

itick=best_cluster(itickn-CL);

7390

end

7584

end

7391

else

7585

else

7392

itick=full_sample_range(itickn);

7586

itick=full_sample_range(itickn);

7393

end

7587

end

7394

7588

7395

itick_cases=itick_cases+1;

7589

itick_cases=itick_cases+1;

7396

7590

7397

sbr=sbr_from_txffe;

7591

sbr=sbr_from_txffe;

7398

cursor_i = raw_cursor_i+itick;

7592

cursor_i = raw_cursor_i+itick;

7399

7593

7400

%Local Search for +/- itick sweep

7594

%Local Search for +/- itick sweep

7401

if middle_search && param.LOCAL_SEARCH>0

7595

if middle_search && param.LOCAL_SEARCH>0

7402

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7596

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7403

itick_skips=itick_skips+1;

7597

itick_skips=itick_skips+1;

7404

continue;

7598

continue;

7405

end

7599

end

7406

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7600

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7407

itick_skips=itick_skips+1;

7601

itick_skips=itick_skips+1;

7408

continue;

7602

continue;

7409

end

7603

end

7410

end

7604

end

7411

7605

7412

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7606

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7413

if min_number_of_UI_in_response < triple_transit_time

7607

if min_number_of_UI_in_response < triple_transit_time

7414

min_number_of_UI_in_response = triple_transit_time;

7608

min_number_of_UI_in_response = triple_transit_time;

7415

end

7609

end

7416

7610

7417

cursor = sbr(cursor_i);

7611

cursor = sbr(cursor_i);

7418

7612

7419

%% RXFFE

7613

%% RXFFE

7420

if OP.RxFFE

7614

if OP.RxFFE

7421

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7615

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7422

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7616

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7423

%if isrow(sbr), sbr=sbr';end

7617

%if isrow(sbr), sbr=sbr';end

7424

7618

7425

%AJG: do not return sbr here (run time improvement)

7619

%AJG: do not return sbr here (run time improvement)

7426

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7620

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7427

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7621

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7428

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7622

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7429

% sbr at this point include the current setting

7623

% sbr at this point include the current setting

7430

% under consideration of txffe h21 ctf and fr

7624

% under consideration of txffe h21 ctf and fr

7431

switch upper(OP.FFE_OPT_METHOD)

7625

switch upper(OP.FFE_OPT_METHOD)

7432

case 'MMSE'

7626

case 'MMSE'

7433

OP.WO_TXFFE=0;

7627

OP.WO_TXFFE=0;

7434

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7628

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7435

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn;

7629

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn;

7436

if 0 % for debug

7630

if 0 % for debug

7437

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7631

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7438

hold on

7632

hold on

7439

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7633

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7440

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7634

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7441

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7635

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7442

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7636

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7443

xlim([0 0.5])

7637

xlim([0 0.5])

7444

% ylim([-190 -160])

7638

% ylim([-190 -160])

7445

set(gcf,'defaulttextinterpreter','none')

7639

set(gcf,'defaulttextinterpreter','none')

7446

xlabel('Normalized Frequency')

7640

xlabel('Normalized Frequency')

7447

ylabel('PSD dBm/Hz')

7641

ylabel('PSD dBm/Hz')

7448

hold on

7642

hold on

7449

grid on

7643

grid on

7450

legend show

7644

legend show

7451

title('PSD')

7645

title('PSD')

7452

end

7646

end

7453

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7647

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7454

% floating_tap_locations=MMSE_results.MLSE_results;

7648

% floating_tap_locations=MMSE_results.MLSE_results;

7455

C=MMSE_results.C;

7649

C=MMSE_results.C;

7456

FOM=MMSE_results.FOM;

7650

FOM=MMSE_results.FOM;

7457

floating_tap_locations=MMSE_results.floating_tap_locations;

7651

floating_tap_locations=MMSE_results.floating_tap_locations;

7458

otherwise

7652

otherwise

7459

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7653

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7460

end

7654

end

7461

%Now there is a stand alone function for determining if RXFFE taps are illegal

7655

%Now there is a stand alone function for determining if RXFFE taps are illegal

7462

%This is because the "force" function will also do a legality check when "backoff" is enabled

7656

%This is because the "force" function will also do a legality check when "backoff" is enabled

7463

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7657

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7464

if RXFFE_Illegal(C,param)

7658

if RXFFE_Illegal(C,param)

7465

continue;

7659

continue;

7466

end

7660

end

7467

end

7661

end

7468

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7662

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7469

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7663

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7470

if isrow(sbr), sbr=sbr';end

7664

if isrow(sbr), sbr=sbr';end

7471

7665

7472

%% second guess at cursor location (t_s) - based on approximate zero crossing

7666

%% second guess at cursor location (t_s) - based on approximate zero crossing

7473

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7667

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7474

%UPDATE: NOT RESAMPLING AFTER RXFFE

7668

%UPDATE: NOT RESAMPLING AFTER RXFFE

7475

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7669

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7476

% if no_zero_crossing

7670

% if no_zero_crossing

7477

% continue;

7671

% continue;

7478

% end

7672

% end

7479

7673

7480

cursor = sbr(cursor_i);

7674

cursor = sbr(cursor_i);

7481

end

7675

end

7482

A_p=sbr(sbr_peak_i);

7676

A_p=sbr(sbr_peak_i);

7483

%% 93A.1.6 step c defines A_s %%

7677

%% 93A.1.6 step c defines A_s %%

7484

A_s = param.R_LM*cursor/(param.levels-1);

7678

A_s = param.R_LM*cursor/(param.levels-1);

7485

if isempty(delta_sbr)

7679

if isempty(delta_sbr)

7486

delta_sbr = sbr;

7680

delta_sbr = sbr;

7487

end

7681

end

7488

sbr=sbr(:);

7682

sbr=sbr(:);

7489

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7683

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7490

7684

7491

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7685

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7492

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7686

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7493

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)))*...

7687

t=((cursor_i+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:length(sbr))-(cursor_i+param.samples_per_ui*(param.ndfe+1)))*...

7494

param.ui/param.samples_per_ui;

7688

param.ui/param.samples_per_ui;

7495

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7689

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7496

precursors = precursors(end:-1:1);

7690

precursors = precursors(end:-1:1);

7497

7691

7498

% % Error message if the sbr is not long enough for the specified range of Nb

7692

% % Error message if the sbr is not long enough for the specified range of Nb

7499

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7693

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7500

% close(hwaitbar);

7694

% close(hwaitbar);

7501

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7695

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7502

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7696

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7503

% end

7697

% end

7504

7698

7505

7699

7506

7700

7507

%% skip this case if FOM has no chance of beating old FOM

7701

%% skip this case if FOM has no chance of beating old FOM

7508

%this is also done below but with excess_dfe_cursors included.

7702

%this is also done below but with excess_dfe_cursors included.

7509

%excess_dfe_cursors requires the floating DFE computation which is

7703

%excess_dfe_cursors requires the floating DFE computation which is

7510

%time consuming, so checking here can have significant run time improvements

7704

%time consuming, so checking here can have significant run time improvements

7511

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7705

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7512

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7706

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7513

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7707

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7514

continue

7708

continue

7515

end

7709

end

7516

end

7710

end

7517

7711

7518

%% Equation 93A-27, when 1<=n<=N_b

7712

%% Equation 93A-27, when 1<=n<=N_b

7519

%required length = cursor + all DFE UI + 1 additional UI

7713

%required length = cursor + all DFE UI + 1 additional UI

7520

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7714

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7521

if length(sbr)<sbr_required_length

7715

if length(sbr)<sbr_required_length

7522

sbr(end+1:sbr_required_length)=0;

7716

sbr(end+1:sbr_required_length)=0;

7523

end

7717

end

7524

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7718

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7525

if param.dfe_delta ~= 0

7719

if param.dfe_delta ~= 0

7526

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7720

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7527

7721

7528

else

7722

else

7529

dfecursors_q=dfecursors;

7723

dfecursors_q=dfecursors;

7530

end

7724

end

7531

if param.Floating_DFE

7725

if param.Floating_DFE

7532

%% floating taps

7726

%% floating taps

7533

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7727

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7534

7728

7535

[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 );

7729

[floating_tap_locations, floating_tap_coef, hisi, bmax]= floatingDFE( postcurors ,param.ndfe_passed,param.N_bf,param.N_bg,param.N_bmax, param.bmaxg, sbr(cursor_i), param.dfe_delta );

7536

7730

7537

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7731

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7538

param.use_bmax=newbmax;

7732

param.use_bmax=newbmax;

7539

%AJG021820

7733

%AJG021820

7540

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7734

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7541

else

7735

else

7542

param.use_bmax=param.bmax;

7736

param.use_bmax=param.bmax;

7543

%AJG021820

7737

%AJG021820

7544

param.use_bmin=param.bmin;

7738

param.use_bmin=param.bmin;

7545

end

7739

end

7546

7740

7547

%AJG021820

7741

%AJG021820

7548

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7742

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7549

if do_C2M

7743

if do_C2M

7550

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);

7744

dfecursors_windowed=sbr(cursor_i-T_O+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe)-T_O);

7551

% readjust SBR

7745

% readjust SBR

7552

if 0

7746

if 0

7553

%PR_DFE_center not currently used, so this is in "if 0" statement

7747

%PR_DFE_center not currently used, so this is in "if 0" statement

7554

PR_DFE_center=sbr;

7748

PR_DFE_center=sbr;

7555

for n=1:param.ndfe

7749

for n=1:param.ndfe

7556

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7750

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7557

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7751

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7558

% dper=sbr(i_sample)- actual_dfecursors(n);

7752

% dper=sbr(i_sample)- actual_dfecursors(n);

7559

% PR_DFE_center(i_sample)=dper;

7753

% PR_DFE_center(i_sample)=dper;

7560

% end

7754

% end

7561

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7755

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7562

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7756

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7563

end

7757

end

7564

end

7758

end

7565

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7759

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7566

else

7760

else

7567

excess_dfe_cursors=dfecursors-actual_dfecursors;

7761

excess_dfe_cursors=dfecursors-actual_dfecursors;

7568

end

7762

end

7569

dfetaps=actual_dfecursors/sbr(cursor_i);

7763

dfetaps=actual_dfecursors/sbr(cursor_i);

7570

7764

7571

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7765

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7572

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7766

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7573

if tail_RSS ~= 0

7767

if tail_RSS ~= 0

7574

if tail_RSS >= param.B_float_RSS_MAX

7768

if tail_RSS >= param.B_float_RSS_MAX

7575

param.use_bmax(param.N_tail_start:end)= ...

7769

param.use_bmax(param.N_tail_start:end)= ...

7576

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7770

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7577

%AJG021820

7771

%AJG021820

7578

param.use_bmin(param.N_tail_start:end)= ...

7772

param.use_bmin(param.N_tail_start:end)= ...

7579

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7773

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7580

end

7774

end

7581

end

7775

end

7582

7776

7583

%AJG021820

7777

%AJG021820

7584

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7778

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7585

if do_C2M

7779

if do_C2M

7586

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7780

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7587

else

7781

else

7588

excess_dfe_cursors=dfecursors-actual_dfecursors;

7782

excess_dfe_cursors=dfecursors-actual_dfecursors;

7589

end

7783

end

7590

dfetaps=actual_dfecursors/sbr(cursor_i);

7784

dfetaps=actual_dfecursors/sbr(cursor_i);

7591

7785

7592

else

7786

else

7593

tail_RSS=0;

7787

tail_RSS=0;

7594

end

7788

end

7595

%% Eq. 93A-28 %%

7789

%% Eq. 93A-28 %%

7596

sampling_offset = mod(cursor_i, param.samples_per_ui);

7790

sampling_offset = mod(cursor_i, param.samples_per_ui);

7597

%ensure we can take early sample

7791

%ensure we can take early sample

7598

if sampling_offset<=1

7792

if sampling_offset<=1

7599

sampling_offset=sampling_offset+param.samples_per_ui;

7793

sampling_offset=sampling_offset+param.samples_per_ui;

7600

end

7794

end

7601

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7795

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7602

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7796

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7603

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7797

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7604

else

7798

else

7605

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7799

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7606

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7800

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7607

end

7801

end

7608

% ensure lengths are equal

7802

% ensure lengths are equal

7609

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7803

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7610

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7804

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7611

if ~OP.SNR_TXwC0

7805

if ~OP.SNR_TXwC0

7612

%% Equation 93A-30 %%

7806

%% Equation 93A-30 %%

7613

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7807

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7614

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7808

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7615

else

7809

else

7616

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7810

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7617

end

7811

end

7618

%% Equation 93A-31 %%

7812

%% Equation 93A-31 %%

7619

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7813

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7620

ISI_N=param.sigma_X*norm( far_cursors);

7814

ISI_N=param.sigma_X*norm( far_cursors);

7621

%% break if FOM has no chance of beating old e

7815

%% break if FOM has no chance of beating old e

7622

OP.EXE_MODE=1;

7816

OP.exe_mode=1;

7623

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7817

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7624

switch OP.EXE_MODE

7818

switch OP.EXE_MODE

7625

case 0

7819

case 0

7626

case 1

7820

case 1

7627

if (20*log10(A_s/sigma_ISI) < best_FOM)

7821

if (20*log10(A_s/sigma_ISI) < best_FOM)

7628

continue

7822

continue

7629

end

7823

end

7630

case 2

7824

case 2

7631

if (20*log10(A_s/sigma_ISI) < best_FOM)

7825

if (20*log10(A_s/sigma_ISI) < best_FOM)

7632

break

7826

break

7633

end

7827

end

7634

end

7828

end

7635

end

7829

end

7636

%% Equation 93A-32 %%

7830

%% Equation 93A-32 %%

7637

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7831

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7638

7832

7639

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7833

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7640

if OP.RX_CALIBRATION

7834

if OP.RX_CALIBRATION

7641

sigma_XT=0;

7835

sigma_XT=0;

7642

else

7836

else

7643

if ~OP.RxFFE

7837

if ~OP.RxFFE

7644

% sigma_FEXT = get_xtlk_noise( 0, 'FEXT', param ,chdata);

7645

% sigma_XT = norm([sigma_NEXT sigma_FEXT]);

7646

[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

7838

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata,phase_memory); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7647

%% Equation 93A-36 denominator (actually its sqrt)

7839

%% Equation 93A-36 denominator (actually its sqrt)

7648

else % John Ewen: 13/12/20018

7840

else % John Ewen: 13/12/20018

+7841

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7649

[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

7842

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata, phase_memory,C); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7650

% sigma_FEXT_ffe= get_xtlk_noise( 0, 'FEXT', param, chdata, C );

7651

% if ~OP.RxFFE

7652

% sigma_NEXT_ffe = get_xtlk_noise(0, 'NEXT', param, chdata);

7653

% else

7654

% sigma_NEXT_ffe = get_xtlk_noise(0, 'NEXT', param, chdata , C);

7843

else % use results from get_PSDs RIM 3/28/2024

7655

% end

7656

% sigma_XT = norm([sigma_NEXT_ffe sigma_FEXT_ffe])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

7844

sigma_XT=PSD_results.S_xn_rms;

+7845

end

7657

end

7846

end

7658

end

7847

end

7659

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7848

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7660

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7849

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7661

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7850

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7662

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7851

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7663

f=chdata(1).faxis;

7852

f=chdata(1).faxis;

7664

H_Rx_FFE=zeros(1,length(f));

7853

H_Rx_FFE=zeros(1,length(f));

7665

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7854

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7666

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7855

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7667

if C(ii+param.RxFFE_cmx+1)==0

7856

if C(ii+param.RxFFE_cmx+1)==0

7668

%speed up: skip cases when rxffe=0

7857

%speed up: skip cases when rxffe=0

7669

continue;

7858

continue;

7670

end

7859

end

7671

if ii+1==0

7860

if ii+1==0

7672

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7861

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7673

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7862

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7674

else

7863

else

7675

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7864

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7676

end

7865

end

7677

end

7866

end

7678

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

7867

sigma_N =sqrt(param.eta_0*sum(H_sy(2:end) .* abs(H_r(2:end) .* H_ctf(2:end) .*H_Rx_FFE(2:end)).^2 .* diff(chdata(1).faxis)/1e9)); % changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7679

end

7868

end

7680

end

7869

end

7681

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7870

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

+7871

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7682

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7872

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

+7873

else

7874

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7875

end

7683

if do_C2M

7876

if do_C2M

7684

if param.Noise_Crest_Factor == 0

7877

if param.Noise_Crest_Factor == 0

7685

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7878

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7686

else

7879

else

7687

ber_q=param.Noise_Crest_Factor;

7880

ber_q=param.Noise_Crest_Factor;

7688

end

7881

end

7689

if OP.force_pdf_bin_size

7882

if OP.force_pdf_bin_size

7690

delta_y = OP.BinSize;

7883

delta_y = OP.BinSize;

7691

else

7884

else

7692

delta_y = min(A_s/1000, OP.BinSize);

7885

delta_y = min(A_s/1000, OP.BinSize);

7693

end

7886

end

7694

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7887

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7695

cci_pdf = normal_dist(0, ber_q, delta_y);

7888

cci_pdf = normal_dist(0, ber_q, delta_y);

7696

chdata(1).eq_pulse_response=sbr;

7889

chdata(1).eq_pulse_response=sbr;

7697

tmp_result.t_s= cursor_i;

7890

tmp_result.t_s= cursor_i;

7698

tmp_result.A_s=A_s;

7891

tmp_result.A_s=A_s;

7699

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7892

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7700

if EH_1st <= param.Min_VEO_Test/1000 -.001

7893

if EH_1st <= param.Min_VEO_Test/1000 -.001

7701

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7894

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7702

continue

7895

continue

7703

else

7896

else

7704

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7897

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7705

end

7898

end

7706

Struct_Noise.sigma_N=sigma_N;

7899

Struct_Noise.sigma_N=sigma_N;

7707

Struct_Noise.sigma_TX=sigma_TX;

7900

Struct_Noise.sigma_TX=sigma_TX;

7708

Struct_Noise.cci_pdf=cci_pdf;

7901

Struct_Noise.cci_pdf=cci_pdf;

7709

Struct_Noise.ber_q=ber_q;

7902

Struct_Noise.ber_q=ber_q;

7710

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7903

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7711

[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);

7904

[Left_EW,Right_EW,eye_contour,EH_T_C2M,EH_B_C2M]=COM_eye_width(chdata,delta_y,tmp_result,param,OP,Struct_Noise,1);

7712

EH=EH_T_C2M-EH_B_C2M;

7905

EH=EH_T_C2M-EH_B_C2M;

7713

N_i=(A_s*2-EH)/2;

7906

N_i=(A_s*2-EH)/2;

7714

if EH <= param.Min_VEO_Test/1000

7907

if EH <= param.Min_VEO_Test/1000

7715

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7908

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7716

continue

7909

continue

7717

else

7910

else

7718

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

7911

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

7719

end

7912

end

7720

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7913

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7721

FOM =20*log10(A_s/N_i);

7914

FOM =20*log10(A_s/N_i);

7722

end

7915

end

7723

else

7916

else

7724

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7917

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7725

FOM = 20*log10(A_s/total_noise_rms);

7918

FOM = 20*log10(A_s/total_noise_rms);

7726

end

7919

end

7727

% if strfind(param.CTLE_type,'CL120e')

7920

% if strfind(param.CTLE_type,'CL120e')

7728

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

7921

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

7729

end

7922

end

7730

if 0 % for loop analysis

7923

if 0 % for loop analysis

7731

result.FOM_array(new_loops)=FOM;

7924

result.FOM_array(new_loops)=FOM;

7732

end

7925

end

7733

7926

7734

if FOM>best_itick_FOM

7927

if FOM>best_itick_FOM

7735

best_itick_FOM=FOM;

7928

best_itick_FOM=FOM;

7736

best_itick_in_cluster=itick;

7929

best_itick_in_cluster=itick;

7737

end

7930

end

7738

7931

7739

if itick>=0 && FOM>best_positive_itick_FOM

7932

if itick>=0 && FOM>best_positive_itick_FOM

7740

best_positive_itick_FOM=FOM;

7933

best_positive_itick_FOM=FOM;

7741

best_positive_itick_in_loop=itick;

7934

best_positive_itick_in_loop=itick;

7742

end

7935

end

7743

if itick<=0 && FOM>best_negative_itick_FOM

7936

if itick<=0 && FOM>best_negative_itick_FOM

7744

best_negative_itick_FOM=FOM;

7937

best_negative_itick_FOM=FOM;

7745

best_negative_itick_in_loop=itick;

7938

best_negative_itick_in_loop=itick;

7746

end

7939

end

7747

7940

7748

itick_index=find(itick==full_sample_range);

7941

itick_index=find(itick==full_sample_range);

7749

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

7942

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

7750

7943

7751

if (FOM > best_FOM)

7944

if (FOM > best_FOM)

7752

best_current_ffegain=param.current_ffegain;

7945

best_current_ffegain=param.current_ffegain;

7753

best_txffe = txffe;

7946

best_txffe = txffe;

7754

%along with best_txffe, save the indices of the best_txffe

7947

%along with best_txffe, save the indices of the best_txffe

7755

%(saves time in LOCAL SEARCH block)

7948

%(saves time in LOCAL SEARCH block)

7756

best_txffe_index=tx_index_vector;

7949

best_txffe_index=tx_index_vector;

7757

best_sbr = sbr;

7950

best_sbr = sbr;

7758

best_ctle = ctle_index;

7951

best_ctle = ctle_index;

7759

best_G_high_pass =g_LP_index;

7952

best_G_high_pass =g_LP_index;

7760

best_FOM = FOM;

7953

best_FOM = FOM;

7761

best_cursor_i = cursor_i;

7954

best_cursor_i = cursor_i;

7762

best_itick = itick;

7955

best_itick = itick;

7763

if ~OP.TDMODE

7956

if ~OP.TDMODE

7764

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7957

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7765

best_IR=effective_channel;

7958

best_IR=effective_channel;

7766

end

7959

end

7767

best_sigma_N = sigma_N;

7960

best_sigma_N = sigma_N;

7768

best_h_J = h_J;

7961

best_h_J = h_J;

7769

best_A_s=A_s;

7962

best_A_s=A_s;

7770

best_A_p=A_p;

7963

best_A_p=A_p;

7771

best_ISI=ISI_N;

7964

best_ISI=ISI_N;

7772

best_bmax=param.use_bmax;

7965

best_bmax=param.use_bmax;

7773

%AJG021820

7966

%AJG021820

7774

best_bmin=param.use_bmin;

7967

best_bmin=param.use_bmin;

7775

best_tail_RSS=tail_RSS;

7968

best_tail_RSS=tail_RSS;

7776

best_dfetaps=dfetaps;

7969

best_dfetaps=dfetaps;

7777

if param.Floating_DFE

7970

if param.Floating_DFE

7778

best_floating_tap_locations=floating_tap_locations;

7971

best_floating_tap_locations=floating_tap_locations;

7779

best_floating_tap_coef=floating_tap_coef;

7972

best_floating_tap_coef=floating_tap_coef;

7780

end

7973

end

7781

if param.Floating_RXFFE

7974

if param.Floating_RXFFE

7782

best_floating_tap_locations=floating_tap_locations;

7975

best_floating_tap_locations=floating_tap_locations;

7783

% best_floating_tap_coef=floating_tap_coef;

7976

% best_floating_tap_coef=floating_tap_coef;

7784

end

7977

end

7785

if OP.RxFFE

7978

if OP.RxFFE

7786

best_RxFFE=C;

7979

best_RxFFE=C;

7787

best_PSD_results=PSD_results;

7980

best_PSD_results=PSD_results;

7788

best_MMSE_results=MMSE_results;

7981

best_MMSE_results=MMSE_results;

7789

end

7982

end

7790

end

7983

end

7791

end

7984

end

7792

end

7985

end

7793

7986

7794

end

7987

end

7795

end

7988

end

7796

end

7989

end

7797

if do_C2M

7990

if do_C2M

7798

if best_FOM == -inf

7991

if best_FOM == -inf

7799

param.Min_VEO_Test=0;

7992

param.Min_VEO_Test=0;

7800

else

7993

else

7801

break

7994

break

7802

end

7995

end

7803

end

7996

end

7804

end

7997

end

7805

if 0

7998

if 0

7806

fprintf('old loops = %d\n',old_loops);

7999

fprintf('old loops = %d\n',old_loops);

7807

fprintf('new loops = %d\n',new_loops);

8000

fprintf('new loops = %d\n',new_loops);

7808

display(sprintf('\n :loops = %g',pxi))

8001

display(sprintf('\n :loops = %g',pxi))

7809

end

8002

end

7810

8003

7811

%turn this on to review if FOM changes sign more than once in an itick loop

8004

%turn this on to review if FOM changes sign more than once in an itick loop

7812

if 0

8005

if 0

7813

DIR_CHANGE={};

8006

DIR_CHANGE={};

7814

for m=1:length(Gffe_values)

8007

for m=1:length(Gffe_values)

7815

for n=1:length(gdc_values)

8008

for n=1:length(gdc_values)

7816

for k=1:lf_indx

8009

for k=1:lf_indx

7817

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

8010

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

7818

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

8011

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

7819

%1 = goes up, -1=goes down

8012

%1 = goes up, -1=goes down

7820

x=sign(diff(FOM_this_mat')');

8013

x=sign(diff(FOM_this_mat')');

7821

%y = change in sign on x. the location of a "2" is where FOM changes direction

8014

%y = change in sign on x. the location of a "2" is where FOM changes direction

7822

y=abs(diff(x'))';

8015

y=abs(diff(x'))';

7823

%the goal is the FOM only changes direction once. so count the occurences of the 2

8016

%the goal is the FOM only changes direction once. so count the occurences of the 2

7824

for j=1:size(FOM_this_mat,1)

8017

for j=1:size(FOM_this_mat,1)

7825

z{j}=find(y(j,:)==2);

8018

z{j}=find(y(j,:)==2);

7826

end

8019

end

7827

zL=cellfun('length',z);

8020

zL=cellfun('length',z);

7828

%return any row where FOM changed direction more than once

8021

%return any row where FOM changed direction more than once

7829

DIR_CHANGE{j,k}=find(zL>1);

8022

DIR_CHANGE{j,k}=find(zL>1);

7830

end

8023

end

7831

end

8024

end

7832

end

8025

end

7833

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

8026

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

7834

end

8027

end

7835

8028

7836

if ~exist('best_cursor_i', 'var')% take last setting

8029

if ~exist('best_cursor_i', 'var')% take last setting

7837

result.eq_failed=true;

8030

result.eq_failed=true;

7838

display('equalization failed')

8031

display('equalization failed')

7839

best_bmax=param.bmax;

8032

best_bmax=param.bmax;

7840

%AJG021820

8033

%AJG021820

7841

best_bmin=param.bmin;

8034

best_bmin=param.bmin;

7842

best_tail_RSS=0;

8035

best_tail_RSS=0;

7843

best_current_ffegain=0;

8036

best_current_ffegain=0;

7844

best_txffe = txffe;

8037

best_txffe = txffe;

7845

best_sbr = sbr;

8038

best_sbr = sbr;

7846

best_ctle = ctle_index;

8039

best_ctle = ctle_index;

7847

if OP.RxFFE

8040

if OP.RxFFE

7848

best_PSD_results=PSD_results;

8041

best_PSD_results=PSD_results;

7849

best_MMSE_results=MMSE_results;

8042

best_MMSE_results=MMSE_results;

7850

best_RxFFE=C;

8043

best_RxFFE=C;

7851

end

8044

end

7852

best_G_high_pass =g_LP_index;

8045

best_G_high_pass =g_LP_index;

7853

best_FOM = FOM;

8046

best_FOM = FOM;

7854

%if this block is reached, the last encountered EQ parameters are used

8047

%if this block is reached, the last encountered EQ parameters are used

7855

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

8048

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

7856

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

8049

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

7857

if isempty(cursor_i)

8050

if isempty(cursor_i)

7858

[~,cursor_i]=max(sbr);

8051

[~,cursor_i]=max(sbr);

7859

end

8052

end

7860

best_cursor_i = cursor_i;

8053

best_cursor_i = cursor_i;

7861

best_itick = itick;

8054

best_itick = itick;

7862

if ~OP.TDMODE

8055

if ~OP.TDMODE

7863

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

8056

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7864

best_IR=effective_channel;

8057

best_IR=effective_channel;

7865

end

8058

end

7866

best_sigma_N = sigma_N;

8059

best_sigma_N = sigma_N;

7867

best_h_J = h_J;

8060

best_h_J = h_J;

7868

best_A_p=max(sbr);

8061

best_A_p=max(sbr);

7869

best_ISI=1;

8062

best_ISI=1;

7870

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) ;

8063

best_dfetaps= sbr( cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe))/sbr(cursor_i) ;

7871

best_A_s= sbr( cursor_i);

8064

best_A_s= sbr( cursor_i);

7872

if param.Floating_DFE

8065

if param.Floating_DFE

7873

best_floating_tap_locations=[];

8066

best_floating_tap_locations=[];

7874

best_floating_tap_coef=[];

8067

best_floating_tap_coef=[];

7875

end

8068

end

7876

if do_C2M

8069

if do_C2M

7877

return

8070

return

7878

end

8071

end

7879

% return

8072

% return

7880

else

8073

else

7881

result.eq_failed=false; % RIM 12/30/2023

8074

result.eq_failed=false; % RIM 12/30/2023

7882

end

8075

end

7883

8076

7884

best_cursor = best_sbr(best_cursor_i);

8077

best_cursor = best_sbr(best_cursor_i);

7885

% report during debug

8078

% report during debug

7886

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

8079

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

7887

%If sbr was zero padded, then PRin needs to do so as well)

8080

%If sbr was zero padded, then PRin needs to do so as well)

7888

if length(PRin)<length(best_sbr)

8081

if length(PRin)<length(best_sbr)

7889

PRin(end+1:length(best_sbr))=0;

8082

PRin(end+1:length(best_sbr))=0;

7890

end

8083

end

7891

f=1e8:1e8:100e9;

8084

f=1e8:1e8:100e9;

7892

8085

7893

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

8086

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

7894

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

8087

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

7895

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

8088

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7896

% need to include H_RCos in noise and when computing the system ir for thru

8089

% need to include H_RCos in noise and when computing the system ir for thru

7897

% and crosstalk

8090

% and crosstalk

7898

H_r=H_bw.*H_bt.*H_RCos;

8091

H_r=H_bw.*H_bt.*H_RCos;

7899

8092

7900

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

8093

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

7901

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

8094

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

7902

8095

7903

switch param.CTLE_type

8096

switch param.CTLE_type

7904

case 'CL93'

8097

case 'CL93'

7905

H_low=1;

8098

H_low=1;

7906

case 'CL120d'

8099

case 'CL120d'

7907

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));

8100

H_low=(10^(param.g_DC_HP_values(best_G_high_pass)/20) + 1i*f/param.f_HP(best_G_high_pass))./(1 + 1i*f/param.f_HP(best_G_high_pass));

7908

case 'CL120e'

8101

case 'CL120e'

7909

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

8102

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

7910

end

8103

end

7911

ctle_gain=H_low.*ctle_gain1.*H_r;

8104

ctle_gain=H_low.*ctle_gain1.*H_r;

7912

8105

7913

8106

7914

8107

7915

%lsbr=length(sbr);

8108

%lsbr=length(sbr);

7916

%use length of best_sbr in case zero padding was performed

8109

%use length of best_sbr in case zero padding was performed

7917

%check "sbr_required_length" variable

8110

%check "sbr_required_length" variable

7918

lsbr=length(best_sbr);

8111

lsbr=length(best_sbr);

7919

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

8112

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

7920

8113

7921

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

8114

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

7922

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

8115

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

7923

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

8116

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

7924

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

8117

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

7925

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

8118

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

7926

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

8119

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

7927

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

8120

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

7928

if param.Floating_DFE

8121

if param.Floating_DFE

7929

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

8122

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

7930

end

8123

end

7931

% apply max tap value constraint

8124

% apply max tap value constraint

7932

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

8125

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

7933

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

8126

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

7934

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

8127

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

7935

8128

7936

%AJG021820

8129

%AJG021820

7937

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

8130

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

7938

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

8131

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

7939

if param.Floating_DFE

8132

if param.Floating_DFE

7940

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

8133

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

7941

end

8134

end

7942

8135

7943

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

8136

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

7944

Symbol_Adj = (param.levels-1);% 3A.1.6

8137

Symbol_Adj = (param.levels-1);% 3A.1.6

7945

if OP.DEBUG ~=0

8138

if OP.DEBUG ~=0

7946

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

8139

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

7947

% display pulse responses in one axis per test case.

8140

% display pulse responses in one axis per test case.

7948

switch upper(OP.TIME_AXIS)

8141

switch upper(OP.TIME_AXIS)

7949

case 'S' % RIM 11-13-2023 added user selectable xaxis

8142

case 'S' % RIM 11-13-2023 added user selectable xaxis

7950

xnorm=1;

8143

xnorm=1;

7951

xaxis_label='seconds';

8144

xaxis_label='seconds';

7952

offset=0;

8145

offset=0;

7953

case 'UI'

8146

case 'UI'

7954

xnorm=param.ui;

8147

xnorm=param.ui;

7955

xaxis_label='UI';

8148

xaxis_label='UI';

7956

offset=t(best_cursor_i)/xnorm;

8149

offset=t(best_cursor_i)/xnorm;

7957

otherwise

8150

otherwise

7958

xnorm=1;

8151

xnorm=1;

7959

xaxis_label='seconds';

8152

xaxis_label='seconds';

7960

offset=0;

8153

offset=0;

7961

end

8154

end

7962

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

8155

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

7963

fig=findobj('Name', figure_name);

8156

fig=findobj('Name', figure_name);

7964

if isempty(fig), fig=figure('Name', figure_name); end

8157

if isempty(fig), fig=figure('Name', figure_name); end

7965

figure(fig);set(gcf,'Tag','COM');

8158

figure(fig);set(gcf,'Tag','COM');

7966

movegui(fig,'north')

8159

movegui(fig,'north')

7967

%figure(fig.Number);

8160

%figure(fig.Number);

7968

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

8161

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

7969

if OP.RxFFE

8162

if OP.RxFFE

7970

ax1=subplot(2,1,1);

8163

ax1=subplot(2,1,1);

7971

end

8164

end

7972

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

8165

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

7973

hold on

8166

hold on

7974

8167

7975

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

8168

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

7976

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

8169

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

7977

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

8170

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

7978

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

8171

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

7979

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

8172

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

7980

ylabel('volts')

8173

ylabel('volts')

7981

xlabel(xaxis_label)

8174

xlabel(xaxis_label)

7982

grid on

8175

grid on

7983

legend show

8176

legend show

7984

legend( 'Location', 'best')

8177

legend( 'Location', 'best')

7985

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

8178

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

7986

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

8179

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

7987

if param.ndfe_passed ~=0

8180

if param.ndfe_passed ~=0

7988

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');

8181

stem((sampled_best_sbr_dfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,DFE_taps_mV(1:param.ndfe_passed)/Symbol_Adj','m', 'LineWidth',2,'disp','DFE-canceled cursors');

7989

end

8182

end

7990

if param.Floating_DFE

8183

if param.Floating_DFE

7991

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');

8184

stem((sampled_best_sbr_fdfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,FDFE_taps_mV/Symbol_Adj, 'MarkerFaceColor','red','MarkerEdgeColor','m','LineWidth',1,'disp','FDFE-canceled cursors');

7992

end

8185

end

7993

if OP.RxFFE

8186

if OP.RxFFE

7994

ax2=subplot(2,1,2);

8187

ax2=subplot(2,1,2);

7995

if param.Floating_RXFFE

8188

if param.Floating_RXFFE

7996

stem((t(best_cursor_i+(best_floating_tap_locations)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

8189

stem((t(best_cursor_i+(best_floating_tap_locations)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

7997

,'filled','disp','RxFFE floating FFE taps')

8190

,'filled','disp','RxFFE floating FFE taps')

7998

hold on

8191

hold on

7999

end

8192

end

8000

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)...

8193

stem((t(best_cursor_i+param.samples_per_ui*(-param.RxFFE_cmx:param.RxFFE_cpx)))/xnorm-offset,best_RxFFE(1:param.RxFFE_cmx+param.RxFFE_cpx+1)...

8001

,'filled','disp','RxFFE fixted FFE taps')

8194

,'filled','disp','RxFFE fixted FFE taps')

8002

legend show

8195

legend show

8003

zoom xon

8196

zoom xon

8004

linkaxes([ax1 ax2],'x')

8197

linkaxes([ax1 ax2],'x')

8005

end

8198

end

8006

8199

8007

8200

8008

grid on

8201

grid on

8009

legend show

8202

legend show

8010

legend( 'Location', 'best')

8203

legend( 'Location', 'best')

8011

zoom xon

8204

zoom xon

8012

% set(hax, 'tag', 'EQE');

8205

% set(hax, 'tag', 'EQE');

8013

%

8206

%

8014

figure(110);set(gcf,'Tag','COM');

8207

figure(110);set(gcf,'Tag','COM');

8015

set(gcf, 'Name', 'CTLE selection');

8208

set(gcf, 'Name', 'CTLE selection');

8016

movegui(gcf, 'southeast');

8209

movegui(gcf, 'southeast');

8017

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8210

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8018

hold on

8211

hold on

8019

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8212

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8020

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8213

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8021

fbaud_tick=find(f >= baud_rate, 1);

8214

fbaud_tick=find(f >= baud_rate, 1);

8022

fnq_tick=find(f >= baud_rate/2, 1);

8215

fnq_tick=find(f >= baud_rate/2, 1);

8023

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8216

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8024

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8217

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8025

recolor_plots(gca);

8218

recolor_plots(gca);

8026

title('CTF/w Rx Filter Response')

8219

title('CTF/w Rx Filter Response')

8027

ylabel('dB')

8220

ylabel('dB')

8028

xlabel('Hz')

8221

xlabel('Hz')

8029

legend show

8222

legend show

8030

end

8223

end

8031

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8224

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8032

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8225

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8033

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8226

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8034

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8227

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8035

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8228

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8036

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8229

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8037

end

8230

end

8038

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

8231

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

8039

eqe_axes = findobj('tag', 'EQE');

8232

eqe_axes = findobj('tag', 'EQE');

8040

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8233

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8041

end

8234

end

8042

if OP.DISPLAY_WINDOW

8235

if OP.DISPLAY_WINDOW

8043

close(hwaitbar);

8236

close(hwaitbar);

8044

else

8237

else

8045

fprintf('\n');

8238

fprintf('\n');

8046

end

8239

end

8047

8240

8048

% % eq_data

8241

% % eq_data

8049

result.cur=cur;

8242

result.cur=cur;

8050

result.txffe = best_txffe;

8243

result.txffe = best_txffe;

8051

result.ctle = best_ctle;

8244

result.ctle = best_ctle;

8052

result.best_G_high_pass=best_G_high_pass;

8245

result.best_G_high_pass=best_G_high_pass;

8053

result.DFE_taps = best_dfetaps; %relative

8246

result.DFE_taps = best_dfetaps; %relative

8054

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8247

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8055

if param.Floating_DFE

8248

if param.Floating_DFE

8056

result.floating_tap_locations=best_floating_tap_locations;

8249

result.floating_tap_locations=best_floating_tap_locations;

8057

result.floating_tap_coef=best_floating_tap_coef;

8250

result.floating_tap_coef=best_floating_tap_coef;

8058

end

8251

end

8059

if param.Floating_RXFFE

8252

if param.Floating_RXFFE

8060

result.floating_tap_locations=best_floating_tap_locations;

8253

result.floating_tap_locations=best_floating_tap_locations;

8061

end

8254

end

8062

result.A_s = best_A_s;

8255

result.A_s = best_A_s;

8063

result.t_s = best_cursor_i;

8256

result.t_s = best_cursor_i;

8064

result.itick = best_itick;

8257

result.itick = best_itick;

8065

result.sigma_N = best_sigma_N;

8258

result.sigma_N = best_sigma_N;

8066

result.h_J = best_h_J;

8259

result.h_J = best_h_J;

8067

result.FOM = best_FOM;

8260

result.FOM = best_FOM;

8068

if ~OP.TDMODE

8261

if ~OP.TDMODE

8069

%If sbr was zero padded, then best_IR needs to do so as well)

8262

%If sbr was zero padded, then best_IR needs to do so as well)

8070

if length(best_IR)<length(best_sbr)

8263

if length(best_IR)<length(best_sbr)

8071

best_IR(end+1:length(best_sbr))=0;

8264

best_IR(end+1:length(best_sbr))=0;

8072

end

8265

end

8073

result.IR = best_IR;

8266

result.IR = best_IR;

8074

end

8267

end

8075

result.t=t;

8268

result.t=t;

8076

result.sbr=best_sbr;

8269

result.sbr=best_sbr;

8077

if OP.RxFFE

8270

if OP.RxFFE

8078

result.RxFFE=best_RxFFE;

8271

result.RxFFE=best_RxFFE;

+8272

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8079

result.PSD_results=best_PSD_results;

8273

result.PSD_results=best_PSD_results;

8080

result.MMSE_results=best_MMSE_results;

8274

result.MMSE_results=best_MMSE_results;

+8275

end

8081

end

8276

end

8082

8277

8083

8278

8084

8279

8085

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8280

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8086

% updated RIM 12/17/2021

8281

% updated RIM 12/17/2021

8087

result.A_p = max(chdata(1).uneq_pulse_response);

8282

result.A_p = max(chdata(1).uneq_pulse_response);

8088

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8283

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8089

PR=chdata(1).uneq_pulse_response;

8284

PR=chdata(1).uneq_pulse_response;

8090

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8285

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8091

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8286

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8092

if iend >= length(PR)

8287

if iend >= length(PR)

8093

iend = length (PR);

8288

iend = length (PR);

8094

end

8289

end

8095

if ibeg < 1

8290

if ibeg < 1

8096

ibeg = 1;

8291

ibeg = 1;

8097

end

8292

end

8098

PR=PR(ibeg:iend);

8293

PR=PR(ibeg:iend);

8099

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8294

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8100

SRn=PR;

8295

SRn=PR;

8101

for ik=1:floor(length(PR)/param.samples_per_ui)

8296

for ik=1:floor(length(PR)/param.samples_per_ui)

8102

SPR=circshift(PR,param.samples_per_ui*ik);

8297

SPR=circshift(PR,param.samples_per_ui*ik);

8103

SPR(1:ik*param.samples_per_ui)=0;

8298

SPR(1:ik*param.samples_per_ui)=0;

8104

SRn=SRn+ SPR;

8299

SRn=SRn+ SPR;

8105

end

8300

end

8106

codedebug=0;

8301

codedebug=0;

8107

if codedebug

8302

if codedebug

8108

fig=figure('Name', 'step and pulse response for code debug');

8303

fig=figure('Name', 'step and pulse response for code debug');

8109

figure(fig);set(gcf,'Tag','COM');

8304

figure(fig);set(gcf,'Tag','COM');

8110

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8305

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8111

plot(UI,SRn)

8306

plot(UI,SRn)

8112

hold on

8307

hold on

8113

plot(UI,PR)

8308

plot(UI,PR)

8114

xlim([-param.D_p param.N_v])

8309

xlim([-param.D_p param.N_v])

8115

grid on;hold off;

8310

grid on;hold off;

8116

result.step=SRn;

8311

result.step=SRn;

8117

end

8312

end

8118

i20=find(SRn>=0.20*result.A_f,1,'first');

8313

i20=find(SRn>=0.20*result.A_f,1,'first');

8119

i80=find(SRn>=0.80*result.A_f,1,'first');

8314

i80=find(SRn>=0.80*result.A_f,1,'first');

8120

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8315

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8121

result.Pmax_by_Vf=result.A_p/result.A_f;

8316

result.Pmax_by_Vf=result.A_p/result.A_f;

8122

result.ISI =best_ISI;

8317

result.ISI =best_ISI;

8123

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8318

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8124

result.best_current_ffegain=best_current_ffegain;

8319

result.best_current_ffegain=best_current_ffegain;

8125

result.best_bmax=best_bmax;

8320

result.best_bmax=best_bmax;

8126

%AJG021820

8321

%AJG021820

8127

result.best_bmin=best_bmin;

8322

result.best_bmin=best_bmin;

8128

result.tail_RSS=best_tail_RSS;

8323

result.tail_RSS=best_tail_RSS;

8129

function param=parameter_size_adjustment(param,OP)

8324

function param=parameter_size_adjustment(param,OP)

8130

8325

8131

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'};

8326

make_length2={'C_pkg_board' 'C_diepad' 'L_comp' 'C_bump' 'tfx' 'C_v' 'C_0' 'C_1' 'pkg_Z_c' 'brd_Z_c' 'R_diepad'};

8132

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8327

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8133

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8328

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8134

make_length_DCHP={'f_HP'};

8329

make_length_DCHP={'f_HP'};

8135

make_length_ncases={'AC_CM_RMS'};

8330

make_length_ncases={'AC_CM_RMS'};

8136

8331

8137

%ncases used by make_length_ncases fields

8332

%ncases used by make_length_ncases fields

8138

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8333

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8139

8334

8140

%PORTZ_mult used by make_length_WCPORTZ fields

8335

%PORTZ_mult used by make_length_WCPORTZ fields

8141

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8336

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8142

if OP.WC_PORTZ

8337

if OP.WC_PORTZ

8143

PORTZ_mult=[1 1];

8338

PORTZ_mult=[1 1];

8144

else

8339

else

8145

PORTZ_mult=pkg_sel_vec;

8340

PORTZ_mult=pkg_sel_vec;

8146

end

8341

end

8147

8342

8148

%Parameters that have length = 2

8343

%Parameters that have length = 2

8149

for j=1:length(make_length2)

8344

for j=1:length(make_length2)

8150

if numel(param.(make_length2{j}))==1

8345

if numel(param.(make_length2{j}))==1

8151

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8346

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8152

end

8347

end

8153

end

8348

end

8154

8349

8155

%Parameters that have length = ncases

8350

%Parameters that have length = ncases

8156

for j=1:length(make_length_ncases)

8351

for j=1:length(make_length_ncases)

8157

if numel(param.(make_length_ncases{j}))==1

8352

if numel(param.(make_length_ncases{j}))==1

8158

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8353

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8159

end

8354

end

8160

end

8355

end

8161

8356

8162

%Parameters that have length = length(ctle_gdc_values)

8357

%Parameters that have length = length(ctle_gdc_values)

8163

for j=1:length(make_length_GDC)

8358

for j=1:length(make_length_GDC)

8164

if numel(param.(make_length_GDC{j}))==1

8359

if numel(param.(make_length_GDC{j}))==1

8165

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8360

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8166

end

8361

end

8167

end

8362

end

8168

8363

8169

%Parameters that have length = length(g_DC_HP_values)

8364

%Parameters that have length = length(g_DC_HP_values)

8170

for j=1:length(make_length_DCHP)

8365

for j=1:length(make_length_DCHP)

8171

if numel(param.(make_length_DCHP{j}))==1

8366

if numel(param.(make_length_DCHP{j}))==1

8172

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8367

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8173

end

8368

end

8174

end

8369

end

8175

8370

8176

%Parameters that have length associated with PORTZ_mult

8371

%Parameters that have length associated with PORTZ_mult

8177

for j=1:length(make_length_WCPORTZ)

8372

for j=1:length(make_length_WCPORTZ)

8178

if numel(param.(make_length_WCPORTZ{j}))==1

8373

if numel(param.(make_length_WCPORTZ{j}))==1

8179

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8374

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8180

end

8375

end

8181

end

8376

end

8182

function sgm = pdf2sgm(pdf)

8377

function sgm = pdf2sgm(pdf)

8183

avg = sum(pdf.x .* pdf.y);

8378

avg = sum(pdf.x .* pdf.y);

8184

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8379

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8185

% end yasuo patch

8380

% end yasuo patch

8186

8381

8187

8382

8188

%% adding tx packgage

8383

%% adding tx packgage

8189

function cdf=pdf_to_cdf(pdf)

8384

function cdf=pdf_to_cdf(pdf)

8190

8385

8191

%Transform PDF to CDF

8386

%Transform PDF to CDF

8192

%The CDF is natively calculated from negative-to-positive voltage.

8387

%The CDF is natively calculated from negative-to-positive voltage.

8193

%This only gives BER calculation for bottom eye. Need to also

8388

%This only gives BER calculation for bottom eye. Need to also

8194

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8389

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8195

%min of top and bottom CDF values.

8390

%min of top and bottom CDF values.

8196

%If only interested in one side, a simple cumsum on y is all that is needed.

8391

%If only interested in one side, a simple cumsum on y is all that is needed.

8197

8392

8198

cdf.yB=cumsum(pdf.y);

8393

cdf.yB=cumsum(pdf.y);

8199

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8394

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8200

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8395

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8201

cdf.x=pdf.x;

8396

cdf.x=pdf.x;

8202

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)

8397

function plot_bathtub_curves(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf,jitt_pdf, combined_interference_and_noise_pdf, bin_size)

8203

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8398

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8204

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8399

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8205

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8400

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8206

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8401

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8207

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8402

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8208

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8403

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8209

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8404

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8210

%% Added by Bill Kirkland, June 14, 2017

8405

%% Added by Bill Kirkland, June 14, 2017

8211

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8406

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8212

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8407

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8213

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8408

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8214

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8409

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8215

8410

8216

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8411

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8217

hold on

8412

hold on

8218

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8413

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8219

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8414

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8220

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)

8415

semilogy(signal_and_system_noise_pdf.x, abs(cumsum(signal_and_system_noise_pdf.y)-0.5) ,'m','Disp','Jitter, SNR_TX,RL_M, eta_0 noise', 'parent', hax)

8221

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8416

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8222

8417

8223

%% Added by Bill Kirkland, June 14, 2017

8418

%% Added by Bill Kirkland, June 14, 2017

8224

% modification allows bathtub curves to cross over and hence one can

8419

% modification allows bathtub curves to cross over and hence one can

8225

% directly read the noise component.

8420

% directly read the noise component.

8226

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8421

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8227

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8422

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8228

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8423

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8229

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8424

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8230

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8425

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8231

8426

8232

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8427

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8233

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8428

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8234

8429

8235

ylabel(hax, 'Probability')

8430

ylabel(hax, 'Probability')

8236

xlabel(hax, 'volts')

8431

xlabel(hax, 'volts')

8237

legend(hax, 'show')

8432

legend(hax, 'show')

8238

% testing code

8433

% testing code

8239

if 0

8434

if 0

8240

figure_name = 'COM curves';

8435

figure_name = 'COM curves';

8241

fig=findobj('Name', figure_name);

8436

fig=findobj('Name', figure_name);

8242

if isempty(fig), fig=figure('Name', figure_name); end

8437

if isempty(fig), fig=figure('Name', figure_name); end

8243

figure(fig);set(gcf,'Tag','COM');

8438

figure(fig);set(gcf,'Tag','COM');

8244

grid on

8439

grid on

8245

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8440

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8246

hold on

8441

hold on

8247

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8442

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8248

ylim([ 1e-6 0.25])

8443

ylim([ 1e-6 0.25])

8249

xlim([0 30])

8444

xlim([0 30])

8250

grid on

8445

grid on

8251

end

8446

end

8252

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)

8447

function plot_pie_com(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf, combined_interference_and_noise_pdf, bin_size,param)

8253

BER=param.specBER;

8448

BER=param.specBER;

8254

delta_dB=param.delta_IL;

8449

delta_dB=param.delta_IL;

8255

8450

8256

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8451

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8257

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8452

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8258

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8453

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8259

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8454

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8260

8455

8261

8456

8262

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8457

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8263

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8458

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8264

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8459

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8265

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8460

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8266

8461

8267

COM=20*log10(max_signal/maxn_tot);

8462

COM=20*log10(max_signal/maxn_tot);

8268

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8463

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8269

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8464

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8270

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8465

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8271

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8466

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8272

8467

8273

pfctr=exp(-0.09054*delta_dB);% less loss

8468

pfctr=exp(-0.09054*delta_dB);% less loss

8274

mfctr=exp(0.09054*delta_dB); % more loss

8469

mfctr=exp(0.09054*delta_dB); % more loss

8275

8470

8276

%less loss

8471

%less loss

8277

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8472

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8278

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8473

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8279

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8474

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8280

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8475

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8281

plus_maxn_tot=norm(plus_maxn);

8476

plus_maxn_tot=norm(plus_maxn);

8282

8477

8283

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8478

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8284

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8479

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8285

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8480

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8286

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8481

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8287

minus_maxn_tot=norm(minus_maxn);

8482

minus_maxn_tot=norm(minus_maxn);

8288

8483

8289

% more loss

8484

% more loss

8290

COMp=20*log10(max_signal*pfctr/maxn_tot);

8485

COMp=20*log10(max_signal*pfctr/maxn_tot);

8291

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8486

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8292

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8487

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8293

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8488

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8294

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8489

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8295

% less loss

8490

% less loss

8296

COMm=20*log10(max_signal*mfctr/maxn_tot);

8491

COMm=20*log10(max_signal*mfctr/maxn_tot);

8297

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8492

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8298

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8493

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8299

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8494

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8300

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8495

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8301

8496

8302

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8497

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8303

8498

8304

8499

8305

if(COM<0)

8500

if(COM<0)

8306

return

8501

return

8307

end

8502

end

8308

8503

8309

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8504

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8310

8505

8311

% pie(COM_per_noise,labels)

8506

% pie(COM_per_noise,labels)

8312

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8507

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8313

% legend('show','Location','bestoutside')

8508

% legend('show','Location','bestoutside')

8314

nullbar= [ 0 0 0 ];

8509

nullbar= [ 0 0 0 ];

8315

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8510

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8316

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8511

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8317

hold on

8512

hold on

8318

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8513

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8319

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8514

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8320

8515

8321

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8516

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8322

% ax=gca;

8517

% ax=gca;

8323

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8518

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8324

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8519

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8325

grid on

8520

grid on

8326

legend(labels,'Location','north')

8521

legend(labels,'Location','north')

8327

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8522

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8328

ylabel('COM (dB)')

8523

ylabel('COM (dB)')

8329

hold off

8524

hold off

8330

8525

8331

8526

8332

8527

8333

8528

8334

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8529

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8335

num_files=length(chdata);

8530

num_files=length(chdata);

8336

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8531

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8337

for i=1:num_files

8532

for i=1:num_files

8338

if param.package_testcase_i==1 && i==1

8533

if param.package_testcase_i==1 && i==1

8339

if OP.TDR && i==1

8534

if OP.TDR && i==1

8340

S.Frequencies=chdata(i).faxis;

8535

S.Frequencies=chdata(i).faxis;

8341

S.Impedance=100;

8536

S.Impedance=100;

8342

if ~OP.SHOW_BRD

8537

if ~OP.SHOW_BRD

8343

Sfield='_orig';

8538

Sfield='_orig';

8344

else

8539

else

8345

Sfield='_raw';

8540

Sfield='_raw';

8346

end

8541

end

8347

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8542

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8348

if ~param.FLAG.S2P

8543

if ~param.FLAG.S2P

8349

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8544

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8350

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8545

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8351

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8546

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8352

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8547

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8353

else

8548

else

8354

S.NumPorts=1;

8549

S.NumPorts=1;

8355

end

8550

end

8356

if OP.TDR_W_TXPKG

8551

if OP.TDR_W_TXPKG

8357

if OP.ERL == 2

8552

if OP.ERL == 2

8358

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8553

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8359

end

8554

end

8360

R_diepad = param.R_diepad;

8555

R_diepad = param.R_diepad;

8361

% RX package length is assumed to be the same for all

8556

% RX package length is assumed to be the same for all

8362

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8557

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8363

% for Rx pkg

8558

% for Rx pkg

8364

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8559

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8365

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8560

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8366

combines4p( s11in, s12in, s21in, s22in, ...

8561

combines4p( s11in, s12in, s21in, s22in, ...

8367

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8562

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8368

% S=sparameters(S.Parameters,S.Frequencies,100);

8563

% S=sparameters(S.Parameters,S.Frequencies,100);

8369

S=SL(S,S.Frequencies,R_diepad(1)*2);

8564

S=SL(S,S.Frequencies,R_diepad(1)*2);

8370

chdata(i).TX_RL=S.Parameters(2,2,:);

8565

chdata(i).TX_RL=S.Parameters(2,2,:);

8371

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8566

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8372

end

8567

end

8373

8568

8374

% need to combine S wiht is page and channel

8569

% need to combine S wiht is page and channel

8375

if param.FLAG.S2P

8570

if param.FLAG.S2P

8376

port_sel=1;

8571

port_sel=1;

8377

else

8572

else

8378

port_sel=[1 2];

8573

port_sel=[1 2];

8379

if OP.AUTO_TFX

8574

if OP.AUTO_TFX

8380

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8575

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8381

pix=find(fir4del==max(fir4del),1);

8576

pix=find(fir4del==max(fir4del),1);

8382

param.tfx(2)=2*tu(pix);

8577

param.tfx(2)=2*tu(pix);

8383

end

8578

end

8384

end

8579

end

8385

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8580

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8386

for ipsl=1:length(port_sel) % do for both port if s4p

8581

for ipsl=1:length(port_sel) % do for both port if s4p

8387

for izt=1:length(param.Z_t) % do for all tdr impedances

8582

for izt=1:length(param.Z_t) % do for all tdr impedances

8388

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8583

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8389

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8584

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8390

% OP.interp_sparam_mag='trend_to_DC';

8585

% OP.interp_sparam_mag='trend_to_DC';

8391

OP.interp_sparam_mag='linear_trend_to_DC';

8586

OP.interp_sparam_mag='linear_trend_to_DC';

8392

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8587

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8393

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8588

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8394

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8589

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8395

if ipsl ==1

8590

if ipsl ==1

8396

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8591

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8397

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8592

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8398

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8593

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8399

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8594

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8400

else

8595

else

8401

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8596

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8402

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8597

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8403

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8598

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8404

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8599

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8405

end

8600

end

8406

if OP.PTDR && i==1

8601

if OP.PTDR && i==1

8407

if ipsl ==1

8602

if ipsl ==1

8408

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8603

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8409

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8604

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8410

else

8605

else

8411

if ~param.FLAG.S2P

8606

if ~param.FLAG.S2P

8412

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8607

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8413

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8608

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8414

else

8609

else

8415

chdata(i).TDR22(izt).ERL=[];

8610

chdata(i).TDR22(izt).ERL=[];

8416

chdata(i).TDR22(izt).ERLRMS=[];

8611

chdata(i).TDR22(izt).ERLRMS=[];

8417

end

8612

end

8418

end

8613

end

8419

else

8614

else

8420

chdata(i).TDR11(izt).ERL=[];

8615

chdata(i).TDR11(izt).ERL=[];

8421

chdata(i).TDR22(izt).ERL=[];

8616

chdata(i).TDR22(izt).ERL=[];

8422

chdata(i).TDR11(izt).ERLRMS=[];

8617

chdata(i).TDR11(izt).ERLRMS=[];

8423

chdata(i).TDR22(izt).ERLRMS=[];

8618

chdata(i).TDR22(izt).ERLRMS=[];

8424

end

8619

end

8425

end

8620

end

8426

end

8621

end

8427

end

8622

end

8428

8623

8429

end

8624

end

8430

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8625

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8431

h=figure(180);set(gcf,'Tag','COM');

8626

h=figure(180);set(gcf,'Tag','COM');

8432

if param.package_testcase_i==1 && i == 1

8627

if param.package_testcase_i==1 && i == 1

8433

if i==1

8628

if i==1

8434

htabgroup = uitabgroup(h);

8629

htabgroup = uitabgroup(h);

8435

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8630

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8436

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8631

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8437

hax1 = axes('Parent', htab1);

8632

hax1 = axes('Parent', htab1);

8438

hax3 = axes('Parent', htab3);

8633

hax3 = axes('Parent', htab3);

8439

if ~param.FLAG.S2P

8634

if ~param.FLAG.S2P

8440

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8635

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8441

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8636

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8442

hax2 = axes('Parent', htab2);

8637

hax2 = axes('Parent', htab2);

8443

hax4 = axes('Parent', htab4);

8638

hax4 = axes('Parent', htab4);

8444

end

8639

end

8445

end

8640

end

8446

set(h,'CurrentAxes',hax1)

8641

set(h,'CurrentAxes',hax1)

8447

hold on

8642

hold on

8448

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8643

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8449

hold off

8644

hold off

8450

legend (hax1, 'off');grid on;zoom xon;

8645

legend (hax1, 'off');grid on;zoom xon;

8451

set(legend (hax1, 'show'), 'interp', 'none');

8646

set(legend (hax1, 'show'), 'interp', 'none');

8452

8647

8453

if ~param.FLAG.S2P

8648

if ~param.FLAG.S2P

8454

set(h,'CurrentAxes',hax2)

8649

set(h,'CurrentAxes',hax2)

8455

hold on

8650

hold on

8456

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8651

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8457

hold off

8652

hold off

8458

legend (hax2, 'off');grid on;zoom xon;

8653

legend (hax2, 'off');grid on;zoom xon;

8459

set(legend (hax2, 'show'), 'interp', 'none');

8654

set(legend (hax2, 'show'), 'interp', 'none');

8460

end

8655

end

8461

8656

8462

set(h,'CurrentAxes',hax3)

8657

set(h,'CurrentAxes',hax3)

8463

hold on

8658

hold on

8464

if OP.PTDR

8659

if OP.PTDR

8465

for izt=1:length(param.Z_t)

8660

for izt=1:length(param.Z_t)

8466

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8661

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8467

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8662

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8468

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8663

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8469

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8664

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8470

end

8665

end

8471

end

8666

end

8472

hold off

8667

hold off

8473

legend (hax3, 'off');grid on;zoom xon;

8668

legend (hax3, 'off');grid on;zoom xon;

8474

set(legend (hax3, 'show'), 'interp', 'none');

8669

set(legend (hax3, 'show'), 'interp', 'none');

8475

if ~param.FLAG.S2P

8670

if ~param.FLAG.S2P

8476

set(h,'CurrentAxes',hax4)

8671

set(h,'CurrentAxes',hax4)

8477

hold on

8672

hold on

8478

if OP.PTDR

8673

if OP.PTDR

8479

for izt=1:length(param.Z_t)

8674

for izt=1:length(param.Z_t)

8480

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8675

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8481

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8676

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8482

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8677

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8483

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8678

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8484

end

8679

end

8485

end

8680

end

8486

hold off

8681

hold off

8487

legend (hax4, 'off');grid on;zoom xon;

8682

legend (hax4, 'off');grid on;zoom xon;

8488

set(legend (hax4, 'show'), 'interp', 'none');

8683

set(legend (hax4, 'show'), 'interp', 'none');

8489

end

8684

end

8490

end

8685

end

8491

end

8686

end

8492

if param.FLAG.S2P, return; end

8687

if param.FLAG.S2P, return; end

8493

end

8688

end

8494

function S =r_parrelell2(zref,f,rpad)

8689

function S =r_parrelell2(zref,f,rpad)

8495

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8690

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8496

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8691

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8497

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8692

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8498

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8693

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8499

% Sm=sparameters(S.Parameters,f,zref);

8694

% Sm=sparameters(S.Parameters,f,zref);

8500

8695

8501

8696

8502

8697

8503

8698

8504

8699

8505

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8700

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8506

8701

8507

%touchstone_file: .sNp touchstone file to read

8702

%touchstone_file: .sNp touchstone file to read

8508

%port_order: port reorder vector

8703

%port_order: port reorder vector

8509

%

8704

%

8510

%sch: sparameter matrix

8705

%sch: sparameter matrix

8511

%schFreqAxis: frequency axis

8706

%schFreqAxis: frequency axis

8512

8707

8513

[file_path,root_name,extension]=fileparts(touchstone_file);

8708

[file_path,root_name,extension]=fileparts(touchstone_file);

8514

fid=fopen(touchstone_file);

8709

fid=fopen(touchstone_file);

8515

8710

8516

%fetch number of ports from extension

8711

%fetch number of ports from extension

8517

num_ports=str2num(char(regexp(extension,'\d*','match')));

8712

num_ports=str2num(char(regexp(extension,'\d*','match')));

8518

8713

8519

%Get option line

8714

%Get option line

8520

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8715

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8521

optcell=textscan(optstr{1}{1},'%s');

8716

optcell=textscan(optstr{1}{1},'%s');

8522

optcell=optcell{1};

8717

optcell=optcell{1};

8523

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8718

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8524

%Some touchstone files need this. can't remember why now. maybe lines

8719

%Some touchstone files need this. can't remember why now. maybe lines

8525

%with whitespace but not empty but not commented

8720

%with whitespace but not empty but not commented

8526

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8721

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8527

optcell=textscan(optstr{1}{1},'%s');

8722

optcell=textscan(optstr{1}{1},'%s');

8528

optcell=optcell{1};

8723

optcell=optcell{1};

8529

end

8724

end

8530

8725

8531

%read the entire file

8726

%read the entire file

8532

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8727

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8533

raw_column_data=raw_read_data{1};

8728

raw_column_data=raw_read_data{1};

8534

fclose(fid);

8729

fclose(fid);

8535

8730

8536

%number of columns for 2D matrix

8731

%number of columns for 2D matrix

8537

columns=num_ports*num_ports*2+1;

8732

columns=num_ports*num_ports*2+1;

8538

8733

8539

%find the frequency lines by searching for the right number of NaN

8734

%find the frequency lines by searching for the right number of NaN

8540

a=sum(isnan(raw_column_data),2);

8735

a=sum(isnan(raw_column_data),2);

8541

if num_ports==3

8736

if num_ports==3

8542

b=find(a==2);

8737

b=find(a==2);

8543

elseif num_ports==1

8738

elseif num_ports==1

8544

b=find(a==6);

8739

b=find(a==6);

8545

else

8740

else

8546

b=find(a==0);

8741

b=find(a==0);

8547

end

8742

end

8548

8743

8549

num_freq=length(b);

8744

num_freq=length(b);

8550

8745

8551

%toss out the NaN and reshape into a 2D matrix

8746

%toss out the NaN and reshape into a 2D matrix

8552

raw_input = raw_column_data.';

8747

raw_input = raw_column_data.';

8553

raw_input = raw_input(~isnan(raw_input));

8748

raw_input = raw_input(~isnan(raw_input));

8554

raw_input = reshape(raw_input,columns,num_freq).';

8749

raw_input = reshape(raw_input,columns,num_freq).';

8555

8750

8556

%get the frequency mult

8751

%get the frequency mult

8557

frequency_mult_text=optcell{2};

8752

frequency_mult_text=optcell{2};

8558

if(strcmpi(frequency_mult_text,'hz'))

8753

if(strcmpi(frequency_mult_text,'hz'))

8559

frequency_mult=1;

8754

frequency_mult=1;

8560

elseif(strcmpi(frequency_mult_text,'khz'))

8755

elseif(strcmpi(frequency_mult_text,'khz'))

8561

frequency_mult=1e3;

8756

frequency_mult=1e3;

8562

elseif(strcmpi(frequency_mult_text,'mhz'))

8757

elseif(strcmpi(frequency_mult_text,'mhz'))

8563

frequency_mult=1e6;

8758

frequency_mult=1e6;

8564

elseif(strcmpi(frequency_mult_text,'ghz'))

8759

elseif(strcmpi(frequency_mult_text,'ghz'))

8565

frequency_mult=1e9;

8760

frequency_mult=1e9;

8566

else

8761

else

8567

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8762

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8568

end

8763

end

8569

8764

8570

%get the RI/MA/DB format

8765

%get the RI/MA/DB format

8571

format=optcell{4};

8766

format=optcell{4};

8572

%get Z0

8767

%get Z0

8573

port_impedance=str2double(optcell(6:end))';

8768

port_impedance=str2double(optcell(6:end))';

8574

8769

8575

8770

8576

%grab frequency

8771

%grab frequency

8577

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8772

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8578

Spar.F=raw_input(:,1);

8773

Spar.F=raw_input(:,1);

8579

Spar.F=transpose(Spar.F(:));

8774

Spar.F=transpose(Spar.F(:));

8580

8775

8581

8776

8582

%transform data to real imaginary

8777

%transform data to real imaginary

8583

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8778

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8584

if(strcmpi(format,'ri'))

8779

if(strcmpi(format,'ri'))

8585

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8780

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8586

elseif(strcmpi(format,'ma'))

8781

elseif(strcmpi(format,'ma'))

8587

mag_data=raw_input(:,2:2:end);

8782

mag_data=raw_input(:,2:2:end);

8588

rad_data=raw_input(:,3:2:end)*pi/180;

8783

rad_data=raw_input(:,3:2:end)*pi/180;

8589

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8784

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8590

elseif(strcmpi(format,'db'))

8785

elseif(strcmpi(format,'db'))

8591

mag_data=10.^(raw_input(:,2:2:end)/20);

8786

mag_data=10.^(raw_input(:,2:2:end)/20);

8592

rad_data=raw_input(:,3:2:end)*pi/180;

8787

rad_data=raw_input(:,3:2:end)*pi/180;

8593

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8788

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8594

else

8789

else

8595

error('Format %s is not supported. Use RI MA or DB',format);

8790

error('Format %s is not supported. Use RI MA or DB',format);

8596

end

8791

end

8597

8792

8598

8793

8599

8794

8600

%transform to 3D

8795

%transform to 3D

8601

%allow for upper/lower matrix specification for touchstone 2.0 support

8796

%allow for upper/lower matrix specification for touchstone 2.0 support

8602

matrix_format=0;

8797

matrix_format=0;

8603

if(matrix_format==0)

8798

if(matrix_format==0)

8604

%full

8799

%full

8605

for j=1:num_ports

8800

for j=1:num_ports

8606

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8801

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8607

end

8802

end

8608

elseif(matrix_format==1)

8803

elseif(matrix_format==1)

8609

%upper

8804

%upper

8610

used_ports=0;

8805

used_ports=0;

8611

for j=1:num_ports

8806

for j=1:num_ports

8612

stated_ports=num_ports-j+1;

8807

stated_ports=num_ports-j+1;

8613

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8808

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8614

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8809

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8615

used_ports=used_ports+stated_ports;

8810

used_ports=used_ports+stated_ports;

8616

end

8811

end

8617

elseif(matrix_format==2)

8812

elseif(matrix_format==2)

8618

%lower

8813

%lower

8619

used_ports=0;

8814

used_ports=0;

8620

for j=1:num_ports

8815

for j=1:num_ports

8621

stated_ports=j;

8816

stated_ports=j;

8622

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8817

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8623

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8818

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8624

used_ports=used_ports+stated_ports;

8819

used_ports=used_ports+stated_ports;

8625

end

8820

end

8626

else

8821

else

8627

error('Matrix format is not supported. Use Full, Lower, or Upper');

8822

error('Matrix format is not supported. Use Full, Lower, or Upper');

8628

end

8823

end

8629

8824

8630

8825

8631

%check for swapping the 2 port matrix (required on 1.x spec)

8826

%check for swapping the 2 port matrix (required on 1.x spec)

8632

two_port_swap=1;

8827

two_port_swap=1;

8633

if(num_ports==2 && two_port_swap==1)

8828

if(num_ports==2 && two_port_swap==1)

8634

temp=pre_out.sp(1,2,:);

8829

temp=pre_out.sp(1,2,:);

8635

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8830

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8636

pre_out.sp(2,1,:)=temp;

8831

pre_out.sp(2,1,:)=temp;

8637

end

8832

end

8638

8833

8639

Spar.S=pre_out.sp;

8834

Spar.S=pre_out.sp;

8640

Spar.Z0=transpose(port_impedance(:));

8835

Spar.Z0=transpose(port_impedance(:));

8641

8836

8642

if length(Spar.Z0)>1

8837

if length(Spar.Z0)>1

8643

error('Each port must have the same reference impedance');

8838

error('Each port must have the same reference impedance');

8644

end

8839

end

8645

if ~isequal(Spar.Z0,50)

8840

if ~isequal(Spar.Z0,50)

8646

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8841

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8647

%Renormalize to 50 ohms

8842

%Renormalize to 50 ohms

8648

rho=(50-Spar.Z0)/(50+Spar.Z0);

8843

rho=(50-Spar.Z0)/(50+Spar.Z0);

8649

p=num_ports;

8844

p=num_ports;

8650

s_old=Spar.S;

8845

s_old=Spar.S;

8651

for k=1:num_freq

8846

for k=1:num_freq

8652

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8847

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8653

end

8848

end

8654

end

8849

end

8655

8850

8656

%These operations sync up with COM style Spar matrix

8851

%These operations sync up with COM style Spar matrix

8657

%1: put frequency as first dimension

8852

%1: put frequency as first dimension

8658

sch=shiftdim(Spar.S,2);

8853

sch=shiftdim(Spar.S,2);

8659

%2: reorder ports according to "ports" input

8854

%2: reorder ports according to "ports" input

8660

sch=sch(:,port_order,port_order);

8855

sch=sch(:,port_order,port_order);

8661

schFreqAxis=Spar.F;

8856

schFreqAxis=Spar.F;

8662

function [chdata, param] = read_PR_files(param, OP, chdata)

8857

function [chdata, param] = read_PR_files(param, OP, chdata)

8663

%% Read in pulse response

8858

%% Read in pulse response

8664

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8859

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8665

num_files=length(chdata);

8860

num_files=length(chdata);

8666

M=param.samples_per_ui;

8861

M=param.samples_per_ui;

8667

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8862

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8668

for i=1:num_files

8863

for i=1:num_files

8669

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8864

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8670

progress = i/num_files;

8865

progress = i/num_files;

8671

if OP.DISPLAY_WINDOW

8866

if OP.DISPLAY_WINDOW

8672

[~,a]=fileparts(chdata(i).filename);

8867

[~,a]=fileparts(chdata(i).filename);

8673

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8868

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8674

else

8869

else

8675

fprintf('%i ',i);

8870

fprintf('%i ',i);

8676

end

8871

end

8677

switch chdata(i).ext

8872

switch chdata(i).ext

8678

case '.csv'

8873

case '.csv'

8679

vt=load(chdata(i).filename);

8874

vt=load(chdata(i).filename);

8680

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8875

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8681

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8876

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8682

dt=vt(2,1)-vt(1,1);

8877

dt=vt(2,1)-vt(1,1);

8683

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8878

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8684

8879

8685

8880

8686

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8881

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8687

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8882

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8688

Vf=step_response(end);

8883

Vf=step_response(end);

8689

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8884

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8690

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8885

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8691

8886

8692

end

8887

end

8693

end

8888

end

8694

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8889

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8695

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8890

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8696

[filepath,name,ext] = fileparts(paramFile);

8891

[filepath,name,ext] = fileparts(paramFile);

8697

if ~isempty(filepath)

8892

if ~isempty(filepath)

8698

filepath=[filepath '\'];

8893

filepath=[filepath '\'];

8699

end

8894

end

8700

matcongfile=[filepath name '.mat'];

8895

matcongfile=[filepath name '.mat'];

8701

try

8896

try

8702

switch upper(ext)

8897

switch upper(ext)

8703

case upper('.mat')

8898

case upper('.mat')

8704

load(matcongfile)

8899

load(matcongfile)

8705

case upper('.csv')

8900

case upper('.csv')

8706

[na1, na2, parameter] = xlsread(paramFile);

8901

[na1, na2, parameter] = xlsread(paramFile);

8707

otherwise

8902

otherwise

8708

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8903

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8709

end

8904

end

8710

8905

8711

catch ME %#ok<NASGU>

8906

catch ME %#ok<NASGU>

8712

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8907

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8713

switch upper(ext)

8908

switch upper(ext)

8714

case upper('.mat')

8909

case upper('.mat')

8715

load(matcongfile)

8910

load(matcongfile)

8716

case upper('.csv')

8911

case upper('.csv')

8717

[na1, na2, parameter] = xlsread(paramFile);

8912

[na1, na2, parameter] = xlsread(paramFile);

8718

otherwise

8913

otherwise

8719

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8914

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8720

end

8915

end

8721

end

8916

end

8722

8917

8723

%% New section to parse .START package data

8918

%% New section to parse .START package data

8724

first_column_data = parameter(:,1);

8919

first_column_data = parameter(:,1);

8725

start_data_rows = find(strcmp(first_column_data,'.START'));

8920

start_data_rows = find(strcmp(first_column_data,'.START'));

8726

if ~isempty(start_data_rows)

8921

if ~isempty(start_data_rows)

8727

end_data_rows = find(strcmp(first_column_data,'.END'));

8922

end_data_rows = find(strcmp(first_column_data,'.END'));

8728

if length(start_data_rows) ~= length(end_data_rows)

8923

if length(start_data_rows) ~= length(end_data_rows)

8729

error('Number of .START and .END must be the same');

8924

error('Number of .START and .END must be the same');

8730

end

8925

end

8731

first_start_row = start_data_rows(1);

8926

first_start_row = start_data_rows(1);

8732

special_parameter = parameter;

8927

special_parameter = parameter;

8733

parameter = parameter(1:first_start_row-1,:);

8928

parameter = parameter(1:first_start_row-1,:);

8734

for j=1:length(start_data_rows)

8929

for j=1:length(start_data_rows)

8735

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

8930

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

8736

pkg_name = special_parameter{start_data_rows(j),2};

8931

pkg_name = special_parameter{start_data_rows(j),2};

8737

8932

8738

%Read all the parameters that make up a package

8933

%Read all the parameters that make up a package

8739

PKG_param = read_package_parameters(this_block);

8934

PKG_param = read_package_parameters(this_block);

8740

8935

8741

%save the data in a field revealed by pkg_name

8936

%save the data in a field revealed by pkg_name

8742

param.PKG.(pkg_name) = PKG_param;

8937

param.PKG.(pkg_name) = PKG_param;

8743

8938

8744

8939

8745

end

8940

end

8746

end

8941

end

8747

%Allow specification of TX and RX package section through PKG_NAME keyword

8942

%Allow specification of TX and RX package section through PKG_NAME keyword

8748

%the values must match package blocks specified in .START sections

8943

%the values must match package blocks specified in .START sections

8749

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

8944

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

8750

if isnan(param.PKG_NAME)

8945

if isnan(param.PKG_NAME)

8751

param.PKG_NAME = '';

8946

param.PKG_NAME = '';

8752

end

8947

end

8753

if isempty(param.PKG_NAME)

8948

if isempty(param.PKG_NAME)

8754

param.PKG_NAME = {};

8949

param.PKG_NAME = {};

8755

else

8950

else

8756

param.PKG_NAME = strsplit(param.PKG_NAME);

8951

param.PKG_NAME = strsplit(param.PKG_NAME);

8757

end

8952

end

8758

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

8953

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

8759

error('PKG_NAME can only be used if .START blocks for package parameters are used');

8954

error('PKG_NAME can only be used if .START blocks for package parameters are used');

8760

end

8955

end

8761

for j=1:length(param.PKG_NAME)

8956

for j=1:length(param.PKG_NAME)

8762

if ~isfield(param.PKG,param.PKG_NAME{j})

8957

if ~isfield(param.PKG,param.PKG_NAME{j})

8763

error('Package Block "%s" not found',param.PKG_NAME{j});

8958

error('Package Block "%s" not found',param.PKG_NAME{j});

8764

end

8959

end

8765

end

8960

end

8766

8961

8767

%%

8962

%%

8768

% just need to define so we can pass

8963

% just need to define so we can pass

8769

param.c=[.4e-12 .4e-12];

8964

param.c=[.4e-12 .4e-12];

8770

param.alen=[ 20 30 550 ];

8965

param.alen=[ 20 30 550 ];

8771

param.az=[100 120 100];

8966

param.az=[100 120 100];

8772

8967

8773

% make control for package/channel reflection control

8968

% make control for package/channel reflection control

8774

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

8969

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

8775

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

8970

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

8776

8971

8777

8972

8778

% make compatible with presentation of kappa

8973

% make compatible with presentation of kappa

8779

8974

8780

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

8975

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

8781

8976

8782

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

8977

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

8783

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

8978

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

8784

8979

8785

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

8980

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

8786

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

8981

param.f2 = xls_parameter(parameter, 'f_2', true, param.fb/1e9 )*1e9; % frequency in GHz for intergration compuation of ICN or FOM_Ild in GHz

8787

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

8982

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

8788

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

8983

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

8789

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

8984

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

8790

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

8985

param.tx_ffe_c0_min = xls_parameter(parameter, 'c(0)', false); % TX equalizer cursor minimum value (actual value is calculated as 1-sum(abs(tap)), Grid seat ingored for when C(0) is below this value

8791

8986

8792

if OP.dynamic_txffe

8987

if OP.dynamic_txffe

8793

found_pre=1;

8988

found_pre=1;

8794

pre_count=1;

8989

pre_count=1;

8795

while found_pre

8990

while found_pre

8796

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

8991

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

8797

if found_pre

8992

if found_pre

8798

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

8993

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

8799

param.(field_name)=p;

8994

param.(field_name)=p;

8800

pre_count=pre_count+1;

8995

pre_count=pre_count+1;

8801

end

8996

end

8802

end

8997

end

8803

found_post=1;

8998

found_post=1;

8804

post_count=1;

8999

post_count=1;

8805

while found_post

9000

while found_post

8806

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

9001

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

8807

if found_post

9002

if found_post

8808

field_name=sprintf('tx_ffe_cp%d_values',post_count);

9003

field_name=sprintf('tx_ffe_cp%d_values',post_count);

8809

param.(field_name)=p;

9004

param.(field_name)=p;

8810

post_count=post_count+1;

9005

post_count=post_count+1;

8811

end

9006

end

8812

end

9007

end

8813

else

9008

else

8814

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

9009

param.tx_ffe_cm4_values = xls_parameter(parameter, 'c(-4)', true,0); % TX equalizer pre cursor tap -4 individual settings or range. If not present ignored

8815

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

9010

param.tx_ffe_cm3_values = xls_parameter(parameter, 'c(-3)', true,0); % TX equalizer pre cursor tap -3 individual settings or range. If not present ignored

8816

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

9011

param.tx_ffe_cm2_values = xls_parameter(parameter, 'c(-2)', true,0); % TX equalizer pre cursor tap -2 individual settings or range. If not present ignored

8817

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

9012

param.tx_ffe_cm1_values = xls_parameter(parameter, 'c(-1)', true,0); % TX equalizer pre cursor tap -1 individual settings or range. If not present ignored

8818

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

9013

param.tx_ffe_cp1_values = xls_parameter(parameter, 'c(1)', true,0); % TX equalizer post cursor tap 1 individual settings or range. If not present ignored

8819

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

9014

param.tx_ffe_cp2_values = xls_parameter(parameter, 'c(2)', true,0); % TX equalizer post cursor tap 2 individual settings or range. If not present ignored

8820

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

9015

param.tx_ffe_cp3_values = xls_parameter(parameter, 'c(3)', true,0); % TX equalizer post cursor tap 3 individual settings or range. If not present ignored

8821

end

9016

end

8822

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

9017

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

8823

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

9018

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

8824

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

9019

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

8825

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

9020

param.N_bx = xls_parameter(parameter, 'N_bx', true, param.ndfe ); % Used for ERL to Compensate for a number of Ui assoicated with the DFE

8826

% support for floating taps

9021

% support for floating taps

8827

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

9022

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

8828

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

9023

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

8829

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

9024

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

8830

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

9025

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

8831

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

9026

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

8832

if param.N_bg == 0, param.N_bmax=param.ndfe; end

9027

if param.N_bg == 0, param.N_bmax=param.ndfe; end

8833

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

9028

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

8834

9029

8835

% support for tail tap power limitations

9030

% support for tail tap power limitations

8836

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

9031

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

8837

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

9032

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

8838

%

9033

%

8839

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

9034

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

8840

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

9035

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

8841

param.RxFFE_cmx=param.ffe_pre_tap_len;

9036

param.RxFFE_cmx=param.ffe_pre_tap_len;

8842

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

9037

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

8843

param.RxFFE_cpx=param.ffe_post_tap_len;

9038

param.RxFFE_cpx=param.ffe_post_tap_len;

8844

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

9039

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

8845

param.RxFFE_stepz=param.ffe_tap_step_size;

9040

param.RxFFE_stepz=param.ffe_tap_step_size;

8846

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

9041

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

8847

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

9042

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

8848

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

9043

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

8849

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

9044

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

8850

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

9045

param.ffe_backoff=xls_parameter(parameter, 'ffe_backoff', true,0); % see if better zero foreced solution is better by backing off the number specified FFE taps one at at time

8851

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

9046

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

8852

OP.RxFFE= true;

9047

OP.RxFFE= true;

8853

else

9048

else

8854

OP.RxFFE=false;

9049

OP.RxFFE=false;

8855

end

9050

end

8856

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

9051

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

8857

9052

8858

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

9053

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

8859

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

9054

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

8860

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

9055

param.f_HP_Z = 1e9*xls_parameter(parameter, 'f_HP_Z', true, []); % CFT zero fz1 is in GHz. Normally a list for 120e. Not normally use elsewise

8861

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

9056

param.f_HP_P = 1e9*xls_parameter(parameter, 'f_HP_P', true, []); % CFT pole fp2 is in GHz. Normally a list for 120e. Not normally use elsewise

8862

9057

8863

9058

8864

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

9059

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

8865

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

9060

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

8866

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)

9061

param.Min_VEO_Test= xls_parameter(parameter, 'EH_min_test', true,0); % Older syntax. Used when PMD_type is C2M. This allow EH to go below EH_min. If set to zero it is ignored (same as Min_VEO_test)

8867

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

9062

param.Min_VEO_Test= xls_parameter(parameter, 'Min_VEO_Test', true,param.Min_VEO_Test); % used when PMD_type is C2M. This allow EH to go blow EH_min. If set to Zero it is ignored

8868

9063

8869

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)

9064

param.CTLE_type= xls_parameter(parameter, 'CTLE_type', false,'CL93'); % Sets the CTLE type default is poles and zeros (i.e. not a list of poles as in 120e)

8870

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

9065

if ~isempty(param.g_DC_HP_values) ; param.CTLE_type='CL120d';end % overrides CL93 if g_DC_HP_values are a spreadsheet entry. Mostly used when baud rare is >= 50Gbps

8871

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

9066

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

8872

% always read in main ctle values. They would be interpreted different baseed

9067

% always read in main ctle values. They would be interpreted different baseed

8873

% on the clause they apply because of different CTF equations

9068

% on the clause they apply because of different CTF equations

8874

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

9069

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

8875

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9070

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8876

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9071

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8877

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9072

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8878

% the contex of the poles an zeros are determined by the clause

9073

% the contex of the poles an zeros are determined by the clause

8879

switch param.CTLE_type

9074

switch param.CTLE_type

8880

case 'CL93'

9075

case 'CL93'

8881

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

9076

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % Continuous time filter DC gain settings (G_DC) or range as specified in Annex 93A

8882

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9077

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8883

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9078

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8884

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9079

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8885

case 'CL120d'

9080

case 'CL120d'

8886

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

9081

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

8887

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

9082

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

8888

case 'CL120e'

9083

case 'CL120e'

8889

% re adjust to get TD_CTLE to work with C:120e equation without

9084

% re adjust to get TD_CTLE to work with C:120e equation without

8890

% changing TD_CTLE code

9085

% changing TD_CTLE code

8891

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

9086

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

8892

end

9087

end

8893

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

9088

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

8894

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

9089

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

8895

param.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9090

param.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

8896

param.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9091

param.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

8897

param.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9092

param.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

8898

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

9093

param.a_icn_fext = xls_parameter(parameter, 'A_ft', true, param.a_fext); % FEXT aggressor amplitude for ICN. Defaults to A_fe if not specified

8899

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

9094

param.a_icn_next = xls_parameter(parameter, 'A_nt', true, param.a_next );% NEXT aggressor amplitude for ICN. Defaults to A_ne if not specified

8900

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

9095

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

8901

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

9096

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

8902

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

9097

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

8903

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

9098

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

8904

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

9099

param.VEC_pass_threshold = xls_parameter(parameter, 'VEC Pass threshold',false,0);% the pass fail threshold for VEC in dB only used when PMD_type is C2M

8905

9100

8906

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

9101

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

8907

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

9102

param.A_DD = xls_parameter(parameter, 'A_DD'); % Normalized peak dual-Dirac noise, this is half of the total bound uncorrelated jitter (BUJ) in UI

8908

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

9103

param.eta_0 = xls_parameter(parameter, 'eta_0'); % One-sided noise spectral density (V^2/GHz).Input refered noise at TP5. Input referred noise at TP5

8909

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

9104

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

8910

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

9105

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

8911

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

9106

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

8912

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

9107

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

8913

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)

9108

param.ts_anchor = xls_parameter(parameter, 'ts_anchor', true, 0); %choice of sampling routine. 0=MM, 1=Peak, 2=max DV (max cursor minus precursor)

8914

% This will keep bmax length 0 if Nb=0

9109

% This will keep bmax length 0 if Nb=0

8915

9110

8916

%AJG021820

9111

%AJG021820

8917

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

9112

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

8918

if isempty(param.bmax)

9113

if isempty(param.bmax)

8919

param.bmin=param.bmax;

9114

param.bmin=param.bmax;

8920

else

9115

else

8921

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.

9116

param.bmin(1:param.ndfe) =xls_parameter(parameter, 'b_min(1)', true,-param.bmax(1) ); % DFE negative magnitude limit. If not specified it defaults to -bmax.

8922

9117

8923

end

9118

end

8924

if param.ndfe >= 2

9119

if param.ndfe >= 2

8925

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

9120

param.bmax(2:param.ndfe) = xls_parameter(parameter, 'b_max(2..N_b)', true, .2); % DFE magnitude limit, second coefficient and on (ignored if Nb<2). Can be a regualar expression

8926

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)

9121

param.bmin(2:param.ndfe) = xls_parameter(parameter, 'b_min(2..N_b)', true, -1*param.bmax(2:param.ndfe) ); % DFE negative magnitude limit, if not specified it defaults to -b_max(2..N_b)

8927

end

9122

end

8928

9123

8929

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)

9124

param.gqual=xls_parameter(parameter, 'G_Qual', true,[]);% G_Qual are the dB ranges of g_DC g DC )which correspond tog_DC_HP (g DC2)

8930

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

9125

param.g2qual=xls_parameter(parameter, 'G2_Qual', true,[]); % G2_Qual limit values of g_DC_HP (g DC2 ) which corresponds to ranges of g_DC g DC specified with G_QUAL

8931

%verify gqual and gqual2 input

9126

%verify gqual and gqual2 input

8932

if ~isempty(param.gqual) || ~isempty(param.g2qual)

9127

if ~isempty(param.gqual) || ~isempty(param.g2qual)

8933

if size(param.gqual,1)~=length(param.g2qual)

9128

if size(param.gqual,1)~=length(param.g2qual)

8934

error('gqual and g2qual size mismatch');

9129

error('gqual and g2qual size mismatch');

8935

end

9130

end

8936

if size(param.gqual,2)~=2

9131

if size(param.gqual,2)~=2

8937

error('gqual must be Nx2 matrix');

9132

error('gqual must be Nx2 matrix');

8938

end

9133

end

8939

end

9134

end

8940

9135

8941

9136

8942

% eval if string for all three - can use different for TX and RX

9137

% eval if string for all three - can use different for TX and RX

8943

param.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9138

param.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

8944

param.C_diepad = xls_parameter(parameter, 'C_d', true)*1e-9; % C_d in nF (single sided)

9139

param.C_diepad = xls_parameter(parameter, 'C_d', true)*1e-9; % C_d in nF (single sided)

8945

% [ahealey] Read values for optional compensating L and "bump" C

9140

% [ahealey] Read values for optional compensating L and "bump" C

8946

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

9141

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

8947

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

9142

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

8948

% [ahealey] End of modifications.

9143

% [ahealey] End of modifications.

8949

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

9144

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

8950

param.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9145

param.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

8951

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

9146

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

8952

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

9147

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

8953

9148

8954

9149

8955

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

9150

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

8956

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9151

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

8957

[ncases, mele]=size(param.z_p_tx_cases);

9152

[ncases, mele]=size(param.z_p_tx_cases);

8958

if mele ==2

9153

if mele ==2

8959

param.flex=2;

9154

param.flex=2;

8960

elseif mele==4

9155

elseif mele==4

8961

param.flex=4;

9156

param.flex=4;

8962

elseif mele==1

9157

elseif mele==1

8963

param.flex=1;

9158

param.flex=1;

8964

else

9159

else

8965

error(sprintf('config file syntax error'))

9160

error(sprintf('config file syntax error'))

8966

end

9161

end

8967

9162

8968

% board parameters

9163

% board parameters

8969

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

9164

param.C_0 = xls_parameter(parameter, 'C_0', true,0)*1e-9; % If Include PCB is set to 1, near device single ended capacitance C0 in nF is added

8970

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

9165

param.C_1 = xls_parameter(parameter, 'C_1', true,0)*1e-9; % if Include PCB is set to 1, connector side single ended capacitance C1 in nF is added

8971

%

9166

%

8972

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9167

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

8973

[ncases1, mele1]=size(param.z_p_next_cases);

9168

[ncases1, mele1]=size(param.z_p_next_cases);

8974

if ncases ~= ncases1 || mele ~= mele1

9169

if ncases ~= ncases1 || mele ~= mele1

8975

error('All TX, NEXT, FEXT, Rx cases must agree');

9170

error('All TX, NEXT, FEXT, Rx cases must agree');

8976

else

9171

else

8977

end

9172

end

8978

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9173

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

8979

[ncases1, mele1]=size(param.z_p_fext_cases);

9174

[ncases1, mele1]=size(param.z_p_fext_cases);

8980

if ncases ~= ncases1 || mele ~= mele1

9175

if ncases ~= ncases1 || mele ~= mele1

8981

error('All TX, NEXT, FEXT, Rx cases must agree');

9176

error('All TX, NEXT, FEXT, Rx cases must agree');

8982

else

9177

else

8983

end

9178

end

8984

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9179

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

8985

[ncases1, mele1]=size(param.z_p_rx_cases);

9180

[ncases1, mele1]=size(param.z_p_rx_cases);

8986

if ncases ~= ncases1 || mele ~= mele1

9181

if ncases ~= ncases1 || mele ~= mele1

8987

error('All TX, NEXT, FEXT, Rx cases must agree');

9182

error('All TX, NEXT, FEXT, Rx cases must agree');

8988

else

9183

else

8989

end

9184

end

8990

% Table 93A-3 parameters

9185

% Table 93A-3 parameters

8991

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.

9186

param.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

8992

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9187

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

8993

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9188

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

8994

[ ncases1, mele1]=size(param.pkg_Z_c);%

9189

[ ncases1, mele1]=size(param.pkg_Z_c);%

8995

if mele ~= mele1

9190

if mele ~= mele1

8996

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9191

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

8997

else

9192

else

8998

end

9193

end

8999

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9194

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9000

for ii=1:ncases

9195

for ii=1:ncases

9001

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9196

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9002

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9197

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9003

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9198

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9004

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9199

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9005

end

9200

end

9006

param.z_p_fext_cases = param.z_p_fext_casesx;

9201

param.z_p_fext_cases = param.z_p_fext_casesx;

9007

param.z_p_next_cases= param.z_p_next_casesx;

9202

param.z_p_next_cases= param.z_p_next_casesx;

9008

param.z_p_tx_cases= param.z_p_tx_casesx;

9203

param.z_p_tx_cases= param.z_p_tx_casesx;

9009

param.z_p_rx_cases= param.z_p_rx_casesx;

9204

param.z_p_rx_cases= param.z_p_rx_casesx;

9010

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9205

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9011

end

9206

end

9012

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9207

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9013

9208

9014

% Table 92-12 parameters

9209

% Table 92-12 parameters

9015

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.

9210

param.brd_gamma0_a1_a2 = xls_parameter(parameter, 'board_tl_gamma0_a1_a2', true, [0 4.114e-4 2.547e-4]); % Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9016

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9211

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9017

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9212

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9018

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9213

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9019

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9214

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9020

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9215

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9021

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9216

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9022

9217

9023

% Unofficial parameters

9218

% Unofficial parameters

9024

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9219

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9025

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9220

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9026

% Deprecated parameters - affect only frequency domain analysis.

9221

% Deprecated parameters - affect only frequency domain analysis.

9027

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

9222

param.f_v = xls_parameter(parameter, 'f_v', true, 4); % For FOM_ILD: Transiton rate cut off frequency for ICN/ILD calc in terms of fb

9028

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

9223

param.f_f = xls_parameter(parameter, 'f_f', true, 4); % For ICN: Fext transiton rate cut off frequency for ICN calc in terms of fb

9029

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

9224

param.f_n = xls_parameter(parameter, 'f_n', true, 4); % For ICN: Next transiton rate cut off frequency for ICN calc in terms of fb

9030

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

9225

param.f_r = xls_parameter(parameter, 'f_r', true, 4); % reference receive filter in COM and in ICN/FOM_ILD calcs in terms of fb

9031

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

9226

param.fb_BT_cutoff= xls_parameter(parameter, 'TDR_f_BT_3db', true, 0.4730); % Bessel-Thomson 3 dB cut off freqeuncy in terms of fb

9032

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9227

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9033

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9228

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9034

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9229

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9035

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9230

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9036

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9231

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9037

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9232

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9038

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9233

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9039

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9234

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9040

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9235

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9041

switch param.Gx

9236

switch param.Gx

9042

case 0

9237

case 0

9043

param.Grr=param.Grr; % just use older Grr ir gx not specified

9238

param.Grr=param.Grr; % just use older Grr ir gx not specified

9044

case 1

9239

case 1

9045

param.Grr=2; % use newer Grr

9240

param.Grr=2; % use newer Grr

9046

end

9241

end

9047

9242

9048

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

9243

param.LOCAL_SEARCH=xls_parameter(parameter,'Local Search',true,0); % Decreases COM compute time. Aetting to 2 seems ok ,if 0 search is full grid

9049

% Operational control variables

9244

% Operational control variables

9050

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9245

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9051

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9246

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9052

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

9247

param.Noise_Crest_Factor= xls_parameter(parameter, 'Noise_Crest_Factor', true, 0); % Normally not used. If set this is q factor used for quantized Gaussian PDFs

9053

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

9248

param.AC_CM_RMS = xls_parameter(parameter, 'AC_CM_RMS', true, 0); % AC_CM_RMS is the CM BBN AWGN RMS at COM source point. Default is 0. Adds common mode noise source to the COM signal path for the through channel

9054

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9249

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9055

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.

9250

param.T_O = xls_parameter(parameter, 'T_O', true, 0 ); % Units are mUI. Histogram for VEC and VEO are computed over T_s +/- T_O.

9056

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.

9251

param.T_O = xls_parameter(parameter, 'T_h', true, param.T_O ); % superceded with T_O but is the internal values that is used. Do not use.

9057

9252

9058

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9253

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9059

9254

9060

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)

9255

OP.Histogram_Window_Weight=xls_parameter(parameter, 'Histogram_Window_Weight', false, 'rectangle' ); %Weighting for VEC and VEO are histogram processing. Type are Gaussian,Dual Rayleigh,Triangle, and Rectangle (default)

9061

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9256

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9062

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9257

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9063

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

9258

param.QL=xls_parameter(parameter, 'QL', true, param.T_O/param.Qr/1000 ); % superceded with sigma_r but is the internal values that is used

9064

9259

9065

%%

9260

%%

9066

9261

9067

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9262

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9068

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9263

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9069

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9264

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9070

param.awgn_mv=param.AC_CM_RMS;

9265

param.awgn_mv=param.AC_CM_RMS;

9071

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9266

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9072

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

9267

param.f_hp=xls_parameter(parameter, 'f_hp', true, 0 ); % for rx testing for eq 162-12 if 0 (default) then rx test using rx bbn

9073

9268

9074

9269

9075

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9270

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9076

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9271

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9077

param.Floating_RXFFE=false;

9272

param.Floating_RXFFE=false;

9078

param.Floating_DFE=false;

9273

param.Floating_DFE=false;

9079

if param.N_bg > 0

9274

if param.N_bg > 0

9080

param.Floating_DFE=true;

9275

param.Floating_DFE=true;

9081

end

9276

end

9082

if OP.RxFFE

9277

if OP.RxFFE

9083

param.Floating_DFE=false;

9278

param.Floating_DFE=false;

9084

if param.N_bg > 0

9279

if param.N_bg > 0

9085

param.Floating_RXFFE=true;

9280

param.Floating_RXFFE=true;

9086

end

9281

end

9087

end

9282

end

9088

%% for introducing Tx or Rx skew on p leg or n leg

9283

%% for introducing Tx or Rx skew on p leg or n leg

9089

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9284

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9090

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9285

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9091

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9286

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9092

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9287

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9093

9288

9094

%%

9289

%%

9095

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9290

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9096

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9291

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9097

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9292

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9098

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9293

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9099

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9294

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9100

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9295

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9101

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9296

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9102

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9297

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9103

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9298

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9104

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

9299

OP.CSV_REPORT = xls_parameter(parameter, 'CSV_REPORT', false, true); % saves all the output parameters to a CSV file in the results directory, If DIAGNOSTICS is set then a mat file is also created

9105

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9300

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9106

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9301

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9107

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9302

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9108

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

9303

OP.GET_FD = xls_parameter(parameter, 'Display frequency domain', false, OP.GET_FD); % Not normally set in the config file. It is normally just set to true to get FD plots

9109

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

9304

OP.INC_PACKAGE = xls_parameter(parameter, 'INC_PACKAGE', false, true); % warning: INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1

9110

if ~OP.INC_PACKAGE

9305

if ~OP.INC_PACKAGE

9111

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');

9306

fprintf('<strong> Warning!!! INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9112

end

9307

end

9113

9308

9114

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9309

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9115

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9310

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9116

if OP.IDEAL_TX_TERM

9311

if OP.IDEAL_TX_TERM

9117

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9312

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9118

end

9313

end

9119

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9314

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9120

if OP.IDEAL_RX_TERM

9315

if OP.IDEAL_RX_TERM

9121

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9316

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9122

end

9317

end

9123

9318

9124

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.

9319

OP.TDMODE = xls_parameter(parameter, 'TDMODE',false, OP.TDMODE); % Enables the the use of pulse response instead of s-parameters. Assumes no packages or the packages are included in the PR. Default is 0.

9125

9320

9126

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9321

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9127

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9322

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9128

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9323

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9129

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

9324

OP.BREAD_CRUMBS = xls_parameter(parameter, 'BREAD_CRUMBS',false, false); % if DIAGNOSTICS is set then param, OP, and chdata are include in the output for each run

9130

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9325

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9131

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

9326

OP.COM_CONTRIBUTION_CURVES = xls_parameter(parameter, 'COM_CONTRIBUTION',false,0); % Default is 0. If set to 1 then a bar graph of COM contributors is produce instead of bathtub curves

9132

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9327

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9133

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

9328

OP.EC_REL_TOL = xls_parameter(parameter, 'Enforce Causality REL_TOL', false, 1e-2); % Relative Tolerance parameter for causality, Hard enforcement, 1e-3, Soft enforcement, 1e-2

9134

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

9329

OP.EC_DIFF_TOL = xls_parameter(parameter, 'Enforce Causality DIFF_TOL', false, 1e-3); % Difference Tolerance parameter for causality, Hard enforcement, 1e-4,Soft enforcement, 1e-3

9135

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

9330

OP.EC_PULSE_TOL = xls_parameter(parameter, 'Enforce Causality pulse start tolerance', false, 0.01); % Tolerance parameter for causality, Hard enforcement, 0.05, Soft enforcement, .01

9136

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9331

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9137

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9332

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9138

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

9333

OP.sigma_bn_STEP = xls_parameter(parameter, 'Sigma BBN step', false, 5e-3); % BBN step for Rx Calibration in volts. Defaults is 0.5e-3

9139

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.

9334

OP.BBN_Q_factor = xls_parameter(parameter, 'BBN Q factor', false, 5); % Overrides NEXT/FEXT noise Qfactor for 'Force BBN Q factor' used for reporting. does not affect COM.

9140

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9335

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9141

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9336

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9142

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9337

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9143

9338

9144

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9339

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9145

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9340

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9146

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.

9341

OP.FORCE_TR = xls_parameter(parameter, 'FORCE_TR', false, false);% Included for earlier version support but should be set to 1 in most later config sheets.

9147

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9342

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9148

% compatibility

9343

% compatibility

9149

if OP.FORCE_TR

9344

if OP.FORCE_TR

9150

OP.T_r_meas_point=0;

9345

OP.T_r_meas_point=0;

9151

OP.T_r_filter_type=1;

9346

OP.T_r_filter_type=1;

9152

end

9347

end

9153

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9348

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9154

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.

9349

OP.TDR_duration= xls_parameter(parameter, 'TDR_duration', false, 5); % only used if N*UI is longer than the TDR duration time. Default is 5 times the raw s-parameter transit time.

9155

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9350

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9156

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9351

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9157

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.

9352

OP.T_k= xls_parameter(parameter, 'T_k', false, .6)*1e-9; % Time span (ns) for which the impedance of port is determined using TDR.

9158

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9353

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9159

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9354

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9160

if OP.ERL

9355

if OP.ERL

9161

OP.PTDR=1;

9356

OP.PTDR=1;

9162

else

9357

else

9163

OP.PTDR=0;

9358

OP.PTDR=0;

9164

end % ERL needs to do a TDR

9359

end % ERL needs to do a TDR

9165

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9360

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9166

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9361

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9167

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9362

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9168

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9363

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9169

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9364

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9170

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9365

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9171

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9366

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9172

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9367

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9173

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.

9368

OP.AUTO_TFX=xls_parameter(parameter, 'AUTO_TFX', false,0); % Mostly used for device ERL. If sent to 1 the fixture tfx will be estimated.

9174

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9369

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9175

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9370

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9176

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.

9371

OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncation threshold', false, 1e-3); % zero padding threshold in fraction of IR peak for the impulse response. Effectively controls the length of time for the PR. Larger values decrease run time and accuracy. Default is 1e-3.

9177

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9372

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9178

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9373

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9179

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9374

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9180

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9375

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9181

if strcmpi(OP.PHY,'C2M')

9376

if strcmpi(OP.PHY,'C2M')

9182

OP.EW=true;

9377

OP.EW=true;

9183

else

9378

else

9184

param.T_O=0; % make sure when c2c that sample is at Ts

9379

param.T_O=0; % make sure when c2c that sample is at Ts

9185

end

9380

end

9186

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9381

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9187

OP.PHY='C2Mcom';

9382

OP.PHY='C2Mcom';

9188

end

9383

end

9189

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9384

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9190

switch lower(OP.TDECQ)

9385

switch lower(OP.TDECQ)

9191

case {false 'none' 'vma'}

9386

case {false 'none' 'vma'}

9192

otherwise

9387

otherwise

9193

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9388

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9194

end

9389

end

9195

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9390

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9196

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9391

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9197

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9392

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9198

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9393

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9199

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

9394

OP.Optimize_loop_speed_up =xls_parameter(parameter, 'Optimize_loop_speed_up', true , 0);% If set to 0 (or default) normal looping, If set to 1 loop speedup by slightly reducing PD Fbin and FIR_threshold for optimize looping only

9200

% Parameters for error burst probability calculation. Not officially used

9395

% Parameters for error burst probability calculation. Not officially used

9201

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9396

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9202

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9397

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9203

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9398

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9204

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.

9399

OP.USE_ETA0_PSD = xls_parameter(parameter, 'USE_ETA0_PSD', false, 0); % Used eta_0 PSD equaiton for sigma_n. Default is 0. Do not use.

9205

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.

9400

OP.SAVE_CONFIG2MAT = xls_parameter(parameter, 'SAVE_CONFIG2MAT', false, 0); % If set to 1 (default) saves parameters in mat file. Requires DIAGNOSTICS to be set.

9206

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9401

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9207

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.

9402

OP.fraction_of_F_range_start_extrap_from= xls_parameter(parameter, 'fraction_of_F_range_start_extrap_from', true, 0.75); % Frequency (fb) where high frequency extropolation begins for computing IR. Helps control Gibbs phenomena. defualt is 0.75.

9208

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9403

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9209

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9404

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9210

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9405

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9211

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9406

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9212

OP.MLSE = xls_parameter(parameter, 'MLSE', false, 0); % MLSE 0,1,2, 3 (no MLSE, U1 MLSE, experimetal MLSE, U3 MLSE)

9407

OP.MLSE = xls_parameter(parameter, 'MLSE', false, 0); % MLSE 0,1,2, 3 (no MLSE, U1 MLSE, experimetal MLSE, U3 MLSE)

9213

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9408

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9214

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9409

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9215

if OP.MLSE && param.ndfe==0

9410

if OP.MLSE && param.ndfe==0

9216

error('At least DFE 1 must be set to use MLSE');

9411

error('At least DFE 1 must be set to use MLSE');

9217

end

9412

end

9218

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9413

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9219

% MNSE parameters

9414

% MNSE parameters

9220

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9415

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9221

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9416

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9222

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9417

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9223

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9418

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9224

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS', 'WIENER-HOPF',

9419

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS', 'WIENER-HOPF',

9225

9420

9226

% need to make sure TD mode does not invoke FD operations

9421

% need to make sure TD mode does not invoke FD operations

9227

if OP.TDMODE % need to set GET_FD false of TDMODE

9422

if OP.TDMODE % need to set GET_FD false of TDMODE

9228

OP.GET_FD=false;

9423

OP.GET_FD=false;

9229

OP.ERL_ONLY=0;

9424

OP.ERL_ONLY=0;

9230

OP.ERL=0;

9425

OP.ERL=0;

9231

OP.PTDR=0;

9426

OP.PTDR=0;

9232

OP.TDR=0;

9427

OP.TDR=0;

9233

OP.RX_CALIBRATION=0;

9428

OP.RX_CALIBRATION=0;

9234

end

9429

end

9235

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9430

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9236

save(matcongfile ,'parameter');

9431

save(matcongfile ,'parameter');

9237

end

9432

end

9238

9433

9239

9434

9240

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9435

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9241

if ~isempty(param.PKG_NAME)

9436

if ~isempty(param.PKG_NAME)

9242

if length(param.PKG_NAME) == 1

9437

if length(param.PKG_NAME) == 1

9243

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9438

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9244

end

9439

end

9245

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9440

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9246

tx_rx_fields_matrix = {'pkg_Z_c'};

9441

tx_rx_fields_matrix = {'pkg_Z_c'};

9247

tx_fields = {'z_p_tx_cases' 'z_p_next_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9442

tx_fields = {'z_p_tx_cases' 'z_p_next_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9248

rx_fields = {'z_p_rx_cases' 'a_next'};

9443

rx_fields = {'z_p_rx_cases' 'a_next'};

9249

tx_pkg_name=param.PKG_NAME{1};

9444

tx_pkg_name=param.PKG_NAME{1};

9250

rx_pkg_name=param.PKG_NAME{2};

9445

rx_pkg_name=param.PKG_NAME{2};

9251

tx_pkg_struct=param.PKG.(tx_pkg_name);

9446

tx_pkg_struct=param.PKG.(tx_pkg_name);

9252

rx_pkg_struct=param.PKG.(rx_pkg_name);

9447

rx_pkg_struct=param.PKG.(rx_pkg_name);

9253

9448

9254

%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

9449

%tx_rx_fields: put the value from the tx package in the Tx position and the value from the rx package in the RX position

9255

for j=1:length(tx_rx_fields)

9450

for j=1:length(tx_rx_fields)

9256

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9451

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9257

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9452

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9258

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9453

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9259

end

9454

end

9260

9455

9261

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9456

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9262

for j=1:length(tx_rx_fields_matrix)

9457

for j=1:length(tx_rx_fields_matrix)

9263

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9458

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9264

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9459

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9265

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9460

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9266

end

9461

end

9267

9462

9268

%tx_fields: use only the tx package values

9463

%tx_fields: use only the tx package values

9269

for j=1:length(tx_fields)

9464

for j=1:length(tx_fields)

9270

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9465

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9271

end

9466

end

9272

9467

9273

%rx_fields: use only the rx package values

9468

%rx_fields: use only the rx package values

9274

for j=1:length(rx_fields)

9469

for j=1:length(rx_fields)

9275

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9470

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9276

end

9471

end

9277

9472

9278

end

9473

end

9279

9474

9280

9475

9281

%%

9476

%%

9282

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9477

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9283

%% FUNCTION :: read_sp4_sparams

9478

%% FUNCTION :: read_sp4_sparams

9284

%

9479

%

9285

% Description

9480

% Description

9286

% Read the fid of single-ended 4-port complex S-parameters

9481

% Read the fid of single-ended 4-port complex S-parameters

9287

% in Touchstone format 'file' and convert to the internal

9482

% in Touchstone format 'file' and convert to the internal

9288

% format using the port transform 'ports'

9483

% format using the port transform 'ports'

9289

%

9484

%

9290

% Created by Mike Y. He

9485

% Created by Mike Y. He

9291

% April 22, 2005

9486

% April 22, 2005

9292

%

9487

%

9293

% Reused some code from

9488

% Reused some code from

9294

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9489

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9295

% for touchstone 4-port S-matrix import.

9490

% for touchstone 4-port S-matrix import.

9296

%

9491

%

9297

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9492

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9298

% optimized for quicker parameter matching and parsing. also, separated out

9493

% optimized for quicker parameter matching and parsing. also, separated out

9299

% the plotting algorithms into their own sub-function routines

9494

% the plotting algorithms into their own sub-function routines

9300

%

9495

%

9301

% Modified December 2021 to use read_Nport_touchstone

9496

% Modified December 2021 to use read_Nport_touchstone

9302

% This is faster reader that is capable of reading touchstone with any number of ports

9497

% This is faster reader that is capable of reading touchstone with any number of ports

9303

%

9498

%

9304

% Input Variables (required)

9499

% Input Variables (required)

9305

% infile -- The s4p file to be read and converted

9500

% infile -- The s4p file to be read and converted

9306

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9501

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9307

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9502

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9308

% ports -- Re-order the port layout

9503

% ports -- Re-order the port layout

9309

%

9504

%

9310

% Output/Return Variables

9505

% Output/Return Variables

9311

% data -- structure containing network parameter data points and frequency axis

9506

% data -- structure containing network parameter data points and frequency axis

9312

% sdc -- the differential in/common-mode out s-parameter data matrix

9507

% sdc -- the differential in/common-mode out s-parameter data matrix

9313

% sdd -- the differential in/differential out s-parameter data matrix

9508

% sdd -- the differential in/differential out s-parameter data matrix

9314

%

9509

%

9315

9510

9316

9511

9317

% backwards compatibility settings. can be removed in updated code.

9512

% backwards compatibility settings. can be removed in updated code.

9318

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9513

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9319

if isempty(ports); ports = [1 2]; end % default order normally used.

9514

if isempty(ports); ports = [1 2]; end % default order normally used.

9320

ports = [1 2];

9515

ports = [1 2];

9321

9516

9322

9517

9323

if OP.DISPLAY_WINDOW

9518

if OP.DISPLAY_WINDOW

9324

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9519

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9325

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9520

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9326

end

9521

end

9327

9522

9328

%AJG: fast touchstone read for any number of ports

9523

%AJG: fast touchstone read for any number of ports

9329

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9524

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9330

9525

9331

9526

9332

9527

9333

D=NaN(size(sch));

9528

D=NaN(size(sch));

9334

% calculate differential s parameter matrix from single ended

9529

% calculate differential s parameter matrix from single ended

9335

for i=1:size(sch,1)

9530

for i=1:size(sch,1)

9336

S(:,:) = sch(i,:,:);

9531

S(:,:) = sch(i,:,:);

9337

T = [1 1 ; 1 -1 ];

9532

T = [1 1 ; 1 -1 ];

9338

W = T * (S / T);

9533

W = T * (S / T);

9339

D(i,:,:) = W(:,:);

9534

D(i,:,:) = W(:,:);

9340

end

9535

end

9341

9536

9342

% D matrix should be

9537

% D matrix should be

9343

% Scc11 Scd11 Scc12 Scd21

9538

% Scc11 Scd11 Scc12 Scd21

9344

% Sdc11 Sdd11 Sdc12 Sdd12

9539

% Sdc11 Sdd11 Sdc12 Sdd12

9345

% Scc21 Scd21 Scc22 Scd22

9540

% Scc21 Scd21 Scc22 Scd22

9346

% Sdc21 Sdd21 Sdc22 Sdd22

9541

% Sdc21 Sdd21 Sdc22 Sdd22

9347

9542

9348

% proper values

9543

% proper values

9349

%AJG: matrix can be properly referenced after fixing mapping

9544

%AJG: matrix can be properly referenced after fixing mapping

9350

SDD(:,1,1) = D(:,2,2);

9545

SDD(:,1,1) = D(:,2,2);

9351

SDC(:,1,1)= D(:,2,1);

9546

SDC(:,1,1)= D(:,2,1);

9352

SCC(:,1,1)= D(:,1,1);

9547

SCC(:,1,1)= D(:,1,1);

9353

SCD(:,1,1)= D(:,1,2);

9548

SCD(:,1,1)= D(:,1,2);

9354

9549

9355

9550

9356

9551

9357

% backwards compatibility output variables

9552

% backwards compatibility output variables

9358

data.m = sch;

9553

data.m = sch;

9359

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9554

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9360

data.freq = schFreqAxis;

9555

data.freq = schFreqAxis;

9361

colors = 'rgbk';

9556

colors = 'rgbk';

9362

9557

9363

if (plot_ini_s_params == 1)

9558

if (plot_ini_s_params == 1)

9364

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9559

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9365

for mj=1:4

9560

for mj=1:4

9366

% subplot(2,2,mj);

9561

% subplot(2,2,mj);

9367

for mi=1:4

9562

for mi=1:4

9368

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9563

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9369

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9564

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9370

hold on

9565

hold on

9371

end

9566

end

9372

xlabel('Frequency (Hz)');

9567

xlabel('Frequency (Hz)');

9373

ylabel('Magnitude (dB)');

9568

ylabel('Magnitude (dB)');

9374

legend show

9569

legend show

9375

grid on

9570

grid on

9376

title(sprintf('Output port %d', mj));

9571

title(sprintf('Output port %d', mj));

9377

end

9572

end

9378

end

9573

end

9379

plot_dif_s_params =0;

9574

plot_dif_s_params =0;

9380

if (plot_dif_s_params == 1)

9575

if (plot_dif_s_params == 1)

9381

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9576

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9382

% subplot(2,1,1);

9577

% subplot(2,1,1);

9383

for mj=1:1

9578

for mj=1:1

9384

for mi=1:1

9579

for mi=1:1

9385

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9580

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9386

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9581

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9387

hold on

9582

hold on

9388

end

9583

end

9389

end

9584

end

9390

xlabel('Frequency (Hz)');

9585

xlabel('Frequency (Hz)');

9391

ylabel('Magnitude (dB)');

9586

ylabel('Magnitude (dB)');

9392

legend show

9587

legend show

9393

grid on

9588

grid on

9394

title(infile);

9589

title(infile);

9395

9590

9396

% subplot(2,1,2);

9591

% subplot(2,1,2);

9397

% for mj=1:2

9592

% for mj=1:2

9398

% for mi=1:2

9593

% for mi=1:2

9399

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9594

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9400

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9595

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9401

% hold on

9596

% hold on

9402

% end

9597

% end

9403

% end

9598

% end

9404

% xlabel('Frequency (Hz)');

9599

% xlabel('Frequency (Hz)');

9405

% ylabel('Magnitude (dB)');

9600

% ylabel('Magnitude (dB)');

9406

% legend show

9601

% legend show

9407

% grid on

9602

% grid on

9408

end

9603

end

9409

9604

9410

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9605

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9411

% end read_sp2_sparam

9606

% end read_sp2_sparam

9412

9607

9413

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9608

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9414

%% FUNCTION :: read_sp4_sparams

9609

%% FUNCTION :: read_sp4_sparams

9415

%

9610

%

9416

% Description

9611

% Description

9417

% Read the fid of single-ended 4-port complex S-parameters

9612

% Read the fid of single-ended 4-port complex S-parameters

9418

% in Touchstone format 'file' and convert to the internal

9613

% in Touchstone format 'file' and convert to the internal

9419

% format using the port transform 'ports'

9614

% format using the port transform 'ports'

9420

%

9615

%

9421

% Created by Mike Y. He

9616

% Created by Mike Y. He

9422

% April 22, 2005

9617

% April 22, 2005

9423

%

9618

%

9424

% Reused some code from

9619

% Reused some code from

9425

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9620

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9426

% for touchstone 4-port S-matrix import.

9621

% for touchstone 4-port S-matrix import.

9427

%

9622

%

9428

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9623

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9429

% optimized for quicker parameter matching and parsing. also, separated out

9624

% optimized for quicker parameter matching and parsing. also, separated out

9430

% the plotting algorithms into their own sub-function routines

9625

% the plotting algorithms into their own sub-function routines

9431

%

9626

%

9432

% Modified December 2021 to use read_Nport_touchstone

9627

% Modified December 2021 to use read_Nport_touchstone

9433

% This is faster reader that is capable of reading touchstone with any number of ports

9628

% This is faster reader that is capable of reading touchstone with any number of ports

9434

%

9629

%

9435

% Input Variables (required)

9630

% Input Variables (required)

9436

% infile -- The s4p file to be read and converted

9631

% infile -- The s4p file to be read and converted

9437

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9632

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9438

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9633

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9439

% ports -- Re-order the port layout

9634

% ports -- Re-order the port layout

9440

% OP

9635

% OP

9441

% param

9636

% param

9442

% Output/Return Variables

9637

% Output/Return Variables

9443

% data -- structure containing network parameter data points and frequency axis

9638

% data -- structure containing network parameter data points and frequency axis

9444

% sdd -- the differential in/differential out s-parameter data matrix

9639

% sdd -- the differential in/differential out s-parameter data matrix

9445

% sdc -- the differential in/common-mode out s-parameter data matrix

9640

% sdc -- the differential in/common-mode out s-parameter data matrix

9446

% scc -- the common mode in/common-mode out s-parameter data matrix

9641

% scc -- the common mode in/common-mode out s-parameter data matrix

9447

%

9642

%

9448

%

9643

%

9449

9644

9450

9645

9451

% backwards compatibility settings. can be removed in updated code.

9646

% backwards compatibility settings. can be removed in updated code.

9452

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9647

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9453

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9648

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9454

9649

9455

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9650

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9456

% pair is reversed.

9651

% pair is reversed.

9457

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9652

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9458

9653

9459

if OP.DISPLAY_WINDOW

9654

if OP.DISPLAY_WINDOW

9460

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9655

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9461

end

9656

end

9462

9657

9463

%AJG: fast touchstone read for any number of ports

9658

%AJG: fast touchstone read for any number of ports

9464

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9659

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9465

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9660

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9466

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9661

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9467

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9662

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9468

Sigfct = ...

9663

Sigfct = ...

9469

@(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]);

9664

@(sigma2,sigma1,sigma4,sigma3)reshape([sigma1.^2,sigma1.*sigma2,sigma1.*sigma3,sigma1.*sigma4,sigma1.*sigma2,sigma2.^2,sigma2.*sigma3,sigma2.*sigma4,sigma1.*sigma3,sigma2.*sigma3,sigma3.^2,sigma3.*sigma4,sigma1.*sigma4,sigma2.*sigma4,sigma3.*sigma4,sigma4.^2],[4,4]);

9470

D=NaN(size(sch));

9665

D=NaN(size(sch));

9471

% calculate differential s parameter matrix from single ended

9666

% calculate differential s parameter matrix from single ended

9472

% skew added RIM 12/29/2023

9667

% skew added RIM 12/29/2023

9473

for i=1:size(sch,1)

9668

for i=1:size(sch,1)

9474

f=schFreqAxis(i);

9669

f=schFreqAxis(i);

9475

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) );

9670

sigma_matrix=Sigfct(exp(2i*pi*f*param.Txpskew*1e-12),exp(2i*pi*f*param.Txnskew*1e-12),exp(2i*pi*f*param.Rxpskew*1e-12),exp(2i*pi*f*param.Rxnskew*1e-12) );

9476

S(:,:) = sch(i,:,:);

9671

S(:,:) = sch(i,:,:);

9477

Snew=sigma_matrix.*S;

9672

Snew=sigma_matrix.*S;

9478

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9673

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9479

W = T * (Snew / T);

9674

W = T * (Snew / T);

9480

D(i,:,:) = W(:,:);

9675

D(i,:,:) = W(:,:);

9481

end

9676

end

9482

9677

9483

% D matrix should be

9678

% D matrix should be

9484

% Scc11 Scd11 Scc12 Scd21

9679

% Scc11 Scd11 Scc12 Scd21

9485

% Sdc11 Sdd11 Sdc12 Sdd12

9680

% Sdc11 Sdd11 Sdc12 Sdd12

9486

% Scc21 Scd21 Scc22 Scd22

9681

% Scc21 Scd21 Scc22 Scd22

9487

% Sdc21 Sdd21 Sdc22 Sdd22

9682

% Sdc21 Sdd21 Sdc22 Sdd22

9488

9683

9489

% proper values

9684

% proper values

9490

SDD(:,1,1) = D(:,2,2);

9685

SDD(:,1,1) = D(:,2,2);

9491

SDD(:,2,2) = D(:,4,4);

9686

SDD(:,2,2) = D(:,4,4);

9492

SDD(:,1,2) = D(:,2,4);

9687

SDD(:,1,2) = D(:,2,4);

9493

SDD(:,2,1) = D(:,4,2);

9688

SDD(:,2,1) = D(:,4,2);

9494

9689

9495

SDC(:,1,1) = D(:,2,1);

9690

SDC(:,1,1) = D(:,2,1);

9496

SDC(:,2,2) = D(:,4,3);

9691

SDC(:,2,2) = D(:,4,3);

9497

SDC(:,1,2) = D(:,2,3);

9692

SDC(:,1,2) = D(:,2,3);

9498

SDC(:,2,1) = D(:,4,1);

9693

SDC(:,2,1) = D(:,4,1);

9499

9694

9500

SCC(:,1,1) = D(:,1,1);

9695

SCC(:,1,1) = D(:,1,1);

9501

SCC(:,2,2) = D(:,3,3);

9696

SCC(:,2,2) = D(:,3,3);

9502

SCC(:,1,2) = D(:,1,3);

9697

SCC(:,1,2) = D(:,1,3);

9503

SCC(:,2,1) = D(:,3,1);

9698

SCC(:,2,1) = D(:,3,1);

9504

9699

9505

% backwards compatibility output variables

9700

% backwards compatibility output variables

9506

data.m = sch;

9701

data.m = sch;

9507

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9702

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9508

data.freq = schFreqAxis;

9703

data.freq = schFreqAxis;

9509

colors = 'rgbk';

9704

colors = 'rgbk';

9510

9705

9511

if (plot_ini_s_params == 1)

9706

if (plot_ini_s_params == 1)

9512

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9707

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9513

for mj=1:4

9708

for mj=1:4

9514

subplot(2,2,mj);

9709

subplot(2,2,mj);

9515

for mi=1:4

9710

for mi=1:4

9516

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9711

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9517

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9712

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9518

hold on

9713

hold on

9519

end

9714

end

9520

xlabel('Frequency (Hz)');

9715

xlabel('Frequency (Hz)');

9521

ylabel('Magnitude (dB)');

9716

ylabel('Magnitude (dB)');

9522

legend show

9717

legend show

9523

grid on

9718

grid on

9524

title(sprintf('Output port %d', mj));

9719

title(sprintf('Output port %d', mj));

9525

end

9720

end

9526

end

9721

end

9527

plot_dif_s_params =0;

9722

plot_dif_s_params =0;

9528

if (plot_dif_s_params == 1)

9723

if (plot_dif_s_params == 1)

9529

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9724

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9530

% subplot(2,1,1);

9725

% subplot(2,1,1);

9531

for mj=1:2

9726

for mj=1:2

9532

for mi=1:2

9727

for mi=1:2

9533

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9728

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9534

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9729

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9535

hold on

9730

hold on

9536

end

9731

end

9537

end

9732

end

9538

xlabel('Frequency (Hz)');

9733

xlabel('Frequency (Hz)');

9539

ylabel('Magnitude (dB)');

9734

ylabel('Magnitude (dB)');

9540

legend show

9735

legend show

9541

grid on

9736

grid on

9542

title(infile);

9737

title(infile);

9543

%

9738

%

9544

% subplot(2,1,2);

9739

% subplot(2,1,2);

9545

% for mj=1:2

9740

% for mj=1:2

9546

% for mi=1:2

9741

% for mi=1:2

9547

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9742

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9548

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9743

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9549

% hold on

9744

% hold on

9550

% end

9745

% end

9551

% end

9746

% end

9552

% xlabel('Frequency (Hz)');

9747

% xlabel('Frequency (Hz)');

9553

% ylabel('Magnitude (dB)');

9748

% ylabel('Magnitude (dB)');

9554

% legend show

9749

% legend show

9555

% grid on

9750

% grid on

9556

end

9751

end

9557

9752

9558

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9753

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9559

% end read_sp4_sparam

9754

% end read_sp4_sparam

9560

function param_struct = read_package_parameters(parameter,param_struct)

9755

function param_struct = read_package_parameters(parameter,param_struct)

9561

9756

9562

%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

9757

%With the introduction of Package sections in COM spreadsheet, it makes sense to have a single function that grabs all package parameters from a parameter block

9563

%This block should eventually replace what is in read_ParamConfigFile

9758

%This block should eventually replace what is in read_ParamConfigFile

9564

%It can be called as: param = read_package_parameters(parameter, param)

9759

%It can be called as: param = read_package_parameters(parameter, param)

9565

9760

9566

if nargin<2

9761

if nargin<2

9567

%param_struct doesn't need to be passed when building a new package structure

9762

%param_struct doesn't need to be passed when building a new package structure

9568

%it is only needed when appending to regular param structure

9763

%it is only needed when appending to regular param structure

9569

param_struct=struct;

9764

param_struct=struct;

9570

end

9765

end

9571

9766

9572

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9767

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9573

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9768

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9574

9769

9575

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9770

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9576

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9771

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9577

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9772

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9578

9773

9579

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

9774

param_struct.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9580

[ncases, mele]=size(param_struct.z_p_tx_cases);

9775

[ncases, mele]=size(param_struct.z_p_tx_cases);

9581

if mele ==2

9776

if mele ==2

9582

param_struct.flex=2;

9777

param_struct.flex=2;

9583

elseif mele==4

9778

elseif mele==4

9584

param_struct.flex=4;

9779

param_struct.flex=4;

9585

elseif mele==1

9780

elseif mele==1

9586

param_struct.flex=1;

9781

param_struct.flex=1;

9587

else

9782

else

9588

error('config file syntax error')

9783

error('config file syntax error')

9589

end

9784

end

9590

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

9785

param_struct.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9591

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9786

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9592

if ncases ~= ncases1 || mele ~= mele1

9787

if ncases ~= ncases1 || mele ~= mele1

9593

error('All TX, NEXT, FEXT, Rx cases must agree');

9788

error('All TX, NEXT, FEXT, Rx cases must agree');

9594

else

9789

else

9595

end

9790

end

9596

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

9791

param_struct.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9597

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9792

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9598

if ncases ~= ncases1 || mele ~= mele1

9793

if ncases ~= ncases1 || mele ~= mele1

9599

error('All TX, NEXT, FEXT, Rx cases must agree');

9794

error('All TX, NEXT, FEXT, Rx cases must agree');

9600

else

9795

else

9601

end

9796

end

9602

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

9797

param_struct.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9603

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9798

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9604

if ncases ~= ncases1 || mele ~= mele1

9799

if ncases ~= ncases1 || mele ~= mele1

9605

error('All TX, NEXT, FEXT, Rx cases must agree');

9800

error('All TX, NEXT, FEXT, Rx cases must agree');

9606

else

9801

else

9607

end

9802

end

9608

% Table 93A-3 parameters

9803

% Table 93A-3 parameters

9609

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.

9804

param_struct.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9610

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9805

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9611

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9806

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9612

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9807

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9613

if mele ~= mele1

9808

if mele ~= mele1

9614

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9809

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9615

else

9810

else

9616

end

9811

end

9617

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9812

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9618

for ii=1:ncases

9813

for ii=1:ncases

9619

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9814

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9620

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9815

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9621

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9816

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9622

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9817

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9623

end

9818

end

9624

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9819

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9625

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9820

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9626

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9821

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9627

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9822

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9628

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9823

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9629

end

9824

end

9630

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9825

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9631

%% extract s-parameter and convert to differential mode

9826

%% extract s-parameter and convert to differential mode

9632

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9827

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9633

num_files=length(chdata);

9828

num_files=length(chdata);

9634

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9829

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9635

for i=1:num_files

9830

for i=1:num_files

9636

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9831

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9637

progress = i/num_files;

9832

progress = i/num_files;

9638

if OP.DISPLAY_WINDOW

9833

if OP.DISPLAY_WINDOW

9639

[~,a]=fileparts(chdata(i).filename);

9834

[~,a]=fileparts(chdata(i).filename);

9640

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9835

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9641

else

9836

else

9642

fprintf('%i ',i);

9837

fprintf('%i ',i);

9643

end

9838

end

9644

9839

9645

% Skip reading file if it was already read (multiple test cases)

9840

% Skip reading file if it was already read (multiple test cases)

9646

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9841

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9647

switch lower(chdata(i).ext)

9842

switch lower(chdata(i).ext)

9648

case '.s2p' % for differential return loss

9843

case '.s2p' % for differential return loss

9649

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9844

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9650

chdata(i).fmaxi = length(Sch.freq);

9845

chdata(i).fmaxi = length(Sch.freq);

9651

chdata(i).faxis = Sch.freq;

9846

chdata(i).faxis = Sch.freq;

9652

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9847

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9653

SDDp2p(i)=NaN;

9848

SDDp2p(i)=NaN;

9654

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9849

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9655

chdata(i).sdd11=chdata(i).sdd11_raw;

9850

chdata(i).sdd11=chdata(i).sdd11_raw;

9656

case '.s4p'

9851

case '.s4p'

9657

if length(param.snpPortsOrder) ~= 4

9852

if length(param.snpPortsOrder) ~= 4

9658

error( 'warning:sNpFilePortMismatch', ...

9853

error( 'warning:sNpFilePortMismatch', ...

9659

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9854

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9660

length(param.snpPortsOrder), ...

9855

length(param.snpPortsOrder), ...

9661

chdata(i).ext ...

9856

chdata(i).ext ...

9662

);

9857

);

9663

end

9858

end

9664

% read function returns differnetial mode parameters

9859

% read function returns differnetial mode parameters

9665

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9860

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9666

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9861

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9667

% param.holdsdata(i).Sch= Sch;

9862

% param.holdsdata(i).Sch= Sch;

9668

% param.holdsdata(i).SDDch= SDDch;

9863

% param.holdsdata(i).SDDch= SDDch;

9669

% param.holdsdata(i).SDCch= SDCch;

9864

% param.holdsdata(i).SDCch= SDCch;

9670

else

9865

else

9671

error('If this line is reached, there is a logic error');

9866

error('If this line is reached, there is a logic error');

9672

% Sch=param.holdsdata(i).Sch;

9867

% Sch=param.holdsdata(i).Sch;

9673

% SDDch=param.holdsdata(i).SDDch;

9868

% SDDch=param.holdsdata(i).SDDch;

9674

% SDCch=param.holdsdata(i).SDCch;

9869

% SDCch=param.holdsdata(i).SDCch;

9675

end

9870

end

9676

chdata(i).fmaxi = length(Sch.freq);

9871

chdata(i).fmaxi = length(Sch.freq);

9677

9872

9678

9873

9679

if Sch.freq(chdata(i).fmaxi) < param.fb

9874

if Sch.freq(chdata(i).fmaxi) < param.fb

9680

warning('COM:read_s4p:MaxFreqTooLow', ...

9875

warning('COM:read_s4p:MaxFreqTooLow', ...

9681

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9876

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9682

chdata(i).filename, Sch.freq(end), param.fb);

9877

chdata(i).filename, Sch.freq(end), param.fb);

9683

end

9878

end

9684

if Sch.freq(1) > param.max_start_freq

9879

if Sch.freq(1) > param.max_start_freq

9685

warning('COM:read_s4p:StartFreqTooHigh', ...

9880

warning('COM:read_s4p:StartFreqTooHigh', ...

9686

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9881

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9687

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9882

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9688

end

9883

end

9689

freqstep=diff(Sch.freq);

9884

freqstep=diff(Sch.freq);

9690

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9885

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9691

if max(freqstep)-min(freqstep) > 1

9886

if max(freqstep)-min(freqstep) > 1

9692

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9887

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9693

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9888

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9694

end

9889

end

9695

if max(freqstep) - param.max_freq_step > 1

9890

if max(freqstep) - param.max_freq_step > 1

9696

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9891

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9697

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9892

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9698

end

9893

end

9699

9894

9700

chdata(i).faxis = Sch.freq;

9895

chdata(i).faxis = Sch.freq;

9701

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9896

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9702

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9897

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9703

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9898

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9704

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9899

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9705

% mode conversion

9900

% mode conversion

9706

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9901

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9707

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9902

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9708

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9903

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9709

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9904

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9710

%save original and add board (if required)

9905

%save original and add board (if required)

9711

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9906

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9712

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

9907

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

9713

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

9908

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

9714

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

9909

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

9715

if OP.include_pcb

9910

if OP.include_pcb

9716

% add boards to sdd

9911

% add boards to sdd

9717

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

9912

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

9718

9913

9719

end

9914

end

9720

%save final return loss (after the boards were included)

9915

%save final return loss (after the boards were included)

9721

chdata(i).sdd11=chdata(i).sdd11_raw;

9916

chdata(i).sdd11=chdata(i).sdd11_raw;

9722

chdata(i).sdd22=chdata(i).sdd22_raw;

9917

chdata(i).sdd22=chdata(i).sdd22_raw;

9723

otherwise

9918

otherwise

9724

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

9919

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

9725

end

9920

end

9726

9921

9727

%Crosstalk frequency axis must be the same as Thru

9922

%Crosstalk frequency axis must be the same as Thru

9728

if i>1

9923

if i>1

9729

%error on length difference

9924

%error on length difference

9730

if length(chdata(i).faxis)~=length(chdata(1).faxis)

9925

if length(chdata(i).faxis)~=length(chdata(1).faxis)

9731

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

9926

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

9732

end

9927

end

9733

%error if any value > 1Hz (don't want to check for exact

9928

%error if any value > 1Hz (don't want to check for exact

9734

%equality in case of floating point error)

9929

%equality in case of floating point error)

9735

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

9930

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

9736

if max(Fdiff)>1

9931

if max(Fdiff)>1

9737

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

9932

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

9738

end

9933

end

9739

end

9934

end

9740

else

9935

else

9741

SDDch(:,1,2)=chdata(i).sdd12_raw;

9936

SDDch(:,1,2)=chdata(i).sdd12_raw;

9742

SDDch(:,2,1)=chdata(i).sdd21_raw;

9937

SDDch(:,2,1)=chdata(i).sdd21_raw;

9743

SDDch(:,1,1)=chdata(i).sdd11_raw;

9938

SDDch(:,1,1)=chdata(i).sdd11_raw;

9744

SDDch(:,2,2)=chdata(i).sdd22_raw;

9939

SDDch(:,2,2)=chdata(i).sdd22_raw;

9745

end

9940

end

9746

chdata(i).sigma_ACCM_at_tp0=0;

9941

chdata(i).sigma_ACCM_at_tp0=0;

9747

if ~param.FLAG.S2P

9942

if ~param.FLAG.S2P

9748

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

9943

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

9749

if (OP.RX_CALIBRATION == 1 && i==2)

9944

if (OP.RX_CALIBRATION == 1 && i==2)

9750

chdata(i).sdd21=chdata(i).sdd21_raw;

9945

chdata(i).sdd21=chdata(i).sdd21_raw;

9751

else

9946

else

9752

%updated package construction with single function for both DD and DC

9947

%updated package construction with single function for both DD and DC

9753

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

9948

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

9754

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

9949

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

9755

chdata(i).sdd21=chdata(i).sdd21p;

9950

chdata(i).sdd21=chdata(i).sdd21p;

9756

if 1 % for AC CM noise inclusion

9951

if 1 % for AC CM noise inclusion

9757

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

9952

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

9758

chdata(i).sdc21=chdata(i).sdc21p;

9953

chdata(i).sdc21=chdata(i).sdc21p;

9759

end

9954

end

9760

end

9955

end

9761

else

9956

else

9762

chdata(i).sdd21=chdata(i).sdd21_raw;

9957

chdata(i).sdd21=chdata(i).sdd21_raw;

9763

end

9958

end

9764

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

9959

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

9765

end

9960

end

9766

end

9961

end

9767

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

9962

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

9768

9963

9769

function result = readdataSnPx(filename, nport)

9964

function result = readdataSnPx(filename, nport)

9770

%function [freq, cs] = readdataSnPx(filename, nport)

9965

%function [freq, cs] = readdataSnPx(filename, nport)

9771

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

9966

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

9772

%

9967

%

9773

% Read Touchstone file with frequencies in units of Hertz

9968

% Read Touchstone file with frequencies in units of Hertz

9774

%

9969

%

9775

% Input:

9970

% Input:

9776

% ======

9971

% ======

9777

% filename: Name of the Touchstone/SnP file

9972

% filename: Name of the Touchstone/SnP file

9778

% nport: Number of ports

9973

% nport: Number of ports

9779

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

9974

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

9780

% Touchstone file)

9975

% Touchstone file)

9781

% nheader: Number of header lines (comment lines plus option line in the

9976

% nheader: Number of header lines (comment lines plus option line in the

9782

% Touchstone file)

9977

% Touchstone file)

9783

%

9978

%

9784

% Output:

9979

% Output:

9785

% =======

9980

% =======

9786

% freq: Vector of frequencies [Hz]

9981

% freq: Vector of frequencies [Hz]

9787

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

9982

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

9788

% at frequency freq(k)

9983

% at frequency freq(k)

9789

%

9984

%

9790

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

9985

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

9791

% frequencies appropriately after reading the data.

9986

% frequencies appropriately after reading the data.

9792

%

9987

%

9793

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

9988

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

9794

% EIA/IBIS Open Forum, 2002.

9989

% EIA/IBIS Open Forum, 2002.

9795

%

9990

%

9796

% Written by Henning Braunisch, September 2004.

9991

% Written by Henning Braunisch, September 2004.

9797

% Updated by Steven Krooswyk, April 2006.

9992

% Updated by Steven Krooswyk, April 2006.

9798

9993

9799

9994

9800

fid = fopen(filename, 'r');

9995

fid = fopen(filename, 'r');

9801

9996

9802

9997

9803

% Skip header lines

9998

% Skip header lines

9804

str = ' ';

9999

str = ' ';

9805

n = 0;

10000

n = 0;

9806

while ~strcmp(str(1),'#')

10001

while ~strcmp(str(1),'#')

9807

str = fgetl(fid);

10002

str = fgetl(fid);

9808

if isempty(str)

10003

if isempty(str)

9809

str=' ' ;

10004

str=' ' ;

9810

if n > 1000

10005

if n > 1000

9811

display('error: could not find config line (#)')

10006

display('error: could not find config line (#)')

9812

break

10007

break

9813

end

10008

end

9814

end

10009

end

9815

n = n + 1;

10010

n = n + 1;

9816

end

10011

end

9817

10012

9818

% parse configuration line

10013

% parse configuration line

9819

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

10014

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

9820

p = find(A=='S'); %position of 'S'

10015

p = find(A=='S'); %position of 'S'

9821

units = lower(A(2:p-1)); %units before 'S'

10016

units = lower(A(2:p-1)); %units before 'S'

9822

format = A(p+1:p+2); %format after 'S'

10017

format = A(p+1:p+2); %format after 'S'

9823

10018

9824

% skip any more header lines

10019

% skip any more header lines

9825

%while ~str

10020

%while ~str

9826

10021

9827

nk = 0; % frequency counter

10022

nk = 0; % frequency counter

9828

while 1

10023

while 1

9829

10024

9830

[temp, count] = fscanf(fid, '%f', 1);

10025

[temp, count] = fscanf(fid, '%f', 1);

9831

if count == 0

10026

if count == 0

9832

temp2 = fscanf(fid, '%s', 1);

10027

temp2 = fscanf(fid, '%s', 1);

9833

if ~isempty(temp2), fgetl(fid); continue, end;

10028

if ~isempty(temp2), fgetl(fid); continue, end;

9834

break

10029

break

9835

end

10030

end

9836

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

10031

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

9837

for ni = 1:nport

10032

for ni = 1:nport

9838

for nj = 1:nport

10033

for nj = 1:nport

9839

switch lower(format)

10034

switch lower(format)

9840

case 'ma'

10035

case 'ma'

9841

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10036

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9842

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

10037

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

9843

case 'ri'

10038

case 'ri'

9844

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

10039

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

9845

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10040

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9846

case 'db'

10041

case 'db'

9847

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10042

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9848

M = 10^(db/20);

10043

M = 10^(db/20);

9849

%re = M*cos(ang);

10044

%re = M*cos(ang);

9850

%im = M*sin(ang);

10045

%im = M*sin(ang);

9851

re = M*cos(ang * pi / 180);

10046

re = M*cos(ang * pi / 180);

9852

im = M*sin(ang * pi / 180);

10047

im = M*sin(ang * pi / 180);

9853

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10048

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9854

otherwise

10049

otherwise

9855

error('readdataSnP: Unknown data format');

10050

error('readdataSnP: Unknown data format');

9856

end

10051

end

9857

end

10052

end

9858

end

10053

end

9859

end

10054

end

9860

10055

9861

fclose(fid);

10056

fclose(fid);

9862

10057

9863

% If 2-port then swap S_12 and S_21 per Touchstone spec

10058

% If 2-port then swap S_12 and S_21 per Touchstone spec

9864

if nport == 2

10059

if nport == 2

9865

temp = cs(2,1,:);

10060

temp = cs(2,1,:);

9866

cs(2,1,:) = cs(1,2,:);

10061

cs(2,1,:) = cs(1,2,:);

9867

cs(1,2,:) = temp;

10062

cs(1,2,:) = temp;

9868

end

10063

end

9869

10064

9870

% Update freq units to Hz

10065

% Update freq units to Hz

9871

switch lower(units)

10066

switch lower(units)

9872

case 'hz'

10067

case 'hz'

9873

10068

9874

case 'khz'

10069

case 'khz'

9875

freq=freq.*1e3;

10070

freq=freq.*1e3;

9876

case 'mhz'

10071

case 'mhz'

9877

freq=freq.*1e6;

10072

freq=freq.*1e6;

9878

case 'ghz'

10073

case 'ghz'

9879

freq=freq.*1e9;

10074

freq=freq.*1e9;

9880

end

10075

end

9881

10076

9882

% passivity check

10077

% passivity check

9883

result.freq = freq;

10078

result.freq = freq;

9884

result.cs = cs;

10079

result.cs = cs;

9885

10080

9886

function recolor_plots(ax)

10081

function recolor_plots(ax)

9887

10082

9888

if ~verLessThan('matlab', '8.4.0')

10083

if ~verLessThan('matlab', '8.4.0')

9889

return

10084

return

9890

end

10085

end

9891

colors='brgcmk';

10086

colors='brgcmk';

9892

ch=flipud(get(ax, 'children'));

10087

ch=flipud(get(ax, 'children'));

9893

10088

9894

for k=1:length(ch)

10089

for k=1:length(ch)

9895

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

10090

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

9896

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

10091

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

9897

end

10092

end

9898

legend (ax, 'off');

10093

legend (ax, 'off');

9899

warning('off', 'MATLAB:legend:PlotEmpty');

10094

warning('off', 'MATLAB:legend:PlotEmpty');

9900

set(legend (ax, 'show'), 'interp', 'none');

10095

set(legend (ax, 'show'), 'interp', 'none');

9901

10096

9902

function result = reduce(var1)

10097

function result = reduce(var1)

9903

% --- Reduce 1x1xn array to 1xn (aka squeeze)

10098

% --- Reduce 1x1xn array to 1xn (aka squeeze)

9904

out = zeros(1,length(var1));

10099

out = zeros(1,length(var1));

9905

out(1,:) = var1(1,1,:);

10100

out(1,:) = var1(1,1,:);

9906

result=out;

10101

result=out;

9907

10102

9908

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

10103

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

9909

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

10104

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

9910

% faxis is the frequency array

10105

% faxis is the frequency array

9911

% s21, s11, s22 are the corresponding array of differential parameters

10106

% s21, s11, s22 are the corresponding array of differential parameters

9912

% s21p includes the VFT and Tx filter if include_die=1

10107

% s21p includes the VFT and Tx filter if include_die=1

9913

if nargin<6

10108

if nargin<6

9914

include_die=1;

10109

include_die=1;

9915

end

10110

end

9916

if nargin<5

10111

if nargin<5

9917

mode='dd';

10112

mode='dd';

9918

end

10113

end

9919

10114

9920

s21=chdata.(['s' mode '21_raw']);

10115

s21=chdata.(['s' mode '21_raw']);

9921

s12=chdata.(['s' mode '12_raw']);

10116

s12=chdata.(['s' mode '12_raw']);

9922

s11=chdata.(['s' mode '11_raw']);

10117

s11=chdata.(['s' mode '11_raw']);

9923

s22=chdata.(['s' mode '22_raw']);

10118

s22=chdata.(['s' mode '22_raw']);

9924

faxis=chdata.faxis;

10119

faxis=chdata.faxis;

9925

channel_type=chdata.type;

10120

channel_type=chdata.type;

9926

10121

9927

if strcmpi(mode,'dd')

10122

if strcmpi(mode,'dd')

9928

s11=s11*param.kappa1;

10123

s11=s11*param.kappa1;

9929

s22=s22*param.kappa2;

10124

s22=s22*param.kappa2;

9930

end

10125

end

9931

10126

9932

10127

9933

Z0=param.Z0;

10128

Z0=param.Z0;

9934

%sigma_ACCM_at_tp0 is only used when mode=DC

10129

%sigma_ACCM_at_tp0 is only used when mode=DC

9935

sigma_ACCM_at_tp0=0;

10130

sigma_ACCM_at_tp0=0;

9936

10131

9937

% The following three parameters have possibly different valuesF for TX and

10132

% The following three parameters have possibly different valuesF for TX and

9938

% RX (so can be 2-element vectors).

10133

% RX (so can be 2-element vectors).

9939

R_diepad = param.R_diepad;

10134

R_diepad = param.R_diepad;

9940

10135

9941

%Make TX Package

10136

%Make TX Package

9942

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

10137

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

9943

10138

9944

%Make RX Package

10139

%Make RX Package

9945

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

10140

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

9946

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

10141

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

9947

10142

9948

10143

9949

% p(1 ,1, :)=s11in;

10144

% p(1 ,1, :)=s11in;

9950

% p(2 ,2, :)=s22in;

10145

% p(2 ,2, :)=s22in;

9951

% p(1 ,2, :)=s12in;

10146

% p(1 ,2, :)=s12in;

9952

% p(2 ,1, :)=s21in;

10147

% p(2 ,1, :)=s21in;

9953

%

10148

%

9954

% S=sparameters(p,faxis);

10149

% S=sparameters(p,faxis);

9955

% rfwrite(S,'temp.s4p');

10150

% rfwrite(S,'temp.s4p');

9956

10151

9957

if strcmpi(mode,'dc')

10152

if strcmpi(mode,'dc')

9958

RTX=R_diepad(param.Tx_rd_sel)/2;

10153

RTX=R_diepad(param.Tx_rd_sel)/2;

9959

RRX=R_diepad(param.Rx_rd_sel)/2;

10154

RRX=R_diepad(param.Rx_rd_sel)/2;

9960

Z0gamma=Z0/2;

10155

Z0gamma=Z0/2;

9961

else

10156

else

9962

RTX=R_diepad(param.Tx_rd_sel);

10157

RTX=R_diepad(param.Tx_rd_sel);

9963

RRX=R_diepad(param.Rx_rd_sel);

10158

RRX=R_diepad(param.Rx_rd_sel);

9964

Z0gamma=Z0;

10159

Z0gamma=Z0;

9965

end

10160

end

9966

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

10161

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

9967

gamma_tx=0;

10162

gamma_tx=0;

9968

else

10163

else

9969

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

10164

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

9970

end

10165

end

9971

if OP.IDEAL_RX_TERM

10166

if OP.IDEAL_RX_TERM

9972

gamma_rx=0;

10167

gamma_rx=0;

9973

else

10168

else

9974

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

10169

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

9975

end

10170

end

9976

10171

9977

if OP.INC_PACKAGE==0

10172

if OP.INC_PACKAGE==0

9978

s21p= s21;

10173

s21p= s21;

9979

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

10174

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

9980

else

10175

else

9981

if OP.RX_CALIBRATION == 1 && channel_number == 2

10176

if OP.RX_CALIBRATION == 1 && channel_number == 2

9982

% for calibration do not include the transmitter package

10177

% for calibration do not include the transmitter package

9983

[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

10178

[s11out_rx, s12out_rx, s21out_rx, s22out_rx ] = combines4p( s11, s12, s21, s22, s22out, s12out, s21out, s11out ); %#ok<ASGLU> % s22 is ball side of package

9984

SCH.Frequencies=faxis;

10179

SCH.Frequencies=faxis;

9985

SCH.Parameters(1,1,:)=s11out_rx;

10180

SCH.Parameters(1,1,:)=s11out_rx;

9986

SCH.Parameters(2,2,:)=s22out_rx;

10181

SCH.Parameters(2,2,:)=s22out_rx;

9987

SCH.Parameters(1,2,:)=s12out_rx;

10182

SCH.Parameters(1,2,:)=s12out_rx;

9988

SCH.Parameters(2,1,:)=s21out_rx;

10183

SCH.Parameters(2,1,:)=s21out_rx;

9989

SCH.NumPorts=2;

10184

SCH.NumPorts=2;

9990

SCH.Impedance=100;

10185

SCH.Impedance=100;

9991

%% Equation 93A-18

10186

%% Equation 93A-18

9992

if include_die

10187

if include_die

9993

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);

10188

s21p= s21out_rx.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11out_rx.*gamma_tx - s22out_rx.*gamma_rx -s21out_rx.^2.*gamma_tx.*gamma_rx +s11out_rx.*s22out_rx.*gamma_tx.*gamma_rx);

9994

else

10189

else

9995

s21p=s21out_rx; % if no die we do not want a VTF

10190

s21p=s21out_rx; % if no die we do not want a VTF

9996

end

10191

end

9997

else

10192

else

9998

%% Equations 93A-4 to 93A-7

10193

%% Equations 93A-4 to 93A-7

9999

if ~OP.IDEAL_TX_TERM

10194

if ~OP.IDEAL_TX_TERM

10000

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10195

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10001

end

10196

end

10002

H_t=ones(1,length(faxis)); % .3bj compatibility

10197

H_t=ones(1,length(faxis)); % .3bj compatibility

10003

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10198

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10004

% for RITT testing with good termination as in some instruments

10199

% for RITT testing with good termination as in some instruments

10005

% and tx filter when required

10200

% and tx filter when required

10006

if OP.T_r_filter_type==0

10201

if OP.T_r_filter_type==0

10007

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10202

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10008

else

10203

else

10009

tr=OP.transmitter_transition_time;

10204

tr=OP.transmitter_transition_time;

10010

f9=faxis/1e9;

10205

f9=faxis/1e9;

10011

if OP.T_r_meas_point == 1

10206

if OP.T_r_meas_point == 1

10012

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10207

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10013

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);

10208

H_t=105./(f9.^4*(k*tr)^4 - f9.^3*(k*tr)^3*10i - 45*f9.^2*(k*tr)^2 + f9*(k*tr)*105i + 105);

10014

else

10209

else

10015

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10210

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10016

end

10211

end

10017

10212

10018

end

10213

end

10019

end

10214

end

10020

if strcmpi(mode,'dc')

10215

if strcmpi(mode,'dc')

10021

% 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?

10216

% H_t=ones(1,length(faxis)); % not sure if we need a H_t or not. Is the CM noise correlated to the edge rate?

10022

end

10217

end

10023

if ~OP.IDEAL_RX_TERM

10218

if ~OP.IDEAL_RX_TERM

10024

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10219

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10025

else

10220

else

10026

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10221

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10027

end

10222

end

10028

%% 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 )

10223

%% Equation 93A-18 and part of 93A-1: Ht fix in V290 identified by Bill Kirkland and Ed Frlan ( s21^2 changed to s12*s21 )

10029

if include_die

10224

if include_die

10030

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);

10225

s21p= H_t.*s21.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11.*gamma_tx - s22.*gamma_rx -s21.*s12.*gamma_tx.*gamma_rx +s11.*s22.*gamma_tx.*gamma_rx);

10031

else

10226

else

10032

s21p=s21; % if no die we do not want a VTF

10227

s21p=s21; % if no die we do not want a VTF

10033

end

10228

end

10034

end

10229

end

10035

10230

10036

if strcmpi(mode,'dc')

10231

if strcmpi(mode,'dc')

10037

% compute AC_CM_RMS at tp0

10232

% compute AC_CM_RMS at tp0

10038

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10233

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10039

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10234

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10040

if channel_number == 1

10235

if channel_number == 1

10041

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10236

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10042

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10237

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10043

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)) ;

10238

sigma_ACCM_at_tp0= sqrt(2*param.AC_CM_RMS_TX^2*sum( abs( H_cc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end)) ;

10044

% S=sparameters(p,faxis);

10239

% S=sparameters(p,faxis);

10045

% rfwrite(S,'temp.s4p');

10240

% rfwrite(S,'temp.s4p');

10046

end

10241

end

10047

end

10242

end

10048

10243

10049

SCH.Frequencies=faxis;

10244

SCH.Frequencies=faxis;

10050

SCH.Parameters(1,1,:)=s11;

10245

SCH.Parameters(1,1,:)=s11;

10051

SCH.Parameters(2,2,:)=s22;

10246

SCH.Parameters(2,2,:)=s22;

10052

SCH.Parameters(1,2,:)=s12;

10247

SCH.Parameters(1,2,:)=s12;

10053

SCH.Parameters(2,1,:)=s21;

10248

SCH.Parameters(2,1,:)=s21;

10054

SCH.NumPorts=2;

10249

SCH.NumPorts=2;

10055

if strcmpi(mode,'dc')

10250

if strcmpi(mode,'dc')

10056

SCH.Impedance=25;

10251

SCH.Impedance=25;

10057

else

10252

else

10058

SCH.Impedance=100;

10253

SCH.Impedance=100;

10059

end

10254

end

10060

10255

10061

end

10256

end

10062

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10257

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10063

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10258

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10064

% Creates a time-domain impulse response from frequency-domain IL data.

10259

% Creates a time-domain impulse response from frequency-domain IL data.

10065

% IL does not need to have DC but a corresponding frequency array

10260

% IL does not need to have DC but a corresponding frequency array

10066

% (freq_array) is required.

10261

% (freq_array) is required.

10067

%

10262

%

10068

% Causality is imposed using the Alternating Projections Method. See also:

10263

% Causality is imposed using the Alternating Projections Method. See also:

10069

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10264

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10070

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10265

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10071

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10266

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10072

10267

10073

ILin=IL;

10268

ILin=IL;

10074

fmax=1/time_step/2;

10269

fmax=1/time_step/2;

10075

freq_step=(freq_array(3)-freq_array(2))/1;

10270

freq_step=(freq_array(3)-freq_array(2))/1;

10076

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10271

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10077

if all(IL==0)

10272

if all(IL==0)

10078

%response with all zeros is problematic. set to all eps and avoid interp function

10273

%response with all zeros is problematic. set to all eps and avoid interp function

10079

IL=ones(1,length(fout))*eps;

10274

IL=ones(1,length(fout))*eps;

10080

else

10275

else

10081

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10276

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10082

IL_nan = find(isnan(IL));

10277

IL_nan = find(isnan(IL));

10083

for in=IL_nan

10278

for in=IL_nan

10084

IL(in)=IL(in-1);

10279

IL(in)=IL(in-1);

10085

end

10280

end

10086

end

10281

end

10087

IL = IL(:);

10282

IL = IL(:);

10088

% add padding for time steps

10283

% add padding for time steps

10089

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10284

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10090

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10285

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10091

impulse_response = real(ifft(IL_symmetric));

10286

impulse_response = real(ifft(IL_symmetric));

10092

L = length(impulse_response);

10287

L = length(impulse_response);

10093

t_base = (0:L-1)/(freq_step*L);

10288

t_base = (0:L-1)/(freq_step*L);

10094

10289

10095

original_impulse_response=impulse_response;

10290

original_impulse_response=impulse_response;

10096

% Correct non-causal effects frequently caused by extrapolation of IL

10291

% Correct non-causal effects frequently caused by extrapolation of IL

10097

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10292

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10098

abs_ir=abs(impulse_response);

10293

abs_ir=abs(impulse_response);

10099

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10294

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10100

start_ind = a(1);

10295

start_ind = a(1);

10101

10296

10102

err=inf;

10297

err=inf;

10103

while ~all(impulse_response==0)

10298

while ~all(impulse_response==0)

10104

impulse_response(1:start_ind)=0;

10299

impulse_response(1:start_ind)=0;

10105

impulse_response(floor(L/2):end)=0;

10300

impulse_response(floor(L/2):end)=0;

10106

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10301

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10107

ir_modified = real(ifft(IL_modified));

10302

ir_modified = real(ifft(IL_modified));

10108

delta = abs(impulse_response-ir_modified);

10303

delta = abs(impulse_response-ir_modified);

10109

10304

10110

err_prev = err;

10305

err_prev = err;

10111

err=max(delta)/max(impulse_response);

10306

err=max(delta)/max(impulse_response);

10112

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10307

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10113

break;

10308

break;

10114

end

10309

end

10115

10310

10116

impulse_response=ir_modified;

10311

impulse_response=ir_modified;

10117

end

10312

end

10118

10313

10119

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10314

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10120

10315

10121

if ~OP.ENFORCE_CAUSALITY

10316

if ~OP.ENFORCE_CAUSALITY

10122

impulse_response = original_impulse_response;

10317

impulse_response = original_impulse_response;

10123

end

10318

end

10124

% truncate final samples smaller than 1e-3 of the peak

10319

% truncate final samples smaller than 1e-3 of the peak

10125

ir_peak = max(abs(impulse_response));

10320

ir_peak = max(abs(impulse_response));

10126

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10321

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10127

10322

10128

voltage = impulse_response(1:ir_last);

10323

voltage = impulse_response(1:ir_last);

10129

t_base = t_base(1:ir_last);

10324

t_base = t_base(1:ir_last);

10130

10325

10131

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10326

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10132

10327

10133

function S =s_for_c2(zref,f,cpad)

10328

function S =s_for_c2(zref,f,cpad)

10134

% S is 2 port s parameters out

10329

% S is 2 port s parameters out

10135

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10330

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10136

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10331

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10137

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10332

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10138

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10333

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10139

S=sparameters(S_Parameters,f,zref);

10334

S=sparameters(S_Parameters,f,zref);

10140

10335

10141

function S =s_for_c4(zref,f,cpad)

10336

function S =s_for_c4(zref,f,cpad)

10142

10337

10143

S2 = s_for_c2(zref,f,cpad);

10338

S2 = s_for_c2(zref,f,cpad);

10144

S4P=s2_to_s4(S2.Parameters);

10339

S4P=s2_to_s4(S2.Parameters);

10145

S=sparameters(S4P,f,zref);

10340

S=sparameters(S4P,f,zref);

10146

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10341

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10147

10342

10148

10343

10149

10344

10150

10345

10151

%%

10346

%%

10152

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10347

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10153

% save commmend string

10348

% save commmend string

10154

% for saving from interactive queries

10349

% for saving from interactive queries

10155

10350

10156

10351

10157

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10352

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10158

for i=1:num_next+num_fext

10353

for i=1:num_next+num_fext

10159

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10354

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10160

end

10355

end

10161

cmd_str= [ cmd_str ')'];

10356

cmd_str= [ cmd_str ')'];

10162

10357

10163

10358

10164

%%%%% require the RF tool box

10359

%%%%% require the RF tool box

10165

%%

10360

%%

10166

function [ h ] = savefigs( param, OP )

10361

function [ h ] = savefigs( param, OP )

10167

10362

10168

%% find the figures

10363

%% find the figures

10169

hw = waitbar(0,'Saving figures...');

10364

hw = waitbar(0,'Saving figures...');

10170

h = findobj(0, 'Type', 'figure');

10365

h = findobj(0, 'Type', 'figure');

10171

for ii=1:length(h)

10366

for ii=1:length(h)

10172

10367

10173

figname= get(h(ii), 'Name'); % use the figure name as file name

10368

figname= get(h(ii), 'Name'); % use the figure name as file name

10174

if isempty(strfind(figname,param.base))

10369

if isempty(strfind(figname,param.base))

10175

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10370

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10176

end

10371

end

10177

if verLessThan('matlab', '8.4.0')

10372

if verLessThan('matlab', '8.4.0')

10178

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10373

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10179

else

10374

else

10180

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10375

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10181

end

10376

end

10182

figname = strrep(figname,':','-');

10377

figname = strrep(figname,':','-');

10183

figname = strrep(figname,' ','_');

10378

figname = strrep(figname,' ','_');

10184

if OP.SAVE_FIGURES==1

10379

if OP.SAVE_FIGURES==1

10185

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10380

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10186

end

10381

end

10187

%% get x y data

10382

%% get x y data

10188

if OP.SAVE_FIGURE_to_CSV==1

10383

if OP.SAVE_FIGURE_to_CSV==1

10189

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10384

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10190

M=[]; %ncol=1;

10385

M=[]; %ncol=1;

10191

for nk=1:length(h_L)

10386

for nk=1:length(h_L)

10192

% get x and data for a line.

10387

% get x and data for a line.

10193

x_data=get(h_L(nk),'xdata')';

10388

x_data=get(h_L(nk),'xdata')';

10194

y_data=get(h_L(nk),'ydata')';

10389

y_data=get(h_L(nk),'ydata')';

10195

% .........>> need to get data in the line structure (legend or label) for headers

10390

% .........>> need to get data in the line structure (legend or label) for headers

10196

M=[M; x_data; y_data]; %#ok<AGROW>

10391

M=[M; x_data; y_data]; %#ok<AGROW>

10197

end

10392

end

10198

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10393

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10199

% clear M y x header h_L

10394

% clear M y x header h_L

10200

end

10395

end

10201

waitbar(ii/length(h),hw)

10396

waitbar(ii/length(h),hw)

10202

10397

10203

end

10398

end

10204

10399

10205

close(hw)

10400

close(hw)

10206

10401

10207

%%

10402

%%

10208

function [ h ] = savefigs_png( param, OP )

10403

function [ h ] = savefigs_png( param, OP )

10209

10404

10210

%% find the figures

10405

%% find the figures

10211

hw = waitbar(0,'Saving figures...');

10406

hw = waitbar(0,'Saving figures...');

10212

h = findobj(0, 'Type', 'figure');

10407

h = findobj(0, 'Type', 'figure');

10213

for ii=1:length(h)

10408

for ii=1:length(h)

10214

10409

10215

figname= get(h(ii), 'Name'); % use the figure name as file name

10410

figname= get(h(ii), 'Name'); % use the figure name as file name

10216

if isempty(strfind(figname,param.base))

10411

if isempty(strfind(figname,param.base))

10217

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10412

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10218

end

10413

end

10219

if verLessThan('matlab', '8.4.0')

10414

if verLessThan('matlab', '8.4.0')

10220

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10415

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10221

else

10416

else

10222

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10417

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10223

end

10418

end

10224

figname = strrep(figname,':','-');

10419

figname = strrep(figname,':','-');

10225

figname = strrep(figname,' ','_');

10420

figname = strrep(figname,' ','_');

10226

if OP.SAVE_FIGURES==1

10421

if OP.SAVE_FIGURES==1

10227

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10422

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10228

end

10423

end

10229

%% get x y data

10424

%% get x y data

10230

if OP.SAVE_FIGURE_to_CSV==1

10425

if OP.SAVE_FIGURE_to_CSV==1

10231

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10426

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10232

M=[]; %ncol=1;

10427

M=[]; %ncol=1;

10233

for nk=1:length(h_L)

10428

for nk=1:length(h_L)

10234

% get x and data for a line.

10429

% get x and data for a line.

10235

x_data=get(h_L(nk),'xdata')';

10430

x_data=get(h_L(nk),'xdata')';

10236

y_data=get(h_L(nk),'ydata')';

10431

y_data=get(h_L(nk),'ydata')';

10237

% .........>> need to get data in the line structure (legend or label) for headers

10432

% .........>> need to get data in the line structure (legend or label) for headers

10238

M=[M; x_data; y_data]; %#ok<AGROW>

10433

M=[M; x_data; y_data]; %#ok<AGROW>

10239

end

10434

end

10240

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10435

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10241

% clear M y x header h_L

10436

% clear M y x header h_L

10242

end

10437

end

10243

waitbar(ii/length(h),hw)

10438

waitbar(ii/length(h),hw)

10244

10439

10245

end

10440

end

10246

10441

10247

close(hw)

10442

close(hw)

10248

10443

10249

%%

10444

%%

10250

function pdf_out = scalePDF(pdf,scale_factor)

10445

function pdf_out = scalePDF(pdf,scale_factor)

10251

pdf_out=pdf;

10446

pdf_out=pdf;

10252

pdf_out.Min=floor(pdf.Min*scale_factor);

10447

pdf_out.Min=floor(pdf.Min*scale_factor);

10253

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10448

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10254

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10449

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10255

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10450

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10256

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10451

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10257

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10452

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10258

function t_params = stot(s_params)

10453

function t_params = stot(s_params)

10259

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10454

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10260

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10455

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10261

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10456

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10262

delta = (s11.*s22-s12.*s21);

10457

delta = (s11.*s22-s12.*s21);

10263

s21(s21==0)=eps;

10458

s21(s21==0)=eps;

10264

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10459

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10265

10460

10266

function csv_string = str2csv(c)

10461

function csv_string = str2csv(c)

10267

% convert a cell array of strings to a csv string

10462

% convert a cell array of strings to a csv string

10268

cell_tmp = cell(2, length(c));

10463

cell_tmp = cell(2, length(c));

10269

cell_tmp(1,:)=c;

10464

cell_tmp(1,:)=c;

10270

cell_tmp(2,:) = {','};

10465

cell_tmp(2,:) = {','};

10271

cell_tmp{2,end} = '';

10466

cell_tmp{2,end} = '';

10272

csv_string=strcat(cell_tmp{:});

10467

csv_string=strcat(cell_tmp{:});

10273

10468

10274

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10469

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10275

f_GHz=f/1e9;

10470

f_GHz=f/1e9;

10276

%% Equation 93A-10 %%

10471

%% Equation 93A-10 %%

10277

gamma_1 = gamma_coeff(2)*(1+1i);

10472

gamma_1 = gamma_coeff(2)*(1+1i);

10278

%% Equation 93A-11 %%

10473

%% Equation 93A-11 %%

10279

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10474

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10280

%% Equation 93A-9 %%

10475

%% Equation 93A-9 %%

10281

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10476

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10282

gamma(f_GHz==0) = gamma_coeff(1);

10477

gamma(f_GHz==0) = gamma_coeff(1);

10283

10478

10284

%% Equation 93A-12 %%

10479

%% Equation 93A-12 %%

10285

if d==0

10480

if d==0

10286

%force matched impedance if length is 0

10481

%force matched impedance if length is 0

10287

%otherwise divide by zero can occur if Z_c=0

10482

%otherwise divide by zero can occur if Z_c=0

10288

rho_rl=0;

10483

rho_rl=0;

10289

else

10484

else

10290

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10485

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10291

end

10486

end

10292

10487

10293

exp_gamma_d = exp(-d*gamma);

10488

exp_gamma_d = exp(-d*gamma);

10294

%% Equations 93A-13 and 93A-14 %%

10489

%% Equations 93A-13 and 93A-14 %%

10295

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10490

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10296

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10491

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10297

s12 = s21;

10492

s12 = s21;

10298

s22 = s11;

10493

s22 = s11;

10299

10494

10300

function s_params = ttos(t_params)

10495

function s_params = ttos(t_params)

10301

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10496

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10302

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10497

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10303

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10498

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10304

delta = t11.*t22-t21.*t12;

10499

delta = t11.*t22-t21.*t12;

10305

t11(t11==0)=eps;

10500

t11(t11==0)=eps;

10306

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10501

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10307

10502

10308

function [out_var,varg_out]=varargin_extractor(varargin)

10503

function [out_var,varg_out]=varargin_extractor(varargin)

10309

10504

10310

if isempty(varargin)

10505

if isempty(varargin)

10311

out_var=[];

10506

out_var=[];

10312

varg_out={};

10507

varg_out={};

10313

else

10508

else

10314

out_var=varargin{1};

10509

out_var=varargin{1};

10315

varg_out=varargin;

10510

varg_out=varargin;

10316

varg_out(1)=[];

10511

varg_out(1)=[];

10317

end

10512

end

10318

10513

10319

10514

10320

function results= vma(PR, M)

10515

function results= vma(PR, M)

10321

% PR=sbr.Data;

10516

% PR=sbr.Data;

10322

% M=32;

10517

% M=32;

10323

% PR is the pulse response

10518

% PR is the pulse response

10324

% M is samples per UI

10519

% M is samples per UI

10325

[ seq, syms, syms_nrz ] = PRBS13Q( );

10520

[ seq, syms, syms_nrz ] = PRBS13Q( );

10326

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10521

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10327

symbols=seq;

10522

symbols=seq;

10328

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10523

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10329

% start end symbols index for 7 3's and 6 0's

10524

% start end symbols index for 7 3's and 6 0's

10330

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10525

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10331

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10526

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10332

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10527

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10333

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10528

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10334

% superposition code

10529

% superposition code

10335

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10530

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10336

Bit_stream_response=filter(PR,1, shifting_vector);

10531

Bit_stream_response=filter(PR,1, shifting_vector);

10337

% find center of 3's and 0's

10532

% find center of 3's and 0's

10338

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10533

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10339

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10534

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10340

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10535

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10341

% hold on

10536

% hold on

10342

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10537

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10343

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10538

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10344

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10539

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10345

VMA= P_3 - P_0;

10540

VMA= P_3 - P_0;

10346

results.P_3=P_3;

10541

results.P_3=P_3;

10347

results.P_0=P_0;

10542

results.P_0=P_0;

10348

results.VMA=VMA;

10543

results.VMA=VMA;

10349

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10544

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10350

10545

10351

%slope of the 2 sample points around vref crossing

10546

%slope of the 2 sample points around vref crossing

10352

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10547

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10353

%x-intercept for the line

10548

%x-intercept for the line

10354

b1=eye_contour(x_in,1)-m1*x_in;

10549

b1=eye_contour(x_in,1)-m1*x_in;

10355

% drawing a horizontal line through vref so slope = 0

10550

% drawing a horizontal line through vref so slope = 0

10356

m2=0;

10551

m2=0;

10357

%special case for horizontal line, b=y

10552

%special case for horizontal line, b=y

10358

b2=vref;

10553

b2=vref;

10359

%the x-value of line intersection = (b2-b1)/(m1-m2)

10554

%the x-value of line intersection = (b2-b1)/(m1-m2)

10360

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10555

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10361

%And usually vref is 0, so it further reduces to -b1/m1

10556

%And usually vref is 0, so it further reduces to -b1/m1

10362

line_intersection=(b2-b1)/(m1-m2);

10557

line_intersection=(b2-b1)/(m1-m2);

10363

10558

10364

10559

10365

10560

10366

10561

10367

10562

10368

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10563

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10369

% helper function to read parameter values from XLS file. Uses names to find values.

10564

% helper function to read parameter values from XLS file. Uses names to find values.

10370

if nargin<3, eval_if_string=0; end

10565

if nargin<3, eval_if_string=0; end

10371

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10566

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10372

if numel(row)*numel(col)==0

10567

if numel(row)*numel(col)==0

10373

if nargin<4

10568

if nargin<4

10374

missingParameter(param_name);

10569

missingParameter(param_name);

10375

else

10570

else

10376

p = default_value;

10571

p = default_value;

10377

end

10572

end

10378

elseif numel(row)*numel(col)>1

10573

elseif numel(row)*numel(col)>1

10379

% if there are several occurrences, use the first, but warn

10574

% if there are several occurrences, use the first, but warn

10380

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10575

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10381

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10576

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10382

error('COM:XLS_parameter:MultipleOccurrence', ...

10577

error('COM:XLS_parameter:MultipleOccurrence', ...

10383

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10578

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10384

p=param_sheet{row(1), col(1)+1};

10579

p=param_sheet{row(1), col(1)+1};

10385

else

10580

else

10386

p=param_sheet{row, col+1};

10581

p=param_sheet{row, col+1};

10387

end

10582

end

10388

if ischar(p) && eval_if_string

10583

if ischar(p) && eval_if_string

10389

p=eval(p);

10584

p=eval(p);

10390

end

10585

end

10391

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10586

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10392

if OP.SAVE_KEYWORD_FILE

10587

if OP.SAVE_KEYWORD_FILE

10393

10588

10394

if nargin<3 || ~exist('default_value','var')

10589

if nargin<3 || ~exist('default_value','var')

10395

default_value=p;

10590

default_value=p;

10396

end

10591

end

10397

if isempty(default_value)

10592

if isempty(default_value)

10398

default_value='-';

10593

default_value='-';

10399

end

10594

end

10400

%%

10595

%%

10401

% Get call-stack info:

10596

% Get call-stack info:

10402

stDebug = dbstack;

10597

stDebug = dbstack;

10403

callerFileName = stDebug(2).file;

10598

callerFileName = stDebug(2).file;

10404

callerLineNumber = stDebug(2).line;

10599

callerLineNumber = stDebug(2).line;

10405

% Open caller file:

10600

% Open caller file:

10406

fCaller = fopen(callerFileName);

10601

fCaller = fopen(callerFileName);

10407

% Iterate through lines to get to desired line number:

10602

% Iterate through lines to get to desired line number:

10408

for iLine = 1 : callerLineNumber

10603

for iLine = 1 : callerLineNumber

10409

% Read current line of text:

10604

% Read current line of text:

10410

currLine = fgetl(fCaller);

10605

currLine = fgetl(fCaller);

10411

end

10606

end

10412

% (currLine) now reflects calling desired code: display this code:

10607

% (currLine) now reflects calling desired code: display this code:

10413

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10608

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10414

% Close caller file:

10609

% Close caller file:

10415

left_side=currLine(1:strfind(currLine,'=')-1);

10610

left_side=currLine(1:strfind(currLine,'=')-1);

10416

cmt_side=currLine(strfind(currLine,'%')+1:end);

10611

cmt_side=currLine(strfind(currLine,'%')+1:end);

10417

if isempty(cmt_side), cmt_side=' ';end

10612

if isempty(cmt_side), cmt_side=' ';end

10418

fclose(fCaller);

10613

fclose(fCaller);

10419

10614

10420

if ~ischar(default_value)

10615

if ~ischar(default_value)

10421

default_str=sprintf('%g ',default_value);

10616

default_str=sprintf('%g ',default_value);

10422

else

10617

else

10423

default_str=default_value;

10618

default_str=default_value;

10424

end

10619

end

10425

if ~isfile('keyworklog.mat')

10620

if ~isfile('keyworklog.mat')

10426

save_p=param_name;

10621

save_p=param_name;

10427

save_d=default_str;

10622

save_d=default_str;

10428

save_r=left_side;

10623

save_r=left_side;

10429

save_c=cmt_side;

10624

save_c=cmt_side;

10430

param_name = {'keyword'};

10625

param_name = {'keyword'};

10431

default_str = {'default'};

10626

default_str = {'default'};

10432

left_side={'matlab variable'};

10627

left_side={'matlab variable'};

10433

cmt_side={'info'};

10628

cmt_side={'info'};

10434

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10629

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10435

param_name=save_p;

10630

param_name=save_p;

10436

default_str=save_d;

10631

default_str=save_d;

10437

left_side=save_r;

10632

left_side=save_r;

10438

cmt_side=save_c;

10633

cmt_side=save_c;

10439

data=load('keyworklog.mat');

10634

data=load('keyworklog.mat');

10440

else

10635

else

10441

load('keyworklog.mat');

10636

load('keyworklog.mat');

10442

end

10637

end

10443

data.left_side = [ data.left_side; left_side];

10638

data.left_side = [ data.left_side; left_side];

10444

data.param_name = [data.param_name; param_name];

10639

data.param_name = [data.param_name; param_name];

10445

data.default_str = [data.default_str; default_str ];

10640

data.default_str = [data.default_str; default_str ];

10446

data.cmt_side = [ data.cmt_side; cmt_side];

10641

data.cmt_side = [ data.cmt_side; cmt_side];

10447

if length(data.default_str)~=length(data.default_str)

10642

if length(data.default_str)~=length(data.default_str)

10448

a=1;

10643

a=1;

10449

end

10644

end

10450

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10645

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10451

save('keyworklog.mat','data');

10646

save('keyworklog.mat','data');

10452

writetable(T,[ 'keywords_' date '.csv' ]);

10647

writetable(T,[ 'keywords_' date '.csv' ]);

10453

end

10648

end

10454

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10649

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10455

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10650

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10456

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10651

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10457

10652

10458

found=1;

10653

found=1;

10459

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10654

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10460

if numel(row)*numel(col)==0

10655

if numel(row)*numel(col)==0

10461

p = 0;

10656

p = 0;

10462

found=0;

10657

found=0;

10463

elseif numel(row)*numel(col)>1

10658

elseif numel(row)*numel(col)>1

10464

% if there are several occurrences, use the first, but warn

10659

% if there are several occurrences, use the first, but warn

10465

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10660

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10466

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10661

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10467

error('COM:XLS_parameter:MultipleOccurrence', ...

10662

error('COM:XLS_parameter:MultipleOccurrence', ...

10468

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10663

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10469

p=param_sheet{row(1), col(1)+1};

10664

p=param_sheet{row(1), col(1)+1};

10470

else

10665

else

10471

p=param_sheet{row, col+1};

10666

p=param_sheet{row, col+1};

10472

end

10667

end

10473

if ischar(p)

10668

if ischar(p)

10474

p=eval(p);

10669

p=eval(p);

10475

end

10670

end

10476

function zzz_list_of_changes

10671

function zzz_list_of_changes

10477

% structures:

10672

% structures:

10478

% chdata(i)

10673

% chdata(i)

10479

% i= 1 --> THRU index

10674

% i= 1 --> THRU index

10480

% i= 2, num_fext+1 --> FEXT channel index

10675

% i= 2, num_fext+1 --> FEXT channel index

10481

% i= num_fext+2, num_next+num_fext+1

10676

% i= num_fext+2, num_next+num_fext+1

10482

% base: name of THRU file

10677

% base: name of THRU file

10483

% A: amplitude

10678

% A: amplitude

10484

% type: 'THRU', 'NEXT', or 'FEXT'

10679

% type: 'THRU', 'NEXT', or 'FEXT'

10485

% ftr: Rise time frequency

10680

% ftr: Rise time frequency

10486

% fmaxi: max number of frequency points

10681

% fmaxi: max number of frequency points

10487

% faxis: frequency array [Hz]

10682

% faxis: frequency array [Hz]

10488

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10683

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10489

% sdd22: differential RL

10684

% sdd22: differential RL

10490

% sdd11: differential RL

10685

% sdd11: differential RL

10491

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10686

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10492

% sdd21f: raw differential IL not filtered use for FD plots

10687

% sdd21f: raw differential IL not filtered use for FD plots

10493

% added output_args.peak_uneq_pulse_mV

10688

% added output_args.peak_uneq_pulse_mV

10494

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10689

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10495

% added: tap c(-2) c(2) and c(3)

10690

% added: tap c(-2) c(2) and c(3)

10496

% added: g_DC_HP and f_HP_PZ

10691

% added: g_DC_HP and f_HP_PZ

10497

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10692

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10498

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10693

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10499

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10694

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10500

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10695

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10501

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10696

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10502

% fixed INCLUDE_CTLE=0 to really remove from computation

10697

% fixed INCLUDE_CTLE=0 to really remove from computation

10503

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10698

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10504

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10699

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10505

% r162 tx and rx package impedance {Zc)

10700

% r162 tx and rx package impedance {Zc)

10506

% r162a Gaussian equation corrected

10701

% r162a Gaussian equation corrected

10507

% r163 cast snr_tx with package test case

10702

% r163 cast snr_tx with package test case

10508

% r164 fix pdf for very low noise and lo pass filter enhancements

10703

% r164 fix pdf for very low noise and lo pass filter enhancements

10509

% r164 add zero gain at nqyist CTLE as in CL12e

10704

% r164 add zero gain at nqyist CTLE as in CL12e

10510

% r165 add simpler congfig command called FORCE_TR (force risetime)

10705

% r165 add simpler congfig command called FORCE_TR (force risetime)

10511

% r200 cm3 and cm4 added cp3 removed

10706

% r200 cm3 and cm4 added cp3 removed

10512

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10707

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10513

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10708

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10514

% r200 improved phase interpolation for return loss time conversion

10709

% r200 improved phase interpolation for return loss time conversion

10515

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10710

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10516

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10711

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10517

% r200c missed on fix for interpolation

10712

% r200c missed on fix for interpolation

10518

% r210 new ERL with time gating function

10713

% r210 new ERL with time gating function

10519

% r224 update ERL with from D3.1

10714

% r224 update ERL with from D3.1

10520

% r226 fix s2p reading problem

10715

% r226 fix s2p reading problem

10521

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10716

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10522

% Fix Rx calibration issue

10717

% Fix Rx calibration issue

10523

% added ERL limit and Nd

10718

% added ERL limit and Nd

10524

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10719

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10525

% INC_PACKAGE=0 not fully supported message

10720

% INC_PACKAGE=0 not fully supported message

10526

% if N=0 use TDR_duration

10721

% if N=0 use TDR_duration

10527

% red display text for fail ERL and COM

10722

% red display text for fail ERL and COM

10528

% r228 fixed ERL pass fail report, default Grr_limit to 1

10723

% r228 fixed ERL pass fail report, default Grr_limit to 1

10529

% r230 add rx ffe

10724

% r230 add rx ffe

10530

% r231 change crosstalk noise to icn like to speed things up

10725

% r231 change crosstalk noise to icn like to speed things up

10531

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10726

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10532

% 1e-5mof-

10727

% 1e-5mof-

10533

% r232 fix default for Rx eq so old spead sheets work

10728

% r232 fix default for Rx eq so old spead sheets work

10534

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10729

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10535

% r235 adding dfe quantization changed to normalized DFE taps reported

10730

% r235 adding dfe quantization changed to normalized DFE taps reported

10536

% r236 adding ffe gain loop and resample after RxFFE

10731

% r236 adding ffe gain loop and resample after RxFFE

10537

% r240 added output for C2M and setting defaults for some FFE eq

10732

% r240 added output for C2M and setting defaults for some FFE eq

10538

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10733

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10539

% r250 adding more complex package

10734

% r250 adding more complex package

10540

% r251 post cursor fix for DFE in force() and ffe backoff

10735

% r251 post cursor fix for DFE in force() and ffe backoff

10541

% r251 remove TDR threshold noise filter

10736

% r251 remove TDR threshold noise filter

10542

% r252 add rx FFE filter to receiver noise filter

10737

% r252 add rx FFE filter to receiver noise filter

10543

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10738

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10544

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10739

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10545

% r254 precursor check fix in optimize_fom % mod fix in force

10740

% r254 precursor check fix in optimize_fom % mod fix in force

10546

% r254 help to align columns in csv file

10741

% r254 help to align columns in csv file

10547

% r254 accept syntax for 2 tline flex package model

10742

% r254 accept syntax for 2 tline flex package model

10548

% r256 speed up optimize FOM

10743

% r256 speed up optimize FOM

10549

% r256 fix problem reading in config file from q/a

10744

% r256 fix problem reading in config file from q/a

10550

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10745

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10551

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10746

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10552

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10747

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10553

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10748

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10554

% r258 CDR switch 'MM' or 'mod-MM'

10749

% r258 CDR switch 'MM' or 'mod-MM'

10555

% r258 correction for asymentirc tx/Rx packages

10750

% r258 correction for asymentirc tx/Rx packages

10556

% r258 revamped display results display window

10751

% r258 revamped display results display window

10557

% r259 fix problem if Min_VEO is set in spreadsheet.

10752

% r259 fix problem if Min_VEO is set in spreadsheet.

10558

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10753

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10559

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10754

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10560

% r259 putting COM_db and IL last in output to terminal

10755

% r259 putting COM_db and IL last in output to terminal

10561

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10756

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10562

% r259 use N_bx for ERL rather than Nb (ndfe))

10757

% r259 use N_bx for ERL rather than Nb (ndfe))

10563

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10758

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10564

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10759

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10565

% r260 used eta_0 PSD equation for sigma_n

10760

% r260 used eta_0 PSD equation for sigma_n

10566

% r260 fix IL graph legend to w/pkg and Tr

10761

% r260 fix IL graph legend to w/pkg and Tr

10567

% r260 define tfx for each port

10762

% r260 define tfx for each port

10568

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10763

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10569

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10764

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10570

% r262 reset on exit default text interpreter to tex

10765

% r262 reset on exit default text interpreter to tex

10571

% r262 localize run timer (John Buck 1/17/19)

10766

% r262 localize run timer (John Buck 1/17/19)

10572

% r262 set db as internal function in force to avoid tool box

10767

% r262 set db as internal function in force to avoid tool box

10573

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10768

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10574

% r263 added to output_args RL structure and report "struct" in csv file

10769

% r263 added to output_args RL structure and report "struct" in csv file

10575

% r264 added EW estimate

10770

% r264 added EW estimate

10576

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10771

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10577

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10772

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10578

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10773

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10579

% r269 changed param.N_bmax to param.N_f

10774

% r269 changed param.N_bmax to param.N_f

10580

% r270 implement JingBo Li's and Howard Heck's floating tap method

10775

% r270 implement JingBo Li's and Howard Heck's floating tap method

10581

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10776

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10582

% r270 added c_0 and c_1 for CA in add_brd

10777

% r270 added c_0 and c_1 for CA in add_brd

10583

% r272 fixed version syntax problem in output_args RL report

10778

% r272 fixed version syntax problem in output_args RL report

10584

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10779

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10585

% r272 removed eye width report if doing a Rx calibration

10780

% r272 removed eye width report if doing a Rx calibration

10586

% r273 better alignment and control for ICN reporting

10781

% r273 better alignment and control for ICN reporting

10587

% r273 fixed PSXTK graph

10782

% r273 fixed PSXTK graph

10588

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10783

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10589

% 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)

10784

% r276 go back to reporting channel IL results (output_args.IL_dB_channel_only_at_Fnq) with board added read_s4p_files (as in r270)

10590

% 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

10785

% r276 chdata(i).Aicn=param.a_icn_fext should have been chdata(i).Aicn=param.a_icn_next for the next selection. Since in most spec's they are the same there is little no impact in results

10591

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10786

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10592

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10787

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10593

% r276 C_1 was instantiated as C_0. This was fixed

10788

% r276 C_1 was instantiated as C_0. This was fixed

10594

% r276 fixed rounding problem in reporting of loss at f_nq

10789

% r276 fixed rounding problem in reporting of loss at f_nq

10595

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10790

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10596

% r277 added nv for deterining steady state voltage for fitting compatibility

10791

% r277 added nv for deterining steady state voltage for fitting compatibility

10597

% r278 added b_min to support asymmetric bmax

10792

% r278 added b_min to support asymmetric bmax

10598

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10793

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10599

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10794

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10600

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10795

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10601

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10796

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10602

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10797

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10603

% 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

10798

% r292 eq. 93A-19 and 93-20 code implementation bug when include .3by change% to fix edge rate equation 93A-46 (h_T). no effect if Rd=50 or IL > 5 dB

10604

% r292 H_t implemented in s21_pkg

10799

% r292 H_t implemented in s21_pkg

10605

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10800

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10606

% r292 add GDC_MIN to optimize_FOM

10801

% r292 add GDC_MIN to optimize_FOM

10607

% r293 fix if ndfe-0 and ERL only and s2p issue

10802

% r293 fix if ndfe-0 and ERL only and s2p issue

10608

% r293a investigate the Tukey filtering

10803

% r293a investigate the Tukey filtering

10609

% r293a if fix if bmin is missing

10804

% r293a if fix if bmin is missing

10610

% r294 fix problems reading s2p files for ERL computation

10805

% r294 fix problems reading s2p files for ERL computation

10611

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10806

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10612

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10807

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10613

% r294 add gdc and gdc2 range limitations

10808

% r294 add gdc and gdc2 range limitations

10614

% r295 add VEC Pass threshold

10809

% r295 add VEC Pass threshold

10615

% r295 removed close force all. Tagged all figures with "COM"

10810

% r295 removed close force all. Tagged all figures with "COM"

10616

% r295 consolidated print in new function "end_display_control"

10811

% r295 consolidated print in new function "end_display_control"

10617

% r295 report pre/pmax for Txffe

10812

% r295 report pre/pmax for Txffe

10618

% r295 speed up test cases by not re-reading in s4p files

10813

% r295 speed up test cases by not re-reading in s4p files

10619

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10814

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10620

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10815

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10621

% r310 refine VEC and EH for C2M from Adam Gregory in

10816

% r310 refine VEC and EH for C2M from Adam Gregory in

10622

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10817

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10623

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10818

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10624

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10819

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10625

% r311 added RILN

10820

% r311 added RILN

10626

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10821

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10627

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10822

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10628

% r316 remove DC computation for RX Calibration loops

10823

% r316 remove DC computation for RX Calibration loops

10629

% r317 for SAVE_TD to include EQ and unEQ FIR

10824

% r317 for SAVE_TD to include EQ and unEQ FIR

10630

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10825

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10631

% 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

10826

% r318 if min_VEO_test fails to find a solution the loop is restarted with min_VEO_test to near zero. Makes sure COM returns results

10632

% r320 fixed RX_CALIBRATION which was broken in r310

10827

% r320 fixed RX_CALIBRATION which was broken in r310

10633

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10828

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10634

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10829

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10635

% r320 removed external feature and replace with TDMODE

10830

% r320 removed external feature and replace with TDMODE

10636

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10831

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10637

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10832

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10638

% r335 fixed typo in when processing the bessel thompson filter option

10833

% r335 fixed typo in when processing the bessel thompson filter option

10639

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10834

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10640

% r335 compute and report CD_CM_RMS

10835

% r335 compute and report CD_CM_RMS

10641

% r335 fixed where output_arg is save i.e. move to end

10836

% r335 fixed where output_arg is save i.e. move to end

10642

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10837

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10643

% r335 change raw IL plot to not include boards

10838

% r335 change raw IL plot to not include boards

10644

% r335 set T_0 to zero if not C2M

10839

% r335 set T_0 to zero if not C2M

10645

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10840

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10646

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10841

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10647

% r335 TD_RILN changes from Hansel Dsilva

10842

% r335 TD_RILN changes from Hansel Dsilva

10648

% r335 Fixed sigma_N for RxFFE

10843

% r335 Fixed sigma_N for RxFFE

10649

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10844

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10650

% r335 added c(2) and C(3) back to read_ParamConfigFile

10845

% r335 added c(2) and C(3) back to read_ParamConfigFile

10651

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10846

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10652

% r335 corrected GDC_MIN per 0.3ck D2.3

10847

% r335 corrected GDC_MIN per 0.3ck D2.3

10653

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10848

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10654

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10849

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10655

% r370 speed up

10850

% r370 speed up

10656

% r370 fix for floating tap missing locations

10851

% r370 fix for floating tap missing locations

10657

% r370 variable Tx FFE taps

10852

% r370 variable Tx FFE taps

10658

% r370 package die load with ladder circuit

10853

% r370 package die load with ladder circuit

10659

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10854

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10660

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10855

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10661

% r380 added capabablity to enable a raised cosine Rx filter0

10856

% r380 added capabablity to enable a raised cosine Rx filter0

10662

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10857

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10663

% r380 added plot for VTF

10858

% r380 added plot for VTF

10664

% r385 added capability for additional Tx FFE per package

10859

% r385 added capability for additional Tx FFE per package

10665

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10860

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10666

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10861

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10667

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10862

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10668

% r389 Improvement by A. Ran for reporting loss at Nq

10863

% r389 Improvement by A. Ran for reporting loss at Nq

10669

% r389 Fixed typo: changed VIM to VMP

10864

% r389 Fixed typo: changed VIM to VMP

10670

% r400 fixed PR with zero pad extension

10865

% r400 fixed PR with zero pad extension

10671

% r400 keyword MLSE and SNRADJ_EQUA for future work

10866

% r400 keyword MLSE and SNRADJ_EQUA for future work

10672

% r400 replaced function db with instances of 20*log10(abs(...))

10867

% r400 replaced function db with instances of 20*log10(abs(...))

10673

% r410 widen voltage distriution for normal_dist doubled max Q

10868

% r410 widen voltage distriution for normal_dist doubled max Q

10674

% r410 improve reading in of config files

10869

% r410 improve reading in of config files

10675

% r410 renormalize s-parameter if not 50 ohm ref

10870

% r410 renormalize s-parameter if not 50 ohm ref

10676

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10871

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10677

% r410 remove RL from output_args bc not need and too much storage allocation

10872

% r410 remove RL from output_args bc not need and too much storage allocation

10678

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10873

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10679

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10874

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10680

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10875

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10681

% r420 updade force to account for pulse responces with short delays in force

10876

% r420 updade force to account for pulse responces with short delays in force

10682

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10877

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10683

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10878

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10684

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10879

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10685

% r420 Wiener-Kofp MMSE optimization for RxFFE

10880

% r420 Wiener-Kofp MMSE optimization for RxFFE

10686

% r430 first pass at healey_3dj_01_2401

10881

% r430 first pass at healey_3dj_01_2401

10687

% r430 RxFFE fixed taps

10882

% r430 RxFFE fixed taps

10688

% r440 RxffE fixed tap index corrections and floating taps

10883

% r440 RxffE fixed tap index corrections and floating taps

10689

% r440 first pass implemenation of MLSE U3

10884

% r440 first pass implemenation of MLSE U3

10690

10885