File Comparison Report

C:\Users\richardm\OneDrive - Samtec\COM\COM\src\com_ieee8023_93a_470beta3.m vs. C:\Users\richardm\OneDrive - Samtec\COM\COM\src\com_ieee8023_93a_470beta1.m

richardm

28-Oct-2024

Files

Left FileRight File
File namecom_ieee8023_93a_470beta3com_ieee8023_93a_470beta1
File pathC:\Users\richardm\OneDrive - Samtec\COM\COM\srcC:\Users\richardm\OneDrive - Samtec\COM\COM\src
Last modified28-Oct-2024 10:51:5312-Aug-2024 14:38: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.

2

% This is NOT an official IEEE document.

3

%% Implementation example of annex 93A IEEE Std 802.3

3

%% Implementation example of annex 93A IEEE Std 802.3

4

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

4

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

5

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

5

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

6

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

6

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

7

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

7

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

8

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

8

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

9

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

9

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

10

% will ask for each of the files interactively.opupu

10

% will ask for each of the files interactively.opupu

11

%

11

%

12

% This program is intended for the development of standard specifications

12

% This program is intended for the development of standard specifications

13

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

13

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

14

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

14

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

15

% original proposal for COM may be found at

15

% original proposal for COM may be found at

16

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

16

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

17

% from the following authors and affiliations in 2012.

17

% from the following authors and affiliations in 2012.

18

% Richard Mellitz, Intel Corporation

18

% Richard Mellitz, Intel Corporation

19

% Charles Moore, Avago Technologies

19

% Charles Moore, Avago Technologies

20

% Mike Dudek, QLogic Corporation

20

% Mike Dudek, QLogic Corporation

21

% Mike Peng Li, Altera Corporation

21

% Mike Peng Li, Altera Corporation

22

% Adee Ran, Intel Corporation

22

% Adee Ran, Intel Corporation

23

%

23

%

24

% Some of the authors and Contributors:

24

% Some of the authors and Contributors:

25

% Adee Ran

25

% Adee Ran

26

% Richard Mellitz

26

% Richard Mellitz

27

% Yasuo Hidaka

27

% Yasuo Hidaka

28

% John Ewen

28

% John Ewen

29

% Bill Kirkland

29

% Bill Kirkland

30

% Adam Gregory

30

% Adam Gregory

31

% Howard Heck

31

% Howard Heck

32

% Jingbo Li

32

% Jingbo Li

33

% Adam Healey

33

% Adam Healey

34

% Matt Brown

34

% Matt Brown

35

% Sameh Elnagar

35

% Sameh Elnagar

36

% Hossein Shakiba

36

% Hossein Shakiba

37

zzz_list_of_changes()

37

zzz_list_of_changes()

38

38

39

%% Opening Preface

39

%% Opening Preface

40

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

40

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

41

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

41

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

42

try % version number at end of call string

42

try % version number at end of call string

43

cmdfile=mfilename;

43

cmdfile=mfilename;

44

hindx=strfind(mfilename,'_');

44

hindx=strfind(mfilename,'_');

45

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

45

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

46

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

46

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

47

catch

47

catch

48

output_args.code_revision ='';

48

output_args.code_revision ='';

49

end

49

end

50

teststr='';

50

teststr='';

51

OP.TESTING=0;

51

OP.TESTING=0;

52

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

52

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

53

teststr='testing';

53

teststr='testing';

54

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

54

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

55

htest = msgbox(testmsg);

55

htest = msgbox(testmsg);

56

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

56

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

57

end

57

end

58

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

58

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

59

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

59

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

60

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

60

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

61

t0=tic;

61

t0=tic;

62

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

62

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

63

% reset to tex on exit

63

% reset to tex on exit

64

%% file_setup

64

%% file_setup

65

%%

65

%%

66

% need to see what happens for version 8

66

% need to see what happens for version 8

67

if verLessThan('matlab', '7.4.1')

67

if verLessThan('matlab', '7.4.1')

68

error('Matlab version 7.4 or higher required')

68

error('Matlab version 7.4 or higher required')

69

end

69

end

70

70

71

results=[];

71

results=[];

72

72

73

%% New Command Line parser

73

%% New Command Line parser

74

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

74

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

75

75

76

76

77

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

77

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

78

if isempty(config_file)

78

if isempty(config_file)

79

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

79

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

80

if isempty(config_file)

80

if isempty(config_file)

81

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

81

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

82

else

82

else

83

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

83

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

84

config_file=[cname cext];

84

config_file=[cname cext];

85

end

85

end

86

if config_file==0

86

if config_file==0

87

% cancel - exit gracefully

87

% cancel - exit gracefully

88

return;

88

return;

89

end

89

end

90

config_file = fullfile(config_file_path, config_file);

90

config_file = fullfile(config_file_path, config_file);

91

end

91

end

92

output_args.config_file = config_file;

92

output_args.config_file = config_file;

93

OP.SAVE_KEYWORD_FILE=0;

93

OP.SAVE_KEYWORD_FILE=0;

94

if OP.SAVE_KEYWORD_FILE

94

if OP.SAVE_KEYWORD_FILE

95

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

95

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

96

delete('keyworklog.mat');

96

delete('keyworklog.mat');

97

end

97

end

98

end

98

end

99

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

99

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

100

if OP.CONFIG2MAT_ONLY

100

if OP.CONFIG2MAT_ONLY

101

return;

101

return;

102

end

102

end

103

if isempty(num_fext)

103

if isempty(num_fext)

104

if OP.RX_CALIBRATION

104

if OP.RX_CALIBRATION

105

num_fext=1;

105

num_fext=1;

106

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

106

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

107

else

107

else

108

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

108

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

109

num_fext=1;

109

num_fext=1;

110

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

110

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

111

elseif ~OP.ERL_ONLY

111

elseif ~OP.ERL_ONLY

112

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

112

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

113

else

113

else

114

num_fext=0;

114

num_fext=0;

115

end

115

end

116

end

116

end

117

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

117

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

118

end

118

end

119

if isempty(num_next)

119

if isempty(num_next)

120

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

120

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

121

num_next=0;

121

num_next=0;

122

else

122

else

123

if OP.RX_CALIBRATION

123

if OP.RX_CALIBRATION

124

num_next=0;

124

num_next=0;

125

elseif ~OP.ERL_ONLY

125

elseif ~OP.ERL_ONLY

126

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

126

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

127

else

127

else

128

num_next=0;

128

num_next=0;

129

end

129

end

130

end

130

end

131

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

131

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

132

end

132

end

133

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

133

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

134

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

134

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

135

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

135

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

136

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

136

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

137

param.num_next=num_next;

137

param.num_next=num_next;

138

param.num_fext=num_fext;

138

param.num_fext=num_fext;

139

param.num_s4p_files=num_fext+num_next+1;

139

param.num_s4p_files=num_fext+num_next+1;

140

% checking for data when running for rx compliance BBN calibration

140

% checking for data when running for rx compliance BBN calibration

141

if OP.RX_CALIBRATION == 1

141

if OP.RX_CALIBRATION == 1

142

if num_fext ~=1

142

if num_fext ~=1

143

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

143

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

144

movegui(h,'northwest')

144

movegui(h,'northwest')

145

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

145

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

146

if OP.DEBUG ~= 1

146

if OP.DEBUG ~= 1

147

return

147

return

148

end

148

end

149

end

149

end

150

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

150

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

151

movegui(h,'southeast')

151

movegui(h,'southeast')

152

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

152

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

153

end

153

end

154

154

155

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

155

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

156

if num_fext ~=1

156

if num_fext ~=1

157

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

157

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

158

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

158

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

159

movegui(h,'northwest')

159

movegui(h,'northwest')

160

if OP.DEBUG ~= 1

160

if OP.DEBUG ~= 1

161

return

161

return

162

end

162

end

163

end

163

end

164

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

164

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

165

movegui(h,'southeast')

165

movegui(h,'southeast')

166

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

166

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

167

end

167

end

168

168

169

169

170

% create result directory if needed

170

% create result directory if needed

171

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

171

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

172

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

172

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

173

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

173

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

174

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

174

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

175

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

175

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

176

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

176

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

177

%OP.EXTERNAL = true;

177

%OP.EXTERNAL = true;

178

%OP.GET_FD = 0;

178

%OP.GET_FD = 0;

179

%ir1a= varargin(2);

179

%ir1a= varargin(2);

180

%ex_var = varargin(3);

180

%ex_var = varargin(3);

181

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

181

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

182

else

182

else

183

if OP.TDMODE

183

if OP.TDMODE

184

OP.GET_FD=false;

184

OP.GET_FD=false;

185

end

185

end

186

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

186

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

187

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

187

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

188

end

188

end

189

%% eveluate any extra arguments as possible modifications of parameters

189

%% eveluate any extra arguments as possible modifications of parameters

190

extra_args = varargin(xtk+2:end);

190

extra_args = varargin(xtk+2:end);

191

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

191

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

192

try

192

try

193

orig_value_is_str = 1;

193

orig_value_is_str = 1;

194

orig_value=eval(extra_args{k});

194

orig_value=eval(extra_args{k});

195

if ~ischar(orig_value)

195

if ~ischar(orig_value)

196

orig_value_is_str = 0;

196

orig_value_is_str = 0;

197

orig_value=mat2str(orig_value);

197

orig_value=mat2str(orig_value);

198

end

198

end

199

catch eval_err

199

catch eval_err

200

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

200

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

201

% trying to modify a nonexistent parameter - probably a

201

% trying to modify a nonexistent parameter - probably a

202

% typo. save the user from his error.

202

% typo. save the user from his error.

203

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

203

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

204

else

204

else

205

% unexpected condition

205

% unexpected condition

206

rethrow(eval_err);

206

rethrow(eval_err);

207

end

207

end

208

end

208

end

209

try

209

try

210

if orig_value_is_str

210

if orig_value_is_str

211

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

211

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

212

else

212

else

213

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

213

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

214

end

214

end

215

eval(mod_string);

215

eval(mod_string);

216

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

216

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

217

% begin yasuo patch 2/11/2018

217

% begin yasuo patch 2/11/2018

218

% output_args.(fname)=mod_string;

218

% output_args.(fname)=mod_string;

219

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

219

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

220

220

221

% re-patch yasuo 3/18/2019

221

% re-patch yasuo 3/18/2019

222

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

222

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

223

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

223

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

224

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

224

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

225

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

225

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

226

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

226

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

227

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

227

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

228

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

228

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

229

else

229

else

230

output_args.(fname)=mod_string;

230

output_args.(fname)=mod_string;

231

end

231

end

232

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

232

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

233

catch eval_err

233

catch eval_err

234

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

234

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

235

end

235

end

236

end

236

end

237

end

237

end

238

end

238

end

239

%% Parameters computationally defined by values from the settings files

239

%% Parameters computationally defined by values from the settings files

240

param.ui=1/param.fb;

240

param.ui=1/param.fb;

241

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

241

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

242

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

242

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

243

factor_3db=0.473037;

243

factor_3db=0.473037;

244

param.fb_BT_cutoff=factor_3db*param.f_r;

244

param.fb_BT_cutoff=factor_3db*param.f_r;

245

param.fb_BW_cutoff=param.f_r;

245

param.fb_BW_cutoff=param.f_r;

246

param.Tx_rd_sel=1;

246

param.Tx_rd_sel=1;

247

param.Rx_rd_sel=2;

247

param.Rx_rd_sel=2;

248

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

248

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

249

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

249

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

250

end

250

end

251

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

251

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

252

param=parameter_size_adjustment(param,OP);

252

param=parameter_size_adjustment(param,OP);

253

253

254

%% get input models

254

%% get input models

255

param.FLAG.S2P=0;

255

param.FLAG.S2P=0;

256

if OP.TDMODE

256

if OP.TDMODE

257

OP.FIXTURE_CALIBRATION= 0;

257

OP.FIXTURE_CALIBRATION= 0;

258

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

258

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

259

else

259

else

260

OP.FIXTURE_CALIBRATION= 0;

260

OP.FIXTURE_CALIBRATION= 0;

261

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

261

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

262

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

262

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

263

param.FLAG.S2P=1;

263

param.FLAG.S2P=1;

264

end

264

end

265

end

265

end

266

266

267

OP.SAVE_CMD_STR=1;

267

OP.SAVE_CMD_STR=1;

268

if OP.SAVE_CMD_STR

268

if OP.SAVE_CMD_STR

269

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

269

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

270

setappdata(0,'cmd_str',cmd_str);

270

setappdata(0,'cmd_str',cmd_str);

271

end

271

end

272

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

272

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

273

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

273

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

274

COM = inf;

274

COM = inf;

275

min_COM=inf; % reset COM prior to calibration

275

min_COM=inf; % reset COM prior to calibration

276

% min_VEO = inf;

276

% min_VEO = inf;

277

min_VEO_mV = inf;

277

min_VEO_mV = inf;

278

max_VEC_dB = -inf;

278

max_VEC_dB = -inf;

279

threshold_DER=inf;

279

threshold_DER=inf;

280

% begin yasuo patch 3/18/2019

280

% begin yasuo patch 3/18/2019

281

threshold_DER_max = 0; % reset worst DER

281

threshold_DER_max = 0; % reset worst DER

282

% end yasuo patch

282

% end yasuo patch

283

sigma_bn=0;

283

sigma_bn=0;

284

DO_ONCE=true;

284

DO_ONCE=true;

285

low_COM_found = 0;

285

low_COM_found = 0;

286

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

286

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

287

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

287

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

288

if ~DO_ONCE

288

if ~DO_ONCE

289

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

289

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

290

break;

290

break;

291

elseif min_COM > param.pass_threshold

291

elseif min_COM > param.pass_threshold

292

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

292

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

293

if low_COM_found

293

if low_COM_found

294

if OP.sigma_bn_STEP>0 % previous increase too small

294

if OP.sigma_bn_STEP>0 % previous increase too small

295

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

295

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

296

else % previously decrease too large

296

else % previously decrease too large

297

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

297

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

298

end

298

end

299

end

299

end

300

else % binary searchparam.Pkg_len_TX

300

else % binary searchparam.Pkg_len_TX

301

low_COM_found=1;

301

low_COM_found=1;

302

if OP.sigma_bn_STEP>0 % previous increase too large

302

if OP.sigma_bn_STEP>0 % previous increase too large

303

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

303

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

304

else % previously decrease too small

304

else % previously decrease too small

305

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

305

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

306

end

306

end

307

end

307

end

308

min_COM = inf; % ignore previous iterations

308

min_COM = inf; % ignore previous iterations

309

min_VEO_mV = inf;

309

min_VEO_mV = inf;

310

max_VEC_dB = -inf;

310

max_VEC_dB = -inf;

311

sigma_bn = sigma_bn + OP.sigma_bn_STEP;

311

sigma_bn = sigma_bn + OP.sigma_bn_STEP;

312

end

312

end

313

msgctr=1;

313

msgctr=1;

314

for package_testcase_i = 1:length(OP.pkg_len_select)

314

for package_testcase_i = 1:length(OP.pkg_len_select)

315

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

315

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

316

package_testcase=OP.pkg_len_select(package_testcase_i);

316

package_testcase=OP.pkg_len_select(package_testcase_i);

317

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

317

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

318

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

318

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

319

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

319

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

320

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

320

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

321

param.AC_CM_RMS_TX= param.AC_CM_RMS(package_testcase);

321

param.AC_CM_RMS_TX= param.AC_CM_RMS(package_testcase);

322

if param.PKG_Tx_FFE_preset ~=0

322

if param.PKG_Tx_FFE_preset ~=0

323

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

323

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

324

else

324

else

325

param.Pkg_TXFFE_preset=0;

325

param.Pkg_TXFFE_preset=0;

326

end

326

end

327

% ki=package_testcase;

327

% ki=package_testcase;

328

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

328

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

329

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

329

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

330

param.Pkg_Zc= param.pkg_Z_c;

330

param.Pkg_Zc= param.pkg_Z_c;

331

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

331

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

332

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

332

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

333

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

333

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

334

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

334

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

335

end

335

end

336

param.package_testcase_i = package_testcase_i;

336

param.package_testcase_i = package_testcase_i;

337

337

338

%% Fill in chdata

338

%% Fill in chdata

339

if OP.TDMODE

339

if OP.TDMODE

340

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

340

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

341

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

341

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

342

else

342

else

343

%fill in chada with s-parameters

343

%fill in chada with s-parameters

344

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

344

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

345

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

345

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

346

end

346

end

347

if OP.BREAD_CRUMBS

347

if OP.BREAD_CRUMBS

348

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

348

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

349

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

349

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

350

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

350

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

351

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

351

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

352

end

352

end

353

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

353

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

354

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

354

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

355

end

355

end

356

end

356

end

357

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

357

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

358

358

359

%% Process TDR & ERL

359

%% Process TDR & ERL

360

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

360

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

361

if OP.ERL_ONLY

361

if OP.ERL_ONLY

362

results = cell(1);

362

results = cell(1);

363

results{1} = output_args;

363

results{1} = output_args;

364

rt=toc(t0);

364

rt=toc(t0);

365

output_args.rtmin=rt/60;

365

output_args.rtmin=rt/60;

366

if 1

366

if 1

367

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

367

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

368

end

368

end

369

if OP.CSV_REPORT ==1

369

if OP.CSV_REPORT ==1

370

Write_CSV(output_args,CSV_FILE);

370

Write_CSV(output_args,CSV_FILE);

371

end

371

end

372

break;

372

break;

373

end

373

end

374

374

375

%% FD processing s-parameter

375

%% FD processing s-parameter

376

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

376

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

377

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

377

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

378

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

378

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

379

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

379

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

380

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

380

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

381

%most operations now wrapped into FD_Processing function

381

%most operations now wrapped into FD_Processing function

382

param.number_of_s4p_files=length(chdata);

382

param.number_of_s4p_files=length(chdata);

383

%ICN=0;

383

%ICN=0;

384

output_args.ICN_mV=0;

384

output_args.ICN_mV=0;

385

output_args.MDNEXT_ICN_92_46_mV=0;

385

output_args.MDNEXT_ICN_92_46_mV=0;

386

output_args.MDFEXT_ICN_92_47_mV=0;

386

output_args.MDFEXT_ICN_92_47_mV=0;

387

if OP.WC_PORTZ

387

if OP.WC_PORTZ

388

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

388

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

389

else

389

else

390

param.SNR_TX=param.SNDR(package_testcase);

390

param.SNR_TX=param.SNDR(package_testcase);

391

end

391

end

392

392

393

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

393

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

394

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

394

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

395

395

396

%% Convert from Frequency Domain to Time Domain

396

%% Convert from Frequency Domain to Time Domain

397

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

397

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

398

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

398

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

399

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

399

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

400

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

400

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

401

if DO_ONCE

401

if DO_ONCE

402

if ~OP.TDMODE

402

if ~OP.TDMODE

403

chdata=COM_FD_to_TD(chdata,param,OP);

403

chdata=COM_FD_to_TD(chdata,param,OP);

404

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

404

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

405

output_args.SCMR_dB=chdata(1).SCMR;

405

output_args.SCMR_dB=chdata(1).SCMR;

406

end

406

end

407

end

407

end

408

408

409

%% Determine equalization settings

409

%% Determine equalization settings

410

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

410

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

411

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

411

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

412

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

412

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

413

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

413

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

414

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

414

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

415

do_C2M=0;

415

do_C2M=0;

416

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

416

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

417

do_C2M=1;

417

do_C2M=1;

418

end

418

end

419

OP.COMPUTE_COM=false;

419

OP.COMPUTE_COM=false;

420

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

420

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

421

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

421

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

422

OP.COMPUTE_COM=true;

422

OP.COMPUTE_COM=true;

423

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

423

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

424

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

424

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

425

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

425

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

426

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

426

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

427

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

427

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

428

428

429

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

429

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

430

param.use_bmax=fom_result.best_bmax.';

430

param.use_bmax=fom_result.best_bmax.';

431

%AJG021820

431

%AJG021820

432

param.use_bmin=fom_result.best_bmin.';

432

param.use_bmin=fom_result.best_bmin.';

433

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

433

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

434

param.current_ffegain=fom_result.best_current_ffegain;

434

param.current_ffegain=fom_result.best_current_ffegain;

435

if OP.force_pdf_bin_size

435

if OP.force_pdf_bin_size

436

param.delta_y = OP.BinSize;

436

param.delta_y = OP.BinSize;

437

else

437

else

438

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

438

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

439

end

439

end

440

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

440

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

441

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

441

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

442

442

443

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

443

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

444

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

444

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

445

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

445

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

446

OP.WO_TXFFE=1;

446

OP.WO_TXFFE=1;

447

PSD_results.w=fom_result.RxFFE;

447

PSD_results.w=fom_result.RxFFE;

448

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

448

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

449

% well as CTLE (CTF) and tx FFE

449

% well as CTLE (CTF) and tx FFE

450

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

450

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

451

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

451

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

452

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

452

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

453

OP.WO_TXFFE=0;

453

OP.WO_TXFFE=0;

454

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

454

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

455

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

455

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

456

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

456

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

457

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

457

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

458

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

458

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

459

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

459

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

460

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

460

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

461

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

461

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

462

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

462

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

463

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

463

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

464

end

464

end

465

%% Create ISI PDF & Individual Crosstalk PDFs

465

%% Create ISI PDF & Individual Crosstalk PDFs

466

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

466

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

467

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

467

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

468

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

468

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

469

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

469

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

470

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

470

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

471

for i=1:param.number_of_s4p_files

471

for i=1:param.number_of_s4p_files

472

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

472

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

473

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

473

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

474

474

475

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

475

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

476

else

476

else

477

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

477

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

478

end

478

end

479

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

479

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

480

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

480

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

481

subplot(2,1,2);

481

subplot(2,1,2);

482

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

482

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

483

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

483

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

484

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

484

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

485

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

485

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

486

hold on; title('PDF')

486

hold on; title('PDF')

487

recolor_plots(gca);

487

recolor_plots(gca);

488

end

488

end

+489

489

chdata(i).pdfr=pdf;

490

chdata(i).pdfr=pdf;

490

% reporting

491

% reporting

491

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

492

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

492

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

493

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

493

494

494

end

495

end

495

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

496

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

496

497

497

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

498

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

498

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

499

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

499

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

500

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

500

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

501

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

501

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

502

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

502

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

503

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

503

combined_interference_and_noise_pdf=PDF;

504

combined_interference_and_noise_pdf=PDF;

504

combined_interference_and_noise_cdf=CDF;

505

combined_interference_and_noise_cdf=CDF;

505

506

506

507

507

%% Calculate COM and other associated outputs

508

%% Calculate COM and other associated outputs

508

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

509

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

509

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

510

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

510

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

511

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

511

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

512

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

512

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

513

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

513

% that satisfies the relationship P(y0) = DER_0

514

% that satisfies the relationship P(y0) = DER_0

514

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

515

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

515

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

516

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

516

517

517

% begin yasuo patch 3/18/2019

518

% begin yasuo patch 3/18/2019

518

% estimate DER at threshold COM

519

% estimate DER at threshold COM

519

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

520

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

520

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

521

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

521

threshold_DER_max = max(threshold_DER_max, threshold_DER);

522

threshold_DER_max = max(threshold_DER_max, threshold_DER);

522

% end yasuo patch

523

% end yasuo patch

523

524

524

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

525

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

525

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

526

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

526

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

527

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

527

if OP.DISPLAY_WINDOW && OP.DEBUG

528

if OP.DISPLAY_WINDOW && OP.DEBUG

528

figure_name = 'Eye at DER0 estimate';

529

figure_name = 'Eye at DER0 estimate';

529

fig=findobj('Name', figure_name);

530

fig=findobj('Name', figure_name);

530

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

531

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

531

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

532

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

532

movegui(fig,'southwest')

533

movegui(fig,'southwest')

533

plot(eye_contour)

534

plot(eye_contour)

534

xlabel('UI %')

535

xlabel('UI %')

535

ylabel('V')

536

ylabel('V')

536

end

537

end

537

538

538

else

539

else

539

EW_UI=0;

540

EW_UI=0;

540

eye_contour=[];

541

eye_contour=[];

541

end

542

end

542

if OP.MLSE==0

543

if OP.MLSE==0

543

if param.T_O ~=0

544

if param.T_O ~=0

544

eye_opening=EH_T_C2M-EH_B_C2M;

545

eye_opening=EH_T_C2M-EH_B_C2M;

545

A_ni=2*A_s-eye_opening;

546

A_ni=2*A_s-eye_opening;

546

%eq 124E-4

547

%eq 124E-4

547

vec_arg=2*A_s/eye_opening;

548

vec_arg=2*A_s/eye_opening;

548

if vec_arg<eps

549

if vec_arg<eps

549

vec_arg=eps;

550

vec_arg=eps;

550

end

551

end

551

VEC_dB = 20*log10(vec_arg);

552

VEC_dB = 20*log10(vec_arg);

552

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

553

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

553

VEO_mV=eye_opening*1000;

554

VEO_mV=eye_opening*1000;

554

min_COM = min(min_COM, COM);

555

min_COM = min(min_COM, COM);

555

min_VEO_mV = min(min_VEO_mV,VEO_mV);

556

min_VEO_mV = min(min_VEO_mV,VEO_mV);

556

max_VEC_dB = max(max_VEC_dB, VEC_dB);

557

max_VEC_dB = max(max_VEC_dB, VEC_dB);

557

else

558

else

558

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

559

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

559

vec_arg=(A_s-A_ni)/A_s;

560

vec_arg=(A_s-A_ni)/A_s;

560

if vec_arg<eps

561

if vec_arg<eps

561

vec_arg=eps;

562

vec_arg=eps;

562

end

563

end

563

VEC_dB = -20*log10(vec_arg);

564

VEC_dB = -20*log10(vec_arg);

564

COM=20*log10(A_s/A_ni);

565

COM=20*log10(A_s/A_ni);

565

min_COM = min(min_COM, COM);

566

min_COM = min(min_COM, COM);

566

min_VEO_mV = min(min_VEO_mV,VEO_mV);

567

min_VEO_mV = min(min_VEO_mV,VEO_mV);

567

max_VEC_dB = max(max_VEC_dB, VEC_dB);

568

max_VEC_dB = max(max_VEC_dB, VEC_dB);

568

end

569

end

569

MLSE_results=struct;

570

MLSE_results=struct;

570

else

571

else

571

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

572

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

572

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

573

if param.T_O ~=0

573

if param.T_O ~=0

574

eye_opening=EH_T_C2M-EH_B_C2M;

574

eye_opening=EH_T_C2M-EH_B_C2M;

575

A_ni=2*A_s-eye_opening;

575

A_ni=2*A_s-eye_opening;

576

%eq 124E-4

576

%eq 124E-4

577

vec_arg=2*A_s/eye_opening;

577

vec_arg=2*A_s/eye_opening;

578

if vec_arg<eps

578

if vec_arg<eps

579

vec_arg=eps;

579

vec_arg=eps;

580

end

580

end

581

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

581

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

582

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

582

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

583

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

583

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

584

COM=MLSE_results.COM;

584

COM=MLSE_results.COM;

585

VEO_mV=eye_opening*1000;

585

VEO_mV=eye_opening*1000;

586

min_COM = min(min_COM, COM);

586

min_COM = min(min_COM, COM);

587

min_VEO_mV = min(min_VEO_mV,VEO_mV);

587

min_VEO_mV = min(min_VEO_mV,VEO_mV);

588

max_VEC_dB = max(max_VEC_dB, VEC_dB);

588

max_VEC_dB = max(max_VEC_dB, VEC_dB);

589

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

589

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

590

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

590

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

591

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

591

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

592

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

592

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

593

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

593

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

594

COM_SNR_Struct.VEC_dB=VEC_dB;

594

COM_SNR_Struct.VEC_dB=VEC_dB;

595

else

595

else

596

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

596

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

597

vec_arg=(A_s-A_ni)/A_s;

597

vec_arg=(A_s-A_ni)/A_s;

598

if vec_arg<eps

598

if vec_arg<eps

599

vec_arg=eps;

599

vec_arg=eps;

600

end

600

end

601

VEC_dB_orig = -20*log10(vec_arg);

601

VEC_dB_orig = -20*log10(vec_arg);

602

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

602

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

603

COM_orig=20*log10(A_s/A_ni);

603

COM_orig=20*log10(A_s/A_ni);

604

COM=MLSE_results.COM;

604

COM=MLSE_results.COM;

605

min_COM = min(min_COM, COM);

605

min_COM = min(min_COM, COM);

606

min_VEO_mV = min(min_VEO_mV,VEO_mV);

606

min_VEO_mV = min(min_VEO_mV,VEO_mV);

607

max_VEC_dB = max(max_VEC_dB, VEC_dB);

607

max_VEC_dB = max(max_VEC_dB, VEC_dB);

608

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

608

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

609

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

609

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

610

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

610

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

611

COM_SNR_Struct.VEC_dB=VEC_dB;

611

COM_SNR_Struct.VEC_dB=VEC_dB;

612

end

612

end

613

end

613

end

614

614

615

%% Create COM_SNR_Struct to hold the main COM outputs

615

%% Create COM_SNR_Struct to hold the main COM outputs

616

COM_SNR_Struct.A_s=A_s;

616

COM_SNR_Struct.A_s=A_s;

617

COM_SNR_Struct.A_ni=A_ni;

617

COM_SNR_Struct.A_ni=A_ni;

618

COM_SNR_Struct.threshold_DER=threshold_DER;

618

COM_SNR_Struct.threshold_DER=threshold_DER;

619

COM_SNR_Struct.EW_UI=EW_UI;

619

COM_SNR_Struct.EW_UI=EW_UI;

620

COM_SNR_Struct.COM=COM;

620

COM_SNR_Struct.COM=COM;

621

COM_SNR_Struct.VEC_dB=VEC_dB;

621

COM_SNR_Struct.VEC_dB=VEC_dB;

622

if OP.MLSE == 0

622

if OP.MLSE == 0

623

COM_SNR_Struct.COM_orig=[];

623

COM_SNR_Struct.COM_orig=[];

624

COM_SNR_Struct.VEC_dB_orig=[];

624

COM_SNR_Struct.VEC_dB_orig=[];

625

else

625

else

626

COM_SNR_Struct.COM_orig=COM_orig;

626

COM_SNR_Struct.COM_orig=COM_orig;

627

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

627

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

628

end

628

end

629

COM_SNR_Struct.VEO_mV=VEO_mV;

629

COM_SNR_Struct.VEO_mV=VEO_mV;

630

COM_SNR_Struct.combined_interference_and_noise_pdf=combined_interference_and_noise_pdf;

630

COM_SNR_Struct.combined_interference_and_noise_pdf=combined_interference_and_noise_pdf;

631

COM_SNR_Struct.combined_interference_and_noise_cdf=combined_interference_and_noise_cdf;

631

COM_SNR_Struct.combined_interference_and_noise_cdf=combined_interference_and_noise_cdf;

632

COM_SNR_Struct.eye_contour=eye_contour;

632

COM_SNR_Struct.eye_contour=eye_contour;

633

633

634

634

635

%% Save TD

635

%% Save TD

636

if OP.SAVE_TD

636

if OP.SAVE_TD

637

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

637

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

638

if ~OP.TDMODE

638

if ~OP.TDMODE

639

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

639

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

640

end

640

end

641

for i=1:param.number_of_s4p_files

641

for i=1:param.number_of_s4p_files

642

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

642

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

643

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

643

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

644

if ~OP.TDMODE

644

if ~OP.TDMODE

645

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

645

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

646

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

646

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

647

end

647

end

648

end

648

end

649

if OP.TDMODE

649

if OP.TDMODE

650

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

650

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

651

else

651

else

652

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

652

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

653

end

653

end

654

end

654

end

655

655

656

%% Bathtub/Contribution Plot

656

%% Bathtub/Contribution Plot

657

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

657

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

658

if OP.MLSE ~= 0

659

COM_SNR_Struct.combined_interference_and_noise_pdf=MLSE_results.PDF;

660

COM_SNR_Struct.combined_interference_and_noise_cdf=MLSE_results.CDF;

661

end

662

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

658

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

663

end

659

end

664

660

665

%% Msg management

661

%% Msg management

666

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

662

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

667

msg=[];

663

msg=[];

668

end

664

end

669

if OP.DEBUG

665

if OP.DEBUG

670

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

666

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

671

switch param.flex

667

switch param.flex

672

case 4

668

case 4

673

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

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

674

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

675

);

671

);

676

case 2

672

case 2

677

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

678

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

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

679

);

675

);

680

otherwise

676

otherwise

681

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

682

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

683

);

679

);

684

680

685

end

681

end

686

else

682

else

687

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

683

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

688

end

684

end

689

685

690

if OP.TDMODE

686

if OP.TDMODE

691

min_ERL=inf;

687

min_ERL=inf;

692

ERL=[inf inf];

688

ERL=[inf inf];

693

end

689

end

694

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

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

695

691

696

692

697

%% Output Args

693

%% Output Args

698

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

694

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

699

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

695

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

700

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

696

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

701

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

697

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

702

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

703

rt=toc(t0);

699

rt=toc(t0);

704

output_args.rtmin=rt/60;

700

output_args.rtmin=rt/60;

705

701

706

if OP.BREAD_CRUMBS

702

if OP.BREAD_CRUMBS

707

output_args.OP=OP;

703

output_args.OP=OP;

708

output_args.param=param;

704

output_args.param=param;

709

output_args.chdata=chdata;

705

output_args.chdata=chdata;

710

output_args.fom_result = fom_result;

706

output_args.fom_result = fom_result;

711

output_args.PDF=PDF; % for exploration

707

output_args.PDF=PDF; % for exploration

712

output_args.CDF=CDF; % for exploration

708

output_args.CDF=CDF; % for exploration

713

output_args.MLSE_results=MLSE_results;

709

output_args.MLSE_results=MLSE_results;

714

output_args.PSD_results=PSD_results;

710

output_args.PSD_results=PSD_results;

715

end

711

end

716

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

712

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

717

713

718

%% making csv file

714

%% making csv file

719

if OP.CSV_REPORT ==1

715

if OP.CSV_REPORT ==1

720

Write_CSV(output_args,CSV_FILE);

716

Write_CSV(output_args,CSV_FILE);

721

end

717

end

722

%% making mat file

718

%% making mat file

723

if(OP.DEBUG)

719

if(OP.DEBUG)

724

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

725

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

721

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

726

end

722

end

727

if 1

723

if 1

728

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)

729

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

725

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

730

end

726

end

731

727

732

if nargout==0

728

if nargout==0

733

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

729

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

734

disp(output_args)

730

disp(output_args)

735

end

731

end

736

732

737

if OP.BREAD_CRUMBS

733

if OP.BREAD_CRUMBS

738

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

734

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

739

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

735

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

740

%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

741

try

737

try

742

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

743

catch

739

catch

744

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

740

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

745

end

741

end

746

end

742

end

747

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

748

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

744

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

749

end

745

end

750

746

751

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

752

end

748

end

753

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

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

754

%%

750

%%

755

751

756

if OP.RX_CALIBRATION ==1

752

if OP.RX_CALIBRATION ==1

757

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

753

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

758

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

754

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

759

end

755

end

760

DO_ONCE=false;

756

DO_ONCE=false;

761

end

757

end

762

758

763

%% Final cleanup

759

%% Final cleanup

764

if OP.DISPLAY_WINDOW

760

if OP.DISPLAY_WINDOW

765

savefigs(param, OP);

761

savefigs(param, OP);

766

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

762

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

767

end

763

end

768

764

769

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)

770

if ~param.f_hp==0

766

if ~param.f_hp==0

771

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

772

if OP.DISPLAY_WINDOW

768

if OP.DISPLAY_WINDOW

773

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

774

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

770

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

775

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

771

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

776

end

772

end

777

else

773

else

778

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

779

if OP.DISPLAY_WINDOW

775

if OP.DISPLAY_WINDOW

780

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

781

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

777

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

782

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

778

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

783

end

779

end

784

end

780

end

785

end

781

end

786

782

787

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

783

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

788

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

789

disp(redo_cmd_str);

785

disp(redo_cmd_str);

790

if isdeployed

786

if isdeployed

791

if OP.exit_if_deployed

787

if OP.exit_if_deployed

792

quit

788

quit

793

end

789

end

794

end

790

end

795

%%

791

%%

796

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

792

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

797

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

793

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

798

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

794

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

799

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

795

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

800

796

801

FB=param.fb;

797

FB=param.fb;

802

FZ=param.CTLE_fz(fom_result.ctle);

798

FZ=param.CTLE_fz(fom_result.ctle);

803

FP1=param.CTLE_fp1(fom_result.ctle);

799

FP1=param.CTLE_fp1(fom_result.ctle);

804

FP2=param.CTLE_fp2(fom_result.ctle);

800

FP2=param.CTLE_fp2(fom_result.ctle);

805

GDC=param.ctle_gdc_values(fom_result.ctle);

801

GDC=param.ctle_gdc_values(fom_result.ctle);

806

if ~isempty(param.f_HP)

802

if ~isempty(param.f_HP)

807

FHP=param.f_HP(fom_result.best_G_high_pass);

803

FHP=param.f_HP(fom_result.best_G_high_pass);

808

end

804

end

809

if ~isempty(param.g_DC_HP_values)

805

if ~isempty(param.g_DC_HP_values)

810

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

811

end

807

end

812

if ~isempty(param.f_HP_Z)

808

if ~isempty(param.f_HP_Z)

813

FHPZ=param.f_HP_Z(fom_result.ctle);

809

FHPZ=param.f_HP_Z(fom_result.ctle);

814

end

810

end

815

if ~isempty(param.f_HP_P)

811

if ~isempty(param.f_HP_P)

816

FHPP=param.f_HP_P(fom_result.ctle);

812

FHPP=param.f_HP_P(fom_result.ctle);

817

end

813

end

818

%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

819

%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

820

%length

816

%length

821

SBR_Len=length(fom_result.sbr);

817

SBR_Len=length(fom_result.sbr);

822

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

818

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

823

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

819

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

824

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

820

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

825

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

821

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

826

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

822

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

827

end

823

end

828

for i=1:param.number_of_s4p_files

824

for i=1:param.number_of_s4p_files

829

% 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

830

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

831

if OP.INCLUDE_CTLE==1

827

if OP.INCLUDE_CTLE==1

832

switch param.CTLE_type

828

switch param.CTLE_type

833

case 'CL93'

829

case 'CL93'

834

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

835

case 'CL120d'

831

case 'CL120d'

836

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

837

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

838

case 'CL120e' % z has been adjusted for gain

834

case 'CL120e' % z has been adjusted for gain

839

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

840

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

841

end

837

end

842

else

838

else

843

eq_ir=uneq_ir;

839

eq_ir=uneq_ir;

844

end

840

end

845

chdata(i).eq_imp_response=eq_ir;

841

chdata(i).eq_imp_response=eq_ir;

846

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

847

843

848

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

844

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

849

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

845

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

850

end

846

end

851

% chdata(i).ctle_imp_response

847

% chdata(i).ctle_imp_response

852

if OP.RxFFE

848

if OP.RxFFE

853

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

849

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

854

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

855

end

851

end

856

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

857

end

853

end

858

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)

859

end

855

end

860

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)

861

857

862

% display bathtub curves in one axis per test case.

858

% display bathtub curves in one axis per test case.

863

case_number=param.package_testcase_i;

859

case_number=param.package_testcase_i;

864

if ~OP.COM_CONTRIBUTION_CURVES

860

if ~OP.COM_CONTRIBUTION_CURVES

865

figure_name = 'Voltage bathtub curves';

861

figure_name = 'Voltage bathtub curves';

866

fig=findobj('Name', figure_name);

862

fig=findobj('Name', figure_name);

867

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

863

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

868

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

864

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

869

movegui(fig,'south')

865

movegui(fig,'south')

870

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

866

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

871

plot_bathtub_curves( hax ...

867

plot_bathtub_curves( hax ...

872

, COM_SNR_Struct.A_s ...

868

, COM_SNR_Struct.A_s ...

873

, Noise_Struct.sci_pdf ...

869

, Noise_Struct.sci_pdf ...

874

, Noise_Struct.cci_pdf ...

870

, Noise_Struct.cci_pdf ...

875

, Noise_Struct.isi_and_xtalk_pdf ...

871

, Noise_Struct.isi_and_xtalk_pdf ...

876

, Noise_Struct.noise_pdf ...

872

, Noise_Struct.noise_pdf ...

877

, Noise_Struct.jitt_pdf ...

873

, Noise_Struct.jitt_pdf ...

878

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

874

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

879

, param.delta_y ...

875

, param.delta_y ...

880

);

876

);

881

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

877

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

882

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

883

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

879

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

884

% show BER target line

880

% show BER target line

885

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

881

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

886

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

882

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

887

else

883

else

888

figure_name = 'COM Contributions (Rough Allocations)';

884

figure_name = 'COM Contributions (Rough Allocations)';

889

fig=findobj('Name', figure_name);

885

fig=findobj('Name', figure_name);

890

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

886

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

891

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

887

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

892

movegui(fig,'south')

888

movegui(fig,'south')

893

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

889

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

894

890

895

plot_pie_com( hax ...

891

plot_pie_com( hax ...

896

, COM_SNR_Struct.A_s ...

892

, COM_SNR_Struct.A_s ...

897

, Noise_Struct.sci_pdf ...

893

, Noise_Struct.sci_pdf ...

898

, Noise_Struct.cci_pdf ...

894

, Noise_Struct.cci_pdf ...

899

, Noise_Struct.isi_and_xtalk_pdf ...

895

, Noise_Struct.isi_and_xtalk_pdf ...

900

, Noise_Struct.noise_pdf ...

896

, Noise_Struct.noise_pdf ...

901

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

897

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

902

, param.delta_y, param...

898

, param.delta_y, param...

903

);

899

);

904

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

900

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

905

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

906

end

902

end

907

903

908

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

904

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

909

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

905

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

910

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

906

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

911

end

907

end

912

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

908

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

913

909

914

if use_BT

910

if use_BT

915

a = bessel( param.BTorder );

911

a = bessel( param.BTorder );

916

acoef=fliplr( a );

912

acoef=fliplr( a );

917

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

918

else

914

else

919

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

915

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

920

end

916

end

921

917

922

918

923

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

919

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

924

920

925

%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

926

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

922

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

927

%All subsequent lines are field names in chdata

923

%All subsequent lines are field names in chdata

928

%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

929

%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

930

%

926

%

931

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

932

%#reduce

928

%#reduce

933

%sdd12_raw

929

%sdd12_raw

934

%sdd21_raw

930

%sdd21_raw

935

%sdd22_raw

931

%sdd22_raw

936

%sdd11_raw

932

%sdd11_raw

937

%

933

%

938

934

939

fid=fopen(fields_file,'r');

935

fid=fopen(fields_file,'r');

940

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

936

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

941

937

942

file_data=file_data{1};

938

file_data=file_data{1};

943

fclose(fid);

939

fclose(fid);

944

940

945

%remove blank lines

941

%remove blank lines

946

L=cellfun('length',file_data);

942

L=cellfun('length',file_data);

947

file_data=file_data(L~=0);

943

file_data=file_data(L~=0);

948

944

949

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

945

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

950

type=file_data{1};

946

type=file_data{1};

951

field_names=file_data(2:end);

947

field_names=file_data(2:end);

952

switch lower(type)

948

switch lower(type)

953

case '#reduce'

949

case '#reduce'

954

remove_fields=field_names;

950

remove_fields=field_names;

955

case '#include'

951

case '#include'

956

all_fields=fieldnames(chdata);

952

all_fields=fieldnames(chdata);

957

remove_fields=setdiff(all_fields,field_names);

953

remove_fields=setdiff(all_fields,field_names);

958

otherwise

954

otherwise

959

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

955

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

960

end

956

end

961

957

962

%remove the "remove_fields" from chdata

958

%remove the "remove_fields" from chdata

963

for j=1:length(remove_fields)

959

for j=1:length(remove_fields)

964

this_field=remove_fields{j};

960

this_field=remove_fields{j};

965

if isfield(chdata,this_field)

961

if isfield(chdata,this_field)

966

chdata=rmfield(chdata,this_field);

962

chdata=rmfield(chdata,this_field);

967

end

963

end

968

end

964

end

969

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)

970

966

971

% 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

972

% 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

973

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

974

970

975

A_s=COM_SNR_Struct.A_s;

971

A_s=COM_SNR_Struct.A_s;

976

% initialize loop with uncorrelated noise and BER

972

% initialize loop with uncorrelated noise and BER

977

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

978

974

979

% 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

980

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

976

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

981

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

977

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

982

% below target BER).

978

% below target BER).

983

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

984

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

985

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

986

if isempty(x_error_propagation)

982

if isempty(x_error_propagation)

987

p_error_propagation(1) = 1e-20;

983

p_error_propagation(1) = 1e-20;

988

else

984

else

989

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

990

end

986

end

991

987

992

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

988

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

993

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

989

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

994

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

990

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

995

if OP.use_simple_EP_model

991

if OP.use_simple_EP_model

996

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>

997

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>

998

else

994

else

999

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>

1000

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>

1001

end

997

end

1002

998

1003

% 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

1004

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

1005

if isempty(x_error_propagation)

1001

if isempty(x_error_propagation)

1006

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

1002

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

1007

else

1003

else

1008

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>

1009

end

1005

end

1010

end

1006

end

1011

1007

1012

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

1008

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

1013

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

1009

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

1014

% of this event by partial sum of the PDF.

1010

% of this event by partial sum of the PDF.

1015

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

1016

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

1017

1013

1018

% probability of bursts of different lengths

1014

% probability of bursts of different lengths

1019

p_burst = cumprod(p_error_propagation);

1015

p_burst = cumprod(p_error_propagation);

1020

function H_bw=Butterworth_Filter(param,f,use_BW)

1016

function H_bw=Butterworth_Filter(param,f,use_BW)

1021

1017

1022

if use_BW

1018

if use_BW

1023

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

1024

else

1020

else

1025

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

1021

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

1026

end

1022

end

1027

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

1023

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

1028

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

1024

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

1029

CDF_ev=CDF(index);

1025

CDF_ev=CDF(index);

1030

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

1026

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

1031

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

1027

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

1032

if isempty(index)

1028

if isempty(index)

1033

CDF_inv_ev=PDF.x(end);

1029

CDF_inv_ev=PDF.x(end);

1034

else

1030

else

1035

CDF_inv_ev=PDF.x(index);

1031

CDF_inv_ev=PDF.x(index);

1036

end

1032

end

1037

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)

1038

1034

1039

1035

1040

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

1036

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

1041

Remember_keyword='Legacy';

1037

Remember_keyword='Legacy';

1042

OP.TDMODE=false;

1038

OP.TDMODE=false;

1043

OP.GET_FD=true;

1039

OP.GET_FD=true;

1044

OP.CONFIG2MAT_ONLY=false;

1040

OP.CONFIG2MAT_ONLY=false;

1045

config_file='';

1041

config_file='';

1046

num_fext=[];

1042

num_fext=[];

1047

num_next=[];

1043

num_next=[];

1048

if ~isempty(varargin)

1044

if ~isempty(varargin)

1049

if ~ischar(varargin{1})

1045

if ~ischar(varargin{1})

1050

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

1046

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

1051

end

1047

end

1052

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

1048

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

1053

if isempty(keyword_idx)

1049

if isempty(keyword_idx)

1054

%Legacy Mode

1050

%Legacy Mode

1055

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

1051

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

1056

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

1052

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

1057

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

1053

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

1058

else

1054

else

1059

%Keyword Mode

1055

%Keyword Mode

1060

my_keyword=varargin{1};

1056

my_keyword=varargin{1};

1061

Remember_keyword=my_keyword;

1057

Remember_keyword=my_keyword;

1062

varargin(1)=[];

1058

varargin(1)=[];

1063

switch my_keyword

1059

switch my_keyword

1064

1060

1065

case 'Legacy'

1061

case 'Legacy'

1066

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

1062

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

1067

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

1063

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

1068

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

1064

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

1069

case 'TD'

1065

case 'TD'

1070

OP.TDMODE=true;

1066

OP.TDMODE=true;

1071

OP.GET_FD=false;

1067

OP.GET_FD=false;

1072

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

1068

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

1073

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

1069

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

1074

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

1070

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

1075

case 'Config2Mat'

1071

case 'Config2Mat'

1076

OP.CONFIG2MAT_ONLY=true;

1072

OP.CONFIG2MAT_ONLY=true;

1077

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

1073

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

1078

end

1074

end

1079

end

1075

end

1080

end

1076

end

1081

function chdata=COM_FD_to_TD(chdata,param,OP)

1077

function chdata=COM_FD_to_TD(chdata,param,OP)

1082

1078

1083

% 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

1084

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

1085

case_number=param.package_testcase_i;

1081

case_number=param.package_testcase_i;

1086

for i=1:param.number_of_s4p_files

1082

for i=1:param.number_of_s4p_files

1087

% RIM 2-01-2023 moved to FD_Processing

1083

% RIM 2-01-2023 moved to FD_Processing

1088

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1084

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1089

% % Equation 93A-20 %%

1085

% % Equation 93A-20 %%

1090

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

1091

% f=chdata(i).faxis;

1087

% f=chdata(i).faxis;

1092

% %

1088

% %

1093

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

1089

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

1094

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

1090

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

1095

% 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

1096

% 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

1097

% 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

1098

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

1094

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

1099

% if OP.DISPLAY_WINDOW

1095

% if OP.DISPLAY_WINDOW

1100

% if i==1

1096

% if i==1

1101

% figure(300+param.package_testcase_i);

1097

% figure(300+param.package_testcase_i);

1102

% subplot(3,1,1)

1098

% subplot(3,1,1)

1103

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

1104

% try

1100

% try

1105

% legend('NumColumns',2)

1101

% legend('NumColumns',2)

1106

% legend('location','south')

1102

% legend('location','south')

1107

% catch

1103

% catch

1108

% end

1104

% end

1109

% end

1105

% end

1110

% end

1106

% end

1111

% end

1107

% end

1112

[chdata(i).uneq_imp_response, ...

1108

[chdata(i).uneq_imp_response, ...

1113

chdata(i).t, ...

1109

chdata(i).t, ...

1114

chdata(i).causality_correction_dB, ...

1110

chdata(i).causality_correction_dB, ...

1115

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

1116

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

1117

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

1118

[chdata(i).uneq_CD_imp_response, ...

1114

[chdata(i).uneq_CD_imp_response, ...

1119

chdata(i).t_DC, ...

1115

chdata(i).t_DC, ...

1120

chdata(i).causality_correction_DC_dB, ...

1116

chdata(i).causality_correction_DC_dB, ...

1121

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

1122

end

1118

end

1123

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

1119

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

1124

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

1120

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

1125

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

1121

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

1126

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

1122

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

1127

1123

1128

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

1129

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

1130

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;

1131

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

1132

% 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

1133

rss=-inf;

1129

rss=-inf;

1134

for im=1:param.samples_per_ui

1130

for im=1:param.samples_per_ui

1135

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

1136

end

1132

end

1137

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

1133

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

1138

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

1139

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

1140

end

1136

end

1141

if OP.DEBUG && OP.DISPLAY_WINDOW

1137

if OP.DEBUG && OP.DISPLAY_WINDOW

1142

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1138

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1143

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

1139

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

1144

screen_size=get(0,'ScreenSize');

1140

screen_size=get(0,'ScreenSize');

1145

pos = get(gcf, 'OuterPosition');

1141

pos = get(gcf, 'OuterPosition');

1146

set(gcf, 'OuterPosition', ...

1142

set(gcf, 'OuterPosition', ...

1147

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

1148

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

1144

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

1149

%movegui(gcf,'northeast')

1145

%movegui(gcf,'northeast')

1150

1146

1151

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

1152

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

1153

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

1154

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

1155

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

1156

end

1152

end

1157

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

1153

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

1158

% scale. thru is shown in another plot.

1154

% scale. thru is shown in another plot.

1159

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

1160

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

1156

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

1161

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

1157

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

1162

end

1158

end

1163

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

1159

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

1164

ylabel('Volts')

1160

ylabel('Volts')

1165

xlabel('seconds')

1161

xlabel('seconds')

1166

1162

1167

recolor_plots(gca);

1163

recolor_plots(gca);

1168

else

1164

else

1169

if param.ndfe~=0

1165

if param.ndfe~=0

1170

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

1171

end

1167

end

1172

end

1168

end

1173

1169

1174

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

1175

if OP.ENFORCE_CAUSALITY

1171

if OP.ENFORCE_CAUSALITY

1176

fprintf('\n');

1172

fprintf('\n');

1177

else

1173

else

1178

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

1174

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

1179

end

1175

end

1180

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

1181

1177

1182

end

1178

end

1183

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)

1184

1180

1185

1181

1186

debug_plot=0;

1182

debug_plot=0;

1187

1183

1188

1184

1189

samp_UI=param.samples_for_C2M;

1185

samp_UI=param.samples_for_C2M;

1190

half_UI=get_center_of_UI(samp_UI);

1186

half_UI=get_center_of_UI(samp_UI);

1191

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

1187

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

1192

start_sample=half_UI-T_O;

1188

start_sample=half_UI-T_O;

1193

end_sample=half_UI+T_O;

1189

end_sample=half_UI+T_O;

1194

1190

1195

1191

1196

%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

1197

%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

1198

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

1199

if pdf_range_flag

1195

if pdf_range_flag

1200

pdf_range=[start_sample end_sample];

1196

pdf_range=[start_sample end_sample];

1201

else

1197

else

1202

pdf_range=[];

1198

pdf_range=[];

1203

end

1199

end

1204

1200

1205

%pdf_full is self ISI pdf for each sample point

1201

%pdf_full is self ISI pdf for each sample point

1206

%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

1207

%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

1208

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

1209

1205

1210

1206

1211

1207

1212

if isempty(pdf_range)

1208

if isempty(pdf_range)

1213

pdf_range=1:samp_UI;

1209

pdf_range=1:samp_UI;

1214

else

1210

else

1215

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

1211

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

1216

end

1212

end

1217

1213

1218

%Test doing Level PDFs

1214

%Test doing Level PDFs

1219

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

1215

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

1220

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

1221

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

1217

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

1222

1218

1223

%add signal vector into pdf

1219

%add signal vector into pdf

1224

for n=1:param.levels

1220

for n=1:param.levels

1225

pdf_full{n}=pdf_full_1;

1221

pdf_full{n}=pdf_full_1;

1226

for j=pdf_range

1222

for j=pdf_range

1227

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

1228

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;

1229

end

1225

end

1230

end

1226

end

1231

1227

1232

1228

1233

% figure;

1229

% figure;

1234

% hold on;

1230

% hold on;

1235

%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

1236

%computed for every sample point

1232

%computed for every sample point

1237

for n=1:param.levels

1233

for n=1:param.levels

1238

for j=pdf_range

1234

for j=pdf_range

1239

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

1240

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

1241

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

1242

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

1243

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

1244

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

1245

% change from adam gregory to include crosstalk

1241

% change from adam gregory to include crosstalk

1246

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

1247

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

1248

1244

1249

%PDF to CDF

1245

%PDF to CDF

1250

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

1251

1247

1252

end

1248

end

1253

end

1249

end

1254

%hold off;

1250

%hold off;

1255

1251

1256

1252

1257

%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

1258

for n=1:param.levels

1254

for n=1:param.levels

1259

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

1255

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

1260

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

1256

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

1261

for j=pdf_range

1257

for j=pdf_range

1262

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

1263

end

1259

end

1264

end

1260

end

1265

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

1266

1262

1267

for n=1:param.levels-1

1263

for n=1:param.levels-1

1268

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

1264

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

1269

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

1265

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

1270

end

1266

end

1271

1267

1272

1268

1273

for n=1:param.levels-1

1269

for n=1:param.levels-1

1274

%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

1275

%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

1276

%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

1277

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

1273

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

1278

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

1274

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

1279

EH=EH_top-EH_bot;

1275

EH=EH_top-EH_bot;

1280

vref=EH_top/2+EH_bot/2;

1276

vref=EH_top/2+EH_bot/2;

1281

%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

1282

%the top and bottom eye contours

1278

%the top and bottom eye contours

1283

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

1284

end

1280

end

1285

1281

1286

%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

1287

eye_contour_tmp=eye_contour;

1283

eye_contour_tmp=eye_contour;

1288

eye_contour=[];

1284

eye_contour=[];

1289

for n=1:param.levels-1

1285

for n=1:param.levels-1

1290

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

1291

end

1287

end

1292

1288

1293

1289

1294

%Find VEC eye height

1290

%Find VEC eye height

1295

out_VT=[];

1291

out_VT=[];

1296

out_VB=[];

1292

out_VB=[];

1297

if param.T_O ~=0

1293

if param.T_O ~=0

1298

1294

1299

switch lower(OP.Histogram_Window_Weight)

1295

switch lower(OP.Histogram_Window_Weight)

1300

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

1296

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

1301

%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

1302

%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

1303

QL_sigma=T_O/param.QL;

1299

QL_sigma=T_O/param.QL;

1304

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

1300

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

1305

case 'triangle'

1301

case 'triangle'

1306

%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

1307

%for the weights

1303

%for the weights

1308

t_slope=1/(T_O);

1304

t_slope=1/(T_O);

1309

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

1305

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

1310

case 'rectangle'

1306

case 'rectangle'

1311

%default = rectangle. all weights = 1

1307

%default = rectangle. all weights = 1

1312

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

1308

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

1313

case 'dual_rayleigh'

1309

case 'dual_rayleigh'

1314

QL_sigma=T_O/param.QL;

1310

QL_sigma=T_O/param.QL;

1315

X=-T_O:T_O;

1311

X=-T_O:T_O;

1316

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

1317

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

1318

weights=weights/max(weights);

1314

weights=weights/max(weights);

1319

otherwise

1315

otherwise

1320

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)

1321

end

1317

end

1322

1318

1323

for n=1:param.levels

1319

for n=1:param.levels

1324

out_pdf{n}=[];

1320

out_pdf{n}=[];

1325

for j=start_sample:end_sample

1321

for j=start_sample:end_sample

1326

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1322

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1327

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

1323

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

1328

if isempty(out_pdf{n})

1324

if isempty(out_pdf{n})

1329

out_pdf{n}=target_pdf;

1325

out_pdf{n}=target_pdf;

1330

else

1326

else

1331

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

1332

end

1328

end

1333

end

1329

end

1334

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

1335

end

1331

end

1336

1332

1337

for n=1:param.levels

1333

for n=1:param.levels

1338

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

1334

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

1339

end

1335

end

1340

1336

1341

for n=1:param.levels

1337

for n=1:param.levels

1342

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

1343

end

1339

end

1344

1340

1345

for n=1:param.levels-1

1341

for n=1:param.levels-1

1346

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

1342

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

1347

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

1343

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

1348

end

1344

end

1349

1345

1350

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

1346

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

1351

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

1347

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

1352

[mineh,min_idx]=min(EH_VT);

1348

[mineh,min_idx]=min(EH_VT);

1353

out_VT=OUT_VT_L(min_idx,1);

1349

out_VT=OUT_VT_L(min_idx,1);

1354

out_VB=OUT_VT_L(min_idx,2);

1350

out_VB=OUT_VT_L(min_idx,2);

1355

1351

1356

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

1352

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

1357

% out_VT=2*CDF_Mean-A_ni_top_O;

1353

% out_VT=2*CDF_Mean-A_ni_top_O;

1358

% out_VB=-1*A_ni_bottom_O;

1354

% out_VB=-1*A_ni_bottom_O;

1359

1355

1360

if debug_plot

1356

if debug_plot

1361

figure;

1357

figure;

1362

hold on;

1358

hold on;

1363

for j=start_sample:end_sample

1359

for j=start_sample:end_sample

1364

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

1365

end

1361

end

1366

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

1362

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

1367

hold off;

1363

hold off;

1368

end

1364

end

1369

end

1365

end

1370

1366

1371

1367

1372

1368

1373

1369

1374

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)

1375

1371

1376

%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

1377

%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

1378

%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

1379

%in other places in COM

1375

%in other places in COM

1380

1376

1381

if OP.RX_CALIBRATION

1377

if OP.RX_CALIBRATION

1382

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

1383

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

1384

switch param.CTLE_type

1380

switch param.CTLE_type

1385

case 'CL93'

1381

case 'CL93'

1386

H_low2=1;

1382

H_low2=1;

1387

case 'CL120d' % this clause uses two gain indexes

1383

case 'CL120d' % this clause uses two gain indexes

1388

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

1389

case 'CL120e' % Z1 has been adjusted

1385

case 'CL120e' % Z1 has been adjusted

1390

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

1391

end

1387

end

1392

H_ctf2=H_low2.*ctle_gain2;

1388

H_ctf2=H_low2.*ctle_gain2;

1393

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

1394

else

1390

else

1395

sigma_ne=0;

1391

sigma_ne=0;

1396

end

1392

end

1397

1393

1398

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

1394

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

1399

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

1395

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

1400

if ~OP.SNR_TXwC0

1396

if ~OP.SNR_TXwC0

1401

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

1397

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

1402

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

1403

else

1399

else

1404

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

1405

end

1401

end

1406

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

1402

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

1407

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

1403

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

1408

else

1404

else

1409

NS.sigma_TX =PSD_results.S_tn_rms;

1405

NS.sigma_TX =PSD_results.S_tn_rms;

1410

NS.sigma_G = PSD_results.S_G_rms;

1406

NS.sigma_G = PSD_results.S_G_rms;

1411

NS.sigma_rjit=PSD_results.S_rj_rms ;

1407

NS.sigma_rjit=PSD_results.S_rj_rms ;

1412

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

1408

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

1413

end

1409

end

1414

% Equation 93A-41 %%

1410

% Equation 93A-41 %%

1415

1411

1416

1412

1417

% Equation 93A-42 %%

1413

% Equation 93A-42 %%

1418

% number of sigmas needed depends on the required BER.

1414

% number of sigmas needed depends on the required BER.

1419

if param.Noise_Crest_Factor == 0

1415

if param.Noise_Crest_Factor == 0

1420

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

1416

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

1421

else

1417

else

1422

NS.ber_q=param.Noise_Crest_Factor;

1418

NS.ber_q=param.Noise_Crest_Factor;

1423

end

1419

end

1424

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

1420

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

1425

% enable overriding the Q factor of the BBN instrument.

1421

% enable overriding the Q factor of the BBN instrument.

1426

if OP.force_BBN_Q_factor

1422

if OP.force_BBN_Q_factor

1427

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

1423

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

1428

else

1424

else

1429

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

1425

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

1430

end

1426

end

1431

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

1427

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

1432

1428

1433

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

1429

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

1434

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

1430

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

1435

1431

1436

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

1432

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

1437

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

1433

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

1438

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

1434

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

1439

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

1435

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

1440

1436

1441

% Implementation of 93A.1.7.3 combination procedure

1437

% Implementation of 93A.1.7.3 combination procedure

1442

% (effectively Equation 93A-44) %%

1438

% (effectively Equation 93A-44) %%

1443

1439

1444

% Self-Channel Interference is thru residual result

1440

% Self-Channel Interference is thru residual result

1445

NS.sci_pdf = chdata(1).pdfr;

1441

NS.sci_pdf = chdata(1).pdfr;

1446

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

1442

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

1447

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

1443

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

1448

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

1444

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

1449

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

1445

NS.sci_sigma=abs(NS.sci_pdf.x(sci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1450

if OP.RX_CALIBRATION ==0

1446

if OP.RX_CALIBRATION ==0

1451

% Co-Channel Interference PDFs (for information only):

1447

% Co-Channel Interference PDFs (for information only):

1452

% initialize to deltas

1448

% initialize to deltas

1453

MDNEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1449

MDNEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1454

MDFEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1450

MDFEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1455

% serially convolve FEXT/NEXT PDFs

1451

% serially convolve FEXT/NEXT PDFs

1456

for k=2:param.number_of_s4p_files

1452

for k=2:param.number_of_s4p_files

1457

if isequal(chdata(k).type, 'NEXT')

1453

if isequal(chdata(k).type, 'NEXT')

1458

MDNEXT_cci_pdf = conv_fct(MDNEXT_cci_pdf, chdata(k).pdfr);

1454

MDNEXT_cci_pdf = conv_fct(MDNEXT_cci_pdf, chdata(k).pdfr);

1459

else % ... must be FEXT

1455

else % ... must be FEXT

1460

MDFEXT_cci_pdf = conv_fct(MDFEXT_cci_pdf, chdata(k).pdfr);

1456

MDFEXT_cci_pdf = conv_fct(MDFEXT_cci_pdf, chdata(k).pdfr);

1461

end

1457

end

1462

end

1458

end

1463

1459

1464

% find "peaks" of MDNEXT/MDFEXT for reporting

1460

% find "peaks" of MDNEXT/MDFEXT for reporting

1465

mdnxi=find(cumsum(MDNEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1461

mdnxi=find(cumsum(MDNEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1466

NS.MDNEXT_peak_interference=abs(MDNEXT_cci_pdf.x(mdnxi));

1462

NS.MDNEXT_peak_interference=abs(MDNEXT_cci_pdf.x(mdnxi));

1467

mdfxi=find(cumsum(MDFEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1463

mdfxi=find(cumsum(MDFEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1468

NS.MDFEXT_peak_interference=abs(MDFEXT_cci_pdf.x(mdfxi));

1464

NS.MDFEXT_peak_interference=abs(MDFEXT_cci_pdf.x(mdfxi));

1469

1465

1470

% Combined crosstalk effect

1466

% Combined crosstalk effect

1471

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1467

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1472

cci_mxi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1468

cci_mxi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1473

cci_msi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1469

cci_msi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1474

NS.cci_sigma=abs(NS.cci_pdf.x(cci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1470

NS.cci_sigma=abs(NS.cci_pdf.x(cci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1475

NS.crosstalk_peak_interference_at_BER=abs(NS.cci_pdf.x(cci_mxi));

1471

NS.crosstalk_peak_interference_at_BER=abs(NS.cci_pdf.x(cci_mxi));

1476

% combine cci and sci

1472

% combine cci and sci

1477

NS.isi_and_xtalk_pdf = conv_fct(NS.sci_pdf, NS.cci_pdf);

1473

NS.isi_and_xtalk_pdf = conv_fct(NS.sci_pdf, NS.cci_pdf);

1478

else

1474

else

1479

% for calibration there is no cci

1475

% for calibration there is no cci

1480

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1476

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1481

end

1477

end

1482

1478

1483

mxi=find(cumsum(NS.isi_and_xtalk_pdf.y)>=param.specBER, 1, 'first');

1479

mxi=find(cumsum(NS.isi_and_xtalk_pdf.y)>=param.specBER, 1, 'first');

1484

NS.peak_interference_at_BER=abs(NS.isi_and_xtalk_pdf.x(mxi));

1480

NS.peak_interference_at_BER=abs(NS.isi_and_xtalk_pdf.x(mxi));

1485

1481

1486

1482

1487

% Equation 93A-45

1483

% Equation 93A-45

1488

combined_interference_and_noise_pdf = conv_fct(NS.isi_and_xtalk_pdf, NS.noise_pdf);

1484

combined_interference_and_noise_pdf = conv_fct(NS.isi_and_xtalk_pdf, NS.noise_pdf);

1489

PDF=combined_interference_and_noise_pdf;

1485

PDF=combined_interference_and_noise_pdf;

1490

1486

1491

% Equation 93A-37

1487

% Equation 93A-37

1492

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1488

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1493

CDF=combined_interference_and_noise_cdf;

1489

CDF=combined_interference_and_noise_cdf;

1494

function [hctf] = FD_CTLE(freq, fb, f_z, f_p1, f_p2, kacdc_dB)

1490

function [hctf] = FD_CTLE(freq, fb, f_z, f_p1, f_p2, kacdc_dB)

1495

hctf = ( 10.^(kacdc_dB/20) + 1i*freq/f_z ) ./ ( (1+1i*freq/f_p1) .* (1+1i*freq/f_p2)) ;

1491

hctf = ( 10.^(kacdc_dB/20) + 1i*freq/f_z ) ./ ( (1+1i*freq/f_p1) .* (1+1i*freq/f_p2)) ;

1496

1492

1497

function [chdata,output_args]=FD_Processing(chdata,output_args,param,OP,SDDp2p,DO_ONCE)

1493

function [chdata,output_args]=FD_Processing(chdata,output_args,param,OP,SDDp2p,DO_ONCE)

1498

%This function calculates various frequency domain metrics

1494

%This function calculates various frequency domain metrics

1499

%Mainly IL_fit, FOM_ILD, ICN, ICN_Fext, and ICN_Next

1495

%Mainly IL_fit, FOM_ILD, ICN, ICN_Fext, and ICN_Next

1500

db = @(x) 20*log10(abs(x));

1496

db = @(x) 20*log10(abs(x));

1501

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1497

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1502

if OP.WC_PORTZ

1498

if OP.WC_PORTZ

1503

A_thru = param.a_thru(param.Tx_rd_sel);

1499

A_thru = param.a_thru(param.Tx_rd_sel);

1504

A_fext = param.a_fext(param.Tx_rd_sel);

1500

A_fext = param.a_fext(param.Tx_rd_sel);

1505

A_next = param.a_next(param.Tx_rd_sel);

1501

A_next = param.a_next(param.Tx_rd_sel);

1506

else

1502

else

1507

A_thru = param.a_thru(package_testcase);

1503

A_thru = param.a_thru(package_testcase);

1508

A_fext = param.a_fext(package_testcase);

1504

A_fext = param.a_fext(package_testcase);

1509

A_next = param.a_next(package_testcase);

1505

A_next = param.a_next(package_testcase);

1510

end

1506

end

1511

for i=1:param.number_of_s4p_files

1507

for i=1:param.number_of_s4p_files

1512

if isequal(chdata(i).type, 'THRU')

1508

if isequal(chdata(i).type, 'THRU')

1513

chdata(i).A=A_thru;

1509

chdata(i).A=A_thru;

1514

chdata(i).Aicn=A_thru;

1510

chdata(i).Aicn=A_thru;

1515

elseif isequal(chdata(i).type, 'FEXT')

1511

elseif isequal(chdata(i).type, 'FEXT')

1516

chdata(i).A=A_fext;

1512

chdata(i).A=A_fext;

1517

chdata(i).Aicn=param.a_icn_fext;

1513

chdata(i).Aicn=param.a_icn_fext;

1518

elseif isequal(chdata(i).type, 'NEXT')

1514

elseif isequal(chdata(i).type, 'NEXT')

1519

chdata(i).A=A_next;

1515

chdata(i).A=A_next;

1520

chdata(i).Aicn=param.a_icn_next;

1516

chdata(i).Aicn=param.a_icn_next;

1521

end

1517

end

1522

end

1518

end

1523

if OP.TDMODE

1519

if OP.TDMODE

1524

for i=1:param.number_of_s4p_files % freq delta for integration

1520

for i=1:param.number_of_s4p_files % freq delta for integration

1525

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1521

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1526

end

1522

end

1527

end

1523

end

1528

if ~DO_ONCE

1524

if ~DO_ONCE

1529

return;

1525

return;

1530

end

1526

end

1531

%Any new output_args fields set in this function should be initialized here as empty

1527

%Any new output_args fields set in this function should be initialized here as empty

1532

output_args.fitted_IL_dB_at_Fnq = [];

1528

output_args.fitted_IL_dB_at_Fnq = [];

1533

output_args.cable__assembley_loss=[];

1529

output_args.cable__assembley_loss=[];

1534

output_args.loss_with_PCB=[];

1530

output_args.loss_with_PCB=[];

1535

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1531

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1536

output_args.IL_dB_channel_only_at_Fnq=[];

1532

output_args.IL_dB_channel_only_at_Fnq=[];

1537

output_args.VTF_loss_dB_at_Fnq=[];

1533

output_args.VTF_loss_dB_at_Fnq=[];

1538

output_args.IL_db_die_to_die_at_Fnq=[];

1534

output_args.IL_db_die_to_die_at_Fnq=[];

1539

output_args.FOM_TDILN=[];

1535

output_args.FOM_TDILN=[];

1540

output_args.TD_ILN=[];

1536

output_args.TD_ILN=[];

1541

output_args.FOM_RILN=[];

1537

output_args.FOM_RILN=[];

1542

output_args.FOM_ILD=[];

1538

output_args.FOM_ILD=[];

1543

%TD_Mode is just a pass through to set the empty values and return

1539

%TD_Mode is just a pass through to set the empty values and return

1544

if ~OP.GET_FD

1540

if ~OP.GET_FD

1545

return;

1541

return;

1546

end

1542

end

1547

case_number=param.package_testcase_i;

1543

case_number=param.package_testcase_i;

1548

f2=param.f2;

1544

f2=param.f2;

1549

f1=param.f1;

1545

f1=param.f1;

1550

MDFEXT_ICN=0; MDNEXT_ICN=0;

1546

MDFEXT_ICN=0; MDNEXT_ICN=0;

1551

for i=1:param.number_of_s4p_files

1547

for i=1:param.number_of_s4p_files

1552

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1548

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1553

% Equation 93A-20 %%

1549

% Equation 93A-20 %%

1554

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(i).faxis./(param.f_r*param.fb));

1550

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(i).faxis./(param.f_r*param.fb));

1555

f=chdata(i).faxis;

1551

f=chdata(i).faxis;

1556

%

1552

%

1557

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

1553

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

1558

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

1554

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

1559

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine); % conditionally include the RCos filter for all IR conversion using COM_FD_to_TD

1555

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine); % conditionally include the RCos filter for all IR conversion using COM_FD_to_TD

1560

H_txffe= Tx_FFE_Filter(param,f,param.Pkg_TXFFE_preset); % RIM 08-18-2022 to add forced TX ffe per package case

1556

H_txffe= Tx_FFE_Filter(param,f,param.Pkg_TXFFE_preset); % RIM 08-18-2022 to add forced TX ffe per package case

1561

H_r=H_bw.*H_bt.*H_RCos.*H_txffe; % RIM 08-18-2022 to add forced TX ffe per package case

1557

H_r=H_bw.*H_bt.*H_RCos.*H_txffe; % RIM 08-18-2022 to add forced TX ffe per package case

1562

chdata(i).sdd21=chdata(i).sdd21.*H_r;

1558

chdata(i).sdd21=chdata(i).sdd21.*H_r;

1563

if OP.DISPLAY_WINDOW

1559

if OP.DISPLAY_WINDOW

1564

if i==1

1560

if i==1

1565

figure(300+param.package_testcase_i);

1561

figure(300+param.package_testcase_i);

1566

subplot(3,1,1)

1562

subplot(3,1,1)

1567

hold on

1563

hold on

1568

plot(chdata(i).faxis/1e9, 20*log10(abs(squeeze(chdata(i).sdd21))), 'k-','linewidth',2, 'Disp',sprintf('VTF (no Tx/Rx eq)')')

1564

plot(chdata(i).faxis/1e9, 20*log10(abs(squeeze(chdata(i).sdd21))), 'k-','linewidth',2, 'Disp',sprintf('VTF (no Tx/Rx eq)')')

1569

try

1565

try

1570

legend('NumColumns',2)

1566

legend('NumColumns',2)

1571

legend('location','south')

1567

legend('location','south')

1572

catch

1568

catch

1573

end

1569

end

1574

end

1570

end

1575

end

1571

end

1576

end

1572

end

1577

end

1573

end

1578

for i=1:param.number_of_s4p_files

1574

for i=1:param.number_of_s4p_files

1579

if i == 2

1575

if i == 2

1580

PSXT(1:length(chdata(i).sdd21f))=0;

1576

PSXT(1:length(chdata(i).sdd21f))=0;

1581

MDFEXT(1:length(chdata(i).sdd21f))=0;

1577

MDFEXT(1:length(chdata(i).sdd21f))=0;

1582

MDNEXT(1:length(chdata(i).sdd21f))=0;

1578

MDNEXT(1:length(chdata(i).sdd21f))=0;

1583

end

1579

end

1584

a=find(chdata(i).faxis(:)>=f2,1,'first');% RIM 01-12-21

1580

a=find(chdata(i).faxis(:)>=f2,1,'first');% RIM 01-12-21

1585

if isempty(a)

1581

if isempty(a)

1586

f2=chdata(i).faxis(end);

1582

f2=chdata(i).faxis(end);

1587

index_f2=length(chdata(i).faxis);

1583

index_f2=length(chdata(i).faxis);

1588

else

1584

else

1589

index_f2=a(1);

1585

index_f2=a(1);

1590

end

1586

end

1591

b=find(chdata(i).faxis(:)<=f1,1,'last');% RIM 01-12-21

1587

b=find(chdata(i).faxis(:)<=f1,1,'last');% RIM 01-12-21

1592

if isempty(b)

1588

if isempty(b)

1593

f1=chdata(i).faxis(1);

1589

f1=chdata(i).faxis(1);

1594

index_f1=1;

1590

index_f1=1;

1595

else

1591

else

1596

index_f1=b(1);

1592

index_f1=b(1);

1597

end

1593

end

1598

% R is the frequency dependent parameter for the sinc function use in the

1594

% R is the frequency dependent parameter for the sinc function use in the

1599

% PWF for ICN

1595

% PWF for ICN

1600

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(i).faxis;

1596

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(i).faxis;

1601

if(chdata(i).faxis(1)==0)

1597

if(chdata(i).faxis(1)==0)

1602

temp_angle(1)=1e-20;% we don't want to divide by zero

1598

temp_angle(1)=1e-20;% we don't want to divide by zero

1603

end

1599

end

1604

SINC = sin(temp_angle)./temp_angle;

1600

SINC = sin(temp_angle)./temp_angle;

1605

PWF_data=SINC.^2;

1601

PWF_data=SINC.^2;

1606

PWF_trf=(1+(chdata(i).faxis/chdata(i).ftr).^4).^-1;

1602

PWF_trf=(1+(chdata(i).faxis/chdata(i).ftr).^4).^-1;

1607

%// bw1=2.613126; bw2=3.4142136; bw3=2.613126;

1603

%// bw1=2.613126; bw2=3.4142136; bw3=2.613126;

1608

fr=param.f_r*param.fb;

1604

fr=param.f_r*param.fb;

1609

PWF_rx=(1+(chdata(i).faxis/fr).^8).^-1;

1605

PWF_rx=(1+(chdata(i).faxis/fr).^8).^-1;

1610

PWF_highpass=1;

1606

PWF_highpass=1;

1611

% Equation 93A-57 %

1607

% Equation 93A-57 %

1612

PWF=PWF_data.*PWF_trf.*PWF_rx.*PWF_highpass; % power weight function

1608

PWF=PWF_data.*PWF_trf.*PWF_rx.*PWF_highpass; % power weight function

1613

% freq delta for integration

1609

% freq delta for integration

1614

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1610

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1615

% from ba spec, this is basically ICN

1611

% from ba spec, this is basically ICN

1616

faxis_GHz = chdata(i).faxis/1e9;

1612

faxis_GHz = chdata(i).faxis/1e9;

1617

if isequal(chdata(i).type, 'THRU')

1613

if isequal(chdata(i).type, 'THRU')

1618

[ILD_magft chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2));

1614

[ILD_magft chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2));

1619

% find fitted loss values by interpolation using full data, no indexing - Adee 2022-08-28

1615

% find fitted loss values by interpolation using full data, no indexing - Adee 2022-08-28

1620

[~, chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f, chdata(i).faxis);

1616

[~, chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f, chdata(i).faxis);

1621

fit_loss = interp1(chdata(i).faxis, -chdata(i).fit_orig, 1/param.ui/2);

1617

fit_loss = interp1(chdata(i).faxis, -chdata(i).fit_orig, 1/param.ui/2);

1622

chdata(i).fit_ILatNq = fit_loss;

1618

chdata(i).fit_ILatNq = fit_loss;

1623

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1619

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1624

IL_interp = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21f)), 1/param.ui/2);

1620

IL_interp = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21f)), 1/param.ui/2);

1625

chdata(i).ILatNq = IL_interp;

1621

chdata(i).ILatNq = IL_interp;

1626

if OP.include_pcb

1622

if OP.include_pcb

1627

cable_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_orig)), 1/param.ui/2);

1623

cable_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_orig)), 1/param.ui/2);

1628

loss_with_PCB = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_raw)), 1/param.ui/2);

1624

loss_with_PCB = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_raw)), 1/param.ui/2);

1629

output_args.cable__assembley_loss=cable_loss;

1625

output_args.cable__assembley_loss=cable_loss;

1630

output_args.loss_with_PCB=loss_with_PCB;

1626

output_args.loss_with_PCB=loss_with_PCB;

1631

end

1627

end

1632

Nq_loss=chdata(i).ILatNq;

1628

Nq_loss=chdata(i).ILatNq;

1633

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1629

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1634

% time domain ref RR = complex fit pulse

1630

% time domain ref RR = complex fit pulse

1635

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1631

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1636

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1632

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1637

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1633

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1638

FOM_ILN_complex= TD_ILN.FOM;

1634

FOM_ILN_complex= TD_ILN.FOM;

1639

end

1635

end

1640

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1636

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1641

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1637

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1642

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1638

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1643

FOM_ILN_complex= TD_ILN.FOM;

1639

FOM_ILN_complex= TD_ILN.FOM;

1644

end

1640

end

1645

if OP.COMPUTE_TDILN

1641

if OP.COMPUTE_TDILN

1646

output_args.FOM_TDILN=FOM_TDILN;

1642

output_args.FOM_TDILN=FOM_TDILN;

1647

output_args.TD_ILN=TD_ILN; % struct

1643

output_args.TD_ILN=TD_ILN; % struct

1648

end

1644

end

1649

if OP.COMPUTE_RILN

1645

if OP.COMPUTE_RILN

1650

% Get RIL, RILN, and TD_RILN

1646

% Get RIL, RILN, and TD_RILN

1651

[RIL_struct]= capture_RIL_RILN(chdata);

1647

[RIL_struct]= capture_RIL_RILN(chdata);

1652

FOM_RILN=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2-1).*RIL_struct.RILN_dB(index_f1:index_f2-1)'.^2));

1648

FOM_RILN=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2-1).*RIL_struct.RILN_dB(index_f1:index_f2-1)'.^2));

1653

output_args.FOM_RILN=FOM_RILN;

1649

output_args.FOM_RILN=FOM_RILN;

1654

%---start. plotting ILN based on ILD and RILN % Hansel 10/18/2021

1650

%---start. plotting ILN based on ILD and RILN % Hansel 10/18/2021

1655

plot_tdomain_debug= 0; % must have OP.COMPUTE_TDILN = 1 to use

1651

plot_tdomain_debug= 0; % must have OP.COMPUTE_TDILN = 1 to use

1656

if plot_tdomain_debug== 1

1652

if plot_tdomain_debug== 1

1657

figure(988); set(gcf,'Tag','COM')

1653

figure(988); set(gcf,'Tag','COM')

1658

ax_1= subplot(3,1,1);

1654

ax_1= subplot(3,1,1);

1659

plot(TD_ILN.REF.t*1e9, TD_ILN.REF.PR*1e3,'disp','ref');

1655

plot(TD_ILN.REF.t*1e9, TD_ILN.REF.PR*1e3,'disp','ref');

1660

hold on;

1656

hold on;

1661

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1657

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1662

hold on;

1658

hold on;

1663

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k','disp','ref - fit (IL noise)');

1659

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k','disp','ref - fit (IL noise)');

1664

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1660

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1665

grid on;

1661

grid on;

1666

box on;

1662

box on;

1667

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1663

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1668

xlabel('Time [nsec]');

1664

xlabel('Time [nsec]');

1669

ylabel('Pulse Response [mV]');

1665

ylabel('Pulse Response [mV]');

1670

1666

1671

ax_2= subplot(3,1,2);

1667

ax_2= subplot(3,1,2);

1672

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1668

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1673

hold on;

1669

hold on;

1674

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1670

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1675

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1671

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1676

grid on;

1672

grid on;

1677

box on;

1673

box on;

1678

legend('REF', 'TD\_RILN');

1674

legend('REF', 'TD\_RILN');

1679

xlabel('Time [nsec]');

1675

xlabel('Time [nsec]');

1680

ylabel('Pulse Response [mV]');

1676

ylabel('Pulse Response [mV]');

1681

ax_3= subplot(3,1,3);

1677

ax_3= subplot(3,1,3);

1682

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1678

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1683

hold on;

1679

hold on;

1684

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1680

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1685

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1681

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1686

grid on;

1682

grid on;

1687

box on;

1683

box on;

1688

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1684

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1689

xlabel('Time [nsec]');

1685

xlabel('Time [nsec]');

1690

ylabel('Pulse Response [mV]');

1686

ylabel('Pulse Response [mV]');

1691

1687

1692

linkaxes([ax_1, ax_2, ax_3], 'x');

1688

linkaxes([ax_1, ax_2, ax_3], 'x');

1693

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1689

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1694

end

1690

end

1695

%---end. plotting ILN based on ILD and RILN

1691

%---end. plotting ILN based on ILD and RILN

1696

end

1692

end

1697

% Equation 93A-56 %

1693

% Equation 93A-56 %

1698

FOM_ILD=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1694

FOM_ILD=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1699

output_args.FOM_ILD=FOM_ILD;

1695

output_args.FOM_ILD=FOM_ILD;

1700

if OP.DEBUG

1696

if OP.DEBUG

1701

if OP.DISPLAY_WINDOW

1697

if OP.DISPLAY_WINDOW

1702

figure(300+case_number);

1698

figure(300+case_number);

1703

set(gcf,'Tag','COM')

1699

set(gcf,'Tag','COM')

1704

screen_size=get(0,'ScreenSize');

1700

screen_size=get(0,'ScreenSize');

1705

pos = get(gcf, 'OuterPosition');

1701

pos = get(gcf, 'OuterPosition');

1706

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1702

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1707

screen_size([3 4 3 4]).*[0 1 0 0] + pos([3 4 3 4]).*[0 -2 1 2] ...IL fit

1703

screen_size([3 4 3 4]).*[0 1 0 0] + pos([3 4 3 4]).*[0 -2 1 2] ...IL fit

1708

- (case_number-1)*[0 20 0 0]);

1704

- (case_number-1)*[0 20 0 0]);

1709

subplot(3,1,1)

1705

subplot(3,1,1)

1710

title('Losses')

1706

title('Losses')

1711

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1707

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1712

hold on

1708

hold on

1713

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1709

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1714

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1710

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1715

ylim(get(gca, 'ylim'));

1711

ylim(get(gca, 'ylim'));

1716

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1712

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1717

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1713

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1718

subplot(3,1,3)

1714

subplot(3,1,3)

1719

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1715

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1720

if OP.PLOT_CM

1716

if OP.PLOT_CM

1721

if case_number ==1

1717

if case_number ==1

1722

h350=figure(350);set(gcf,'Tag','COM')

1718

h350=figure(350);set(gcf,'Tag','COM')

1723

screen_size=get(0,'ScreenSize');

1719

screen_size=get(0,'ScreenSize');

1724

pos = get(gcf, 'OuterPosition');

1720

pos = get(gcf, 'OuterPosition');

1725

set(gcf, 'OuterPosition',screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-2 -2 2 1])

1721

set(gcf, 'OuterPosition',screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-2 -2 2 1])

1726

movegui(gcf,'center');

1722

movegui(gcf,'center');

1727

htabgroup350 = uitabgroup(h350);

1723

htabgroup350 = uitabgroup(h350);

1728

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1724

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1729

hax1 = axes('Parent', htab1);

1725

hax1 = axes('Parent', htab1);

1730

set(h350,'CurrentAxes',hax1)

1726

set(h350,'CurrentAxes',hax1)

1731

hold on

1727

hold on

1732

set(gcf,'Tag','COM')

1728

set(gcf,'Tag','COM')

1733

screen_size=get(0,'ScreenSize');

1729

screen_size=get(0,'ScreenSize');

1734

pos = get(gcf, 'OuterPosition');

1730

pos = get(gcf, 'OuterPosition');

1735

title('IL & CM Losses')

1731

title('IL & CM Losses')

1736

base=strrep(chdata(i).base,'_',' ');

1732

base=strrep(chdata(i).base,'_',' ');

1737

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp', [ 'sdd21(IL) TP0-TP5 ' base])

1733

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp', [ 'sdd21(IL) TP0-TP5 ' base])

1738

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1734

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1739

ylabel('dB')

1735

ylabel('dB')

1740

xlabel('GHz')

1736

xlabel('GHz')

1741

legend show

1737

legend show

1742

legend('Location','eastoutside')

1738

legend('Location','eastoutside')

1743

hold on

1739

hold on

1744

grid on

1740

grid on

1745

if param.number_of_s4p_files > 1

1741

if param.number_of_s4p_files > 1

1746

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1742

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1747

hax2 = axes('Parent', htab2);

1743

hax2 = axes('Parent', htab2);

1748

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1744

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1749

hax3 = axes('Parent', htab3);

1745

hax3 = axes('Parent', htab3);

1750

end

1746

end

1751

1747

1752

end

1748

end

1753

end

1749

end

1754

else

1750

else

1755

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1751

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1756

end

1752

end

1757

end

1753

end

1758

else % NEXT or FEXT

1754

else % NEXT or FEXT

1759

if isequal(chdata(i).type, 'FEXT')

1755

if isequal(chdata(i).type, 'FEXT')

1760

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1756

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1761

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46

1757

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46

1762

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1758

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1763

elseif isequal(chdata(i).type, 'NEXT')

1759

elseif isequal(chdata(i).type, 'NEXT')

1764

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1760

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1765

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47

1761

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47

1766

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1762

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1767

end

1763

end

1768

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1764

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1769

ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));

1765

ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));

1770

output_args.ICN_mV=ICN*1000;

1766

output_args.ICN_mV=ICN*1000;

1771

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1767

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1772

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1768

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1773

if case_number ==1

1769

if case_number ==1

1774

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1770

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1775

% hax2 = axes('Parent', htab2);

1771

% hax2 = axes('Parent', htab2);

1776

set(h350,'CurrentAxes',hax2)

1772

set(h350,'CurrentAxes',hax2)

1777

hold on

1773

hold on

1778

title('CM Losses')

1774

title('CM Losses')

1779

base=strrep(chdata(i).base,'_',' ');

1775

base=strrep(chdata(i).base,'_',' ');

1780

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1776

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1781

legend('Location','eastoutside')

1777

legend('Location','eastoutside')

1782

hold on

1778

hold on

1783

grid on

1779

grid on

1784

set(h350,'CurrentAxes',hax3)

1780

set(h350,'CurrentAxes',hax3)

1785

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1781

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1786

legend('Location','eastoutside')

1782

legend('Location','eastoutside')

1787

hold on

1783

hold on

1788

grid on

1784

grid on

1789

end

1785

end

1790

end

1786

end

1791

end

1787

end

1792

end % for loop

1788

end % for loop

1793

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1789

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1794

if OP.DEBUG && OP.DISPLAY_WINDOW

1790

if OP.DEBUG && OP.DISPLAY_WINDOW

1795

figure(300+case_number);set(gcf,'Tag','COM');

1791

figure(300+case_number);set(gcf,'Tag','COM');

1796

if param.number_of_s4p_files > 1

1792

if param.number_of_s4p_files > 1

1797

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1793

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1798

subplot(3,1,1)

1794

subplot(3,1,1)

1799

hold on

1795

hold on

1800

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1796

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1801

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1797

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1802

subplot(3,1,2)

1798

subplot(3,1,2)

1803

grid on

1799

grid on

1804

ILtemp=20*log10(abs(chdata(1).sdd21f));

1800

ILtemp=20*log10(abs(chdata(1).sdd21f));

1805

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1801

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1806

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1802

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1807

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1803

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1808

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1804

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1809

hold on

1805

hold on

1810

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1806

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1811

end

1807

end

1812

subplot(3,1,1)

1808

subplot(3,1,1)

1813

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1809

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1814

grid on; legend show

1810

grid on; legend show

1815

subplot(3,1,2)

1811

subplot(3,1,2)

1816

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1812

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1817

ylim([0 80])

1813

ylim([0 80])

1818

xlim([.1 100])

1814

xlim([.1 100])

1819

grid on; %legend show

1815

grid on; %legend show

1820

subplot(3,1,3)

1816

subplot(3,1,3)

1821

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1817

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1822

ylim([-3 3])

1818

ylim([-3 3])

1823

grid on; legend show

1819

grid on; legend show

1824

end

1820

end

1825

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1821

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1826

total_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21)), 1/param.ui/2);

1822

total_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21)), 1/param.ui/2);

1827

d2d_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p_nodie)), 1/param.ui/2);

1823

d2d_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p_nodie)), 1/param.ui/2);

1828

VIP_VMP_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p)), 1/param.ui/2);

1824

VIP_VMP_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p)), 1/param.ui/2);

1829

output_args.VTF_loss_dB_at_Fnq=total_loss;

1825

output_args.VTF_loss_dB_at_Fnq=total_loss;

1830

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1826

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1831

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1827

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1832

function [ V0 ] = FFE( C , cmx,spui, V )

1828

function [ V0 ] = FFE( C , cmx,spui, V )

1833

% C FFE taps

1829

% C FFE taps

1834

% cmx number of precursors taps

1830

% cmx number of precursors taps

1835

% spui samples per ui

1831

% spui samples per ui

1836

% V input signal

1832

% V input signal

1837

%speed ups implemented:

1833

%speed ups implemented:

1838

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1834

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1839

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1835

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1840

1836

1841

V0=0;

1837

V0=0;

1842

if iscolumn(V); V=V.';end

1838

if iscolumn(V); V=V.';end

1843

for i=1:length(C)

1839

for i=1:length(C)

1844

if C(i)~=0

1840

if C(i)~=0

1845

ishift=(i-1-cmx)*spui;

1841

ishift=(i-1-cmx)*spui;

1846

V0=circshift(V',[ishift,0])*C(i)+V0;

1842

V0=circshift(V',[ishift,0])*C(i)+V0;

1847

end

1843

end

1848

end

1844

end

1849

%V0=circshift(V0,[(-cmx)*spui,0]);

1845

%V0=circshift(V0,[(-cmx)*spui,0]);

1850

% disp(max(V0));

1846

% disp(max(V0));

1851

1847

1852

1848

1853

% begin yasuo patch 12/11/2018

1849

% begin yasuo patch 12/11/2018

1854

% calculate sigma (standard deviation) value of PDF

1850

% calculate sigma (standard deviation) value of PDF

1855

function [ V0 ] = FFE_Fast( C,V_shift )

1851

function [ V0 ] = FFE_Fast( C,V_shift )

1856

% C FFE taps

1852

% C FFE taps

1857

% V input signal separated into length(C) columns with circshift already performed

1853

% V input signal separated into length(C) columns with circshift already performed

1858

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1854

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1859

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1855

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1860

% saved by pre-shifting it and remembering it across loops

1856

% saved by pre-shifting it and remembering it across loops

1861

% Another speed up: only multiply by indices of C that are not 0

1857

% Another speed up: only multiply by indices of C that are not 0

1862

1858

1863

V0=0;

1859

V0=0;

1864

for i=1:length(C)

1860

for i=1:length(C)

1865

if C(i)~=0

1861

if C(i)~=0

1866

V0=V_shift(:,i)*C(i)+V0;

1862

V0=V_shift(:,i)*C(i)+V0;

1867

end

1863

end

1868

end

1864

end

1869

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1865

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1870

1866

1871

hisi=h(isi_start:isi_end);

1867

hisi=h(isi_start:isi_end);

1872

hisi=hisi(param.RxFFE_cpx+1:param.N_bmax);

1868

hisi=hisi(param.RxFFE_cpx+1:param.N_bmax);

1873

bank_size = param.N_bf;

1869

bank_size = param.N_bf;

1874

num_groups = param.N_bg;

1870

num_groups = param.N_bg;

1875

1871

1876

1872

1877

%start with one by one Floating Tap

1873

%start with one by one Floating Tap

1878

num_isi=length(hisi);

1874

num_isi=length(hisi);

1879

max_isi=num_isi-bank_size+1;

1875

max_isi=num_isi-bank_size+1;

1880

valid_tap_locations=1:max_isi;

1876

valid_tap_locations=1:max_isi;

1881

all_idx=[];

1877

all_idx=[];

1882

for j=1:num_groups

1878

for j=1:num_groups

1883

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1879

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1884

for k=1:length(valid_tap_locations)

1880

for k=1:length(valid_tap_locations)

1885

this_location=valid_tap_locations(k);

1881

this_location=valid_tap_locations(k);

1886

new_idx = [all_idx this_location:this_location+bank_size-1];

1882

new_idx = [all_idx this_location:this_location+bank_size-1];

1887

new_idx=sort(new_idx);

1883

new_idx=sort(new_idx);

1888

new_idx = new_idx+param.RxFFE_cpx;

1884

new_idx = new_idx+param.RxFFE_cpx;

1889

%calculate FOM for each one

1885

%calculate FOM for each one

1890

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1886

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1891

end

1887

end

1892

%choose the location with best FOM

1888

%choose the location with best FOM

1893

%add it to the "all_idx" list and remove it from valid locations

1889

%add it to the "all_idx" list and remove it from valid locations

1894

[~,best_FOM_idx]=max(best_FOM);

1890

[~,best_FOM_idx]=max(best_FOM);

1895

start_tap = valid_tap_locations(best_FOM_idx);

1891

start_tap = valid_tap_locations(best_FOM_idx);

1896

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1892

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1897

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1893

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1898

remove_range(remove_range>length(valid_tap_locations))=[];

1894

remove_range(remove_range>length(valid_tap_locations))=[];

1899

valid_tap_locations(remove_range)=[];

1895

valid_tap_locations(remove_range)=[];

1900

1896

1901

%Also remove illegal taps from valid locations

1897

%Also remove illegal taps from valid locations

1902

%illegal taps are ones that would overlap with the chosen bank

1898

%illegal taps are ones that would overlap with the chosen bank

1903

bad_tap=start_tap-bank_size+1:start_tap-1;

1899

bad_tap=start_tap-bank_size+1:start_tap-1;

1904

bad_tap(bad_tap<1)=[];

1900

bad_tap(bad_tap<1)=[];

1905

for n=1:length(bad_tap)

1901

for n=1:length(bad_tap)

1906

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1902

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1907

if ~isempty(bad_tap_idx)

1903

if ~isempty(bad_tap_idx)

1908

valid_tap_locations(bad_tap_idx)=[];

1904

valid_tap_locations(bad_tap_idx)=[];

1909

end

1905

end

1910

end

1906

end

1911

end

1907

end

1912

1908

1913

%put idx back in the right location (adding RxFFE_cpx)

1909

%put idx back in the right location (adding RxFFE_cpx)

1914

idx = all_idx+param.RxFFE_cpx;

1910

idx = all_idx+param.RxFFE_cpx;

1915

idx = sort(idx);

1911

idx = sort(idx);

1916

function [ V0 ] = Fract_T_FFE( V , skew_step)

1912

function [ V0 ] = Fract_T_FFE( V , skew_step)

1917

% skew_step sub UI skew assuming param.samples_per_ui

1913

% skew_step sub UI skew assuming param.samples_per_ui

1918

% V input signal

1914

% V input signal

1919

% V0 output signal

1915

% V0 output signal

1920

% Richard Mellitz 8/17/2021

1916

% Richard Mellitz 8/17/2021

1921

V0=0;

1917

V0=0;

1922

if iscolumn(V); V=V.';end

1918

if iscolumn(V); V=V.';end

1923

ishift=skew_step;

1919

ishift=skew_step;

1924

V0=circshift(V',[ishift,0])'+V;

1920

V0=circshift(V',[ishift,0])'+V;

1925

V0=V0/2;

1921

V0=V0/2;

1926

function out=Full_Grid_Matrix(in)

1922

function out=Full_Grid_Matrix(in)

1927

1923

1928

%create a full grid matrix of input variables

1924

%create a full grid matrix of input variables

1929

%used to create the full grid of all txffe cases

1925

%used to create the full grid of all txffe cases

1930

%example:

1926

%example:

1931

%Full_Grid_Matrix({ [1 2] [100 200] })

1927

%Full_Grid_Matrix({ [1 2] [100 200] })

1932

%out =

1928

%out =

1933

% 1 100

1929

% 1 100

1934

% 1 200

1930

% 1 200

1935

% 2 100

1931

% 2 100

1936

% 2 200

1932

% 2 200

1937

%

1933

%

1938

%input can also be mixed between numeric and cell of char

1934

%input can also be mixed between numeric and cell of char

1939

%example:

1935

%example:

1940

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1936

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1941

%out =

1937

%out =

1942

% {[1]} {'A'}

1938

% {[1]} {'A'}

1943

% {[1]} {'B'}

1939

% {[1]} {'B'}

1944

% {[2]} {'A'}

1940

% {[2]} {'A'}

1945

% {[2]} {'B'}

1941

% {[2]} {'B'}

1946

1942

1947

if ~iscell(in)

1943

if ~iscell(in)

1948

error('input must be cell array of individual sweep variables');

1944

error('input must be cell array of individual sweep variables');

1949

end

1945

end

1950

1946

1951

num_columns=length(in);

1947

num_columns=length(in);

1952

num_cases=prod(cellfun('length',in));

1948

num_cases=prod(cellfun('length',in));

1953

1949

1954

cell_output=0;

1950

cell_output=0;

1955

cell_indices=cellfun(@(x) iscell(x),in);

1951

cell_indices=cellfun(@(x) iscell(x),in);

1956

if any(cell_indices)

1952

if any(cell_indices)

1957

cell_output=1;

1953

cell_output=1;

1958

end

1954

end

1959

if cell_output

1955

if cell_output

1960

for k=find(~cell_indices)

1956

for k=find(~cell_indices)

1961

in{k}=num2cell(in{k});

1957

in{k}=num2cell(in{k});

1962

end

1958

end

1963

end

1959

end

1964

1960

1965

if cell_output

1961

if cell_output

1966

out=cell(num_cases,num_columns);

1962

out=cell(num_cases,num_columns);

1967

else

1963

else

1968

out=zeros(num_cases,num_columns);

1964

out=zeros(num_cases,num_columns);

1969

end

1965

end

1970

1966

1971

%num_repetitions controls how many times each element of the column

1967

%num_repetitions controls how many times each element of the column

1972

%repeats. The first column is always just a copy of itself since every

1968

%repeats. The first column is always just a copy of itself since every

1973

%case will vary.

1969

%case will vary.

1974

num_repetitions=1;

1970

num_repetitions=1;

1975

for k=num_columns:-1:1

1971

for k=num_columns:-1:1

1976

this_column=in{k}(:);

1972

this_column=in{k}(:);

1977

%copy the column into a matrix to create the repetitions needed

1973

%copy the column into a matrix to create the repetitions needed

1978

B=repmat(this_column,[1 num_repetitions]);

1974

B=repmat(this_column,[1 num_repetitions]);

1979

%reshape into single column (actual repetitions)

1975

%reshape into single column (actual repetitions)

1980

C=reshape(B',[numel(B) 1]);

1976

C=reshape(B',[numel(B) 1]);

1981

%repeat the single column to build the entire length required

1977

%repeat the single column to build the entire length required

1982

num_repeats=num_cases/length(C);

1978

num_repeats=num_cases/length(C);

1983

D=repmat(C,[num_repeats 1]);

1979

D=repmat(C,[num_repeats 1]);

1984

out(:,k)=D;

1980

out(:,k)=D;

1985

%determine how many repetitions the next column needs

1981

%determine how many repetitions the next column needs

1986

num_repetitions=num_repetitions*length(this_column);

1982

num_repetitions=num_repetitions*length(this_column);

1987

end

1983

end

1988

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1984

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1989

% p=cpdf(type, ...)

1985

% p=cpdf(type, ...)

1990

%

1986

%

1991

% CPDF is a probability mass function for discrete distributions or an

1987

% CPDF is a probability mass function for discrete distributions or an

1992

% approxmation of a PDF for continuous distributions.

1988

% approxmation of a PDF for continuous distributions.

1993

%

1989

%

1994

% cpdf is internally normalized so that the sum of probabilities is 1

1990

% cpdf is internally normalized so that the sum of probabilities is 1

1995

% (regardless of bin size).

1991

% (regardless of bin size).

1996

1992

1997

% Internal fields:

1993

% Internal fields:

1998

% Min: *bin number* of minimum value.

1994

% Min: *bin number* of minimum value.

1999

% BinSize: size of PDF bins. Bin center is the representative value.

1995

% BinSize: size of PDF bins. Bin center is the representative value.

2000

% Vec: vector of probabilities per bin.

1996

% Vec: vector of probabilities per bin.

2001

1997

2002

pdf=EmptyPDF;

1998

pdf=EmptyPDF;

2003

1999

2004

rounded_values_div_binsize=round(values/pdf.BinSize);

2000

rounded_values_div_binsize=round(values/pdf.BinSize);

2005

%values=pdf.BinSize*rounded_values_div_binsize;

2001

%values=pdf.BinSize*rounded_values_div_binsize;

2006

2002

2007

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2003

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2008

% if all(values==0)

2004

% if all(values==0)

2009

% return;

2005

% return;

2010

% end

2006

% end

2011

%

2007

%

2012

% %speed up for all values rounded to the same bin

2008

% %speed up for all values rounded to the same bin

2013

% %The output pdf is the same as the

2009

% %The output pdf is the same as the

2014

% %empty pdf, but the x value is non-zero (but still scalar)

2010

% %empty pdf, but the x value is non-zero (but still scalar)

2015

% if all(values==values(1))

2011

% if all(values==values(1))

2016

% pdf.Min=rounded_values_div_binsize(1);

2012

% pdf.Min=rounded_values_div_binsize(1);

2017

% pdf.x=values(1);

2013

% pdf.x=values(1);

2018

% return;

2014

% return;

2019

% end

2015

% end

2020

%

2016

%

2021

% %The code below requires that values is

2017

% %The code below requires that values is

2022

% %sorted. Generally this should be true, but check to be sure

2018

% %sorted. Generally this should be true, but check to be sure

2023

% if ~issorted(values)

2019

% if ~issorted(values)

2024

% [values,si]=sort(values);

2020

% [values,si]=sort(values);

2025

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2021

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2026

% probs=probs(si);

2022

% probs=probs(si);

2027

% end

2023

% end

2028

2024

2029

2025

2030

%pdf.x=values(1):pdf.BinSize:values(end);

2026

%pdf.x=values(1):pdf.BinSize:values(end);

2031

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2027

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2032

pdf.Min=rounded_values_div_binsize(1);

2028

pdf.Min=rounded_values_div_binsize(1);

2033

2029

2034

pdf.y=zeros(size(pdf.x));

2030

pdf.y=zeros(size(pdf.x));

2035

%The rounded values divided by binsize will reveal the bin number if

2031

%The rounded values divided by binsize will reveal the bin number if

2036

%pdf.Min is subtracted from it

2032

%pdf.Min is subtracted from it

2037

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2033

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2038

%Can avoid one addition by inserting the first probability

2034

%Can avoid one addition by inserting the first probability

2039

%actually helps when calling this 2 million times

2035

%actually helps when calling this 2 million times

2040

pdf.y(bin_placement(1))=probs(1);

2036

pdf.y(bin_placement(1))=probs(1);

2041

for k=2:length(values)

2037

for k=2:length(values)

2042

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2038

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2043

end

2039

end

2044

2040

2045

2041

2046

%Have already ensured that sum(pdf.y)=1

2042

%Have already ensured that sum(pdf.y)=1

2047

%pdf.y=pdf.y/sum(pdf.y);

2043

%pdf.y=pdf.y/sum(pdf.y);

2048

2044

2049

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2045

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2050

% error('PDF must be real and nonnegative');

2046

% error('PDF must be real and nonnegative');

2051

% end

2047

% end

2052

2048

2053

% pMax=pdf.Min+length(pdf.y)-1;

2049

% pMax=pdf.Min+length(pdf.y)-1;

2054

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2050

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2055

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2051

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2056

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2052

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2057

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2053

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2058

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2054

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2059

2055

2060

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2056

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2061

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2057

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2062

2058

2063

%% step 0

2059

%% step 0

2064

COM_from_matlab=20*log10(A_s/A_ni);

2060

COM_from_matlab=20*log10(A_s/A_ni);

2065

L=param.levels;

2061

L=param.levels;

2066

DER0=param.specBER;

2062

DER0=param.specBER;

2067

%% step 1 from slide 6/5

2063

%% step 1 from slide 6/5

2068

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2064

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2069

main=A_peak;

2065

main=A_peak;

2070

k_DER=qfuncinv(param.specBER);

2066

k_DER=qfuncinv(param.specBER);

2071

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2067

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2072

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2068

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2073

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2069

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2074

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2070

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2075

if A_s >= A_ni

2071

if A_s >= A_ni

2076

%% step 2 slide 10/8

2072

%% step 2 slide 10/8

2077

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2073

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2078

%% step 2 slide 10/8

2074

%% step 2 slide 10/8

2079

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2075

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2080

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2076

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2081

%% step 3 side 11/9

2077

%% step 3 side 11/9

2082

j=1:200;

2078

j=1:200;

2083

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2079

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2084

DER_MLSE_CDF=0; jj=1;

2080

DER_MLSE_CDF=0; jj=1;

2085

DER_delta = inf;

2081

DER_delta = inf;

2086

while DER_delta > .001

2082

while DER_delta > .001

2087

last_DER_MLSE_CDF=DER_MLSE_CDF;

2083

last_DER_MLSE_CDF=DER_MLSE_CDF;

2088

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2084

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2089

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2085

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2090

jj=jj+1;

2086

jj=jj+1;

2091

end

2087

end

2092

%% step 4 slide 12/10

2088

%% step 4 slide 12/10

2093

SNR_DFE_eqivalent=SNR_DFE*(...

2089

SNR_DFE_eqivalent=SNR_DFE*(...

2094

(L-1)*sigma_noise/main * qfuncinv(...

2090

(L-1)*sigma_noise/main * qfuncinv(...

2095

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2091

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2096

) ...

2092

) ...

2097

)^2;

2093

)^2;

2098

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2094

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2099

(L-1)/main * CDF_inv_ev(...

2095

(L-1)/main * CDF_inv_ev(...

2100

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2096

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2101

,PDF, CDF ) ...

2097

,PDF, CDF ) ...

2102

)^2;

2098

)^2;

2103

2099

2104

%% step 5 slide 13/11

2100

%% step 5 slide 13/11

2105

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2101

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2106

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2102

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2107

new_com_CDF=COM_from_matlab+delta_com_CDF;

2103

new_com_CDF=COM_from_matlab+delta_com_CDF;

2108

else

2104

else

2109

warning('MLSE not applied because there is more noise than signal')

2105

warning('MLSE not applied because there is more noise than signal')

2110

DER_MLSE=[];

2106

DER_MLSE=[];

2111

DER_MLSE_CDF=[];

2107

DER_MLSE_CDF=[];

2112

SNR_DFE_eqivalent=[];

2108

SNR_DFE_eqivalent=[];

2113

SNR_DFE_eqivalent_CDF=[];

2109

SNR_DFE_eqivalent_CDF=[];

2114

new_com_CDF=COM_from_matlab;

2110

new_com_CDF=COM_from_matlab;

2115

delta_com_CDF=0;

2111

delta_com_CDF=0;

2116

delta_com=0;

2112

delta_com=0;

2117

SNR_DFE=[];

2113

SNR_DFE=[];

2118

end

2114

end

2119

2115

2120

%%

2116

%%

2121

MLSE_results.COM_from_matlab=COM_from_matlab;

2117

MLSE_results.COM_from_matlab=COM_from_matlab;

2122

MLSE_results.SNR_DFE=SNR_DFE;

2118

MLSE_results.SNR_DFE=SNR_DFE;

2123

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2119

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2124

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2120

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2125

MLSE_results.sigma_noise=sigma_noise;

2121

MLSE_results.sigma_noise=sigma_noise;

2126

MLSE_results.SNR_dB=SNR_dB ;

2122

MLSE_results.SNR_dB=SNR_dB ;

2127

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2123

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2128

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2124

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2129

MLSE_results.COM_Gaussian=new_com_CDF;

2125

MLSE_results.COM_Gaussian=new_com_CDF;

2130

MLSE_results.COM_CDF=new_com_CDF;

2126

MLSE_results.COM_CDF=new_com_CDF;

2131

MLSE_results.k_DER=k_DER;

2127

MLSE_results.k_DER=k_DER;

2132

MLSE_results.delta_com_CDF=delta_com_CDF;

2128

MLSE_results.delta_com_CDF=delta_com_CDF;

2133

MLSE_results.delta_com_Gaussian=delta_com;

2129

MLSE_results.delta_com_Gaussian=delta_com;

2134

2130

2135

2131

2136

2132

+2133

function [MLSE_results] = MLSE_U1_c(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2134

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2135

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2136

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2137

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2138

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2139

%% step 0

2140

COM_from_matlab=20*log10(A_s/A_ni);

2141

L=param.levels;

2142

DER0=param.specBER;

2143

%% step 1 from slide 6 shakiba_3dj_01_230116

2144

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2145

main=A_peak;

2146

k_DER=qfuncinv(param.specBER);

2147

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2148

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2149

% if A_s >= A_ni

2150

if 1

2151

%% step 2 slide 10 shakiba_3dj_01_230116

2152

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2153

%% step 2 slide 10 not used

2154

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2155

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2156

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2157

S_n=PSD_results.Sn_rho; % total agregate noise PSD

2158

Rn=ifft(S_n)*param.fb;

2159

Rho_row=Rn/Rn(1);

2160

Rn_len=length(Rn);

2161

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2162

for j=1:Rn_len

2163

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2164

end

2165

rho_noiseEE_row=Rho_row.*alphas_row;

2166

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2167

for j=1:Rn_len

2168

rho_noiseEE(j,j)=(1-alpha)^2;

2169

end

2170

rho_noiseEE(1,1)=1;

2171

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2172

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2173

% determine complete matrix

2174

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2175

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2176

%% shakiba_3dj_elec_01a_230504 slide 17

2177

j=1:Rn_len;

2178

DER_MLSE=[];

2179

DER_MLSE_CDF=0; jj=1;

2180

DER_MLSE_CDFold=0;

2181

DER_delta = inf;

2182

% slight modified for PAM4 DER vs SER

2183

while DER_delta > .0001 && jj<=Rn_len || jj==1

2184

last_DER_MLSE_CDF=DER_MLSE_CDF;

2185

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2186

DER_MLSE_CDF= ...

2187

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2188

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2189

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2190

jj=jj+1;

2191

end

2192

%% shakiba_3dj_elec_01a_230504 slide 19

2193

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2194

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2195

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2196

(L-1)/main * CDF_inv_ev(...

2197

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2198

,PDF, CDF ) ...

2199

)^2;

2200

%% step 5 shakiba_3dj_01_230116 slide 13

2201

delta_com=[];

2202

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2203

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2204

2205

new_com_CDF=COM_from_matlab+delta_com_CDF;

2206

else

2207

warning('MLSE not applied because there is more noise than signal')

2208

DER_MLSE=[];

2209

DER_MLSE_CDF=[];

2210

SNR_DFE_eqivalent=[];

2211

SNR_DFE_eqivalent_CDF=[];

2212

new_com_CDF=COM_from_matlab;

2213

delta_com_CDF=0;

2214

delta_com=0;

2215

SNR_DFE=[];

2216

end

2217

SNR_DFE_eqivalent=[];

2218

%%

2219

MLSE_results.COM_from_matlab=COM_from_matlab;

2220

MLSE_results.SNR_DFE=SNR_DFE;

2221

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2222

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2223

MLSE_results.sigma_noise=sigma_noise;

2224

MLSE_results.SNR_dB=SNR_dB ;

2225

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2226

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2227

MLSE_results.COM_Gaussian=new_com_CDF;

2228

MLSE_results.COM_CDF=new_com_CDF;

2229

MLSE_results.k_DER=k_DER;

2230

MLSE_results.delta_com_CDF=delta_com_CDF;

2231

MLSE_results.delta_com_Gaussian=delta_com;

2232

2233

2234

2137

function [MLSE_results] = MLSE_U1_c_178A(param,b,A_s,A_ni,PDF,CDF,PSD_results)

2235

function [MLSE_results] = MLSE_U1_c_178A(param,b,A_s,A_ni,PDF,CDF,PSD_results)

2138

if 1

2236

if 1

2139

num_ui=param.num_ui_RXFF_noise;

2237

num_ui=param.num_ui_RXFF_noise;

2140

M=param.samples_per_ui;

2238

M=param.samples_per_ui;

2141

L=param.levels;

2239

L=param.levels;

2142

sigma_X2=(L^2-1)/(3*(L-1)^2);

2240

sigma_X2=(L^2-1)/(3*(L-1)^2);

2143

f_b=param.fb;

2241

f_b=param.fb;

2144

DER0=param.specBER; % align terminology

2145

delta_COM_an=param.pass_threshold; % align terminology

2146

end

2242

end

2147

% new function to scale CDF at specified DER; healey_3dj_01_2409 slide 8, 12, and 13

2148

% directly compute p_an (PDF) and P_an (CDF);

2149

[p_an, P_an, ~] = scaleCDF( PDF,delta_COM_an,DER0, A_s );

2150

sigma_an_2_pdf=sum(p_an.y.*p_an.x.^2)-sum(PDF.y.*PDF.x.^2);

2151

sigma_G_2=PSD_results.S_G_rms^2;

2152

g_an=(sigma_an_2_pdf-PSD_results.S_G_rms^2)/PSD_results.S_rn_rms^2;

2153

2154

% g_an be squared since votltage was scalted: healey_3dj_01_2409 slide 12 (178A –X) units are power

2155

% g_an=g_an^2;

2156

COM_from_matlab=20*log10(A_s/A_ni);

2243

COM_from_matlab=20*log10(A_s/A_ni);

2157

DER_DFE= 2*(L-1)/L*CDF_ev(A_s,PDF, CDF);

2244

DER_DFE= 2*(L-1)/L*CDF_ev(A_s,PDF, CDF);

2158

if 1 % comparing to healey_3dj_01_2409 slide 8

2159

figure(1200);set(gcf,'Tag','COM');

2160

semilogy(PDF.x/A_s,CDF,'disp',sprintf('P(y) case %g',param.package_testcase_i))

2161

ylim([1e-7 1e-1])

2162

grid on

2163

movegui(gcf,[randn randn]*100)

2164

xlabel('-A_ni/A_s')

2165

ylabel('DER')

2166

hold on

2167

semilogy(p_an.x/A_s,P_an,'disp',sprintf('P_a_n(y) case %g',param.package_testcase_i'))

2168

legend show

2169

% fprintf('checking %.4g dB is the com threshold\n', db(CDF_inv_ev ( param.specBER,p_an,P_an )/CDF_inv_ev ( param.specBER,PDF,CDF ) ))

2170

end

2171

% PDF=p_an;

2172

% CDF=P_an;

2173

S_an=g_an*PSD_results.S_rn.*PSD_results.H_rxffe_2; % healey_3dj_01_2409 slide 12

2174

S_ni=PSD_results.S_isi +PSD_results.S_n +S_an; % 178A-40, healey_3dj_01_2409 slide 15

2245

S_ni=PSD_results.Sn_rho;

2175

R_ni=ifft(S_ni)*f_b;

2246

R_ni=ifft(S_ni)*f_b;

2176

p_scaled_by_b=scalePDF(p_an,b(1));

2247

p_scaled_by_b=scalePDF(PDF,b(1));

2177

p_j=conv_fct(p_an,p_scaled_by_b);

2248

p_j=conv_fct(PDF,p_scaled_by_b);

2178

p_scaled_by_1mb=scalePDF(p_an,1-b(1));

2249

p_scaled_by_1mb=scalePDF(PDF,1-b(1));

2179

%% %% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2250

%% %% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2180

p_trunc = p_an;

2251

p_trunc = PDF;

2181

%

2252

%

2182

j=1; DER_MLSE=0; DER_MLSE_j= inf;

2253

j=1; DER_MLSE=0; DER_MLSE_j= inf;

2183

P_j.y=cumsum(p_j.y);

2254

P_j.y=cumsum(p_j.y);

2184

smallest_relative_change=.0001;

2255

smallest_relative_change=.0001;

2185

%% 178A–37

2256

%% 178A–37

2186

rou=R_ni'/R_ni(1);

2257

rou=R_ni'/R_ni(1);

2187

if DER_DFE <= param.DER_CDR

2258

if DER_DFE <= param.DER_CDR

2188

while j <= floor(num_ui/2) && DER_MLSE_j> DER_MLSE*smallest_relative_change

2259

while j <= floor(num_ui/2) && DER_MLSE_j> DER_MLSE*smallest_relative_change

2189

u_j=[ 1;(1-b(1))*ones(j-1,1); (-1)^(j+1)*b(1) ] ;% Eq slide (178A–38)

2260

u_j=[ 1;(1-b(1))*ones(j-1,1); (-1)^(j+1)*b(1) ] ;% Eq slide (178A–38)

2190

u_j(2:2:end-1)=-u_j(2:2:end-1);

2261

u_j(2:2:end-1)=-u_j(2:2:end-1);

2191

% V_j=toeplitz(R_ni(1:j+1).'/R_ni(1));

2262

% V_j=toeplitz(R_ni(1:j+1).'/R_ni(1));

2192

V_j=toeplitz(rou(1:j+1));

2263

V_j=toeplitz(rou(1:j+1));

2193

P_j=cumsum(p_j.y);

2264

P_j=cumsum(p_j.y);

2194

DER_MLSE_j= ((L-1)/L)^(j-1) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(1/2), p_j, P_j ) ) ; % CDF_ev is (1-P_an)

2265

DER_MLSE_j= ((L-1)/L)^(j-1) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(1/2), p_j, P_j ) ) ; % CDF_ev is (1-CDF)

2195

% DER_MLSE_j= 2*(3/4)^(j) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(0.5), p_j, P_j ) ) ; % CDF_ev is (1-CDF)

2266

% DER_MLSE_j= 2*(3/4)^(j) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(0.5), p_j, P_j ) ) ; % CDF_ev is (1-CDF)

2196

DER_MLSE=DER_MLSE+DER_MLSE_j;

2267

DER_MLSE=DER_MLSE+DER_MLSE_j;

2197

p_j=conv_fct(p_j,p_scaled_by_1mb);

2268

p_j=conv_fct(p_j,p_scaled_by_1mb);

2198

%% %% shakiba_3dj_01_2407(to add MLSE sequence truncation penalty)

2269

%% %% shakiba_3dj_01_2407(to add MLSE sequence truncation penalty)

2199

if j == param.trunc

2270

if j == param.trunc

2200

u_trunc = u_j(1:j);

2271

u_trunc = u_j(1:j);

2201

V_trunc = V_j(1:j, 1:j);

2272

V_trunc = V_j(1:j, 1:j);

2202

P_trunc = cumsum(p_trunc.y);

2273

P_trunc = cumsum(p_trunc.y);

2203

DER_MLSE_trunc = DER_MLSE_trunc+L*((L-1)/L)^(j-1)*CDF_ev(A_s*(u_trunc'*u_trunc)^(3/2)/(u_trunc'*V_trunc*u_trunc)^(1/2), p_trunc, P_trunc);

2274

DER_MLSE_trunc = DER_MLSE_trunc+L*((L-1)/L)^(j-1)*CDF_ev(A_s*(u_trunc'*u_trunc)^(3/2)/(u_trunc'*V_trunc*u_trunc)^(1/2), p_trunc, P_trunc);

2204

elseif j < param.trunc

2275

elseif j < param.trunc

2205

DER_MLSE_trunc = DER_MLSE;

2276

DER_MLSE_trunc = DER_MLSE;

2206

p_trunc = conv_fct(p_trunc, p_scaled_by_1mb); % Convolves trunc-1 times

2277

p_trunc = conv_fct(p_trunc, p_scaled_by_1mb); % Convolves trunc-1 times

2207

P_trunc = cumsum(p_trunc.y);

2208

end

2278

end

2209

j=j+1;

2279

j=j+1;

2210

end

2280

end

2211

%% healey_3dj_01a_2407

2281

%% healey_3dj_01a_2407

2212

if param.Q_budget_adj == 0

2282

if param.Q_budget_adj == 0

2213

Q_budget_adj=0;

2283

Q_budget_adj=0;

2214

else

2284

else

2215

Q_budget_adj=param.Q_budget_adj(1) -param.Q_budget_adj(2)*COM_from_matlab;

2285

Q_budget_adj=param.Q_budget_adj(1) -param.Q_budget_adj(2)*COM_from_matlab;

2216

end

2286

end

2217

%% shakiba_3dj_01_2407

2287

%% shakiba_3dj_01_2407

2218

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE ,p_an,P_an ) )- param.Q ;% shakiba_3dj_01_2405

2288

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE ,PDF,CDF ) )- param.Q ;% shakiba_3dj_01_2405

2219

delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE_trunc,p_an,P_an ) )- Q_budget_adj ;% shakiba_3dj_01_2405

2289

delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE_trunc,PDF,CDF ) )- Q_budget_adj ;% shakiba_3dj_01_2405

2220

%% shakiba_3dj_01_2407

2290

%% shakiba_3dj_01_2407

2221

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( 2/3*DER_MLSE,p_an,CDF ) )- Q ;% (178A–36)

2291

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( 2/3*DER_MLSE,PDF,CDF ) )- Q ;% (178A–36)

2222

new_com=COM_from_matlab+delta_com;

2292

new_com=COM_from_matlab+delta_com;

2223

if(delta_com<0)

2293

if(delta_com<0)

2224

delta_com=0;

2294

delta_com=0;

2225

warning('MLSE truncation failed. Try increasing trunc')

2295

warning('MLSE truncation failed. Try increasing trunc')

2226

try

2296

try

2227

hx=msgbox('MLSE truncation failed. Try increasing N_tc','warning','warn');

2297

hx=msgbox('MLSE truncation failed. Try increasing N_tc','warning','warn');

2228

set(hx,'Color',[1 0 1]);

2298

set(hx,'Color',[1 0 1]);

2229

movegui(hx,[randn randn]*100)

2299

movegui(hx,[randn randn]*100)

2230

set(hx,'Tag','COM') %

2300

set(hx,'Tag','COM') %

2231

catch

2301

catch

2232

end

2302

end

2233

end

2303

end

2234

else

2304

else

2235

warning('MLSE not applied because the DER is less than that required for the CDR to lock')

2305

warning('MLSE not applied because the DER is less than that required for the CDR to lock')

2236

DER_MLSE=NaN;

2306

DER_MLSE=NaN;

2237

new_com=COM_from_matlab;

2307

new_com=COM_from_matlab;

2238

delta_com=0;

2308

delta_com=0;

2239

Q=0;

2309

Q=0;

2240

Q_budget_adj=0;

2310

Q_budget_adj=0;

2241

DER_MLSE_trunc=NaN;

2242

%% shakiba_3dj_01_2407

2311

%% shakiba_3dj_01_2407

2243

end

2312

end

2244

2313

2245

%%

2314

%%

2246

[PDF1, CDF1, ~] = scaleCDF( PDF,-delta_com,DER0, A_s ); % create new pdf/cdf estimate for display only

2247

MLSE_results.CDF=CDF1;

2248

MLSE_results.PDF=PDF1;

2249

MLSE_results.DER_MLSE_trunc = DER_MLSE_trunc;% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2315

MLSE_results.DER_MLSE_trunc = DER_MLSE_trunc;% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2250

MLSE_results.Q_budget_adj=Q_budget_adj; % healey_3dj_01a_2407

2316

MLSE_results.Q_budget_adj=Q_budget_adj; % healey_3dj_01a_2407

2251

MLSE_results.COM_from_matlab=COM_from_matlab;

2317

MLSE_results.COM_from_matlab=COM_from_matlab;

2252

MLSE_results.DER_MLSE=DER_MLSE;

2318

MLSE_results.DER_MLSE=DER_MLSE;

2253

MLSE_results.DER_DFE=DER_DFE;

2319

MLSE_results.DER_DFE=DER_DFE;

2254

MLSE_results.COM=new_com;

2320

MLSE_results.COM=new_com;

2255

MLSE_results.delta_com=delta_com;

2321

MLSE_results.delta_com=delta_com;

+2322

2323

2324

2325

function [MLSE_results] = MLSE_U3(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2326

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2327

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2328

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2329

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2330

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2331

%% step 0

2332

COM_from_matlab=20*log10(A_s/A_ni);

2333

L=param.levels;

2334

DER0=param.specBER;

2335

%% step 1 from slide 6 shakiba_3dj_01_230116

2336

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2337

main=A_peak;

2338

k_DER=qfuncinv(param.specBER);

2339

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2340

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2341

% if A_s >= A_ni

2342

if 1

2343

%% step 2 slide 10 shakiba_3dj_01_230116

2344

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2345

%% step 2 slide 10 not used

2346

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2347

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2348

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2349

S_n=PSD_results.S_n; % total agregate noise PSD

2350

Rn=ifft(S_n)*param.fb;

2351

Rho_row=Rn/Rn(1);

2352

Rn_len=length(Rn);

2353

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2354

for j=1:Rn_len

2355

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2356

end

2357

rho_noiseEE_row=Rho_row.*alphas_row;

2358

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2359

for j=1:Rn_len

2360

rho_noiseEE(j,j)=(1-alpha)^2;

2361

end

2362

rho_noiseEE(1,1)=1;

2363

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2364

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2365

% determine complete matrix

2366

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2367

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2368

%% shakiba_3dj_elec_01a_230504 slide 17

2369

j=1:Rn_len;

2370

DER_MLSE=[];

2371

DER_MLSE_CDF=0; jj=1;

2372

DER_MLSE_CDFold=0;

2373

DER_delta = inf;

2374

% slight modified for PAM4 DER vs SER

2375

while DER_delta > .0001 && jj<=Rn_len || jj==1

2376

last_DER_MLSE_CDF=DER_MLSE_CDF;

2377

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2378

DER_MLSE_CDF= ...

2379

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;

2380

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;

2381

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2382

jj=jj+1;

2383

end

2384

%% shakiba_3dj_elec_01a_230504 slide 19

2385

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2386

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2387

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2388

(L-1)/main * CDF_inv_ev(...

2389

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2390

,PDF, CDF ) ...

2391

)^2;

2392

%% step 5 shakiba_3dj_01_230116 slide 13

2393

delta_com=[];

2394

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2395

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2396

new_com_CDF=COM_from_matlab+delta_com_CDF;

2397

else

2398

warning('MLSE not applied because there is more noise than signal')

2399

DER_MLSE=[];

2400

DER_MLSE_CDF=[];

2401

SNR_DFE_eqivalent=[];

2402

SNR_DFE_eqivalent_CDF=[];

2403

new_com_CDF=COM_from_matlab;

2404

delta_com_CDF=0;

2405

delta_com=0;

2406

SNR_DFE=[];

2407

end

2408

SNR_DFE_eqivalent=[];

2409

%%

2410

MLSE_results.COM_from_matlab=COM_from_matlab;

2411

MLSE_results.SNR_DFE=SNR_DFE;

2412

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2413

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2414

MLSE_results.sigma_noise=sigma_noise;

2415

MLSE_results.SNR_dB=SNR_dB ;

2416

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2417

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2418

MLSE_results.COM_Gaussian=new_com_CDF;

2419

MLSE_results.COM_CDF=new_com_CDF;

2420

MLSE_results.k_DER=k_DER;

2421

MLSE_results.delta_com_CDF=delta_com_CDF;

2422

MLSE_results.delta_com_Gaussian=delta_com;

2423

2424

2425

2426

function [MLSE_results] = MLSE_instu(param,alpha,A_s,A_ni,PDF,CDF)

2427

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2428

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2429

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2430

2431

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2432

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2433

2434

%% step 0

2435

COM_from_matlab=20*log10(A_s/A_ni);

2436

L=param.levels;

2437

DER0=param.specBER;

2438

%% step 1 from slide 6/5

2439

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2440

main=A_peak;

2441

k_DER=qfuncinv(param.specBER);

2442

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2443

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2444

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2445

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2446

if A_s >= A_ni

2447

%% step 2 slide 10/8

2448

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2449

%% step 2 slide 10/8

2450

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) ;

2451

2452

%% step 3 side 11/9

2453

j=1:200;

2454

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2455

DER_MLSE_CDF=0; jj=1;

2456

DER_delta = inf;

2457

while DER_delta > .001

2458

last_DER_MLSE_CDF=DER_MLSE_CDF;

2459

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;

2460

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2461

jj=jj+1;

2462

end

2463

%%

2464

dscale=.05;

2465

scale=1;

2466

last_scale_tune=inf;

2467

scale_tune=inf;

2468

while abs(scale_tune) >= .1

2469

istart=-PDF.Min+1;

2470

scale=scale-dscale;

2471

PDF_SCALED = scalePDF(PDF,scale);

2472

cdf_scaled=pdf_to_cdf(PDF_SCALED);

2473

test_snr=snr_dfe(DER_MLSE_CDF,PDF_SCALED,cdf_scaled.y);

2474

test_DER=2*(L-1)/L* (CDF_ev(main/(L-1),PDF_SCALED,cdf_scaled.y) );

2475

scale_tune=(test_DER-DER_MLSE_CDF)/DER_MLSE_CDF;

2476

if sign(scale_tune) ~= sign(last_scale_tune)

2477

% scale=scale+dscale % back up

2478

dscale=-dscale/2;

2479

end

2480

last_scale_tune=scale_tune;

2481

end

2482

new_com_CDF=10*log10((A_s./CDF_inv_ev(DER0,PDF_SCALED,cdf_scaled.y)).^2);

2483

delta_com=new_com_CDF-10*log10((A_s./CDF_inv_ev(DER0,PDF,CDF)).^2);

2484

else

2485

warning('MLSE not applied because there is more noise than signal')

2486

DER_MLSE=[];

2487

DER_MLSE_CDF=[];

2488

SNR_DFE_eqivalent=[];

2489

SNR_DFE_eqivalent_CDF=[];

2490

new_com_CDF=COM_from_matlab;

2491

delta_com_CDF=0;

2492

delta_com=0;

2493

SNR_DFE=[];

2494

PDF_SCALED=[];

2495

cdf_scaled=[];

2496

end

2497

2498

%%

2499

MLSE_results.COM_from_matlab=COM_from_matlab;

2500

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2501

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2502

MLSE_results.sigma_noise=sigma_noise;

2503

MLSE_results.k_DER=k_DER;

2504

MLSE_results.COM_CDF=new_com_CDF;

2505

MLSE_results.delta_com_CDF=delta_com;

2506

MLSE_results.delta_com_Gaussian=delta_com;

2507

MLSE_results.PDF=PDF_SCALED;

2508

MLSE_results.CDF=cdf_scaled.y;

2256

MLSE_results.g_an=g_an;

2509

MLSE_results.PDF_scale=scale;

+2510

2257

2511

2258

2512

2259

2513

2260

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2514

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2261

if 1

2515

if 1

2262

num_ui=param.num_ui_RXFF_noise;

2516

num_ui=param.num_ui_RXFF_noise;

2263

M=param.samples_per_ui;

2517

M=param.samples_per_ui;

2264

L=param.levels;

2518

L=param.levels;

2265

sigma_X2=(L^2-1)/(3*(L-1)^2);

2519

sigma_X2=(L^2-1)/(3*(L-1)^2);

2266

fb=param.fb;

2520

fb=param.fb;

2267

R_LM=param.R_LM;

2521

R_LM=param.R_LM;

2268

end

2522

end

2269

% h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2523

% h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2270

% h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2524

% h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2271

% h=reshape(h,1,[]); % make row vectors

2525

% h=reshape(h,1,[]); % make row vectors

2272

% h=[ h(1:floor(length(h)/M)*M) ];

2526

% h=[ h(1:floor(length(h)/M)*M) ];

2273

% h= [h zeros(1,num_ui*M-length(h)) ];

2527

% h= [h zeros(1,num_ui*M-length(h)) ];

2274

% h=h(1:M:end);% resample

2528

% h=h(1:M:end);% resample

2275

% N=length(h);

2529

% N=length(h);

2276

% dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2530

% dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2277

% dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2531

% dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2278

2532

2279

samp_idx = (mod(cursor_i-1,M )+1):M:length(sbr);

2533

samp_idx = (mod(cursor_i-1,M )+1):M:length(sbr);

2280

dh= find(samp_idx == cursor_i)-1;

2534

dh= find(samp_idx == cursor_i)-1;

2281

dw=param.RxFFE_cmx;

2535

dw=param.RxFFE_cmx;

2282

h = reshape(sbr(samp_idx),1,[]); % make row vector

2536

h = reshape(sbr(samp_idx),1,[]); % make row vector

2283

h(end+1:num_ui)=0;

2537

h(end+1:num_ui)=0;

2284

h = h(1:num_ui); % h needs to have num_ui points

2538

h = h(1:num_ui); % h needs to have num_ui points

2285

N=length(h); % used in subsequent expressions

2539

N=length(h); % used in subsequent expressions

2286

2540

2287

if param.N_bg == 0

2541

if param.N_bg == 0

2288

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2542

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2289

bmax=param.bmax;

2543

bmax=param.bmax;

2290

bmin=param.bmin ;

2544

bmin=param.bmin ;

2291

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 ];

2545

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 ];

2292

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 ];

2546

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 ];

2293

idx=[];

2547

idx=[];

2294

else

2548

else

2295

Nfloating_taps=param.N_bf*param.N_bg;

2549

Nfloating_taps=param.N_bf*param.N_bg;

2296

Nmax=param.N_bmax;

2550

Nmax=param.N_bmax;

2297

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2551

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2298

Ng=param.N_bg;

2552

Ng=param.N_bg;

2299

Nf=param.N_bf;

2553

Nf=param.N_bf;

2300

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2554

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2301

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2555

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2302

% hisi=h(dh+2:((dh-dw)+Nw));

2556

% hisi=h(dh+2:((dh-dw)+Nw));

2303

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2557

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2304

% idx=sort(idx);

2558

% idx=sort(idx);

2305

bmax=param.bmax;

2559

bmax=param.bmax;

2306

bmin=param.bmin ;

2560

bmin=param.bmin ;

2307

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 ];

2561

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 ];

2308

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 ];

2562

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 ];

2309

end

2563

end

2310

Nb=param.ndfe; % DFE taps

2564

Nb=param.ndfe; % DFE taps

2311

d=dw+dh; % used for index in algorithms

2565

d=dw+dh; % used for index in algorithms

2312

indx(1:N)=(1:N)-dh-1;

2566

indx(1:N)=(1:N)-dh-1;

2313

S_n=PSD_results.S_n; % total agregate noise PSD

2567

S_n=PSD_results.S_n; % total agregate noise PSD

2314

Rn=ifft(S_n)*fb;

2568

Rn=ifft(S_n)*fb;

2315

%% HH and R

2569

%% HH and R

2316

2570

2317

%Test routine finding rxffe floating taps using best FOM for each bank

2571

%Test routine finding rxffe floating taps using best FOM for each bank

2318

isi_start = dh+2;

2572

isi_start = dh+2;

2319

isi_end = (dh-dw)+Nw;

2573

isi_end = (dh-dw)+Nw;

2320

2574

2321

%check for num_ui too small

2575

%check for num_ui too small

2322

if isi_end > length(h)

2576

if isi_end > length(h)

2323

error('num_ui_RXFF_noise (%d) is too small',num_ui);

2577

error('num_ui_RXFF_noise (%d) is too small',num_ui);

2324

end

2578

end

2325

2579

2326

hc1=[ h zeros(1,Nw-1) ];

2580

hc1=[ h zeros(1,Nw-1) ];

2327

hr1=[ h(1) zeros(1,Nw-1)];

2581

hr1=[ h(1) zeros(1,Nw-1)];

2328

H=toeplitz(hc1,hr1);

2582

H=toeplitz(hc1,hr1);

2329

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2583

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2330

if param.N_bg ~= 0

2584

if param.N_bg ~= 0

2331

switch lower(OP.RXFFE_FLOAT_CTL)

2585

switch lower(OP.RXFFE_FLOAT_CTL)

2332

case 'isi'

2586

case 'isi'

2333

hisi=h(dh+2:((dh-dw)+Nw));

2587

hisi=h(dh+2:((dh-dw)+Nw));

2334

[idx]=findbankloc( hisi ,param.RxFFE_cpx+1,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2588

[idx]=findbankloc( hisi ,param.RxFFE_cpx+1,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2335

idx=sort(idx);

2589

idx=sort(idx);

2336

otherwise

2590

otherwise

2337

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2591

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2338

idx=sort(idx);

2592

idx=sort(idx);

2339

end

2593

end

2340

end

2594

end

2341

[sigma_e,FOM,w,idx,Nw,blim] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx); % bring out blim for

2595

[sigma_e,FOM,w,idx] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx);

2342

MMSE_results.sigma_e=sigma_e; %

2596

MMSE_results.sigma_e=sigma_e; %

2343

MMSE_results.FOM=FOM;

2597

MMSE_results.FOM=FOM;

2344

Craw=w/w(dw+1); % returned Rx FFE taps

2598

Craw=w/w(dw+1); % returned Rx FFE taps

2345

% re-align Cmod to floating tap locations

2599

% re-align Cmod to floating tap locations

2346

if param.N_bg ~= 0

2600

if param.N_bg ~= 0

2347

C=Craw;

2601

C=Craw;

2348

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2602

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2349

C(idx+param.RxFFE_cmx+1 )=Craw(Nfix+(1:Nfloating_taps));

2603

C(idx+param.RxFFE_cmx+1 )=Craw(Nfix+(1:Nfloating_taps));

2350

else

2604

else

2351

C=Craw;

2605

C=Craw;

2352

end

2606

end

2353

MMSE_results.floating_tap_locations=idx + param.RxFFE_cmx+1;

2607

MMSE_results.floating_tap_locations=idx + param.RxFFE_cmx+1;

2354

MMSE_results.C=C;

2608

MMSE_results.C=C;

2355

MMSE_results.blim=blim; % added blim passed out for MLSD for 178A-39

2356

MMSE_results.Nw=Nw;

2357

2609

2358

2610

2359

2611

2360

2612

2361

2362

function [sigma_e,FOM,w,idx,Nw,blim] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2613

function [sigma_e,FOM,w,idx,Nw] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2363

% added blim passed out for MLSD

2364

if isempty(idx)

2614

if isempty(idx)

2365

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2615

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2366

bmax=param.bmax;

2616

bmax=param.bmax;

2367

bmin=param.bmin ;

2617

bmin=param.bmin ;

2368

else

2618

else

2369

Nfloating_taps=param.N_bf*param.N_bg;

2619

Nfloating_taps=param.N_bf*param.N_bg;

2370

%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

2620

%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

2371

Nfloating_taps = length(idx);

2621

Nfloating_taps = length(idx);

2372

Nmax=param.N_bmax;

2622

Nmax=param.N_bmax;

2373

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2623

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2374

Ng=param.N_bg;

2624

Ng=param.N_bg;

2375

Nf=param.N_bf;

2625

Nf=param.N_bf;

2376

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2626

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2377

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2627

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2378

end

2628

end

2379

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2629

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2380

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2630

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2381

% hc1=[ h zeros(1,Nw-1) ];

2631

% hc1=[ h zeros(1,Nw-1) ];

2382

% hr1=[ h(1) zeros(1,Nw-1)];

2632

% hr1=[ h(1) zeros(1,Nw-1)];

2383

% H=toeplitz(hc1,hr1);

2633

% H=toeplitz(hc1,hr1);

2384

2634

2385

if param.N_bg ~= 0

2635

if param.N_bg ~= 0

2386

H=H( :,[1:Nfix idx+param.RxFFE_cmx+1 ]);

2636

H=H( :,[1:Nfix idx+param.RxFFE_cmx+1 ]);

2387

end

2637

end

2388

%% HH and R

2638

%% HH and R

2389

HH= H'*H;

2639

HH= H'*H;

2390

if param.N_bg ~= 0

2640

if param.N_bg ~= 0

2391

Rnn=Rnn( [1:Nfix idx+param.RxFFE_cmx+1],[1:Nfix idx+param.RxFFE_cmx+1]);

2641

Rnn=Rnn( [1:Nfix idx+param.RxFFE_cmx+1],[1:Nfix idx+param.RxFFE_cmx+1]);

2392

end

2642

end

2393

R=HH+Rnn/sigma_X2;

2643

R=HH+Rnn/sigma_X2;

2394

%% hb and h0

2644

%% hb and h0

2395

Hb= H(d+2:d+Nb+1,:);

2645

Hb= H(d+2:d+Nb+1,:);

2396

h0=H(d+1,:);

2646

h0=H(d+1,:);

2397

% display(floor(h0));

2647

% display(floor(h0));

2398

2648

2399

%% Ib and zb (slide 10)

2649

%% Ib and zb (slide 10)

2400

ib=eye(Nb);

2650

ib=eye(Nb);

2401

zb=zeros(1,Nb);

2651

zb=zeros(1,Nb);

2402

wbl= [ R -Hb' -h0';...

2652

wbl= [ R -Hb' -h0';...

2403

-Hb ib zb'; ...

2653

-Hb ib zb'; ...

2404

h0 zb 0]\[h0'; zb' ;1];

2654

h0 zb 0]\[h0'; zb' ;1];

2405

2655

2406

%% re-adjust Nw to number of used taps

2656

%% re-adjust Nw to number of used taps

2407

if param.N_bg ~= 0

2657

if param.N_bg ~= 0

2408

Nw=Nwft;

2658

Nw=Nwft;

2409

end

2659

end

2410

%% check equalized pulse

2660

%% check equalized pulse

2411

w=wbl(1:Nw);

2661

w=wbl(1:Nw);

2412

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2662

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2413

2663

2414

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2664

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2415

blim = min(bmax(:), max(bmin(:), b));

2665

blim = min(bmax(:), max(bmin(:), b));

2416

if (Nb > 0) && ~isequal(b, blim)

2666

if (Nb > 0) && ~isequal(b, blim)

2417

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2667

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2418

w = wl(1:Nw);

2668

w = wl(1:Nw);

2419

end

2669

end

2420

2670

2421

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2671

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2422

%so need to chop off the extra indices on wmax and wmin

2672

%so need to chop off the extra indices on wmax and wmin

2423

if length(w)<length(wmax)

2673

if length(w)<length(wmax)

2424

wmax=wmax(1:length(w));

2674

wmax=wmax(1:length(w));

2425

wmin=wmin(1:length(w));

2675

wmin=wmin(1:length(w));

2426

end

2676

end

2427

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2677

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2428

if ~isequal(w, wlim)

2678

if ~isequal(w, wlim)

2429

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2679

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2430

if Nb > 0

2680

if Nb > 0

2431

b = Hb*wlim; % Update the feedback coefficients.

2681

b = Hb*wlim; % Update the feedback coefficients.

2432

blim = min(bmax(:), max(bmin(:), b));

2682

blim = min(bmax(:), max(bmin(:), b));

2433

end

2683

end

2434

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2684

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2435

% wl = wl(1:Nw);

2685

% wl = wl(1:Nw);

2436

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2686

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2437

end

2687

end

2438

% w=w(1:Nw) ;

2688

% w=w(1:Nw) ;

2439

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2689

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2440

w=wlim;

2690

w=wlim;

2441

b=blim;

2691

b=blim;

2442

sigma_e=sqrt(sigma_X2*(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b)); % Commit request 4p4_5 from healey_3dj_COM_01_240416

2692

sigma_e=sqrt(sigma_X2*(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b)); % Commit request 4p4_5 from healey_3dj_COM_01_240416

2443

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2693

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2444

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2694

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2445

2695

2446

%not all output_args are filled here but most are

2696

%not all output_args are filled here but most are

2447

2697

2448

switch lower(OP.TDECQ)

2698

switch lower(OP.TDECQ)

2449

case { false 'none' } % should be the default

2699

case { false 'none' } % should be the default

2450

output_args.VMA=[];

2700

output_args.VMA=[];

2451

case 'vma'

2701

case 'vma'

2452

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2702

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2453

output_args.VMA=est_vma.VMA;

2703

output_args.VMA=est_vma.VMA;

2454

otherwise

2704

otherwise

2455

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2705

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2456

end

2706

end

2457

2707

2458

fileset_str=str2csv({chdata.base});

2708

fileset_str=str2csv({chdata.base});

2459

output_args.file_names=sprintf('"%s"', fileset_str);

2709

output_args.file_names=sprintf('"%s"', fileset_str);

2460

% [ahealey] Echo the termination parameters in the output arguments..

2710

% [ahealey] Echo the termination parameters in the output arguments..

2461

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2711

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2462

output_args.(odt_param{:}) = param.(odt_param{:});

2712

output_args.(odt_param{:}) = param.(odt_param{:});

2463

end

2713

end

2464

% [ahealey] End of modifications.

2714

% [ahealey] End of modifications.

2465

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2715

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2466

output_args.(pkg_params{:})= param.(pkg_params{:});

2716

output_args.(pkg_params{:})= param.(pkg_params{:});

2467

end

2717

end

2468

output_args.baud_rate_GHz=param.fb/1e9;

2718

output_args.baud_rate_GHz=param.fb/1e9;

2469

output_args.f_Nyquist_GHz = param.fb/2e9;

2719

output_args.f_Nyquist_GHz = param.fb/2e9;

2470

output_args.BER=param.specBER;

2720

output_args.BER=param.specBER;

2471

output_args.FOM = fom_result.FOM;

2721

output_args.FOM = fom_result.FOM;

2472

output_args.sigma_N=Noise_Struct.sigma_N;

2722

output_args.sigma_N=Noise_Struct.sigma_N;

2473

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2723

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2474

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2724

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2475

output_args.tail_RSS=fom_result.tail_RSS;

2725

output_args.tail_RSS=fom_result.tail_RSS;

2476

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2726

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2477

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2727

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2478

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2728

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2479

try

2729

try

2480

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2730

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2481

catch

2731

catch

2482

output_args.uneq_FIR_peak_time=[];

2732

output_args.uneq_FIR_peak_time=[];

2483

end

2733

end

2484

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2734

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2485

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2735

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2486

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2736

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2487

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2737

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2488

2738

2489

if OP.RX_CALIBRATION== 1

2739

if OP.RX_CALIBRATION== 1

2490

output_args.sigma_bn=sigma_bn;

2740

output_args.sigma_bn=sigma_bn;

2491

else

2741

else

2492

output_args.sigma_bn=[];

2742

output_args.sigma_bn=[];

2493

end

2743

end

2494

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2744

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2495

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2745

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2496

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2746

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2497

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2747

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2498

2748

2499

if OP.RX_CALIBRATION == 0

2749

if OP.RX_CALIBRATION == 0

2500

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2750

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2501

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2751

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2502

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2752

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2503

else

2753

else

2504

output_args.peak_MDXTK_interference_at_BER_mV=[];

2754

output_args.peak_MDXTK_interference_at_BER_mV=[];

2505

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2755

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2506

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2756

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2507

end

2757

end

2508

%output_args.ICN_mV=ICN*1000;

2758

%output_args.ICN_mV=ICN*1000;

2509

% output_args.ICN_test_mV=ICN_test*1000;

2759

% output_args.ICN_test_mV=ICN_test*1000;

2510

xtk=param.num_next+param.num_fext;

2760

xtk=param.num_next+param.num_fext;

2511

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2761

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2512

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2762

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2513

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2763

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2514

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2764

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2515

else

2765

else

2516

output_args.MDNEXT_ICN_92_46_mV=0;

2766

output_args.MDNEXT_ICN_92_46_mV=0;

2517

output_args.MDFEXT_ICN_92_47_mV=0;

2767

output_args.MDFEXT_ICN_92_47_mV=0;

2518

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2768

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2519

end

2769

end

2520

%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

2770

%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

2521

if 1

2771

if 1

2522

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)));

2772

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)));

2523

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2773

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2524

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2774

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2525

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2775

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2526

end

2776

end

2527

2777

2528

2778

2529

switch param.CTLE_type

2779

switch param.CTLE_type

2530

case 'CL93'

2780

case 'CL93'

2531

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2781

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2532

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2782

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2533

output_args.g_DC_HP=[];

2783

output_args.g_DC_HP=[];

2534

output_args.HP_poles_zero=[];

2784

output_args.HP_poles_zero=[];

2535

case 'CL120d'

2785

case 'CL120d'

2536

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2786

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2537

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2787

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2538

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2788

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2539

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2789

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2540

case 'CL120e'

2790

case 'CL120e'

2541

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)];

2791

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)];

2542

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2792

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2543

output_args.g_DC_HP=[];

2793

output_args.g_DC_HP=[];

2544

output_args.HP_poles_zero=[];

2794

output_args.HP_poles_zero=[];

2545

end

2795

end

2546

output_args.TXLE_taps=fom_result.txffe;

2796

output_args.TXLE_taps=fom_result.txffe;

2547

if length(output_args.TXLE_taps) >= 3

2797

if length(output_args.TXLE_taps) >= 3

2548

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2798

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2549

else

2799

else

2550

output_args.Pre2Pmax=[];

2800

output_args.Pre2Pmax=[];

2551

end

2801

end

2552

output_args.DFE_taps=fom_result.DFE_taps;

2802

output_args.DFE_taps=fom_result.DFE_taps;

2553

if param.Floating_DFE || param.Floating_RXFFE

2803

if param.Floating_DFE || param.Floating_RXFFE

2554

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2804

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2555

else

2805

else

2556

output_args.floating_tap_locations=[];

2806

output_args.floating_tap_locations=[];

2557

end

2807

end

2558

2808

2559

if OP.RxFFE

2809

if OP.RxFFE

2560

output_args.RxFFE=fom_result.RxFFE;

2810

output_args.RxFFE=fom_result.RxFFE;

2561

output_args.RxFFEgain=param.current_ffegain;

2811

output_args.RxFFEgain=param.current_ffegain;

2562

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2812

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2563

output_args.RxFFE=[];

2813

output_args.RxFFE=[];

2564

output_args.RxFFEgain=[];

2814

output_args.RxFFEgain=[];

2565

end

2815

end

2566

2816

2567

output_args.itick=fom_result.itick;

2817

output_args.itick=fom_result.itick;

2568

2818

2569

% Calculation of error propagation and burst probability

2819

% Calculation of error propagation and burst probability

2570

if OP.nburst>0

2820

if OP.nburst>0

2571

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2821

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2572

output_args.error_propagation_probability = p_error_propagation;

2822

output_args.error_propagation_probability = p_error_propagation;

2573

output_args.burst_probabilities = p_burst;

2823

output_args.burst_probabilities = p_burst;

2574

else

2824

else

2575

output_args.error_propagation_probability = [];

2825

output_args.error_propagation_probability = [];

2576

output_args.burst_probabilities = [];

2826

output_args.burst_probabilities = [];

2577

end

2827

end

2578

2828

2579

2829

2580

%begin yasuo patch 12/11/2018

2830

%begin yasuo patch 12/11/2018

2581

% collect sigma values to report

2831

% collect sigma values to report

2582

% pdf2sgm() is a function to calculate sigma value from PDF

2832

% pdf2sgm() is a function to calculate sigma value from PDF

2583

% It is added at the end of this file code.

2833

% It is added at the end of this file code.

2584

% I am not sure if an equivalent function already exists.

2834

% I am not sure if an equivalent function already exists.

2585

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2835

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2586

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2836

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2587

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2837

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2588

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2838

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2589

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2839

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2590

output_args.sgm_G = Noise_Struct.sigma_G;

2840

output_args.sgm_G = Noise_Struct.sigma_G;

2591

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2841

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2592

output_args.sgm_N = Noise_Struct.sigma_N;

2842

output_args.sgm_N = Noise_Struct.sigma_N;

2593

output_args.sgm_TX = Noise_Struct.sigma_TX;

2843

output_args.sgm_TX = Noise_Struct.sigma_TX;

2594

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2844

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2595

if OP.RX_CALIBRATION == 0

2845

if OP.RX_CALIBRATION == 0

2596

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2846

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2597

else

2847

else

2598

output_args.sgm_xt=[];

2848

output_args.sgm_xt=[];

2599

end

2849

end

2600

% end yasuo patch

2850

% end yasuo patch

2601

2851

2602

% r259 putting COM, VEO and loss last in report

2852

% r259 putting COM, VEO and loss last in report

2603

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2853

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2604

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2854

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2605

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2855

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2606

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2856

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2607

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2857

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2608

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2858

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2609

output_args.VEO_window_mUI= param.T_O;

2859

output_args.VEO_window_mUI= param.T_O;

2610

else

2860

else

2611

output_args.EW_UI_est=[];

2861

output_args.EW_UI_est=[];

2612

output_args.eye_contour=[];

2862

output_args.eye_contour=[];

2613

output_args.VEO_window_mUI= [];

2863

output_args.VEO_window_mUI= [];

2614

end

2864

end

2615

2865

2616

if sum(param.AC_CM_RMS) ~= 0

2866

if sum(param.AC_CM_RMS) ~= 0

2617

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2867

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2618

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2868

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2619

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2869

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2620

else

2870

else

2621

output_args.sigma_ACCM_at_tp0_mV=[];

2871

output_args.sigma_ACCM_at_tp0_mV=[];

2622

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2872

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2623

end

2873

end

2624

if OP.MLSE

2874

if OP.MLSE

2625

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2875

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2626

output_args.delta_COM = COM_SNR_Struct.delta_COM;

2876

output_args.delta_COM = COM_SNR_Struct.delta_COM;

2627

output_args.DER_DFE= COM_SNR_Struct.DER_DFE;

2877

output_args.DER_DFE= COM_SNR_Struct.DER_DFE;

2628

output_args.DER_MLSE= COM_SNR_Struct.DER_MLSE;

2878

output_args.DER_MLSE= COM_SNR_Struct.DER_MLSE;

2629

if strcmpi(upper(OP.PHY),'C2M')

2879

if strcmpi(upper(OP.PHY),'C2M')

2630

output_args.VEC_dB_orig= COM_SNR_Struct.VEC_dB_orig;

2880

output_args.VEC_dB_orig= COM_SNR_Struct.VEC_dB_orig;

2631

output_args.delta_VEC = COM_SNR_Struct.delta_VEC;

2881

output_args.delta_VEC = COM_SNR_Struct.delta_VEC;

2632

output_args.VEC_dB_orig = COM_SNR_Struct.VEC_dB_orig;

2882

output_args.VEC_dB_orig = COM_SNR_Struct.VEC_dB_orig;

2633

output_args.VEC_dB= COM_SNR_Struct.VEC_dB;

2883

output_args.VEC_dB= COM_SNR_Struct.VEC_dB;

2634

end

2884

end

2635

end

2885

end

2636

%

2886

%

2637

output_args.COM_dB=COM_SNR_Struct.COM;

2887

output_args.COM_dB=COM_SNR_Struct.COM;

2638

% end yasuo patch

2888

% end yasuo patch

2639

% begin yasuo patch 3/18/2019

2889

% begin yasuo patch 3/18/2019

2640

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2890

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2641

% end yasuo patch

2891

% end yasuo patch

2642

function [ seq syms syms_nrz ] = PRBS13Q( )

2892

function [ seq syms syms_nrz ] = PRBS13Q( )

2643

%UNTITLED Summary of this function goes here

2893

%UNTITLED Summary of this function goes here

2644

% Detailed explanation goes here

2894

% Detailed explanation goes here

2645

2895

2646

2896

2647

taps = ([13 12 2 1]);

2897

taps = ([13 12 2 1]);

2648

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2898

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2649

[seq_nrz c] =LFSR(seed,taps);

2899

[seq_nrz c] =LFSR(seed,taps);

2650

seq_nrz=2*(seq_nrz-0.5);

2900

seq_nrz=2*(seq_nrz-0.5);

2651

seq=pam(seq_nrz);

2901

seq=pam(seq_nrz);

2652

% syms=round(2*(seq+1));

2902

% syms=round(2*(seq+1));

2653

syms((round(2*(seq+1))/2==2))=3;

2903

syms((round(2*(seq+1))/2==2))=3;

2654

syms((round(2*(seq+1))/2==1.5))=2;

2904

syms((round(2*(seq+1))/2==1.5))=2;

2655

syms((round(2*(seq+1))/2==.5))=1;

2905

syms((round(2*(seq+1))/2==.5))=1;

2656

syms((round(2*(seq+1))/2==0))=0;

2906

syms((round(2*(seq+1))/2==0))=0;

2657

2907

2658

% syms_nrz=((seq_nrz+1)/2);

2908

% syms_nrz=((seq_nrz+1)/2);

2659

2909

2660

syms_nrz=seq_nrz;

2910

syms_nrz=seq_nrz;

2661

2911

2662

2912

2663

function[seq c]=LFSR(s,t)

2913

function[seq c]=LFSR(s,t)

2664

%s=initial state of LFSR, you can choose any lenght of LFSR

2914

%s=initial state of LFSR, you can choose any lenght of LFSR

2665

%Instruction:==========

2915

%Instruction:==========

2666

%Save LFSR.m in your current directory and type following

2916

%Save LFSR.m in your current directory and type following

2667

%on Command window for simulating 5 bit LFSR with tap [5 2]

2917

%on Command window for simulating 5 bit LFSR with tap [5 2]

2668

%---------------------

2918

%---------------------

2669

%>>s=[1 1 0 0 1]

2919

%>>s=[1 1 0 0 1]

2670

%>>t=[5 2]

2920

%>>t=[5 2]

2671

%>>[seq c] =LFSR(s,t)

2921

%>>[seq c] =LFSR(s,t)

2672

%---------------------------

2922

%---------------------------

2673

%seq = generated sequence

2923

%seq = generated sequence

2674

%c will be matrix containing the states of LFSR raw wise

2924

%c will be matrix containing the states of LFSR raw wise

2675

%

2925

%

2676

%-----------------------------------------------------------

2926

%-----------------------------------------------------------

2677

%If any doubt, confusion or feedback please contact me

2927

%If any doubt, confusion or feedback please contact me

2678

% NIKESH BAJAJ

2928

% NIKESH BAJAJ

2679

% bajaj.nikkey@gmail.com (+91-9915522564)

2929

% bajaj.nikkey@gmail.com (+91-9915522564)

2680

% Asst. Professor at Lovely Profesional University

2930

% Asst. Professor at Lovely Profesional University

2681

% Masters from Aligarh Muslim University,INDIA

2931

% Masters from Aligarh Muslim University,INDIA

2682

%--------------------------------------------------

2932

%--------------------------------------------------

2683

n=length(s);

2933

n=length(s);

2684

c(1,:)=s;

2934

c(1,:)=s;

2685

m=length(t);

2935

m=length(t);

2686

for k=1:2^n-2;

2936

for k=1:2^n-2;

2687

b(1)=xor(s(t(1)), s(t(2)));

2937

b(1)=xor(s(t(1)), s(t(2)));

2688

if m>2;

2938

if m>2;

2689

for i=1:m-2;

2939

for i=1:m-2;

2690

b(i+1)=xor(s(t(i+2)), b(i));

2940

b(i+1)=xor(s(t(i+2)), b(i));

2691

end

2941

end

2692

end

2942

end

2693

j=1:n-1;

2943

j=1:n-1;

2694

s(n+1-j)=s(n-j);

2944

s(n+1-j)=s(n-j);

2695

s(1)=b(m-1);

2945

s(1)=b(m-1);

2696

c(k+1,:)=s;

2946

c(k+1,:)=s;

2697

end

2947

end

2698

seq=c(:,n)';

2948

seq=c(:,n)';

2699

2949

2700

function [ dataout ] = pam( data )

2950

function [ dataout ] = pam( data )

2701

% mapping data usng Grey Coding

2951

% mapping data usng Grey Coding

2702

for i=1:2:floor(length(data)/2)*2

2952

for i=1:2:floor(length(data)/2)*2

2703

if data(i:i+1)==[ -1 -1 ]

2953

if data(i:i+1)==[ -1 -1 ]

2704

dataout(ceil(i/2)) = -1;

2954

dataout(ceil(i/2)) = -1;

2705

elseif data(i:i+1)==[ -1 1 ]

2955

elseif data(i:i+1)==[ -1 1 ]

2706

dataout(ceil(i/2)) = -1/3;

2956

dataout(ceil(i/2)) = -1/3;

2707

elseif data(i:i+1)==[ 1 1 ]

2957

elseif data(i:i+1)==[ 1 1 ]

2708

dataout(ceil(i/2)) = 1/3;

2958

dataout(ceil(i/2)) = 1/3;

2709

elseif data(i:i+1)==[ 1 -1 ]

2959

elseif data(i:i+1)==[ 1 -1 ]

2710

dataout(ceil(i/2)) = 1;

2960

dataout(ceil(i/2)) = 1;

2711

end

2961

end

2712

end

2962

end

2713

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2963

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2714

db = @(x) 20*log10(abs(x));

2964

db = @(x) 20*log10(abs(x));

2715

disp('computing TD_RILN...')

2965

disp('computing TD_RILN...')

2716

sdd21=squeeze(sdd21);

2966

sdd21=squeeze(sdd21);

2717

if iscolumn(sdd21)

2967

if iscolumn(sdd21)

2718

sdd21=sdd21.';

2968

sdd21=sdd21.';

2719

end

2969

end

2720

RIL=squeeze(RIL);

2970

RIL=squeeze(RIL);

2721

if iscolumn(RIL)

2971

if iscolumn(RIL)

2722

RIL=RIL.';

2972

RIL=RIL.';

2723

end

2973

end

2724

print_for_codereview=1;

2974

print_for_codereview=1;

2725

if exist('OP','var')

2975

if exist('OP','var')

2726

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2976

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2727

2977

2728

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2978

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2729

H_bw=Butterworth_Filter(param,faxis_f2,1);

2979

H_bw=Butterworth_Filter(param,faxis_f2,1);

2730

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2980

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2731

H_tw=Tukey_Window(faxis_f2,param);

2981

H_tw=Tukey_Window(faxis_f2,param);

2732

H_tw=ones(1,length(faxis_f2) );

2982

H_tw=ones(1,length(faxis_f2) );

2733

[RILN_TD_struct.REF.FIR, ...

2983

[RILN_TD_struct.REF.FIR, ...

2734

RILN_TD_struct.REF.t, ...

2984

RILN_TD_struct.REF.t, ...

2735

RILN_TD_struct.REF.causality_correction_dB, ...

2985

RILN_TD_struct.REF.causality_correction_dB, ...

2736

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2986

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2737

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2987

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2738

[RILN_TD_struct.FIT.FIR, ...

2988

[RILN_TD_struct.FIT.FIR, ...

2739

RILN_TD_struct.FIT.t, ...

2989

RILN_TD_struct.FIT.t, ...

2740

RILN_TD_struct.FIT.causality_correction_dB, ...

2990

RILN_TD_struct.FIT.causality_correction_dB, ...

2741

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2991

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2742

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2992

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2743

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2993

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2744

NrangeUI=1000;

2994

NrangeUI=1000;

2745

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2995

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2746

range=ipeak:range_end;

2996

range=ipeak:range_end;

2747

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2997

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2748

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2998

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2749

RILN_TD_struct.FOM=-inf;

2999

RILN_TD_struct.FOM=-inf;

2750

RILN_TD_struct.FOM_PDF=-inf;

3000

RILN_TD_struct.FOM_PDF=-inf;

2751

rms_fom=-inf;

3001

rms_fom=-inf;

2752

for im=1:param.samples_per_ui

3002

for im=1:param.samples_per_ui

2753

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

3003

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2754

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

3004

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2755

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

3005

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2756

cdf=pdf; cdf.y=cumsum(pdf.y);

3006

cdf=pdf; cdf.y=cumsum(pdf.y);

2757

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

3007

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2758

% signal_and_isi_pdf = conv_fct(cursors, pdf);

3008

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2759

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

3009

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2760

if print_for_codereview % remove once all checked out

3010

if print_for_codereview % remove once all checked out

2761

h=figure(191);set(gcf,'Tag','COM');

3011

h=figure(191);set(gcf,'Tag','COM');

2762

semilogy(-cdf.x,cdf.y);

3012

semilogy(-cdf.x,cdf.y);

2763

% xlim ([0,-cdf.x(1)])

3013

% xlim ([0,-cdf.x(1)])

2764

ylim([param.specBER 1]);title ('CDF of RILN')

3014

ylim([param.specBER 1]);title ('CDF of RILN')

2765

hold on

3015

hold on

2766

end

3016

end

2767

if rms>rms_fom

3017

if rms>rms_fom

2768

rms_fom=rms;

3018

rms_fom=rms;

2769

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

3019

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2770

RILN_TD_struct.PDF=pdf;

3020

RILN_TD_struct.PDF=pdf;

2771

end

3021

end

2772

end

3022

end

2773

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

3023

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2774

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

3024

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2775

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

3025

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2776

if print_for_codereview % remove once all checked out

3026

if print_for_codereview % remove once all checked out

2777

figure(9003);set(gcf,'Tag','COM');

3027

figure(9003);set(gcf,'Tag','COM');

2778

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

3028

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2779

hold on

3029

hold on

2780

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

3030

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2781

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

3031

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2782

hold off

3032

hold off

2783

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)

3033

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)

2784

figure(9004);set(gcf,'Tag','COM');

3034

figure(9004);set(gcf,'Tag','COM');

2785

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

3035

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2786

hold on

3036

hold on

2787

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

3037

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2788

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

3038

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2789

grid on

3039

grid on

2790

legend('show')

3040

legend('show')

2791

end

3041

end

2792

end

3042

end

2793

function is_illegal=RXFFE_Illegal(C,param,last_index)

3043

function is_illegal=RXFFE_Illegal(C,param,last_index)

2794

3044

2795

%check if RXFFE taps are illegal

3045

%check if RXFFE taps are illegal

2796

%C = RXFFE taps

3046

%C = RXFFE taps

2797

%param = COM param struct

3047

%param = COM param struct

2798

%last_index is used when computing illegality prior to Backoff. It will be set so taps

3048

%last_index is used when computing illegality prior to Backoff. It will be set so taps

2799

% in the Backoff region are not considered in the legality check.

3049

% in the Backoff region are not considered in the legality check.

2800

3050

2801

%If last index is omitted, set it to length(C)

3051

%If last index is omitted, set it to length(C)

2802

if nargin<3

3052

if nargin<3

2803

last_index=length(C);

3053

last_index=length(C);

2804

end

3054

end

2805

3055

2806

is_illegal=0;

3056

is_illegal=0;

2807

3057

2808

%Check cursor tap

3058

%Check cursor tap

2809

Ccur_i=param.RxFFE_cmx+1;

3059

Ccur_i=param.RxFFE_cmx+1;

2810

if C(Ccur_i) < param.ffe_main_cursor_min

3060

if C(Ccur_i) < param.ffe_main_cursor_min

2811

is_illegal=1;

3061

is_illegal=1;

2812

return;

3062

return;

2813

end

3063

end

2814

3064

2815

%Check postcursors

3065

%Check postcursors

2816

if param.ffe_post_tap_len ~=0

3066

if param.ffe_post_tap_len ~=0

2817

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

3067

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

2818

is_illegal=1;

3068

is_illegal=1;

2819

return;

3069

return;

2820

end

3070

end

2821

if (param.ffe_post_tap_len > 1)

3071

if (param.ffe_post_tap_len > 1)

2822

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

3072

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

2823

is_illegal=1;

3073

is_illegal=1;

2824

return;

3074

return;

2825

end

3075

end

2826

end

3076

end

2827

end

3077

end

2828

3078

2829

%Check precursors

3079

%Check precursors

2830

if param.ffe_pre_tap_len ~=0

3080

if param.ffe_pre_tap_len ~=0

2831

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

3081

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

2832

is_illegal=1;

3082

is_illegal=1;

2833

return;

3083

return;

2834

end

3084

end

2835

if (param.ffe_pre_tap_len > 1)

3085

if (param.ffe_pre_tap_len > 1)

2836

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

3086

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

2837

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

3087

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

2838

is_illegal=1;

3088

is_illegal=1;

2839

return;

3089

return;

2840

end % 11.22.2018 Yasou Hadaka

3090

end % 11.22.2018 Yasou Hadaka

2841

end

3091

end

2842

end

3092

end

2843

function S =R_series2(zref,f,R)

3093

function S =R_series2(zref,f,R)

2844

r=ones(1,length(f))*R;

3094

r=ones(1,length(f))*R;

2845

S.Parameters(1,1,:) = r./(r + 2*zref);

3095

S.Parameters(1,1,:) = r./(r + 2*zref);

2846

S.Parameters(2,2,:) = r./(r + 2*zref);

3096

S.Parameters(2,2,:) = r./(r + 2*zref);

2847

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

3097

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

2848

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

3098

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

2849

% Sm=sparameters(S.Parameters,f,zref);

3099

% Sm=sparameters(S.Parameters,f,zref);

2850

3100

2851

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

3101

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

2852

3102

2853

if use_RC

3103

if use_RC

2854

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

3104

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

2855

else

3105

else

2856

H_tw=ones(1,length(f));

3106

H_tw=ones(1,length(f));

2857

end

3107

end

2858

function SLD=SL(S,f,R)

3108

function SLD=SL(S,f,R)

2859

% source load impact return loss add to S21

3109

% source load impact return loss add to S21

2860

% S and SLD are the same structure

3110

% S and SLD are the same structure

2861

% S.Parameters

3111

% S.Parameters

2862

% S.Impedance

3112

% S.Impedance

2863

% S.NumPorts

3113

% S.NumPorts

2864

% S.Frequencies

3114

% S.Frequencies

2865

SLD=S; % assign the fields

3115

SLD=S; % assign the fields

2866

zref=100;

3116

zref=100;

2867

if R==0

3117

if R==0

2868

warndlg('Termination should not be set to zero');

3118

warndlg('Termination should not be set to zero');

2869

SLD=S;

3119

SLD=S;

2870

return

3120

return

2871

end

3121

end

2872

3122

2873

if R > zref

3123

if R > zref

2874

spr =R_series2(zref,f,(R-zref)); % make series sparameter

3124

spr =R_series2(zref,f,(R-zref)); % make series sparameter

2875

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

3125

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

2876

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3126

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2877

combines4p( ...

3127

combines4p( ...

2878

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3128

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2879

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3129

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2880

);

3130

);

2881

elseif R < zref

3131

elseif R < zref

2882

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

3132

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

2883

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

3133

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

2884

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3134

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2885

combines4p( ...

3135

combines4p( ...

2886

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3136

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2887

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3137

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2888

);

3138

);

2889

else

3139

else

2890

SLD=S;

3140

SLD=S;

2891

end

3141

end

2892

3142

2893

%%

3143

%%

2894

3144

2895

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

3145

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

2896

p1=param.CTLE_fp1(1);

3146

p1=param.CTLE_fp1(1);

2897

z1=param.CTLE_fz(1);

3147

z1=param.CTLE_fz(1);

2898

p2=param.CTLE_fp2(1);

3148

p2=param.CTLE_fp2(1);

2899

zlf=param.f_HP(1);

3149

zlf=param.f_HP(1);

2900

plf=param.f_HP(1);

3150

plf=param.f_HP(1);

2901

f_b=param.fb;

3151

f_b=param.fb;

2902

f_r=param.f_r;

3152

f_r=param.f_r;

2903

eta_0=param.eta_0;

3153

eta_0=param.eta_0;

2904

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));

3154

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));

2905

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

3155

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

2906

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

3156

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

2907

if 0

3157

if 0

2908

figure

3158

figure

2909

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

3159

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

2910

% see if it looks correct

3160

% see if it looks correct

2911

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

3161

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

2912

ylabel('dB');

3162

ylabel('dB');

2913

xlabel('GHz');

3163

xlabel('GHz');

2914

title( 'H_ctf with H_r')

3164

title( 'H_ctf with H_r')

2915

grid on

3165

grid on

2916

ylim([-30 0])

3166

ylim([-30 0])

2917

end

3167

end

2918

3168

2919

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

3169

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

2920

3170

2921

%Fill TDR data

3171

%Fill TDR data

2922

if package_testcase_i == 1

3172

if package_testcase_i == 1

2923

if OP.TDR

3173

if OP.TDR

2924

output_args.Z11est=chdata(1).TDR11.avgZport;

3174

output_args.Z11est=chdata(1).TDR11.avgZport;

2925

if ~param.FLAG.S2P

3175

if ~param.FLAG.S2P

2926

output_args.Z22est=chdata(1).TDR22.avgZport;

3176

output_args.Z22est=chdata(1).TDR22.avgZport;

2927

else

3177

else

2928

output_args.Z22est=[];

3178

output_args.Z22est=[];

2929

end

3179

end

2930

if OP.AUTO_TFX

3180

if OP.AUTO_TFX

2931

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

3181

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

2932

else

3182

else

2933

output_args.tfx_estimate=[];

3183

output_args.tfx_estimate=[];

2934

end

3184

end

2935

else

3185

else

2936

output_args.Z11est=[];

3186

output_args.Z11est=[];

2937

output_args.Z22est=[];

3187

output_args.Z22est=[];

2938

output_args.tfx_estimate=[];

3188

output_args.tfx_estimate=[];

2939

end

3189

end

2940

end

3190

end

2941

3191

2942

% Process ERL

3192

% Process ERL

2943

if package_testcase_i == 1

3193

if package_testcase_i == 1

2944

if OP.ERL

3194

if OP.ERL

2945

output_args.ERL11=chdata(1).TDR11.ERL;

3195

output_args.ERL11=chdata(1).TDR11.ERL;

2946

if ~param.FLAG.S2P

3196

if ~param.FLAG.S2P

2947

output_args.ERL22=chdata(1).TDR22.ERL;

3197

output_args.ERL22=chdata(1).TDR22.ERL;

2948

else

3198

else

2949

output_args.ERL22=[];

3199

output_args.ERL22=[];

2950

end

3200

end

2951

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

3201

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

2952

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

3202

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

2953

else

3203

else

2954

output_args.ERL11=[];

3204

output_args.ERL11=[];

2955

output_args.ERL22=[];

3205

output_args.ERL22=[];

2956

end

3206

end

2957

end

3207

end

2958

if OP.ERL

3208

if OP.ERL

2959

if OP.TDR_W_TXPKG

3209

if OP.TDR_W_TXPKG

2960

min_ERL=output_args.ERL22;

3210

min_ERL=output_args.ERL22;

2961

ERL= [ nan output_args.ERL22 ];

3211

ERL= [ nan output_args.ERL22 ];

2962

else

3212

else

2963

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

3213

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

2964

min_ERL=output_args.ERL11;

3214

min_ERL=output_args.ERL11;

2965

ERL= [ output_args.ERL11 nan ];

3215

ERL= [ output_args.ERL11 nan ];

2966

else

3216

else

2967

min_ERL=min(output_args.ERL11,output_args.ERL22);

3217

min_ERL=min(output_args.ERL11,output_args.ERL22);

2968

ERL= [ output_args.ERL11 output_args.ERL22 ];

3218

ERL= [ output_args.ERL11 output_args.ERL22 ];

2969

end

3219

end

2970

end

3220

end

2971

output_args.ERL=min_ERL;

3221

output_args.ERL=min_ERL;

2972

else

3222

else

2973

min_ERL=[];

3223

min_ERL=[];

2974

ERL= [];

3224

ERL= [];

2975

output_args.ERL=[];

3225

output_args.ERL=[];

2976

end

3226

end

2977

if OP.ERL_ONLY

3227

if OP.ERL_ONLY

2978

if OP.BREAD_CRUMBS

3228

if OP.BREAD_CRUMBS

2979

output_args.OP=OP;

3229

output_args.OP=OP;

2980

output_args.param=param;

3230

output_args.param=param;

2981

output_args.chdata=chdata;

3231

output_args.chdata=chdata;

2982

%This seems to be the intent of setting fom_result.ran=0. Add it

3232

%This seems to be the intent of setting fom_result.ran=0. Add it

2983

%to output_args so there is a fom_result field.

3233

%to output_args so there is a fom_result field.

2984

fom_result.ran=0;

3234

fom_result.ran=0;

2985

output_args.fom_result=fom_result;

3235

output_args.fom_result=fom_result;

2986

end

3236

end

2987

output_args.Z_t=param.Z_t;

3237

output_args.Z_t=param.Z_t;

2988

fileset_str=str2csv({chdata(1).base});

3238

fileset_str=str2csv({chdata(1).base});

2989

output_args.file_names=sprintf('"%s"', fileset_str);

3239

output_args.file_names=sprintf('"%s"', fileset_str);

2990

if OP.DISPLAY_WINDOW

3240

if OP.DISPLAY_WINDOW

2991

savefigs(param, OP);

3241

savefigs(param, OP);

2992

end

3242

end

2993

end

3243

end

2994

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3244

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

2995

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3245

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

2996

p1_ctle = -2*pi*f_p1;

3246

p1_ctle = -2*pi*f_p1;

2997

p2_ctle = -2*pi*f_p2;

3247

p2_ctle = -2*pi*f_p2;

2998

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3248

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

2999

k_ctle = -p2_ctle;

3249

k_ctle = -p2_ctle;

3000

bilinear_fs = 2*fb*oversampling;

3250

bilinear_fs = 2*fb*oversampling;

3001

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3251

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3002

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3252

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3003

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3253

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3004

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3254

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3005

% allow for different pole zeros RIM 9-29-2015

3255

% allow for different pole zeros RIM 9-29-2015

3006

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3256

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3007

B_filt =k_ctle*kd*poly([zd, -1]);

3257

B_filt =k_ctle*kd*poly([zd, -1]);

3008

A_filt=poly([p1d, p2d]);

3258

A_filt=poly([p1d, p2d]);

3009

impulse_response=filter(B_filt,A_filt,ir_in);

3259

impulse_response=filter(B_filt,A_filt,ir_in);

3010

3260

3011

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3261

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3012

Over_sample=2;

3262

Over_sample=2;

3013

num_files=length(chdata);

3263

num_files=length(chdata);

3014

for i=1:num_files

3264

for i=1:num_files

3015

V=chdata(i).uneq_pulse_response;

3265

V=chdata(i).uneq_pulse_response;

3016

T=chdata(i).t;

3266

T=chdata(i).t;

3017

dt=T(2)-T(1);

3267

dt=T(2)-T(1);

3018

f=0:1/max(T):1/dt;

3268

f=0:1/max(T):1/dt;

3019

chdata(i).faxis=f;

3269

chdata(i).faxis=f;

3020

f75=find(f >= param.fb*.75,1,'first');

3270

f75=find(f >= param.fb*.75,1,'first');

3021

fnq=find(f >= param.fb*.5,1,'first');

3271

fnq=find(f >= param.fb*.5,1,'first');

3022

chdata(i).fmaxi = length(f);

3272

chdata(i).fmaxi = length(f);

3023

chdata(i).faxis = f;

3273

chdata(i).faxis = f;

3024

UI=param.ui; % unit interval

3274

UI=param.ui; % unit interval

3025

M=param.samples_per_ui; % sample per UI

3275

M=param.samples_per_ui; % sample per UI

3026

N_v=param.N_v; % number of UI for Vf determination

3276

N_v=param.N_v; % number of UI for Vf determination

3027

3277

3028

% filters

3278

% filters

3029

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3279

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3030

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3280

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3031

H_ftr=H_bw.*H_bt;

3281

H_ftr=H_bw.*H_bt;

3032

H_ftr=H_ftr(:);

3282

H_ftr=H_ftr(:);

3033

% fd of PR

3283

% fd of PR

3034

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3284

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3035

prr = prr(:);

3285

prr = prr(:);

3036

if f(1)==0, prr(1)=1; end %remove NaN

3286

if f(1)==0, prr(1)=1; end %remove NaN

3037

fd=fft(V);

3287

fd=fft(V);

3038

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3288

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3039

3289

3040

%% get Vf

3290

%% get Vf

3041

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3291

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3042

step_response=filter(V,1, shifting_vector);

3292

step_response=filter(V,1, shifting_vector);

3043

Vf=step_response(end);

3293

Vf=step_response(end);

3044

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3294

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3045

%%

3295

%%

3046

% 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

3296

% 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

3047

% figure

3297

% figure

3048

% plot(f(1:f75),ILest)

3298

% plot(f(1:f75),ILest)

3049

3299

3050

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

3300

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

3051

% set same variables as get_s4p_files

3301

% set same variables as get_s4p_files

3052

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3302

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3053

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3303

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3054

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3304

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3055

zero_vector=zeros(length(IL_conv),1);

3305

zero_vector=zeros(length(IL_conv),1);

3056

for j=1:length(IL_fields)

3306

for j=1:length(IL_fields)

3057

chdata(i).(IL_fields{j})=IL_conv;

3307

chdata(i).(IL_fields{j})=IL_conv;

3058

end

3308

end

3059

for j=1:length(Zero_fields)

3309

for j=1:length(Zero_fields)

3060

chdata(i).(Zero_fields{j})=zero_vector;

3310

chdata(i).(Zero_fields{j})=zero_vector;

3061

end

3311

end

3062

3312

3063

if i==1

3313

if i==1

3064

SDDch(:,1,2)=chdata.sdd12_raw;

3314

SDDch(:,1,2)=chdata.sdd12_raw;

3065

SDDch(:,2,1)=chdata.sdd21_raw;

3315

SDDch(:,2,1)=chdata.sdd21_raw;

3066

SDDch(:,1,1)=chdata.sdd11_raw;

3316

SDDch(:,1,1)=chdata.sdd11_raw;

3067

SDDch(:,2,2)=chdata.sdd22_raw;

3317

SDDch(:,2,2)=chdata.sdd22_raw;

3068

SDDp2p= zeros(length(IL_conv),1);

3318

SDDp2p= zeros(length(IL_conv),1);

3069

end

3319

end

3070

chdata(i).TX_RL=[];

3320

chdata(i).TX_RL=[];

3071

chdata(i).TDR11=[];

3321

chdata(i).TDR11=[];

3072

chdata(i).PDTR11=[];

3322

chdata(i).PDTR11=[];

3073

chdata(i).TDR22=[];

3323

chdata(i).TDR22=[];

3074

chdata(i).PDTR22=[];

3324

chdata(i).PDTR22=[];

3075

end

3325

end

3076

3326

3077

3327

3078

function H_tw=Tukey_Window(f,param,fr,fb)

3328

function H_tw=Tukey_Window(f,param,fr,fb)

3079

% RIM 05/26/2022 added optional fr and fb

3329

% RIM 05/26/2022 added optional fr and fb

3080

% fr is the start of the raised cosine window

3330

% fr is the start of the raised cosine window

3081

% fb is the end of the raised cosine window

3331

% fb is the end of the raised cosine window

3082

if ~exist('fr','var') && ~exist('fb','var')

3332

if ~exist('fr','var') && ~exist('fb','var')

3083

fb=param.fb;

3333

fb=param.fb;

3084

fr=param.f_r*param.fb;

3334

fr=param.f_r*param.fb;

3085

end

3335

end

3086

fperiod=2*(fb-fr);

3336

fperiod=2*(fb-fr);

3087

H_tw = [ ones(1,length(f(f<fr))) ...

3337

H_tw = [ ones(1,length(f(f<fr))) ...

3088

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3338

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3089

zeros(1,length(f(f>fb)) )];

3339

zeros(1,length(f(f>fb)) )];

3090

H_tw=H_tw(1:length(f));

3340

H_tw=H_tw(1:length(f));

3091

if 0

3341

if 0

3092

plot(f/1e9,H_tw)

3342

plot(f/1e9,H_tw)

3093

end

3343

end

3094

3344

3095

3345

3096

3346

3097

%% moved output control to functions

3347

%% moved output control to functions

3098

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3348

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3099

% Author: Richard Mellitz

3349

% Author: Richard Mellitz

3100

% Date: 7/29/2022

3350

% Date: 7/29/2022

3101

% generate FD tx ffe system function

3351

% generate FD tx ffe system function

3102

% varagins...

3352

% varagins...

3103

% param - stucture

3353

% param - stucture

3104

% param.fb baud rate

3354

% param.fb baud rate

3105

% param.Tx_FFE Tx FFE coef

3355

% param.Tx_FFE Tx FFE coef

3106

% f - freq array

3356

% f - freq array

3107

% Use_Tx_FFE = flag to use or not

3357

% Use_Tx_FFE = flag to use or not

3108

% H_TxFFE is system function for Tx_FFE

3358

% H_TxFFE is system function for Tx_FFE

3109

db = @(x) 20*log10(abs(x));

3359

db = @(x) 20*log10(abs(x));

3110

[param,varargin]=varargin_extractor(varargin{:});

3360

[param,varargin]=varargin_extractor(varargin{:});

3111

[f,varargin]=varargin_extractor(varargin{:});

3361

[f,varargin]=varargin_extractor(varargin{:});

3112

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3362

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3113

if isempty(Use_Tx_FFE)

3363

if isempty(Use_Tx_FFE)

3114

Use_Tx_FFE=0;

3364

Use_Tx_FFE=0;

3115

end

3365

end

3116

if isempty(param)

3366

if isempty(param)

3117

param.fb=106.25e9;

3367

param.fb=106.25e9;

3118

Tx_FFE=[1 ];

3368

Tx_FFE=[1 ];

3119

else

3369

else

3120

if ~isfield(param, 'Pkg_TXFFE_preset')

3370

if ~isfield(param, 'Pkg_TXFFE_preset')

3121

Tx_FFE=[ 1 ];

3371

Tx_FFE=[ 1 ];

3122

else

3372

else

3123

Tx_FFE=param.Pkg_TXFFE_preset;

3373

Tx_FFE=param.Pkg_TXFFE_preset;

3124

end

3374

end

3125

end

3375

end

3126

if isempty(f)

3376

if isempty(f)

3127

f=0:10e6:param.fb;

3377

f=0:10e6:param.fb;

3128

end

3378

end

3129

3379

3130

3380

3131

if Use_Tx_FFE ~=0

3381

if Use_Tx_FFE ~=0

3132

[mcur,icur] = max(Tx_FFE);

3382

[mcur,icur] = max(Tx_FFE);

3133

H_TxFFE=zeros(1,length(f));

3383

H_TxFFE=zeros(1,length(f));

3134

for ii=1:length(Tx_FFE)

3384

for ii=1:length(Tx_FFE)

3135

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3385

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3136

end

3386

end

3137

else

3387

else

3138

H_TxFFE=ones(1,length(f));

3388

H_TxFFE=ones(1,length(f));

3139

end

3389

end

3140

% figure (1102320)

3390

% figure (1102320)

3141

% plot(f/1e9,db(H_TxFFE))

3391

% plot(f/1e9,db(H_TxFFE))

3142

% hold on

3392

% hold on

+3393

function C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs)

3394

cmx=param.RxFFE_cmx;

3395

cpx=param.RxFFE_cpx;

3396

% do this early on so we can reuse the old code

3397

% to be replaced with MMSE function from healey...

3398

if param.N_bg ~=0 % must be floating taps

3399

cpx=param.N_bmax; % N_f in spreadsheet

3400

end

3401

num_taps=cmx+cpx+1;

3402

ndfe=param.ndfe;

3403

spui=param.samples_per_ui;

3404

%% Start of WIENER-HOPF MMSE EQ code

3405

R_n = zeros(num_taps,num_taps);

3406

R_xt = zeros(num_taps,num_taps);

3407

3408

if OP.Do_Colored_Noise

3409

% Form Noise Autocorrelation matrix

3410

Noise_XC = reshape (Noise_XC,1,[]);

3411

len = length(Noise_XC);

3412

if len < num_taps, Noise_XC = [Noise_XC,zeros(1,num_taps-len)]; end

3413

Noise_XC = Noise_XC(1:num_taps);

3414

R_n = toeplitz (Noise_XC,Noise_XC);

3415

end

3416

%% Calculate Cross Talk Correlation matrix at T intervals.

3417

if OP.Do_XT_Noise

3418

% Calculate variance of Tx signal based on +/-1 outer limits

3419

Tx_sigma = sqrt( (param.levels^2-1)/(3*(param.levels-1)^2) );

3420

for jj = 2:length(chdata)

3421

if isequal(chdata(jj).type, 'FEXT') || isequal(chdata(jj).type, 'NEXT')

3422

if isequal(chdata(jj).type, 'FEXT')

3423

% len = length(chdata(jj).ctle_imp_response);

3424

% ch_imp = ifft( fft(reshape(chdata(jj).ctle_imp_response,1,[])) .* fft(reshape(upsample(txffe, param.samples_per_ui),1,[]),len) );

3425

ch_imp= FFE( txffe , cmx,param.samples_per_ui, chdata(jj).ctle_imp_response).';

3426

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3427

elseif isequal(chdata(jj).type, 'NEXT')

3428

ch_imp = chdata(jj).ctle_imp_response;

3429

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3430

end

3431

norms = zeros(1,spui);

3432

for ii = 1:spui

3433

norms(ii) = norm(ch_imp(ii:spui:end));

3434

end

3435

% Pick out sampling phase with largest noise contribution

3436

[~,cursor] = max(norms);

3437

sub_sample_ch = ch_imp(cursor:spui:end);

3438

xc = xcorr(sub_sample_ch,num_taps)* Tx_sigma^2;

3439

xc = xc(num_taps+1:end);

3440

xc = xc(1:num_taps);

3441

R = toeplitz (xc,xc);

3442

R_xt = R_xt + R;

3443

end

3444

end

3445

end

3446

%% Noise + Cross Talk contribution to R matrix

3447

R_n_xc = zeros(num_taps+ndfe);

3448

R_n_xc(1:num_taps,1:num_taps) = R_n + R_xt ;

3449

%% For least means squares, we want to solve

3450

%

3451

% ro = |Ryy Ryx| * w

3452

% |Rxy Rxx|

3453

% see Cioffi chapter 3, 3.7.3

3454

3455

himp = vsampled;

3456

RefTap = cmx+1;

3457

Signal_Variance = mean ( [-1, -1/3, 1/3, 1].^2 );

3458

Ryy.r = [1:num_taps];

3459

Ryy.c = [1:num_taps];

3460

Ryx.r = 1:num_taps;

3461

Ryx.c = num_taps + (1:ndfe);

3462

Rxy.r = num_taps + (1:ndfe);

3463

Rxy.c = 1:num_taps;

3464

Rxx.r = num_taps+(1:ndfe);

3465

Rxx.c = num_taps+(1:ndfe);

3466

himp = reshape (himp,1,[]);

3467

%% ro is simply the channel response reversed in time

3468

himp_lr = fliplr(himp); % make sure himp has enough pre/post cursors, e.g. numtaps+ndfe

3469

himp_lr = [zeros(1,num_taps+ndfe), himp_lr, zeros(1,num_taps+ndfe)];

3470

[~,pk] = max(himp_lr);

3471

r_indx = (1:num_taps) - RefTap;

3472

ro = [himp_lr(pk+r_indx), zeros(1,ndfe)].';

3473

ro = ro*Signal_Variance;

3474

%% Setup up the covariance matrix

3475

R = zeros(num_taps+ndfe);

3476

% Form Ryy

3477

% Note: important to use whole impulse response

3478

% not just the part that spans the FFE.

3479

[ryy,lags] = xcorr(himp,himp, num_taps-1);

3480

R(Ryy.r,Ryy.c) = toeplitz (ryy(num_taps:end));

3481

3482

% Form Rxx

3483

R(Rxx.r,Rxx.c) = diag(ones(1,ndfe));

3484

3485

% Form Ryx columns

3486

Ryx_indxs = (1:num_taps)-1;

3487

for jj = 0:ndfe-1

3488

% R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk+1 + Ryx_indxs -jj ).';

3489

R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk-cmx-1 + Ryx_indxs -jj ).';

3490

end

3491

% Form Rxy rows

3492

R(Rxy.r,Rxy.c ) = R(Ryx.r,Ryx.c )';

3493

3494

% add in Signal Variance

3495

R = R*Signal_Variance;

3496

Rtmp = R;

3497

% Add in Xt and colored noise terms

3498

R = R + R_n_xc;

3499

3500

% SNR = 25 dB

3501

SNR = OP.FFE_SNR;

3502

Noise_var = max(vsampled)^2*Signal_Variance/10^(SNR/10);

3503

R_noise = diag(ones(1,num_taps))*Noise_var;

3504

if ~OP.Do_Colored_Noise && ~OP.Do_XT_Noise

3505

R(Ryy.r,Ryy.c) = R(Ryy.r,Ryy.c) + R_noise;

3506

end

3507

3508

3509

%% Solve for equalizer weights

3510

w = inv(R)*ro;

3511

C = w;

3512

%% Deal with 1st post Cursor DFE weight saturation

3513

% ro = Rw by moving "saturated" weights over to the LHS

3514

DFE_h1_indx = num_taps+1;

3515

Indx_full = 1:length(C);

3516

ws = C;

3517

if ndfe>0 && abs(C(DFE_h1_indx)) > param.bmax(1)

3518

rtmp = reshape (ro,[],1);

3519

Rtmp = R;

3520

% Move saturated DFE weights over to left hand side of equation

3521

ws = zeros (size(C));

3522

ws (DFE_h1_indx) = sign(C(DFE_h1_indx))*param.bmax(1);

3523

rtmp = rtmp - Rtmp*ws;

3524

3525

% and remove the corresponding column from R

3526

Rtmp(:,DFE_h1_indx) = [];

3527

Indx_full (DFE_h1_indx) = [];

3528

% now Rtmp isn't square so have to use the R'R trick

3529

% Probably a little dicey "theoretically" because

3530

% w = inv(R)*ro is already the mmse solution

3531

% now we at doing a R'R operation, but hey

3532

% seems to work

3533

% Alternative, since R is now over specified, more rows than

3534

% columns, one could try removing one of the DFE rows from the

3535

% Rxy Rxx portion of the R matrix.

3536

3537

w_partial = inv(Rtmp'*Rtmp)*(Rtmp'*rtmp);

3538

ws (Indx_full,:) = w_partial;

3539

C = ws;

3540

end

3541

% From Cioffi, Chapter 3

3542

var_ffe_dfe = Signal_Variance-ws.'*ro;

3543

SNR_Eq = 10*log10(Signal_Variance/var_ffe_dfe-1);

3544

3545

%% Scale FFE gain to target output voltage

3546

Target_ouput = vsampled(ivs)*10^(param.current_ffegain/20);

3547

C = C*Target_ouput;

3548

C = C(1:num_taps);

3549

%% End MMSE dfe code

3143

function Write_CSV(output_args,csv_file)

3550

function Write_CSV(output_args,csv_file)

3144

3551

3145

items = fieldnames(output_args);

3552

items = fieldnames(output_args);

3146

item_value_strings = cell(size(items));

3553

item_value_strings = cell(size(items));

3147

for field_id=1:length(items)

3554

for field_id=1:length(items)

3148

field_name=items{field_id};

3555

field_name=items{field_id};

3149

field_value=output_args.(field_name);

3556

field_value=output_args.(field_name);

3150

if isstruct(output_args.(field_name))

3557

if isstruct(output_args.(field_name))

3151

field_value='struct';

3558

field_value='struct';

3152

end

3559

end

3153

if ischar(field_value)

3560

if ischar(field_value)

3154

item_value_strings{field_id}=field_value;

3561

item_value_strings{field_id}=field_value;

3155

elseif isempty(field_value)

3562

elseif isempty(field_value)

3156

item_value_strings{field_id}='';

3563

item_value_strings{field_id}='';

3157

elseif numel(field_value)==1

3564

elseif numel(field_value)==1

3158

item_value_strings{field_id}=num2str(field_value);

3565

item_value_strings{field_id}=num2str(field_value);

3159

else

3566

else

3160

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3567

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3161

end

3568

end

3162

end

3569

end

3163

3570

3164

header_string = str2csv(items);

3571

header_string = str2csv(items);

3165

data_string = str2csv(item_value_strings);

3572

data_string = str2csv(item_value_strings);

3166

fid = fopen(csv_file,'w');

3573

fid = fopen(csv_file,'w');

3167

fprintf(fid,'%s\n', header_string);

3574

fprintf(fid,'%s\n', header_string);

3168

fprintf(fid,'%s\n', data_string);

3575

fprintf(fid,'%s\n', data_string);

3169

fclose(fid);

3576

fclose(fid);

3170

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3577

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3171

%% Used in Clause 92 for adding board trace between TP0 and TP2

3578

%% Used in Clause 92 for adding board trace between TP0 and TP2

3172

3579

3173

switch chdata.type

3580

switch chdata.type

3174

case 'THRU'

3581

case 'THRU'

3175

z_bp_tx = param.z_bp_tx;

3582

z_bp_tx = param.z_bp_tx;

3176

z_bp_rx = param.z_bp_rx;

3583

z_bp_rx = param.z_bp_rx;

3177

case 'NEXT'

3584

case 'NEXT'

3178

z_bp_tx = param.z_bp_rx;

3585

z_bp_tx = param.z_bp_rx;

3179

z_bp_rx = param.z_bp_next;

3586

z_bp_rx = param.z_bp_next;

3180

case 'FEXT'

3587

case 'FEXT'

3181

z_bp_tx = param.z_bp_fext;

3588

z_bp_tx = param.z_bp_fext;

3182

z_bp_rx = param.z_bp_rx;

3589

z_bp_rx = param.z_bp_rx;

3183

end

3590

end

3184

% Same cap on each tx and rx three is a data stratue for bifrucation but

3591

% Same cap on each tx and rx three is a data stratue for bifrucation but

3185

% logic no implemented here RIM 06/28/2019

3592

% logic no implemented here RIM 06/28/2019

3186

zref=param.Z0;

3593

zref=param.Z0;

3187

c1=param.C_0;

3594

c1=param.C_0;

3188

c2=param.C_1;

3595

c2=param.C_1;

3189

f=chdata.faxis;

3596

f=chdata.faxis;

3190

f(f<eps)=eps;

3597

f(f<eps)=eps;

3191

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3598

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3192

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3599

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3193

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3600

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3194

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3601

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3195

[ 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);

3602

[ 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);

3196

% add Tx caps

3603

% add Tx caps

3197

[s11tx, s12tx, s21tx, s22tx ]= ...

3604

[s11tx, s12tx, s21tx, s22tx ]= ...

3198

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3605

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3199

[s11tx, s12tx, s21tx, s22tx ]= ...

3606

[s11tx, s12tx, s21tx, s22tx ]= ...

3200

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3607

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3201

3608

3202

3609

3203

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3610

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3204

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3611

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3205

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3612

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3206

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3613

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3207

[ 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);

3614

[ 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);

3208

% add Rx caps

3615

% add Rx caps

3209

[s11rx, s12rx, s21rx, s22rx ]= ...

3616

[s11rx, s12rx, s21rx, s22rx ]= ...

3210

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3617

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3211

[s11rx, s12rx, s21rx, s22rx ]= ...

3618

[s11rx, s12rx, s21rx, s22rx ]= ...

3212

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3619

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3213

3620

3214

3621

3215

switch OP.include_pcb

3622

switch OP.include_pcb

3216

case 1

3623

case 1

3217

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3624

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3218

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3625

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3219

case 2

3626

case 2

3220

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3627

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3221

end

3628

end

3222

3629

3223

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3630

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3224

% Used in Clause 92 for adding board trace between TP0 and TP2

3631

% Used in Clause 92 for adding board trace between TP0 and TP2

3225

switch chdata.type

3632

switch chdata.type

3226

case 'THRU'

3633

case 'THRU'

3227

z_bp_tx = param.z_bp_tx;

3634

z_bp_tx = param.z_bp_tx;

3228

case 'NEXT'

3635

case 'NEXT'

3229

z_bp_tx = param.z_bp_next;

3636

z_bp_tx = param.z_bp_next;

3230

case 'FEXT'

3637

case 'FEXT'

3231

z_bp_tx = param.z_bp_fext;

3638

z_bp_tx = param.z_bp_fext;

3232

end

3639

end

3233

3640

3234

[ 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);

3641

[ 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);

3235

[ 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);

3642

[ 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);

3236

3643

3237

switch OP.include_pcb

3644

switch OP.include_pcb

3238

case 1

3645

case 1

3239

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3646

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3240

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3647

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3241

case 2

3648

case 2

3242

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3649

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3243

end

3650

end

3244

3651

3245

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3652

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3246

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3653

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3247

% applying a bank of DFE at desired location

3654

% applying a bank of DFE at desired location

3248

% hisi: waveform with cursor values;

3655

% hisi: waveform with cursor values;

3249

% idx: starting index of the bank;

3656

% idx: starting index of the bank;

3250

% tap_bk: number of taps in bank;

3657

% tap_bk: number of taps in bank;

3251

% bmaxg: maxmum coefficient in bank;

3658

% bmaxg: maxmum coefficient in bank;

3252

3659

3253

if nargin<6

3660

if nargin<6

3254

dfe_delta=0;

3661

dfe_delta=0;

3255

end

3662

end

3256

3663

3257

rng=idx:idx+tap_bk-1;

3664

rng=idx:idx+tap_bk-1;

3258

flt_curval=hisi(rng);

3665

flt_curval=hisi(rng);

3259

3666

3260

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3667

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3261

3668

3262

if dfe_delta~=0

3669

if dfe_delta~=0

3263

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3670

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3264

dfe_delta.*sign(flt_curval)*curval;

3671

dfe_delta.*sign(flt_curval)*curval;

3265

else

3672

else

3266

flt_curval_q=hisi(rng);

3673

flt_curval_q=hisi(rng);

3267

end

3674

end

3268

3675

3269

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3676

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3270

hisi(rng)= hisi(rng) - curval*tap_coef;

3677

hisi(rng)= hisi(rng) - curval*tap_coef;

3271

hisi_ref(rng)=0;

3678

hisi_ref(rng)=0;

3272

3679

3273

%AJG021820

3680

%AJG021820

3274

function [ a] = bessel( n )

3681

function [ a] = bessel( n )

3275

% bessel polynomial

3682

% bessel polynomial

3276

for ii= 0:n

3683

for ii= 0:n

3277

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3684

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3278

end

3685

end

3279

3686

3280

3687

3281

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3688

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3282

% History:

3689

% History:

3283

% 1. 14th October, 2021 (Intial release)

3690

% 1. 14th October, 2021 (Intial release)

3284

3691

3285

% Definition:

3692

% Definition:

3286

% This function captures the channel delay through the time domain using causality enforcement.

3693

% This function captures the channel delay through the time domain using causality enforcement.

3287

% Following are the steps being followed.

3694

% Following are the steps being followed.

3288

% Step 1. Cascade negative frequencies

3695

% Step 1. Cascade negative frequencies

3289

% Step 2. Extract magnitude

3696

% Step 2. Extract magnitude

3290

% Step 3. IFFT of the magnitude

3697

% Step 3. IFFT of the magnitude

3291

% Step 4. Multiply by the sign(t)

3698

% Step 4. Multiply by the sign(t)

3292

% Step 5. Calculate the phase of the 1j*causal_phase

3699

% Step 5. Calculate the phase of the 1j*causal_phase

3293

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3700

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3294

% Step 7. f-domain to t-domain pulse response

3701

% Step 7. f-domain to t-domain pulse response

3295

% Step 8. Calculate the delay

3702

% Step 8. Calculate the delay

3296

3703

3297

% Author:

3704

% Author:

3298

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3705

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3299

3706

3300

% Reference:

3707

% Reference:

3301

% 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.

3708

% 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.

3302

3709

3303

% Input:

3710

% Input:

3304

% freq %frequency in hertz (odd number points)

3711

% freq %frequency in hertz (odd number points)

3305

% sdd21 %insertion loss in complex (odd number points)

3712

% sdd21 %insertion loss in complex (odd number points)

3306

% param %COM native structure passed

3713

% param %COM native structure passed

3307

% OP %COM native structure passed

3714

% OP %COM native structure passed

3308

3715

3309

% Output:

3716

% Output:

3310

% delay_sec %channel delay in seconds

3717

% delay_sec %channel delay in seconds

3311

% delay_idx %channel delay index

3718

% delay_idx %channel delay index

3312

3719

3313

if iscolumn(sdd21)

3720

if iscolumn(sdd21)

3314

sdd21= sdd21.';

3721

sdd21= sdd21.';

3315

end

3722

end

3316

if iscolumn(freq)

3723

if iscolumn(freq)

3317

freq= freq.';

3724

freq= freq.';

3318

end

3725

end

3319

3726

3320

%---start. Step 1. Cascade negative frequencies

3727

%---start. Step 1. Cascade negative frequencies

3321

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3728

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3322

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3729

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3323

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3730

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3324

%---end. Step 1. Cascade negative frequencies

3731

%---end. Step 1. Cascade negative frequencies

3325

3732

3326

%---start. Step 2. Extract magnitude

3733

%---start. Step 2. Extract magnitude

3327

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3734

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3328

%---end. Step 2. Extract magnitude

3735

%---end. Step 2. Extract magnitude

3329

3736

3330

%---start. Step 3. IFFT of the magnitude

3737

%---start. Step 3. IFFT of the magnitude

3331

sdd21_mag_time = ifft(sdd21_mag_conj);

3738

sdd21_mag_time = ifft(sdd21_mag_conj);

3332

%---end. Step 3. IFFT of the magnitude

3739

%---end. Step 3. IFFT of the magnitude

3333

3740

3334

%---start. Step 4. Multiply by the sign(t)

3741

%---start. Step 4. Multiply by the sign(t)

3335

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3742

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3336

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3743

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3337

%---end. Step 4. Multiply by the sign(t)

3744

%---end. Step 4. Multiply by the sign(t)

3338

3745

3339

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3746

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3340

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3747

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3341

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3748

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3342

3749

3343

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3750

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3344

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3751

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3345

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3752

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3346

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3753

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3347

3754

3348

%---start. Step 7. f-domain to t-domain pulse response

3755

%---start. Step 7. f-domain to t-domain pulse response

3349

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3756

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3350

%--------- Extrapolation has been already done by the COM tool

3757

%--------- Extrapolation has been already done by the COM tool

3351

freq_array= freq;

3758

freq_array= freq;

3352

time_step= param.sample_dt;

3759

time_step= param.sample_dt;

3353

fmax=1/time_step/2;

3760

fmax=1/time_step/2;

3354

freq_step=(freq_array(3)-freq_array(2))/1;

3761

freq_step=(freq_array(3)-freq_array(2))/1;

3355

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3762

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3356

3763

3357

ILin=sdd21;

3764

ILin=sdd21;

3358

IL=interp_Sparam(ILin,freq_array,fout, ...

3765

IL=interp_Sparam(ILin,freq_array,fout, ...

3359

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3766

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3360

IL_nan = find(isnan(IL));

3767

IL_nan = find(isnan(IL));

3361

for in=IL_nan

3768

for in=IL_nan

3362

IL(in)=IL(in-1);

3769

IL(in)=IL(in-1);

3363

end

3770

end

3364

IL = IL(:);

3771

IL = IL(:);

3365

% add padding for time steps

3772

% add padding for time steps

3366

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3773

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3367

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3774

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3368

clear IL IL_nan IL_symmetric

3775

clear IL IL_nan IL_symmetric

3369

3776

3370

ILin=sdd21_causality_enforced;

3777

ILin=sdd21_causality_enforced;

3371

IL=interp_Sparam(ILin,freq_array,fout, ...

3778

IL=interp_Sparam(ILin,freq_array,fout, ...

3372

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3779

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3373

IL_nan = find(isnan(IL));

3780

IL_nan = find(isnan(IL));

3374

for in=IL_nan

3781

for in=IL_nan

3375

IL(in)=IL(in-1);

3782

IL(in)=IL(in-1);

3376

end

3783

end

3377

IL = IL(:);

3784

IL = IL(:);

3378

% add padding for time steps

3785

% add padding for time steps

3379

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3786

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3380

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3787

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3381

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3788

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3382

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3789

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3383

clear IL IL_nan IL_symmetric

3790

clear IL IL_nan IL_symmetric

3384

3791

3385

clear time_step fmax freq_step freq_array

3792

clear time_step fmax freq_step freq_array

3386

3793

3387

freq_step=(fout(3)-fout(2))/1;

3794

freq_step=(fout(3)-fout(2))/1;

3388

L= length(sdd21_PR);

3795

L= length(sdd21_PR);

3389

t_base = (0:L-1)/(freq_step*L);

3796

t_base = (0:L-1)/(freq_step*L);

3390

clear fout freq_step L

3797

clear fout freq_step L

3391

%---end. Step 7. f-domain to t-domain pulse response

3798

%---end. Step 7. f-domain to t-domain pulse response

3392

3799

3393

%---start. Step 8. Calculate the delay

3800

%---start. Step 8. Calculate the delay

3394

%------start. Remove the last 5% of the waveform for noise due to IFFT

3801

%------start. Remove the last 5% of the waveform for noise due to IFFT

3395

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3802

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3396

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3803

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3397

%------end. Remove the last 5% of the waveform for noise due to IFFT

3804

%------end. Remove the last 5% of the waveform for noise due to IFFT

3398

3805

3399

%---start. calculate the difference in index between the peaks

3806

%---start. calculate the difference in index between the peaks

3400

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3807

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3401

[~, peak_y_idx] = max(sdd21_PR_reduced);

3808

[~, peak_y_idx] = max(sdd21_PR_reduced);

3402

peak_idx_difference = peak_x_idx - peak_y_idx;

3809

peak_idx_difference = peak_x_idx - peak_y_idx;

3403

%---end. calculate the difference in index between the peaks

3810

%---end. calculate the difference in index between the peaks

3404

3811

3405

if peak_idx_difference~=0

3812

if peak_idx_difference~=0

3406

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

3813

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

3407

error_value = length(sdd21_causality_enforced_PR_reduced);

3814

error_value = length(sdd21_causality_enforced_PR_reduced);

3408

error_idx = 0;

3815

error_idx = 0;

3409

% i= 1;

3816

% i= 1;

3410

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3817

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3411

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3818

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3412

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3819

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3413

if (error_value > current_error)

3820

if (error_value > current_error)

3414

error_idx = shift_value;

3821

error_idx = shift_value;

3415

error_value = current_error;

3822

error_value = current_error;

3416

end

3823

end

3417

% error_idx_H(i)= error_idx;

3824

% error_idx_H(i)= error_idx;

3418

% i= i+ 1;

3825

% i= i+ 1;

3419

end

3826

end

3420

%plot(error_idx_H);

3827

%plot(error_idx_H);

3421

3828

3422

if error_idx==0

3829

if error_idx==0

3423

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3830

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3424

end

3831

end

3425

3832

3426

delay_idx = error_idx;

3833

delay_idx = error_idx;

3427

else

3834

else

3428

delay_idx= 1;

3835

delay_idx= 1;

3429

end

3836

end

3430

3837

3431

delay_sec= t_base(abs(delay_idx));

3838

delay_sec= t_base(abs(delay_idx));

3432

3839

3433

3840

3434

function [return_struct]= capture_RIL_RILN(chdata)

3841

function [return_struct]= capture_RIL_RILN(chdata)

3435

% History:

3842

% History:

3436

% 1. 12th April, 2019 (Intial release)

3843

% 1. 12th April, 2019 (Intial release)

3437

%

3844

%

3438

% 2. 11th October, 2021

3845

% 2. 11th October, 2021

3439

% - Details:

3846

% - Details:

3440

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3847

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3441

% 2] Revised the selection criteria for the solution of the quadratic

3848

% 2] Revised the selection criteria for the solution of the quadratic

3442

% equation in finding the reflection coefficient (rho).

3849

% equation in finding the reflection coefficient (rho).

3443

% - Impact:

3850

% - Impact:

3444

% => Zero impact in |RIL|, while impact on angle(RIL).

3851

% => Zero impact in |RIL|, while impact on angle(RIL).

3445

% - Previous:

3852

% - Previous:

3446

% %---start. For passive networks the reflection coefficient should be less than one

3853

% %---start. For passive networks the reflection coefficient should be less than one

3447

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3854

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3448

% rho_port2= solution_1;

3855

% rho_port2= solution_1;

3449

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3856

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3450

% rho_port2= solution_2;

3857

% rho_port2= solution_2;

3451

% else

3858

% else

3452

% rho_port2= solution_1;

3859

% rho_port2= solution_1;

3453

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3860

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3454

% end

3861

% end

3455

% %---end. For passive networks the reflection coefficient should be less than one

3862

% %---end. For passive networks the reflection coefficient should be less than one

3456

%

3863

%

3457

% 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) ) );

3864

% 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) ) );

3458

% - Change:

3865

% - Change:

3459

% %---start. Given the real part of the impedance is to be positive

3866

% %---start. Given the real part of the impedance is to be positive

3460

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3867

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3461

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3868

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3462

%

3869

%

3463

% rho_port2= zeros(length(solution_1), 1);

3870

% rho_port2= zeros(length(solution_1), 1);

3464

% for solution_idx= 1:length(solution_1)

3871

% for solution_idx= 1:length(solution_1)

3465

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3872

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3466

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3873

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3467

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3874

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3468

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3875

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3469

% else

3876

% else

3470

% error('An odd case has occured. Please contact the tool developer.');

3877

% error('An odd case has occured. Please contact the tool developer.');

3471

% end

3878

% end

3472

% end

3879

% end

3473

% %---end. Given the real part of the impedance is to be positive

3880

% %---end. Given the real part of the impedance is to be positive

3474

% 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) ) );

3881

% 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) ) );

3475

3882

3476

% Definition:

3883

% Definition:

3477

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3884

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3478

3885

3479

% Author:

3886

% Author:

3480

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3887

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3481

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3888

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3482

3889

3483

% 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.

3890

% 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.

3484

3891

3485

% Reference:

3892

% Reference:

3486

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3893

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3487

% 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.

3894

% 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.

3488

3895

3489

% Input:

3896

% Input:

3490

% 1] SCH: S-matrix structure

3897

% 1] SCH: S-matrix structure

3491

% SCH.Frequencies= faxis;

3898

% SCH.Frequencies= faxis;

3492

% SCH.Parameters(1,1,:)= sdd11;

3899

% SCH.Parameters(1,1,:)= sdd11;

3493

% SCH.Parameters(2,2,:)= sdd22;

3900

% SCH.Parameters(2,2,:)= sdd22;

3494

% SCH.Parameters(1,2,:)= sdd12;

3901

% SCH.Parameters(1,2,:)= sdd12;

3495

% SCH.Parameters(2,1,:)= sdd21;

3902

% SCH.Parameters(2,1,:)= sdd21;

3496

% SCH.NumPorts= 2;

3903

% SCH.NumPorts= 2;

3497

% SCH.Impedance= 100;

3904

% SCH.Impedance= 100;

3498

3905

3499

% Output: Struct returned has the following,

3906

% Output: Struct returned has the following,

3500

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3907

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3501

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3908

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3502

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3909

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3503

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3910

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3504

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3911

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3505

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3912

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3506

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3913

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3507

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3914

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3508

% return_struct.freq %Frequency axis

3915

% return_struct.freq %Frequency axis

3509

3916

3510

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3917

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3511

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3918

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3512

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3919

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3513

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3920

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3514

SCH.Frequencies=chdata(1).faxis;

3921

SCH.Frequencies=chdata(1).faxis;

3515

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3922

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3516

SCH.NumPorts= 2;

3923

SCH.NumPorts= 2;

3517

3924

3518

%---start. allowed is only a 2-port network having a transmitter and receiver

3925

%---start. allowed is only a 2-port network having a transmitter and receiver

3519

if size(SCH.Parameters, 1)~=2

3926

if size(SCH.Parameters, 1)~=2

3520

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3927

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3521

error('Allowed is only a 2-port network having a transmitter and receiver.');

3928

error('Allowed is only a 2-port network having a transmitter and receiver.');

3522

end

3929

end

3523

%---end. allowed is only a 2-port network having a transmitter and receiver

3930

%---end. allowed is only a 2-port network having a transmitter and receiver

3524

3931

3525

%---start. do not include the DC point given sinusoidals at DC are not

3932

%---start. do not include the DC point given sinusoidals at DC are not

3526

%defined

3933

%defined

3527

if SCH.Frequencies(1)==0

3934

if SCH.Frequencies(1)==0

3528

idx_start= 2;

3935

idx_start= 2;

3529

else

3936

else

3530

idx_start= 1;

3937

idx_start= 1;

3531

end

3938

end

3532

%---end. do not include the DC point given sinusoidals at DC are not

3939

%---end. do not include the DC point given sinusoidals at DC are not

3533

%defined

3940

%defined

3534

3941

3535

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3942

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3536

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3943

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3537

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3944

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3538

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3945

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3539

3946

3540

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3947

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3541

b= 1+ Sdd22.*conj(Sdd22)+...

3948

b= 1+ Sdd22.*conj(Sdd22)+...

3542

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3949

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3543

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3950

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3544

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3951

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3545

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3952

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3546

Sdd11.*conj(Sdd11);

3953

Sdd11.*conj(Sdd11);

3547

c= -conj(Sdd22)-...

3954

c= -conj(Sdd22)-...

3548

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3955

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3549

Sdd11.*conj(Sdd11).*conj(Sdd22);

3956

Sdd11.*conj(Sdd11).*conj(Sdd22);

3550

3957

3551

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3958

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3552

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3959

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3553

3960

3554

clear a b c

3961

clear a b c

3555

3962

3556

%---start. Given the real part of the impedance is to be positive

3963

%---start. Given the real part of the impedance is to be positive

3557

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3964

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3558

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3965

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3559

3966

3560

rho_port2= zeros(length(solution_1), 1);

3967

rho_port2= zeros(length(solution_1), 1);

3561

for solution_idx= 1:length(solution_1)

3968

for solution_idx= 1:length(solution_1)

3562

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3969

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3563

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3970

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3564

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3971

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3565

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3972

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3566

else

3973

else

3567

error('An odd case has occured. Please contact the tool developer.');

3974

error('An odd case has occured. Please contact the tool developer.');

3568

end

3975

end

3569

end

3976

end

3570

%---end. Given the real part of the impedance is to be positive

3977

%---end. Given the real part of the impedance is to be positive

3571

3978

3572

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3979

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3573

3980

3574

%---start. calculate the equivalent port impedance

3981

%---start. calculate the equivalent port impedance

3575

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3982

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3576

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3983

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3577

%---end. calculate the equivalent port impedance

3984

%---end. calculate the equivalent port impedance

3578

3985

3579

3986

3580

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3987

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3581

% %to zero reflections.

3988

% %to zero reflections.

3582

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) ) );

3989

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) ) );

3583

%---end. The reflectionless insertion loss is the insertion loss corresponding

3990

%---end. The reflectionless insertion loss is the insertion loss corresponding

3584

%to zero reflections.

3991

%to zero reflections.

3585

3992

3586

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3993

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3587

RILN= RIL- Sdd21;

3994

RILN= RIL- Sdd21;

3588

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3995

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3589

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3996

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3590

3997

3591

%---start. preparing returns struct

3998

%---start. preparing returns struct

3592

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3999

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3593

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

4000

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3594

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

4001

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3595

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

4002

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3596

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

4003

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3597

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

4004

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3598

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

4005

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3599

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

4006

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3600

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

4007

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3601

%---end. preparing returns struct

4008

%---end. preparing returns struct

3602

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

4009

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3603

4010

3604

4011

3605

%For the given BER, find the top & bottom voltage level in the CDF

4012

%For the given BER, find the top & bottom voltage level in the CDF

3606

4013

3607

%for the top, just find the first index at the spec BER

4014

%for the top, just find the first index at the spec BER

3608

nidx=find(cdf.y>specBER, 1, 'first');

4015

nidx=find(cdf.y>specBER, 1, 'first');

3609

noise_bottom = cdf.x(nidx);

4016

noise_bottom = cdf.x(nidx);

3610

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

4017

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3611

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

4018

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3612

%the true index without flipping

4019

%the true index without flipping

3613

nidx=length(cdf.y)-nidx+1;

4020

nidx=length(cdf.y)-nidx+1;

3614

noise_top = cdf.x(nidx);

4021

noise_top = cdf.x(nidx);

3615

function p=comb_fct(p1, p2)

4022

function p=comb_fct(p1, p2)

3616

if p1.BinSize ~= p2.BinSize

4023

if p1.BinSize ~= p2.BinSize

3617

error('bin size must be equal')

4024

error('bin size must be equal')

3618

end

4025

end

3619

4026

3620

p=p1;

4027

p=p1;

3621

p.BinSize=p1.BinSize;

4028

p.BinSize=p1.BinSize;

3622

%p.Min=p1.Min+p2.Min;

4029

%p.Min=p1.Min+p2.Min;

3623

p.Min=min(p1.Min,p2.Min);

4030

p.Min=min(p1.Min,p2.Min);

3624

difsz=abs(p1.Min-p2.Min);

4031

difsz=abs(p1.Min-p2.Min);

3625

lp1=length(p1.y);

4032

lp1=length(p1.y);

3626

lp2=length(p2.y);

4033

lp2=length(p2.y);

3627

if p1.Min == p.Min

4034

if p1.Min == p.Min

3628

p2.y(difsz+1:lp2+difsz)=p2.y;

4035

p2.y(difsz+1:lp2+difsz)=p2.y;

3629

p2.y(1:difsz)=0;

4036

p2.y(1:difsz)=0;

3630

p2.y(lp2+difsz+1:lp1)=0;

4037

p2.y(lp2+difsz+1:lp1)=0;

3631

elseif p2.Min == p.Min

4038

elseif p2.Min == p.Min

3632

p1.y(difsz+1:lp1+difsz)=p1.y;

4039

p1.y(difsz+1:lp1+difsz)=p1.y;

3633

p1.y(1:difsz)=0;

4040

p1.y(1:difsz)=0;

3634

p1.y(lp1+difsz+1:lp2)=0;

4041

p1.y(lp1+difsz+1:lp2)=0;

3635

end

4042

end

3636

% p.y=conv(p1.y, p2.y);

4043

% p.y=conv(p1.y, p2.y);

3637

p.y=(p1.y+p2.y);

4044

p.y=(p1.y+p2.y);

3638

% p.y=p.y/sum(p.y);

4045

% p.y=p.y/sum(p.y);

3639

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

4046

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3640

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

4047

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3641

4048

3642

4049

3643

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

4050

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

3644

4051

3645

if pdf1.BinSize ~= pdf2.BinSize

4052

if pdf1.BinSize ~= pdf2.BinSize

3646

error('bin size must be equal')

4053

error('bin size must be equal')

3647

end

4054

end

3648

4055

3649

x1=pdf1.x;

4056

x1=pdf1.x;

3650

y1=pdf1.y;

4057

y1=pdf1.y;

3651

x2=pdf2.x;

4058

x2=pdf2.x;

3652

y2=pdf2.y;

4059

y2=pdf2.y;

3653

%find the pdf with a larger min, force it to have the same min, and insert

4060

%find the pdf with a larger min, force it to have the same min, and insert

3654

%probability = 0

4061

%probability = 0

3655

min1=pdf1.x(1);

4062

min1=pdf1.x(1);

3656

min2=pdf2.x(1);

4063

min2=pdf2.x(1);

3657

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

4064

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

3658

if min1<min2

4065

if min1<min2

3659

x2=[pdf1.x(1:shift_amount) pdf2.x];

4066

x2=[pdf1.x(1:shift_amount) pdf2.x];

3660

y2=[zeros(1,shift_amount) pdf2.y];

4067

y2=[zeros(1,shift_amount) pdf2.y];

3661

else

4068

else

3662

x1=[pdf2.x(1:shift_amount) pdf1.x];

4069

x1=[pdf2.x(1:shift_amount) pdf1.x];

3663

y1=[zeros(1,shift_amount) pdf1.y];

4070

y1=[zeros(1,shift_amount) pdf1.y];

3664

end

4071

end

3665

%find the pdf with smaller max, force it to have the same max, and insert

4072

%find the pdf with smaller max, force it to have the same max, and insert

3666

%probability=0

4073

%probability=0

3667

L1=length(x1);

4074

L1=length(x1);

3668

L2=length(x2);

4075

L2=length(x2);

3669

Ldiff=abs(L1-L2);

4076

Ldiff=abs(L1-L2);

3670

if L1>L2

4077

if L1>L2

3671

out_x=x1;

4078

out_x=x1;

3672

y2=[y2 zeros(1,Ldiff)];

4079

y2=[y2 zeros(1,Ldiff)];

3673

else

4080

else

3674

out_x=x2;

4081

out_x=x2;

3675

y1=[y1 zeros(1,Ldiff)];

4082

y1=[y1 zeros(1,Ldiff)];

3676

end

4083

end

3677

%now the 2 pdfs have the same voltage axis, add probabilities together

4084

%now the 2 pdfs have the same voltage axis, add probabilities together

3678

%renormalization is not handled here, so the output pdf will not have sum=1

4085

%renormalization is not handled here, so the output pdf will not have sum=1

3679

%It is the responsibility of the calling function to handle renormalization

4086

%It is the responsibility of the calling function to handle renormalization

3680

%if needed

4087

%if needed

3681

out_y=y1+y2;

4088

out_y=y1+y2;

3682

out_pdf.x=out_x;

4089

out_pdf.x=out_x;

3683

out_pdf.y=out_y;

4090

out_pdf.y=out_y;

3684

out_pdf.BinSize=pdf1.BinSize;

4091

out_pdf.BinSize=pdf1.BinSize;

3685

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

4092

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

3686

4093

3687

%original method:

4094

%original method:

3688

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

4095

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

3689

% for i=1:length(s11in1)

4096

% for i=1:length(s11in1)

3690

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

4097

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

3691

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

4098

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

3692

% end

4099

% end

3693

% t1=stot(s1);

4100

% t1=stot(s1);

3694

% t2=stot(s2);

4101

% t2=stot(s2);

3695

% for i=1:length(s11in1)

4102

% for i=1:length(s11in1)

3696

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

4103

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

3697

% end

4104

% end

3698

% s3=ttos(t3);

4105

% s3=ttos(t3);

3699

% s11out=s3(1,1,:);

4106

% s11out=s3(1,1,:);

3700

% s11out=transpose(s11out(:));

4107

% s11out=transpose(s11out(:));

3701

% s12out=s3(1,2,:);

4108

% s12out=s3(1,2,:);

3702

% s12out=transpose(s12out(:));

4109

% s12out=transpose(s12out(:));

3703

% s21out=s3(2,1,:);

4110

% s21out=s3(2,1,:);

3704

% s21out=transpose(s21out(:));

4111

% s21out=transpose(s21out(:));

3705

% s22out=s3(2,2,:);

4112

% s22out=s3(2,2,:);

3706

% s22out=transpose(s22out(:));

4113

% s22out=transpose(s22out(:));

3707

4114

3708

4115

3709

%vectorized method:

4116

%vectorized method:

3710

s1(1,1,:)=s11in1;

4117

s1(1,1,:)=s11in1;

3711

s1(1,2,:)=s12in1;

4118

s1(1,2,:)=s12in1;

3712

s1(2,1,:)=s21in1;

4119

s1(2,1,:)=s21in1;

3713

s1(2,2,:)=s22in1;

4120

s1(2,2,:)=s22in1;

3714

s2(1,1,:)=s11in2;

4121

s2(1,1,:)=s11in2;

3715

s2(1,2,:)=s12in2;

4122

s2(1,2,:)=s12in2;

3716

s2(2,1,:)=s21in2;

4123

s2(2,1,:)=s21in2;

3717

s2(2,2,:)=s22in2;

4124

s2(2,2,:)=s22in2;

3718

4125

3719

4126

3720

N = (1-s1(2,2,:).*s2(1,1,:)) ;

4127

N = (1-s1(2,2,:).*s2(1,1,:)) ;

3721

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

4128

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

3722

s12out = s1(1,2,:).*s2(1,2,:)./N ;

4129

s12out = s1(1,2,:).*s2(1,2,:)./N ;

3723

s21out = s2(2,1,:).*s1(2,1,:)./N;

4130

s21out = s2(2,1,:).*s1(2,1,:)./N;

3724

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

4131

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

3725

4132

3726

s11out=transpose(squeeze(s11out));

4133

s11out=transpose(squeeze(s11out));

3727

s12out=transpose(squeeze(s12out));

4134

s12out=transpose(squeeze(s12out));

3728

s21out=transpose(squeeze(s21out));

4135

s21out=transpose(squeeze(s21out));

3729

s22out=transpose(squeeze(s22out));

4136

s22out=transpose(squeeze(s22out));

3730

function p=conv_fct(p1, p2)

4137

function p=conv_fct(p1, p2)

3731

if p1.BinSize ~= p2.BinSize

4138

if p1.BinSize ~= p2.BinSize

3732

error('bin size must be equal')

4139

error('bin size must be equal')

3733

end

4140

end

3734

4141

3735

p=p1;

4142

p=p1;

3736

%p.BinSize=p1.BinSize;

4143

%p.BinSize=p1.BinSize;

3737

%p.Min=p1.Min+p2.Min;

4144

%p.Min=p1.Min+p2.Min;

3738

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4145

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3739

p.y=conv2(p1.y, p2.y);

4146

p.y=conv2(p1.y, p2.y);

3740

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

4147

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3741

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

4148

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3742

pMax=p.Min+length(p.y)-1;

4149

pMax=p.Min+length(p.y)-1;

3743

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4150

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3744

4151

3745

4152

3746

4153

3747

4154

3748

function p=conv_fct_MeanNotZero(p1, p2)

4155

function p=conv_fct_MeanNotZero(p1, p2)

3749

4156

3750

if p1.BinSize ~= p2.BinSize

4157

if p1.BinSize ~= p2.BinSize

3751

error('bin size must be equal')

4158

error('bin size must be equal')

3752

end

4159

end

3753

4160

3754

p=p1;

4161

p=p1;

3755

%p.BinSize=p1.BinSize;

4162

%p.BinSize=p1.BinSize;

3756

%p.Min=p1.Min+p2.Min;

4163

%p.Min=p1.Min+p2.Min;

3757

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4164

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3758

p.y=conv2(p1.y, p2.y);

4165

p.y=conv2(p1.y, p2.y);

3759

4166

3760

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

4167

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

3761

%But it is faster to pre-multiply BinSize instead of multiplying the entire

4168

%But it is faster to pre-multiply BinSize instead of multiplying the entire

3762

%vector by BinSize

4169

%vector by BinSize

3763

pMax=p.Min+length(p.y)-1;

4170

pMax=p.Min+length(p.y)-1;

3764

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4171

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3765

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

4172

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

3766

4173

3767

%IN:

4174

%IN:

3768

%sbr = pulse response

4175

%sbr = pulse response

3769

%param = COM "param" struct

4176

%param = COM "param" struct

3770

%OP = COM "OP" struct

4177

%OP = COM "OP" struct

3771

%peak_search_range= a limited range to search for the peak (for speed up)

4178

%peak_search_range= a limited range to search for the peak (for speed up)

3772

% it is usually +/- 20 UI

4179

% it is usually +/- 20 UI

3773

%

4180

%

3774

%OUT:

4181

%OUT:

3775

%cursor_i = sampling location

4182

%cursor_i = sampling location

3776

%no_zero_crossing = flag that reveals if sampling is not possible.

4183

%no_zero_crossing = flag that reveals if sampling is not possible.

3777

% When this function is called in optimize_fom, it signals to quit the current case

4184

% When this function is called in optimize_fom, it signals to quit the current case

3778

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

4185

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

3779

% time consuming, so saving the peak in one spot is advantageous

4186

% time consuming, so saving the peak in one spot is advantageous

3780

%zxi = zero crossing index (returned because RXFFE uses it)

4187

%zxi = zero crossing index (returned because RXFFE uses it)

3781

4188

3782

no_zero_crossing=0;

4189

no_zero_crossing=0;

3783

%need to set cursor_i to empty in case no_zero_crossing flag is set

4190

%need to set cursor_i to empty in case no_zero_crossing flag is set

3784

cursor_i=[];

4191

cursor_i=[];

3785

4192

3786

%get peak of pulse and peak index

4193

%get peak of pulse and peak index

3787

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

4194

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

3788

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

4195

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

3789

4196

3790

4197

3791

% initial guess at cursor location (t_s) - based on approximate zero crossing

4198

% initial guess at cursor location (t_s) - based on approximate zero crossing

3792

%limit search space for speed up

4199

%limit search space for speed up

3793

search_start=sbr_peak_i-4*param.samples_per_ui;

4200

search_start=sbr_peak_i-4*param.samples_per_ui;

3794

if search_start<1

4201

if search_start<1

3795

search_start=1;

4202

search_start=1;

3796

end

4203

end

3797

%Find zero crossings

4204

%Find zero crossings

3798

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

4205

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

3799

4206

3800

%Note: the original implementation of zxi:

4207

%Note: the original implementation of zxi:

3801

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

4208

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

3802

% zxi = zxi(zxi<sbr_peak_i);

4209

% zxi = zxi(zxi<sbr_peak_i);

3803

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

4210

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

3804

% The changes to limit search space and remember max(sbr) give 10x speed up

4211

% The changes to limit search space and remember max(sbr) give 10x speed up

3805

% A test case of 25k runs, reduced from 1.2s to 0.1s

4212

% A test case of 25k runs, reduced from 1.2s to 0.1s

3806

4213

3807

4214

3808

if isempty(zxi)

4215

if isempty(zxi)

3809

%if no zero crossing, the calling program must respond (since sample point will be empty)

4216

%if no zero crossing, the calling program must respond (since sample point will be empty)

3810

no_zero_crossing=1;

4217

no_zero_crossing=1;

3811

return;

4218

return;

3812

elseif length(zxi)>1

4219

elseif length(zxi)>1

3813

%only need the last zero crossing

4220

%only need the last zero crossing

3814

zxi=zxi(end);

4221

zxi=zxi(end);

3815

end

4222

end

3816

if param.ndfe==0

4223

if param.ndfe==0

3817

max_dfe1=0;

4224

max_dfe1=0;

3818

else

4225

else

3819

max_dfe1=param.bmax(1);

4226

max_dfe1=param.bmax(1);

3820

end

4227

end

3821

% adjust cursor_i to Solve equation 93A-25 %%

4228

% adjust cursor_i to Solve equation 93A-25 %%

3822

% Muller-Mueller criterion with DFE

4229

% Muller-Mueller criterion with DFE

3823

mm_range = zxi+(0:2*param.samples_per_ui);

4230

mm_range = zxi+(0:2*param.samples_per_ui);

3824

switch OP.CDR

4231

switch OP.CDR

3825

case 'Mod-MM'

4232

case 'Mod-MM'

3826

mm_metric = ...

4233

mm_metric = ...

3827

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

4234

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

3828

otherwise % MM

4235

otherwise % MM

3829

%MM is generally: first precursor = 0

4236

%MM is generally: first precursor = 0

3830

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

4237

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

3831

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

4238

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

3832

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

4239

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

3833

%first precursor = first postcursor - max_dfe

4240

%first precursor = first postcursor - max_dfe

3834

mm_metric = ...

4241

mm_metric = ...

3835

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

4242

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

3836

end

4243

end

3837

[~, mm_cursor_offset] = min(mm_metric);

4244

[~, mm_cursor_offset] = min(mm_metric);

3838

4245

3839

%cursor_i = the sample location

4246

%cursor_i = the sample location

3840

cursor_i = zxi+mm_cursor_offset-1;

4247

cursor_i = zxi+mm_cursor_offset-1;

3841

function pdf=d_cpdf( binsize, values, probs)

4248

function pdf=d_cpdf( binsize, values, probs)

3842

% p=cpdf(type, ...)

4249

% p=cpdf(type, ...)

3843

%

4250

%

3844

% CPDF is a probability mass function for discrete distributions or an

4251

% CPDF is a probability mass function for discrete distributions or an

3845

% approxmation of a PDF for continuous distributions.

4252

% approxmation of a PDF for continuous distributions.

3846

%

4253

%

3847

% cpdf is internally normalized so that the sum of probabilities is 1

4254

% cpdf is internally normalized so that the sum of probabilities is 1

3848

% (regardless of bin size).

4255

% (regardless of bin size).

3849

4256

3850

% Internal fields:

4257

% Internal fields:

3851

% Min: *bin number* of minimum value.

4258

% Min: *bin number* of minimum value.

3852

% BinSize: size of PDF bins. Bin center is the representative value.

4259

% BinSize: size of PDF bins. Bin center is the representative value.

3853

% Vec: vector of probabilities per bin.

4260

% Vec: vector of probabilities per bin.

3854

4261

3855

%speed up for initializing empty pdf

4262

%speed up for initializing empty pdf

3856

if all(values==0)

4263

if all(values==0)

3857

pdf.BinSize=binsize;

4264

pdf.BinSize=binsize;

3858

pdf.Min=0;

4265

pdf.Min=0;

3859

pdf.y=1;

4266

pdf.y=1;

3860

pdf.x=0;

4267

pdf.x=0;

3861

return;

4268

return;

3862

end

4269

end

3863

4270

3864

if ~issorted(values)

4271

if ~issorted(values)

3865

[values,si]=sort(values);

4272

[values,si]=sort(values);

3866

probs=probs(si);

4273

probs=probs(si);

3867

end

4274

end

3868

values=binsize*round(values/binsize);

4275

values=binsize*round(values/binsize);

3869

t=(values(1):binsize:values(end));

4276

t=(values(1):binsize:values(end));

3870

pdf.Min=values(1)/binsize;

4277

pdf.Min=values(1)/binsize;

3871

pdf.y=zeros(size(t));

4278

pdf.y=zeros(size(t));

3872

for k=1:length(values)

4279

for k=1:length(values)

3873

if k==1

4280

if k==1

3874

bin=1;

4281

bin=1;

3875

elseif k==length(values)

4282

elseif k==length(values)

3876

bin=length(t);

4283

bin=length(t);

3877

else

4284

else

3878

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

4285

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

3879

end

4286

end

3880

pdf.y(bin) = pdf.y(bin)+probs(k);

4287

pdf.y(bin) = pdf.y(bin)+probs(k);

3881

end

4288

end

3882

4289

3883

pdf.BinSize=binsize;

4290

pdf.BinSize=binsize;

3884

pdf.y=pdf.y/sum(pdf.y);

4291

pdf.y=pdf.y/sum(pdf.y);

3885

if any(~isreal(pdf.y)) || any(pdf.y<0)

4292

if any(~isreal(pdf.y)) || any(pdf.y<0)

3886

error('PDF must be real and nonnegative');

4293

error('PDF must be real and nonnegative');

3887

end

4294

end

3888

support=find(pdf.y);

4295

support=find(pdf.y);

3889

pdf.y=pdf.y(support(1):support(end));

4296

pdf.y=pdf.y(support(1):support(end));

3890

pdf.Min=pdf.Min+(support(1)-1);

4297

pdf.Min=pdf.Min+(support(1)-1);

3891

pdf.x=(pdf.Min:-pdf.Min)*binsize;

4298

pdf.x=(pdf.Min:-pdf.Min)*binsize;

3892

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

4299

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

3893

4300

3894

if isrow(input)

4301

if isrow(input)

3895

max_threshold=max_threshold(:).';

4302

max_threshold=max_threshold(:).';

3896

min_threshold=min_threshold(:).';

4303

min_threshold=min_threshold(:).';

3897

else

4304

else

3898

max_threshold=max_threshold(:);

4305

max_threshold=max_threshold(:);

3899

min_threshold=min_threshold(:);

4306

min_threshold=min_threshold(:);

3900

end

4307

end

3901

4308

3902

clip_output=input;

4309

clip_output=input;

3903

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

4310

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

3904

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

4311

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

3905

4312

3906

4313

3907

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

4314

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

3908

[ncases, mele]=size(param.z_p_tx_cases);

4315

[ncases, mele]=size(param.z_p_tx_cases);

3909

if mele ==2

4316

if mele ==2

3910

param.flex=2;

4317

param.flex=2;

3911

elseif mele==4

4318

elseif mele==4

3912

param.flex=4;

4319

param.flex=4;

3913

elseif mele==1

4320

elseif mele==1

3914

param.flex=1;

4321

param.flex=1;

3915

else

4322

else

3916

error(springf('config file syntax error'))

4323

error(springf('config file syntax error'))

3917

end

4324

end

3918

4325

3919

4326

3920

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

4327

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

3921

% display bathtub curves in one axis per test case.

4328

% display bathtub curves in one axis per test case.

3922

% h=findall(0, 'Name', 'COM results');

4329

% h=findall(0, 'Name', 'COM results');

3923

if ~exist('h','var')

4330

if ~exist('h','var')

3924

msgtext = cell(1, length(OP.pkg_len_select));

4331

msgtext = cell(1, length(OP.pkg_len_select));

3925

msgcolor = 'g';

4332

msgcolor = 'g';

3926

else

4333

else

3927

msgtext=get(findobj(h, 'type', 'text'), 'string');

4334

msgtext=get(findobj(h, 'type', 'text'), 'string');

3928

msgcolor = get(h, 'color');

4335

msgcolor = get(h, 'color');

3929

close(h); % will be recreated

4336

close(h); % will be recreated

3930

end

4337

end

3931

msgctr=size(msgtext,1)+1;

4338

msgctr=size(msgtext,1)+1;

3932

if ~OP.ERL_ONLY

4339

if ~OP.ERL_ONLY

3933

switch OP.PHY

4340

switch OP.PHY

3934

case 'C2M'

4341

case 'C2M'

3935

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4342

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

3936

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4343

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

3937

msg, VEO_mV);

4344

msg, VEO_mV);

3938

else

4345

else

3939

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4346

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

3940

msg, VEO_mV);

4347

msg, VEO_mV);

3941

msgcolor = 'r';

4348

msgcolor = 'r';

3942

end

4349

end

3943

4350

3944

if VEC_dB <= param.VEC_pass_threshold

4351

if VEC_dB <= param.VEC_pass_threshold

3945

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4352

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

3946

(msg), VEC_dB);

4353

(msg), VEC_dB);

3947

else

4354

else

3948

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4355

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

3949

(msg), VEC_dB);

4356

(msg), VEC_dB);

3950

msgcolor = 'r';

4357

msgcolor = 'r';

3951

end

4358

end

3952

case 'C2C'

4359

case 'C2C'

3953

if COM >= param.pass_threshold

4360

if COM >= param.pass_threshold

3954

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4361

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

3955

% msg, COM);

4362

% msg, COM);

3956

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4363

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

3957

msg, COM);

4364

msg, COM);

3958

else

4365

else

3959

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4366

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

3960

% msg, COM);

4367

% msg, COM);

3961

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4368

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

3962

msg, COM);

4369

msg, COM);

3963

msgcolor = 'r';

4370

msgcolor = 'r';

3964

end

4371

end

3965

% begin yasuo patch 3/18/2019

4372

% begin yasuo patch 3/18/2019

3966

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4373

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

3967

% end yasuo patch

4374

% end yasuo patch

3968

case 'C2Mcom'

4375

case 'C2Mcom'

3969

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4376

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

3970

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4377

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

3971

msg, VEO_mV);

4378

msg, VEO_mV);

3972

else

4379

else

3973

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4380

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

3974

msg, VEO_mV);

4381

msg, VEO_mV);

3975

msgcolor = 'r';

4382

msgcolor = 'r';

3976

end

4383

end

3977

4384

3978

if VEC_dB <= param.VEC_pass_threshold

4385

if VEC_dB <= param.VEC_pass_threshold

3979

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4386

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

3980

(msg), VEC_dB);

4387

(msg), VEC_dB);

3981

else

4388

else

3982

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4389

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

3983

(msg), VEC_dB);

4390

(msg), VEC_dB);

3984

msgcolor = 'r';

4391

msgcolor = 'r';

3985

end

4392

end

3986

if COM >= param.pass_threshold

4393

if COM >= param.pass_threshold

3987

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4394

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

3988

% msg, COM);

4395

% msg, COM);

3989

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4396

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

3990

msg, COM);

4397

msg, COM);

3991

else

4398

else

3992

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4399

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

3993

% msg, COM);

4400

% msg, COM);

3994

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4401

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

3995

msg, COM);

4402

msg, COM);

3996

msgcolor = 'r';

4403

msgcolor = 'r';

3997

end

4404

end

3998

% begin yasuo patch 3/18/2019

4405

% begin yasuo patch 3/18/2019

3999

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4406

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4000

% end yasuo patch

4407

% end yasuo patch

4001

end

4408

end

4002

end

4409

end

4003

if OP.ERL

4410

if OP.ERL

4004

if ~isempty(ERL)

4411

if ~isempty(ERL)

4005

if min_ERL >= param.ERL_pass_threshold

4412

if min_ERL >= param.ERL_pass_threshold

4006

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4413

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4007

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4414

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4008

else

4415

else

4009

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4416

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4010

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4417

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4011

msgcolor = 'r';

4418

msgcolor = 'r';

4012

end

4419

end

4013

end

4420

end

4014

end

4421

end

4015

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4422

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4016

set(h, 'color', msgcolor, 'tag', 'COM');

4423

set(h, 'color', msgcolor, 'tag', 'COM');

4017

movegui(h, 'center');

4424

movegui(h, 'center');

4018

else % no windows

4425

else % no windows

4019

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4426

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4020

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4427

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4021

if ~OP.ERL_ONLY

4428

if ~OP.ERL_ONLY

4022

switch OP.PHY

4429

switch OP.PHY

4023

case 'C2C'

4430

case 'C2C'

4024

if COM >= param.pass_threshold

4431

if COM >= param.pass_threshold

4025

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4432

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4026

else

4433

else

4027

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4434

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4028

end

4435

end

4029

% begin yasuo patch 3/18/2019

4436

% begin yasuo patch 3/18/2019

4030

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4437

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4031

% end yasuo patch

4438

% end yasuo patch

4032

case 'C2Mcom'

4439

case 'C2Mcom'

4033

if VEC_dB <= param.VEC_pass_threshold

4440

if VEC_dB <= param.VEC_pass_threshold

4034

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4441

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4035

else

4442

else

4036

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4443

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4037

end

4444

end

4038

4445

4039

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4446

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4040

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4447

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4041

else

4448

else

4042

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4449

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4043

end

4450

end

4044

if COM >= param.pass_threshold

4451

if COM >= param.pass_threshold

4045

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4452

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4046

else

4453

else

4047

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4454

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4048

end

4455

end

4049

% begin yasuo patch 3/18/2019

4456

% begin yasuo patch 3/18/2019

4050

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4457

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4051

% end yasuo patch

4458

% end yasuo patch

4052

case 'C2M'

4459

case 'C2M'

4053

if VEC_dB <= param.VEC_pass_threshold

4460

if VEC_dB <= param.VEC_pass_threshold

4054

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4461

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4055

else

4462

else

4056

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4463

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4057

end

4464

end

4058

4465

4059

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4466

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4060

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4467

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4061

else

4468

else

4062

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4469

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4063

end

4470

end

4064

end

4471

end

4065

end

4472

end

4066

if OP.ERL

4473

if OP.ERL

4067

if ~isempty(ERL)

4474

if ~isempty(ERL)

4068

if min_ERL >= param.ERL_pass_threshold

4475

if min_ERL >= param.ERL_pass_threshold

4069

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4476

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4070

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4477

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4071

else

4478

else

4072

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4479

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4073

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4480

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4074

end

4481

end

4075

end

4482

end

4076

end

4483

end

4077

end

4484

end

4078

4485

4079

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4486

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4080

4487

4081

%Left eye Width (Top Eye)

4488

%Left eye Width (Top Eye)

4082

left_top=eye_contour(half_UI:-1:1,1);

4489

left_top=eye_contour(half_UI:-1:1,1);

4083

%vref_crossing is the first point less than vref (usually first point < 0)

4490

%vref_crossing is the first point less than vref (usually first point < 0)

4084

vref_crossing=find(left_top<vref,1,'first');

4491

vref_crossing=find(left_top<vref,1,'first');

4085

if isempty(vref_crossing)

4492

if isempty(vref_crossing)

4086

%this case handles completely open eye

4493

%this case handles completely open eye

4087

L1=half_UI;

4494

L1=half_UI;

4088

elseif vref_crossing==1

4495

elseif vref_crossing==1

4089

%this case handles completely closed eye

4496

%this case handles completely closed eye

4090

L1=0;

4497

L1=0;

4091

else

4498

else

4092

%this case handles the normal eye

4499

%this case handles the normal eye

4093

%INT is a linear interpolation between the 2 points on either side of

4500

%INT is a linear interpolation between the 2 points on either side of

4094

%vref to determine where the vref crossing occurred. In systems with

4501

%vref to determine where the vref crossing occurred. In systems with

4095

%a small number of samples_per_UI, interpolation improves accuracy over

4502

%a small number of samples_per_UI, interpolation improves accuracy over

4096

%just using the integer sample point

4503

%just using the integer sample point

4097

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4504

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4098

L1=half_UI-INT;

4505

L1=half_UI-INT;

4099

end

4506

end

4100

%Left eye Width (Bottom Eye)

4507

%Left eye Width (Bottom Eye)

4101

left_bot=eye_contour(half_UI:-1:1,2);

4508

left_bot=eye_contour(half_UI:-1:1,2);

4102

vref_crossing=find(left_bot>vref,1,'first');

4509

vref_crossing=find(left_bot>vref,1,'first');

4103

if isempty(vref_crossing)

4510

if isempty(vref_crossing)

4104

L0=half_UI;

4511

L0=half_UI;

4105

elseif vref_crossing==1

4512

elseif vref_crossing==1

4106

L0=0;

4513

L0=0;

4107

else

4514

else

4108

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4515

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4109

L0=half_UI-INT;

4516

L0=half_UI-INT;

4110

end

4517

end

4111

%Right eye Width (Top Eye)

4518

%Right eye Width (Top Eye)

4112

right_top=eye_contour(half_UI:end,1);

4519

right_top=eye_contour(half_UI:end,1);

4113

vref_crossing=find(right_top<vref,1,'first');

4520

vref_crossing=find(right_top<vref,1,'first');

4114

if isempty(vref_crossing)

4521

if isempty(vref_crossing)

4115

R1=samples_per_UI-half_UI;

4522

R1=samples_per_UI-half_UI;

4116

elseif vref_crossing==1

4523

elseif vref_crossing==1

4117

R1=0;

4524

R1=0;

4118

else

4525

else

4119

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4526

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4120

R1=INT-half_UI;

4527

R1=INT-half_UI;

4121

end

4528

end

4122

%Right eye Width (Bottom Eye)

4529

%Right eye Width (Bottom Eye)

4123

right_bot=eye_contour(half_UI:end,2);

4530

right_bot=eye_contour(half_UI:end,2);

4124

vref_crossing=find(right_bot>vref,1,'first');

4531

vref_crossing=find(right_bot>vref,1,'first');

4125

if isempty(vref_crossing)

4532

if isempty(vref_crossing)

4126

R0=samples_per_UI-half_UI;

4533

R0=samples_per_UI-half_UI;

4127

elseif vref_crossing==1

4534

elseif vref_crossing==1

4128

R0=0;

4535

R0=0;

4129

else

4536

else

4130

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4537

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4131

R0=INT-half_UI;

4538

R0=INT-half_UI;

4132

end

4539

end

4133

4540

4134

%L1 = top left eye width

4541

%L1 = top left eye width

4135

%L0 = bottom left eye width

4542

%L0 = bottom left eye width

4136

%Left eye width is the minimum

4543

%Left eye width is the minimum

4137

%R1 = top right eye width

4544

%R1 = top right eye width

4138

%R0 = bottom right eye width

4545

%R0 = bottom right eye width

4139

%Right eye width is the minimum

4546

%Right eye width is the minimum

4140

Left_EW=min([L1 L0]);

4547

Left_EW=min([L1 L0]);

4141

Right_EW=min([R1 R0]);

4548

Right_EW=min([R1 R0]);

4142

4549

4143

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4550

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4144

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4551

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4145

% find the location of the DFE bank

4552

% find the location of the DFE bank

4146

% hisi: waveform with cursor values;

4553

% hisi: waveform with cursor values;

4147

% idx_st: starting index;

4554

% idx_st: starting index;

4148

% idx_en: ending index ;

4555

% idx_en: ending index ;

4149

% tap_bk: number of taps per bank;

4556

% tap_bk: number of taps per bank;

4150

% bmaxg: maximum coefficient;

4557

% bmaxg: maximum coefficient;

4151

4558

4152

hisi=hisi(:);

4559

hisi=hisi(:);

4153

len=idx_en-idx_st+1;

4560

len=idx_en-idx_st+1;

4154

h0=abs(hisi(idx_st:idx_en));

4561

h0=abs(hisi(idx_st:idx_en));

4155

h1=max(0,h0-bmaxg*curval);

4562

h1=max(0,h0-bmaxg*curval);

4156

4563

4157

%if cursor value is negative, force h1 to all zeros

4564

%if cursor value is negative, force h1 to all zeros

4158

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4565

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4159

%this makes the weakest isi the most desirable to choose so everything breaks

4566

%this makes the weakest isi the most desirable to choose so everything breaks

4160

if curval<0

4567

if curval<0

4161

h1=zeros(size(h0));

4568

h1=zeros(size(h0));

4162

end

4569

end

4163

4570

4164

h0n=zeros(len-tap_bk+1,1);

4571

h0n=zeros(len-tap_bk+1,1);

4165

h1n=h0n;

4572

h1n=h0n;

4166

4573

4167

for ii=1:tap_bk

4574

for ii=1:tap_bk

4168

h0tmp=h0(ii:ii+len-tap_bk);

4575

h0tmp=h0(ii:ii+len-tap_bk);

4169

h0n=h0n+h0tmp.^2;

4576

h0n=h0n+h0tmp.^2;

4170

h1tmp=h1(ii:ii+len-tap_bk);

4577

h1tmp=h1(ii:ii+len-tap_bk);

4171

h1n=h1n+h1tmp.^2;

4578

h1n=h1n+h1tmp.^2;

4172

end

4579

end

4173

4580

4174

ndiff=h0n-h1n;

4581

ndiff=h0n-h1n;

4175

4582

4176

min_energy = -Inf;

4583

min_energy = -Inf;

4177

4584

4178

idx=zeros(1,tap_bk*N_bg);

4585

idx=zeros(1,tap_bk*N_bg);

4179

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4586

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4180

set_next_bank=0;

4587

set_next_bank=0;

4181

%Loop through each group

4588

%Loop through each group

4182

for k=1:N_bg

4589

for k=1:N_bg

4183

%Sort to choose the strongest

4590

%Sort to choose the strongest

4184

[~,val_sort]=sort(ndiff,'descend');

4591

[~,val_sort]=sort(ndiff,'descend');

4185

if k==1

4592

if k==1

4186

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4593

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4187

if isequal(sort(val_sort(ordered_set)),ordered_set)

4594

if isequal(sort(val_sort(ordered_set)),ordered_set)

4188

idx=1:N_bg*tap_bk;

4595

idx=1:N_bg*tap_bk;

4189

break;

4596

break;

4190

end

4597

end

4191

end

4598

end

4192

if set_next_bank>0

4599

if set_next_bank>0

4193

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4600

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4194

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4601

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4195

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4602

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4196

set_next_bank=0;

4603

set_next_bank=0;

4197

ndiff(new_bank)=min_energy;

4604

ndiff(new_bank)=min_energy;

4198

bad_start=new_bank(1)-tap_bk+1;

4605

bad_start=new_bank(1)-tap_bk+1;

4199

bad_end=new_bank(1)-1;

4606

bad_end=new_bank(1)-1;

4200

if bad_end<=0

4607

if bad_end<=0

4201

badV=[];

4608

badV=[];

4202

elseif bad_start>0

4609

elseif bad_start>0

4203

badV=bad_start:bad_end;

4610

badV=bad_start:bad_end;

4204

else

4611

else

4205

badV=1:bad_end;

4612

badV=1:bad_end;

4206

end

4613

end

4207

if ~isempty(badV)

4614

if ~isempty(badV)

4208

ndiff(badV)=min_energy;

4615

ndiff(badV)=min_energy;

4209

end

4616

end

4210

continue;

4617

continue;

4211

end

4618

end

4212

%potential bank = the strongest tap group

4619

%potential bank = the strongest tap group

4213

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4620

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4214

if k==N_bg

4621

if k==N_bg

4215

%Last group: just choose the strongest

4622

%Last group: just choose the strongest

4216

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4623

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4217

break;

4624

break;

4218

end

4625

end

4219

4626

4220

do_it_again=1;

4627

do_it_again=1;

4221

first_time=1;

4628

first_time=1;

4222

num_loops=0;

4629

num_loops=0;

4223

while do_it_again

4630

while do_it_again

4224

do_it_again=0;

4631

do_it_again=0;

4225

if num_loops>length(ndiff)

4632

if num_loops>length(ndiff)

4226

break;

4633

break;

4227

end

4634

end

4228

%note badV: taps smaller and less than 1 group away

4635

%note badV: taps smaller and less than 1 group away

4229

bad_start=new_bank(1)-tap_bk+1;

4636

bad_start=new_bank(1)-tap_bk+1;

4230

bad_end=new_bank(1)-1;

4637

bad_end=new_bank(1)-1;

4231

if bad_end<=0

4638

if bad_end<=0

4232

badV=[];

4639

badV=[];

4233

elseif bad_start>0

4640

elseif bad_start>0

4234

badV=bad_start:bad_end;

4641

badV=bad_start:bad_end;

4235

else

4642

else

4236

badV=1:bad_end;

4643

badV=1:bad_end;

4237

end

4644

end

4238

for j=length(badV):-1:1

4645

for j=length(badV):-1:1

4239

if any(badV(j)-idx==0)

4646

if any(badV(j)-idx==0)

4240

badV(j)=[];

4647

badV(j)=[];

4241

end

4648

end

4242

end

4649

end

4243

%note goodV: the tap exactly 1 tap_bk smaller

4650

%note goodV: the tap exactly 1 tap_bk smaller

4244

goodV=new_bank(1)-tap_bk;

4651

goodV=new_bank(1)-tap_bk;

4245

if ~isempty(badV)

4652

if ~isempty(badV)

4246

if ~first_time

4653

if ~first_time

4247

[~,val_sort]=sort(ndiff,'descend');

4654

[~,val_sort]=sort(ndiff,'descend');

4248

end

4655

end

4249

first_time=0;

4656

first_time=0;

4250

checkV=[badV new_bank];

4657

checkV=[badV new_bank];

4251

4658

4252

badV_pos=zeros(1,length(badV));

4659

badV_pos=zeros(1,length(badV));

4253

for j=1:length(badV)

4660

for j=1:length(badV)

4254

badV_pos(j)=find(badV(j)==val_sort);

4661

badV_pos(j)=find(badV(j)==val_sort);

4255

end

4662

end

4256

4663

4257

%loop through the sorted list to find the first tap outside the group and not a member of badV

4664

%loop through the sorted list to find the first tap outside the group and not a member of badV

4258

found_goodV=0;

4665

found_goodV=0;

4259

for ii=1:length(val_sort)

4666

for ii=1:length(val_sort)

4260

if val_sort(ii)==goodV

4667

if val_sort(ii)==goodV

4261

found_goodV=1;

4668

found_goodV=1;

4262

break;

4669

break;

4263

end

4670

end

4264

if all(val_sort(ii)-checkV~=0)

4671

if all(val_sort(ii)-checkV~=0)

4265

break;

4672

break;

4266

end

4673

end

4267

end

4674

end

4268

4675

4269

if ~found_goodV && min(badV_pos)<ii

4676

if ~found_goodV && min(badV_pos)<ii

4270

%if goodV wasn't found and bad taps occur before non group members are found

4677

%if goodV wasn't found and bad taps occur before non group members are found

4271

%throw out the strongest tap and take the next strongest

4678

%throw out the strongest tap and take the next strongest

4272

do_it_again=1;

4679

do_it_again=1;

4273

ndiff(new_bank(1))=min_energy;

4680

ndiff(new_bank(1))=min_energy;

4274

%speed up: new max_val is always val_sort(2)

4681

%speed up: new max_val is always val_sort(2)

4275

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4682

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4276

end

4683

end

4277

if found_goodV

4684

if found_goodV

4278

%if goodV was found, set the next bank to goodV

4685

%if goodV was found, set the next bank to goodV

4279

set_next_bank=goodV;

4686

set_next_bank=goodV;

4280

end

4687

end

4281

end

4688

end

4282

num_loops=num_loops+1;

4689

num_loops=num_loops+1;

4283

end

4690

end

4284

%at the end, the floating taps are set to idx

4691

%at the end, the floating taps are set to idx

4285

%and ndiff has illegal values set to zero

4692

%and ndiff has illegal values set to zero

4286

ndiff(new_bank)=min_energy;

4693

ndiff(new_bank)=min_energy;

4287

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4694

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4288

if ~isempty(badV)

4695

if ~isempty(badV)

4289

ndiff(badV)=min_energy;

4696

ndiff(badV)=min_energy;

4290

end

4697

end

4291

end

4698

end

4292

4699

4293

4700

4294

idx=idx+idx_st-1;

4701

idx=idx+idx_st-1;

4295

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4702

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4296

4703

4297

% hisi = postcursor isi

4704

% hisi = postcursor isi

4298

% N_b = number of fixed dfe taps (before floating taps begin)

4705

% N_b = number of fixed dfe taps (before floating taps begin)

4299

% N_bf = number of floating taps per group

4706

% N_bf = number of floating taps per group

4300

% N_bg = nubmber of groups

4707

% N_bg = nubmber of groups

4301

% N_bmax = max tap number that can be used for floating tap

4708

% N_bmax = max tap number that can be used for floating tap

4302

% bmaxg = max tap strength for floating taps

4709

% bmaxg = max tap strength for floating taps

4303

% curval = value of the cursor

4710

% curval = value of the cursor

4304

4711

4305

4712

4306

if nargin<8, dfe_delta=0;end

4713

if nargin<8, dfe_delta=0;end

4307

4714

4308

4715

4309

tap_coef=zeros(1,length(hisi));

4716

tap_coef=zeros(1,length(hisi));

4310

b=zeros(1,length(hisi));

4717

b=zeros(1,length(hisi));

4311

4718

4312

4719

4313

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4720

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4314

4721

4315

%Apply DFE to all taps

4722

%Apply DFE to all taps

4316

flt_curval=hisi(tap_loc);

4723

flt_curval=hisi(tap_loc);

4317

if dfe_delta~=0

4724

if dfe_delta~=0

4318

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4725

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4319

dfe_delta.*sign(flt_curval)*curval;

4726

dfe_delta.*sign(flt_curval)*curval;

4320

else

4727

else

4321

flt_curval_q=hisi(tap_loc);

4728

flt_curval_q=hisi(tap_loc);

4322

end

4729

end

4323

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4730

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4324

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4731

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4325

tap_coef(tap_loc)=applied_coef;

4732

tap_coef(tap_loc)=applied_coef;

4326

4733

4327

4734

4328

4735

4329

tap_loc=sort(tap_loc,'ascend');

4736

tap_loc=sort(tap_loc,'ascend');

4330

b(tap_loc)=bmaxg;

4737

b(tap_loc)=bmaxg;

4331

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4738

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4332

% Richard Mellitz: 04/23/2019

4739

% Richard Mellitz: 04/23/2019

4333

% hisi is the isi 1 ui/sample

4740

% hisi is the isi 1 ui/sample

4334

% N_b number of fixed dfe taps

4741

% N_b number of fixed dfe taps

4335

% N_bf number of floating taps per group

4742

% N_bf number of floating taps per group

4336

% N_bg number of floating tap groups. 1 2 or 3 right now

4743

% N_bg number of floating tap groups. 1 2 or 3 right now

4337

% N_bmax number of ui for the max reach of the floating taps

4744

% N_bmax number of ui for the max reach of the floating taps

4338

% bmaxg limit for the floating taps

4745

% bmaxg limit for the floating taps

4339

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4746

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4340

%

4747

%

4341

%

4748

%

4342

% function to remove isi or add noise above bmaxg

4749

% function to remove isi or add noise above bmaxg

4343

if ~exist('COOP','var'), COOP=0;end

4750

if ~exist('COOP','var'), COOP=0;end

4344

if iscolumn(hisi); hisi=hisi.';end

4751

if iscolumn(hisi); hisi=hisi.';end

4345

hsis_in=hisi;

4752

hsis_in=hisi;

4346

% find all the reduction group taken N_bf at a time

4753

% find all the reduction group taken N_bf at a time

4347

% we are looking for the group when when remove yield the miminim isi, h, power

4754

% we are looking for the group when when remove yield the miminim isi, h, power

4348

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4755

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4349

% add on switch and loop for each potential group

4756

% add on switch and loop for each potential group

4350

switch N_bg

4757

switch N_bg

4351

case 0

4758

case 0

4352

bmax=0;

4759

bmax=0;

4353

return

4760

return

4354

case 1

4761

case 1

4355

end1=N_bmax-N_bf;

4762

end1=N_bmax-N_bf;

4356

end2=N_b+1;

4763

end2=N_b+1;

4357

end3=N_b+1;

4764

end3=N_b+1;

4358

case 2

4765

case 2

4359

end1=N_bmax-N_bf;

4766

end1=N_bmax-N_bf;

4360

end2=N_bmax-N_bf;

4767

end2=N_bmax-N_bf;

4361

end3=N_b+1;

4768

end3=N_b+1;

4362

case 3

4769

case 3

4363

end1=N_bmax-N_bf;

4770

end1=N_bmax-N_bf;

4364

end2=N_bmax-N_bf;

4771

end2=N_bmax-N_bf;

4365

end3=N_bmax-N_bf;

4772

end3=N_bmax-N_bf;

4366

end

4773

end

4367

if COOP

4774

if COOP

4368

for ig1= N_b+1:end1 % now remove the 2nd group

4775

for ig1= N_b+1:end1 % now remove the 2nd group

4369

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4776

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4370

% loop for 2rd group

4777

% loop for 2rd group

4371

for ig2= N_b+1: end2

4778

for ig2= N_b+1: end2

4372

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4779

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4373

if N_bg < 2; hcap2 =hcap; end

4780

if N_bg < 2; hcap2 =hcap; end

4374

for ig3= N_b+1: end3

4781

for ig3= N_b+1: end3

4375

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4782

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4376

if N_bg < 3 ; hcap3=hcap2 ; end

4783

if N_bg < 3 ; hcap3=hcap2 ; end

4377

sigma=norm( hcap3 );

4784

sigma=norm( hcap3 );

4378

if sigma < best_sigma

4785

if sigma < best_sigma

4379

best_sigma=sigma;

4786

best_sigma=sigma;

4380

best_ig1=ig1;

4787

best_ig1=ig1;

4381

best_ig2=ig2;

4788

best_ig2=ig2;

4382

best_ig3=ig3;

4789

best_ig3=ig3;

4383

best_hcap=hcap3;

4790

best_hcap=hcap3;

4384

end

4791

end

4385

end

4792

end

4386

end

4793

end

4387

end

4794

end

4388

else % sequentail

4795

else % sequentail

4389

for ig1= N_b+1:end1 % now remove the 1st group

4796

for ig1= N_b+1:end1 % now remove the 1st group

4390

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4797

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4391

sigma=norm( hcap );

4798

sigma=norm( hcap );

4392

if sigma < best_sigma

4799

if sigma < best_sigma

4393

best_sigma=sigma;

4800

best_sigma=sigma;

4394

best_ig1=ig1;

4801

best_ig1=ig1;

4395

best_hcap=hcap;

4802

best_hcap=hcap;

4396

end

4803

end

4397

end

4804

end

4398

% loop for 2rd group

4805

% loop for 2rd group

4399

hisi=best_hcap;

4806

hisi=best_hcap;

4400

for ig2= N_b+1: end2

4807

for ig2= N_b+1: end2

4401

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4808

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4402

sigma=norm( hcap );

4809

sigma=norm( hcap );

4403

if sigma < best_sigma

4810

if sigma < best_sigma

4404

best_sigma=sigma;

4811

best_sigma=sigma;

4405

best_ig2=ig2;

4812

best_ig2=ig2;

4406

best_hcap=hcap;

4813

best_hcap=hcap;

4407

end

4814

end

4408

end

4815

end

4409

hisi=best_hcap;

4816

hisi=best_hcap;

4410

% loop for 3rd group

4817

% loop for 3rd group

4411

for ig3= N_b+1: end3

4818

for ig3= N_b+1: end3

4412

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4819

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4413

sigma=norm( hcap );

4820

sigma=norm( hcap );

4414

if sigma < best_sigma

4821

if sigma < best_sigma

4415

best_sigma=sigma;

4822

best_sigma=sigma;

4416

best_ig3=ig3;

4823

best_ig3=ig3;

4417

best_hcap=hcap;

4824

best_hcap=hcap;

4418

end

4825

end

4419

end

4826

end

4420

4827

4421

end

4828

end

4422

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4829

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4423

switch N_bg

4830

switch N_bg

4424

case 1

4831

case 1

4425

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4832

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4426

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4833

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4427

case 2

4834

case 2

4428

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4835

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4429

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4836

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4430

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4837

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4431

case 3

4838

case 3

4432

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4839

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4433

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4840

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4434

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4841

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4435

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4842

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4436

end

4843

end

4437

floating_tap_locations=sort(floating_tap_locations);

4844

floating_tap_locations=sort(floating_tap_locations);

4438

if 0 % for code debug

4845

if 0 % for code debug

4439

close force all

4846

close force all

4440

stem(best_hcap,'disp','hcap')

4847

stem(best_hcap,'disp','hcap')

4441

hold on

4848

hold on

4442

stem(bmax,'-k','disp','bmax')

4849

stem(bmax,'-k','disp','bmax')

4443

stem(hisi,'disp','hisi')

4850

stem(hisi,'disp','hisi')

4444

hold off

4851

hold off

4445

end

4852

end

4446

4853

4447

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4854

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4448

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4855

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4449

% Vfilter is vector forced filtered sbr

4856

% Vfilter is vector forced filtered sbr

4450

% Cmod is the ffe tap co-efficient vector

4857

% Cmod is the ffe tap co-efficient vector

4451

% if C is passed, just process V with C else compute C

4858

% if C is passed, just process V with C else compute C

4452

% cmx=param.rx_cmx; number of pre cursor taps

4859

% cmx=param.rx_cmx; number of pre cursor taps

4453

% cpx=param.rx_cps; number of post cursor taps

4860

% cpx=param.rx_cps; number of post cursor taps

4454

% V=sbr; pass pulse response

4861

% V=sbr; pass pulse response

4455

% ix the sample point in the passed pulse response

4862

% ix the sample point in the passed pulse response

4456

% the sample point is recomputed by optimize_fom

4863

% the sample point is recomputed by optimize_fom

4457

% idx - return floating tap location (RIM 9-19-2023)

4864

% idx - return floating tap location (RIM 9-19-2023)

4458

% OP not used for now

4865

% OP not used for now

4459

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4866

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4460

% this allows significant speed up in optimize_fom since FFE is time consuming

4867

% this allows significant speed up in optimize_fom since FFE is time consuming

4461

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4868

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4462

% Vfiltered to be calculated

4869

% Vfiltered to be calculated

4463

% test with load('SBR_FIR_resp.mydata','-mat')

4870

% test with load('SBR_FIR_resp.mydata','-mat')

4464

idx=[];

4871

idx=[];

4465

if nargin<4

4872

if nargin<4

4466

ix=find(V==max(V),1,'first');

4873

ix=find(V==max(V),1,'first');

4467

end

4874

end

4468

if nargin<5

4875

if nargin<5

4469

C=[];

4876

C=[];

4470

end

4877

end

4471

if nargin<6

4878

if nargin<6

4472

return_V=1;

4879

return_V=1;

4473

end

4880

end

4474

cmx=param.RxFFE_cmx;

4881

cmx=param.RxFFE_cmx;

4475

cpx=param.RxFFE_cpx;

4882

cpx=param.RxFFE_cpx;

4476

% do this early on so we can reuse the old code

4883

% do this early on so we can reuse the old code

4477

if param.N_bg ~=0 % must be floating taps

4884

if param.N_bg ~=0 % must be floating taps

4478

cpx=param.N_bmax; % N_f in spreadsheet

4885

cpx=param.N_bmax; % N_f in spreadsheet

4479

end

4886

end

4480

num_taps=cmx+cpx+1;

4887

num_taps=cmx+cpx+1;

4481

cstep=param.RxFFE_stepz;

4888

cstep=param.RxFFE_stepz;

4482

ndfe=param.ndfe;

4889

ndfe=param.ndfe;

4483

spui=param.samples_per_ui;

4890

spui=param.samples_per_ui;

4484

param.current_ffegain=0;

4891

param.current_ffegain=0;

4485

if return_V && ~isempty(C)

4892

if return_V && ~isempty(C)

4486

% RIM 2-3-23 when we just want to EQ not find EQ

4893

% RIM 2-3-23 when we just want to EQ not find EQ

4487

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4894

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4488

Cmod=C;

4895

Cmod=C;

4489

return

4896

return

4490

end

4897

end

4491

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4898

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4492

if ix < length(V)

4899

if ix < length(V)

4493

if isrow(V)

4900

if isrow(V)

4494

if mod(ix,spui) == 0

4901

if mod(ix,spui) == 0

4495

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4902

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4496

else

4903

else

4497

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4904

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4498

end

4905

end

4499

4906

4500

else

4907

else

4501

if mod(ix,spui) == 0

4908

if mod(ix,spui) == 0

4502

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4909

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4503

else

4910

else

4504

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4911

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4505

end

4912

end

4506

end

4913

end

4507

else

4914

else

4508

if isrow(V)

4915

if isrow(V)

4509

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4916

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4510

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4917

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4511

else

4918

else

4512

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4919

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4513

end

4920

end

4514

else

4921

else

4515

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4922

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4516

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4923

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4517

else

4924

else

4518

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4925

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4519

end

4926

end

4520

end

4927

end

4521

end

4928

end

4522

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4929

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4523

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4930

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4524

4931

4525

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4932

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4526

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4933

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4527

% Upen Kareti suggested fix for indexing 11/04/18

4934

% Upen Kareti suggested fix for indexing 11/04/18

4528

if ix < length(V)

4935

if ix < length(V)

4529

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4936

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4530

else

4937

else

4531

ivs=find(vsampled == max(vsampled),1,'first');

4938

ivs=find(vsampled == max(vsampled),1,'first');

4532

end

4939

end

4533

4940

4534

4941

4535

%% create VV matrix of shifted UI spaced sample of the pulse response

4942

%% create VV matrix of shifted UI spaced sample of the pulse response

4536

% only consider the VV matrix that correstonds to the FFE taps

4943

% only consider the VV matrix that correstonds to the FFE taps

4537

VV=zeros(num_taps,num_taps);

4944

VV=zeros(num_taps,num_taps);

4538

for i=1:num_taps

4945

for i=1:num_taps

4539

start_idx=ivs+i-1;

4946

start_idx=ivs+i-1;

4540

end_idx=start_idx-num_taps+1;

4947

end_idx=start_idx-num_taps+1;

4541

VV(:,i)=vsampled(start_idx:-1:end_idx);

4948

VV(:,i)=vsampled(start_idx:-1:end_idx);

4542

end

4949

end

4543

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4950

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4544

%% Apply RXFFE

4951

%% Apply RXFFE

4545

if isempty(C)

4952

if isempty(C)

4546

switch upper(OP.FFE_OPT_METHOD)

4953

switch upper(OP.FFE_OPT_METHOD)

4547

case 'WIENER-HOPF'

4954

case 'WIENER-HOPF'

4548

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4955

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4549

Cmod=C(1:num_taps);

4956

Cmod=C(1:num_taps);

4550

otherwise

4957

otherwise

4551

% cmx+1 is the cursor or sample point

4958

% cmx+1 is the cursor or sample point

4552

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4959

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4553

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4960

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4554

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4961

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4555

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4962

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4556

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4963

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4557

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4964

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4558

end

4965

end

4559

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4966

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4560

if diff(size(VV))==0

4967

if diff(size(VV))==0

4561

%For square matrix, can solve C using simple inv(VV')*FV'

4968

%For square matrix, can solve C using simple inv(VV')*FV'

4562

C=VV'\FV';

4969

C=VV'\FV';

4563

else

4970

else

4564

%otherwise use the general solution with psuedo inverse

4971

%otherwise use the general solution with psuedo inverse

4565

%note: this is the same as doing pinv(VV') but pinv is far slower

4972

%note: this is the same as doing pinv(VV') but pinv is far slower

4566

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4973

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4567

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4974

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4568

end

4975

end

4569

4976

4570

Cmod=C(1:num_taps);

4977

Cmod=C(1:num_taps);

4571

end

4978

end

4572

4979

4573

4980

4574

% added for 4.2 find floating taps with either ISI or taps

4981

% added for 4.2 find floating taps with either ISI or taps

4575

switch lower(OP.RXFFE_FLOAT_CTL)

4982

switch lower(OP.RXFFE_FLOAT_CTL)

4576

case 'taps'

4983

case 'taps'

4577

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4984

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4578

otherwise

4985

otherwise

4579

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4986

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4580

end

4987

end

4581

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4988

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4582

case 'unity cursor'

4989

case 'unity cursor'

4583

Cmod=Cmod/Cmod(cmx+1);

4990

Cmod=Cmod/Cmod(cmx+1);

4584

otherwise

4991

otherwise

4585

Cmod=C;

4992

Cmod=C;

4586

end

4993

end

4587

if cstep ~= 0

4994

if cstep ~= 0

4588

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4995

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4589

end

4996

end

4590

4997

4591

if ~isempty(idx)

4998

if ~isempty(idx)

4592

idx=sort(idx);

4999

idx=sort(idx);

4593

C1=Cmod;

5000

C1=Cmod;

4594

% C1(param.N_tail_start:end)=0;

5001

% C1(param.N_tail_start:end)=0;

4595

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

5002

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4596

C1(cmx+1+idx)=Cmod(cmx+1+idx);

5003

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4597

Cmod=C1;

5004

Cmod=C1;

4598

else

5005

else

4599

% Cmod=C;

5006

% Cmod=C;

4600

end

5007

end

4601

5008

4602

% now when ussing RxFFE floating taps need to tag stems correctly and

5009

% now when ussing RxFFE floating taps need to tag stems correctly and

4603

% make sure DFEfloating tap code does not get exectuted

5010

% make sure DFEfloating tap code does not get exectuted

4604

5011

4605

%

5012

%

4606

else

5013

else

4607

Cmod=C;%just us the FFE taps, C, passed for filtering

5014

Cmod=C;%just us the FFE taps, C, passed for filtering

4608

end

5015

end

4609

%%

5016

%%

4610

%% filter the pulse response with the solved FFE

5017

%% filter the pulse response with the solved FFE

4611

% (now option to avoid this and just return Cmod for speed up)

5018

% (now option to avoid this and just return Cmod for speed up)

4612

if return_V

5019

if return_V

4613

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

5020

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4614

else

5021

else

4615

Vfiltered=[];

5022

Vfiltered=[];

4616

end

5023

end

4617

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

5024

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4618

% used for FD IL fitting

5025

% used for FD IL fitting

4619

% sdd21 us a complex insertion loss

5026

% sdd21 us a complex insertion loss

4620

db = @(x) 20*log10(abs(x));

5027

db = @(x) 20*log10(abs(x));

4621

sdd21=squeeze(sdd21);

5028

sdd21=squeeze(sdd21);

4622

if iscolumn(sdd21)

5029

if iscolumn(sdd21)

4623

sdd21=sdd21.';

5030

sdd21=sdd21.';

4624

end

5031

end

4625

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)) ];

5032

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)) ];

4626

warning('off','MATLAB:nearlySingularMatrix');

5033

warning('off','MATLAB:nearlySingularMatrix');

4627

LGw=transpose(abs(sdd21).*db(sdd21));

5034

LGw=transpose(abs(sdd21).*db(sdd21));

4628

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5035

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4629

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5036

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4630

ILN = db(sdd21)-efit;

5037

ILN = db(sdd21)-efit;

4631

5038

4632

5039

4633

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

5040

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4634

% Complex IL fitting

5041

% Complex IL fitting

4635

% sdd21 us a complex insertion loss

5042

% sdd21 us a complex insertion loss

4636

% efit and ILN are in db

5043

% efit and ILN are in db

4637

% faxix_f2 needs to be at least to fb

5044

% faxix_f2 needs to be at least to fb

4638

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

5045

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

4639

% still need to settle on voltage scaling.

5046

% still need to settle on voltage scaling.

4640

% maybe db(peak/Rss

5047

% maybe db(peak/Rss

4641

5048

4642

OP.interp_sparam_mag= 'trend_to_DC';

5049

OP.interp_sparam_mag= 'trend_to_DC';

4643

OP.interp_sparam_phase= 'interp_to_DC';

5050

OP.interp_sparam_phase= 'interp_to_DC';

4644

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5051

% OP.interp_sparam_mag= 'linear_trend_to_DC';

4645

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5052

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

4646

5053

4647

print_for_codereview=0;

5054

print_for_codereview=0;

4648

if ~exist('A_T','var')

5055

if ~exist('A_T','var')

4649

A_T=1;

5056

A_T=1;

4650

end

5057

end

4651

5058

4652

db = @(x) 20*log10(abs(x));

5059

db = @(x) 20*log10(abs(x));

4653

sdd21=squeeze(sdd21);

5060

sdd21=squeeze(sdd21);

4654

if iscolumn(sdd21)

5061

if iscolumn(sdd21)

4655

sdd21=sdd21.';

5062

sdd21=sdd21.';

4656

end

5063

end

4657

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) ];

5064

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) ];

4658

warning('off','MATLAB:nearlySingularMatrix');

5065

warning('off','MATLAB:nearlySingularMatrix');

4659

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5066

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

4660

LGw=transpose(sdd21.*unwraplog);

5067

LGw=transpose(sdd21.*unwraplog);

4661

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5068

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4662

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5069

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4663

FIT=transpose(exp(transpose(efit_C)));

5070

FIT=transpose(exp(transpose(efit_C)));

4664

efit=db(abs(FIT));

5071

efit=db(abs(FIT));

4665

ILN = db(sdd21)-efit;

5072

ILN = db(sdd21)-efit;

4666

% time domain

5073

% time domain

4667

fprintf('computing TD_ILN (dB) ...')

5074

fprintf('computing TD_ILN (dB) ...')

4668

if exist('OP','var')

5075

if exist('OP','var')

4669

% OP.fraction_of_F_range_start_extrap_from=.95;

5076

% OP.fraction_of_F_range_start_extrap_from=.95;

4670

OP.impulse_response_truncation_threshold =1e-7;

5077

OP.impulse_response_truncation_threshold =1e-7;

4671

5078

4672

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5079

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

4673

H_bw=Butterworth_Filter(param,faxis_f2,1);

5080

H_bw=Butterworth_Filter(param,faxis_f2,1);

4674

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5081

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

4675

H_tw=Tukey_Window(faxis_f2,param);

5082

H_tw=Tukey_Window(faxis_f2,param);

4676

H_tw=ones(1,length(faxis_f2) );

5083

H_tw=ones(1,length(faxis_f2) );

4677

5084

4678

[TD_ILN.REF.FIR, ...

5085

[TD_ILN.REF.FIR, ...

4679

TD_ILN.REF.t, ...

5086

TD_ILN.REF.t, ...

4680

TD_ILN.REF.causality_correction_dB, ...

5087

TD_ILN.REF.causality_correction_dB, ...

4681

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5088

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4682

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

5089

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

4683

5090

4684

[TD_ILN.FIT.FIR, ...

5091

[TD_ILN.FIT.FIR, ...

4685

TD_ILN.FIT.t, ...

5092

TD_ILN.FIT.t, ...

4686

TD_ILN.FIT.causality_correction_dB, ...

5093

TD_ILN.FIT.causality_correction_dB, ...

4687

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5094

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4688

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

5095

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

4689

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

5096

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

4690

% NrangeUI=1000;

5097

% NrangeUI=1000;

4691

% 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);

5098

% 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);

4692

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

5099

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

4693

range=ipeak:range_end;

5100

range=ipeak:range_end;

4694

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

5101

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

4695

TD_ILN.t=TD_ILN.FIT.t(range);

5102

TD_ILN.t=TD_ILN.FIT.t(range);

4696

TD_ILN.FOM=-inf;

5103

TD_ILN.FOM=-inf;

4697

TD_ILN.FOM_PDF=-inf;

5104

TD_ILN.FOM_PDF=-inf;

4698

rms_fom=-inf;

5105

rms_fom=-inf;

4699

for im=1:param.samples_per_ui

5106

for im=1:param.samples_per_ui

4700

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

5107

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

4701

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5108

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

4702

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5109

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

4703

cdf=pdf; cdf.y=cumsum(pdf.y);

5110

cdf=pdf; cdf.y=cumsum(pdf.y);

4704

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5111

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

4705

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5112

% signal_and_isi_pdf = conv_fct(cursors, pdf);

4706

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5113

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

4707

if print_for_codereview % remove once all checked out

5114

if print_for_codereview % remove once all checked out

4708

h=figure(190);set(gcf,'Tag','COM');

5115

h=figure(190);set(gcf,'Tag','COM');

4709

semilogy(-cdf.x,cdf.y);

5116

semilogy(-cdf.x,cdf.y);

4710

% xlim ([0,-cdf.x(1)])

5117

% xlim ([0,-cdf.x(1)])

4711

ylim([param.specBER 1]);title ('CDF of ILN')

5118

ylim([param.specBER 1]);title ('CDF of ILN')

4712

hold on

5119

hold on

4713

end

5120

end

4714

if rms>rms_fom

5121

if rms>rms_fom

4715

rms_fom=rms;

5122

rms_fom=rms;

4716

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5123

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

4717

TD_ILN.PDF=pdf;

5124

TD_ILN.PDF=pdf;

4718

end

5125

end

4719

end

5126

end

4720

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

5127

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

4721

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

5128

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

4722

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

5129

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

4723

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

5130

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

4724

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

5131

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

4725

if print_for_codereview % remove once all checked out

5132

if print_for_codereview % remove once all checked out

4726

figure(9000);set(gcf,'Tag','COM');

5133

figure(9000);set(gcf,'Tag','COM');

4727

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

5134

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

4728

hold on

5135

hold on

4729

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

5136

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

4730

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

5137

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

4731

hold off

5138

hold off

4732

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)

5139

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)

4733

figure(9002);set(gcf,'Tag','COM');

5140

figure(9002);set(gcf,'Tag','COM');

4734

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

5141

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

4735

hold on

5142

hold on

4736

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5143

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

4737

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5144

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

4738

grid on

5145

grid on

4739

legend('show')

5146

legend('show')

4740

end

5147

end

4741

end

5148

end

4742

% display('got to end of get_ILN_cmp_td')

5149

% display('got to end of get_ILN_cmp_td')

4743

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

5150

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

4744

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

5151

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

4745

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

5152

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

4746

if 1 % force indent for doc

5153

if 1 % force indent for doc

4747

num_ui=param.num_ui_RXFF_noise;

5154

num_ui=param.num_ui_RXFF_noise;

4748

M=param.samples_per_ui;

5155

M=param.samples_per_ui;

4749

L=param.levels;

5156

L=param.levels;

4750

f_b=param.fb;

5157

f_b=param.fb;

4751

SNR_TX=param.SNR_TX;

5158

SNR_TX=param.SNR_TX;

4752

dw=param.RxFFE_cmx;

5159

dw=param.RxFFE_cmx;

4753

bmax=param.bmax;

5160

bmax=param.bmax;

4754

bmin=param.bmin ;

5161

bmin=param.bmin ;

4755

Nb=param.ndfe;

5162

Nb=param.ndfe;

4756

sigma_X2=(L^2-1)/(3*(L-1)^2);

5163

sigma_X2=(L^2-1)/(3*(L-1)^2);

4757

eta_0=param.eta_0; %V^2/GHz

5164

eta_0=param.eta_0; %V^2/GHz

4758

T_b=1/f_b;

5165

T_b=1/f_b;

4759

delta_f = f_b/num_ui; % Units are Hz.

5166

delta_f = f_b/num_ui; % Units are Hz.

4760

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

5167

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

4761

result.fvec=fvec;

5168

result.fvec=fvec;

4762

end

5169

end

4763

if OP.COMPUTE_COM

5170

if OP.COMPUTE_COM

4764

%% H_rxffe eq 178A-28 d1.0

5171

%% H_rxffe eq 178A-28 d1.0

4765

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

5172

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

4766

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

5173

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

4767

H_rxffe=0;

5174

H_rxffe=0;

4768

for nn=1:length(result.w)

5175

for nn=1:length(result.w)

4769

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

5176

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

4770

end

5177

end

4771

H_rxffe_2_of_f=abs(H_rxffe).^2;

5178

H_rxffe_2_of_f=abs(H_rxffe).^2;

4772

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

5179

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

4773

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))];

5180

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))];

4774

else

5181

else

4775

H_rxffe_2=1;

5182

H_rxffe_2=1;

4776

end

5183

end

4777

result.H_rxffe_2=H_rxffe_2;% pass as output for compuation in healey_3dj_01_2409 slide 12

+5184

4778

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

5185

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

4779

% --->this is the point in the code may fork where we add extra rx noise

5186

% --->this is the point in the code may fork where we add extra rx noise

4780

%% compute S_rn ( eq 178A-15 d0.2 )

5187

%% compute S_rn ( eq 178A-15 d0.2 )

4781

if ~OP.COMPUTE_COM

5188

if ~OP.COMPUTE_COM

4782

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

5189

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

4783

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

5190

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

4784

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

5191

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

4785

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

5192

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

4786

S_rn = sum(reshape(rxn_psd, num_ui, M).');

5193

S_rn = sum(reshape(rxn_psd, num_ui, M).');

4787

S_rn=S_rn(1:num_ui/2+1);

5194

S_rn=S_rn(1:num_ui/2+1);

4788

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

5195

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

4789

result.S_rn=S_rn;

5196

result.S_rn=S_rn;

4790

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5197

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4791

else

5198

else

4792

result.S_rn=result.S_rn.*H_rxffe_2;

5199

result.S_rn=result.S_rn.*H_rxffe_2;

4793

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5200

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4794

end

5201

end

4795

5202

4796

else % find noise for item that set have tx ffe for each loop

5203

else % find noise for item that set have tx ffe for each loop

4797

%% S_xn from eq 178A-16

5204

%% S_xn from eq 178A-16

4798

%% Crosstalk power spectral density

5205

%% Crosstalk power spectral density

4799

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

5206

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

4800

result.S_xn=0;

5207

result.S_xn=0;

4801

if length(chdata)~=1

5208

if length(chdata)~=1

4802

for xchan=2:length(chdata)

5209

for xchan=2:length(chdata)

4803

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

5210

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

4804

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

5211

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

4805

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

5212

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

4806

% enable less UI for computation speed improvement

5213

% enable less UI for computation speed improvement

4807

%%

5214

%%

4808

if num_ui*M > length(pulse_ctle)

5215

if num_ui*M > length(pulse_ctle)

4809

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

5216

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

4810

else

5217

else

4811

hk(xchan).k=hk(xchan).k(1:num_ui*M);

5218

hk(xchan).k=hk(xchan).k(1:num_ui*M);

4812

end

5219

end

4813

for i1=1:M

5220

for i1=1:M

4814

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

5221

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

4815

end

5222

end

4816

iphase(xchan)=find(hxn==max(hxn));

5223

iphase(xchan)=find(hxn==max(hxn));

4817

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

5224

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

4818

result.hk(xchan).hrn= hk(xchan).hrn;

5225

result.hk(xchan).hrn= hk(xchan).hrn;

4819

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

5226

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

4820

result.S_xn=hk(xchan).S_xn+result.S_xn;

5227

result.S_xn=hk(xchan).S_xn+result.S_xn;

4821

end

5228

end

4822

result.S_xn=result.S_xn;

5229

result.S_xn=result.S_xn;

4823

result.hk=hk;

5230

result.hk=hk;

4824

result.iphase=iphase;

5231

result.iphase=iphase;

4825

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5232

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4826

else % if no crosstalk, perserve structure and return 0 for S_xn

5233

else % if no crosstalk, perserve structure and return 0 for S_xn

4827

result.S_xn=0;

5234

result.S_xn=0;

4828

result.hk=[];

5235

result.hk=[];

4829

result.iphase=1;

5236

result.iphase=1;

4830

result.S_xn_rms = 0;

5237

result.S_xn_rms = 0;

4831

end

5238

end

4832

else % adjust for H_rxffe when computing COM

5239

else % adjust for H_rxffe when computing COM

4833

result.S_xn=result.S_xn.*H_rxffe_2;

5240

result.S_xn=result.S_xn.*H_rxffe_2;

4834

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5241

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4835

end

5242

end

4836

%% S_tn from eq 178A-17

5243

%% S_tn from eq 178A-17

4837

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

5244

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

4838

%% Transmitter noise power spectral density

5245

%% Transmitter noise power spectral density

4839

if ~OP.COMPUTE_COM

5246

if ~OP.COMPUTE_COM

4840

if ~OP.TDMODE

5247

if ~OP.TDMODE

4841

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

5248

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

4842

else % only use when the input was a pulse response not s-parameters

5249

else % only use when the input was a pulse response not s-parameters

4843

if isfield(chdata(1),'ctle_pulse_response')

5250

if isfield(chdata(1),'ctle_pulse_response')

4844

htn=chdata(1).ctle_pulse_response;

5251

htn=chdata(1).ctle_pulse_response;

4845

else

5252

else

4846

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

5253

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

4847

end

5254

end

4848

end

5255

end

4849

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

5256

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

4850

htn=reshape(htn,1,[]); % make row vectors

5257

htn=reshape(htn,1,[]); % make row vectors

4851

htn=[ htn(1:floor(length(htn)/M)*M) ];

5258

htn=[ htn(1:floor(length(htn)/M)*M) ];

4852

htn= [htn zeros(1,num_ui*M-length(htn)) ];

5259

htn= [htn zeros(1,num_ui*M-length(htn)) ];

4853

htn=htn(1:M:end);% resample

5260

htn=htn(1:M:end);% resample

4854

if num_ui>length(htn)

5261

if num_ui>length(htn)

4855

hext=[htn zeros(1,num_ui-length(htn))];

5262

hext=[htn zeros(1,num_ui-length(htn))];

4856

else

5263

else

4857

hext=htn(1:num_ui);

5264

hext=htn(1:num_ui);

4858

end

5265

end

4859

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

5266

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

4860

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5267

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4861

else

5268

else

4862

result.S_tn=result.S_tn.*H_rxffe_2;

5269

result.S_tn=result.S_tn.*H_rxffe_2;

4863

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5270

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4864

end

5271

end

4865

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

5272

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

4866

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

5273

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

4867

%% Power spectral density of noise due to jitter

5274

%% Power spectral density of noise due to jitter

4868

%% Eq. 93A-28 %%

5275

%% Eq. 93A-28 %%

4869

if ~OP.COMPUTE_COM

5276

if ~OP.COMPUTE_COM

4870

sampling_offset = mod(cursor_i, M);

5277

sampling_offset = mod(cursor_i, M);

4871

%ensure we can take early sample

5278

%ensure we can take early sample

4872

if sampling_offset<=1

5279

if sampling_offset<=1

4873

sampling_offset=sampling_offset+M;

5280

sampling_offset=sampling_offset+M;

4874

end

5281

end

4875

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

5282

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

4876

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

5283

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

4877

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

5284

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

4878

else

5285

else

4879

cursors_early_sample = h(sampling_offset-1:M:end);

5286

cursors_early_sample = h(sampling_offset-1:M:end);

4880

cursors_late_sample = h(sampling_offset+1:M:end);

5287

cursors_late_sample = h(sampling_offset+1:M:end);

4881

end

5288

end

4882

% ensure lengths are equal

5289

% ensure lengths are equal

4883

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

5290

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

4884

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

5291

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

4885

h_J=reshape(h_J,1,[]); % make row vectors

5292

h_J=reshape(h_J,1,[]); % make row vectors

4886

if num_ui>length(h_J)

5293

if num_ui>length(h_J)

4887

h_J=[h_J zeros(1,num_ui-length(h_J))];

5294

h_J=[h_J zeros(1,num_ui-length(h_J))];

4888

else

5295

else

4889

h_J=h_J(1:num_ui);

5296

h_J=h_J(1:num_ui);

4890

end

5297

end

4891

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5298

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4892

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5299

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4893

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5300

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4894

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5301

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4895

else

5302

else

4896

result.S_jn=result.S_jn.*H_rxffe_2;

5303

result.S_jn=result.S_jn.*H_rxffe_2;

4897

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5304

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4898

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

5305

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

4899

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5306

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4900

end

5307

end

4901

% result.S_jnesult.S_rn

5308

% result.S_jn

4902

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn;

5309

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn;

4903

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

5310

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

4904

5311

4905

%%

5312

%%

4906

%% Hisi to be included in MLSE rho eq 178a-28

5313

%% Hisi to be included in MLSE rho eq 178a-28

4907

if OP.COMPUTE_COM

5314

if OP.COMPUTE_COM

4908

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

5315

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

4909

% sampling_offset = mod(cursor_i-1, M)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

5316

% sampling_offset = mod(cursor_i-1, M)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

4910

% hisi=h(sampling_offset:M:end);

5317

% hisi=h(sampling_offset:M:end);

4911

% hisi=hisi(:).';

5318

% hisi=hisi(:).';

4912

% if num_ui>length(hisi)

5319

% if num_ui>length(hisi)

4913

% hisi=[hisi zeros(1,num_ui-length(hisi))];

5320

% hisi=[hisi zeros(1,num_ui-length(hisi))];

4914

% else

5321

% else

4915

% hisi=hisi(1:num_ui);% sometime cable channels need a bigger num_ui. prehap compare to the tripple transit time and compute num_ui

5322

% hisi=hisi(1:num_ui);% sometime cable channels need a bigger num_ui. prehap compare to the tripple transit time and compute num_ui

4916

% end

5323

% end

4917

% cursor_n=find(hisi==max(hisi),1','first');

5324

% cursor_n=find(hisi==max(hisi),1','first');

4918

samp_idx = (mod(cursor_i-1,M)+1):M:length(h);% Commit request 4p5_2, healey_3dj_COM_01_240521.pdf

5325

samp_idx = (mod(cursor_i-1,M)+1):M:length(h);% Commit request 4p5_2, healey_3dj_COM_01_240521.pdf

4919

cursor_n=find(samp_idx == cursor_i);

5326

cursor_n=find(samp_idx == cursor_i);

4920

hisi=h(samp_idx);

5327

hisi=h(samp_idx);

4921

hisi(end+1:num_ui)=0;

5328

hisi(end+1:num_ui)=0;

4922

hisi=reshape(hisi(1:num_ui),1,[]);

5329

hisi=reshape(hisi(1:num_ui),1,[]);

4923

%% Eq 178a-29

5330

%% Eq 178a-29

4924

for ii=1:length(hisi)

5331

for ii=1:length(hisi)

4925

if ii==cursor_n % cursor

5332

if ii==cursor_n % cursor

4926

cursor=hisi(ii);

5333

cursor=hisi(ii);

4927

hisi(ii)= 0;

5334

hisi(ii)= 0;

4928

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

5335

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

4929

ib_indx=ii-cursor_n;

5336

ib_indx=ii-cursor_n;

4930

if hisi(ii) >= bmax(ib_indx)*cursor

5337

if hisi(ii) >= bmax(ib_indx)*cursor

4931

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

5338

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

4932

elseif hisi(ii) <= bmin(ib_indx)*cursor

5339

elseif hisi(ii) <= bmin(ib_indx)*cursor

4933

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

5340

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

4934

else

5341

else

4935

hisi(ii)=0;

5342

hisi(ii)=0;

4936

end

5343

end

4937

end

5344

end

4938

end

5345

end

4939

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

5346

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

4940

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

5347

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

4941

%%

5348

%%

4942

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

5349

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

4943

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

5350

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

4944

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

5351

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

4945

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

5352

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

4946

end

5353

end

4947

end

5354

end

4948

function result=get_PulseR(ir,param,cb_step,ZT)

5355

function result=get_PulseR(ir,param,cb_step,ZT)

4949

%ir = impulse response

5356

%ir = impulse response

4950

%t_base=time array with equal time steps

5357

%t_base=time array with equal time steps

4951

%samp_UI = number of samples per UI for ir

5358

%samp_UI = number of samples per UI for ir

4952

5359

4953

% t for debug

5360

% t for debug

4954

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5361

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

4955

5362

4956

if cb_step

5363

if cb_step

4957

Ag=1;

5364

Ag=1;

4958

dt=1/param.fb/param.samples_per_ui;

5365

dt=1/param.fb/param.samples_per_ui;

4959

edge_time=param.TR_TDR*1e-9;

5366

edge_time=param.TR_TDR*1e-9;

4960

fedge=1/edge_time;

5367

fedge=1/edge_time;

4961

tedge=0:dt:edge_time*2;

5368

tedge=0:dt:edge_time*2;

4962

%

5369

%

4963

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5370

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

4964

drive_pulse=[edge ones(1,param.samples_per_ui)];

5371

drive_pulse=[edge ones(1,param.samples_per_ui)];

4965

%pulse=filter(UI_ones,1,ir);

5372

%pulse=filter(UI_ones,1,ir);

4966

% t for debug

5373

% t for debug

4967

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5374

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

4968

5375

4969

pulse=filter(drive_pulse,1,ir);

5376

pulse=filter(drive_pulse,1,ir);

4970

else

5377

else

4971

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5378

pulse=filter( ones(1,param.samples_per_ui),1,ir);

4972

end

5379

end

4973

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5380

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

4974

result.PDR=PDR_response;

5381

result.PDR=PDR_response;

4975

result.pulse=pulse;

5382

result.pulse=pulse;

4976

5383

4977

5384

4978

5385

4979

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5386

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

4980

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

5387

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

4981

if ~iscolumn(H), H=H.';end

5388

if ~iscolumn(H), H=H.';end

4982

if ~iscolumn(H_r), H_r=H_r.';end

5389

if ~iscolumn(H_r), H_r=H_r.';end

4983

H=H(:).*H_r;

5390

H=H(:).*H_r;

4984

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5391

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

4985

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5392

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

4986

5393

4987

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5394

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

4988

% Complex reflection and re-reflection noise using the concept of zero'ing

5395

% Complex reflection and re-reflection noise using the concept of zero'ing

4989

% out of reflections

5396

% out of reflections

4990

% sdd21 us a complex insertion loss

5397

% sdd21 us a complex insertion loss

4991

% RIL_struct is the output of capture_RIL_RILN()

5398

% RIL_struct is the output of capture_RIL_RILN()

4992

% faxix_f2 needs to be at least to fb

5399

% faxix_f2 needs to be at least to fb

4993

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5400

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

4994

% still need to settle on voltage scaling.

5401

% still need to settle on voltage scaling.

4995

% maybe db(peak/Rss

5402

% maybe db(peak/Rss

4996

db = @(x) 20*log10(abs(x));

5403

db = @(x) 20*log10(abs(x));

4997

fprintf('computing TD_RILN (dB) ...');

5404

fprintf('computing TD_RILN (dB) ...');

4998

5405

4999

OP.interp_sparam_mag= 'trend_to_DC';

5406

OP.interp_sparam_mag= 'trend_to_DC';

5000

OP.interp_sparam_phase= 'interp_to_DC';

5407

OP.interp_sparam_phase= 'interp_to_DC';

5001

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5408

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5002

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5409

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5003

5410

5004

sdd21=squeeze(sdd21);

5411

sdd21=squeeze(sdd21);

5005

if iscolumn(sdd21)

5412

if iscolumn(sdd21)

5006

sdd21=sdd21.';

5413

sdd21=sdd21.';

5007

end

5414

end

5008

RIL=squeeze(RIL_struct.RIL);

5415

RIL=squeeze(RIL_struct.RIL);

5009

if iscolumn(RIL)

5416

if iscolumn(RIL)

5010

RIL=RIL.';

5417

RIL=RIL.';

5011

end

5418

end

5012

rho_port1=squeeze(RIL_struct.rho_port1);

5419

rho_port1=squeeze(RIL_struct.rho_port1);

5013

if iscolumn(rho_port1)

5420

if iscolumn(rho_port1)

5014

rho_port1=rho_port1.';

5421

rho_port1=rho_port1.';

5015

end

5422

end

5016

rho_port2=squeeze(RIL_struct.rho_port2);

5423

rho_port2=squeeze(RIL_struct.rho_port2);

5017

if iscolumn(rho_port2)

5424

if iscolumn(rho_port2)

5018

rho_port2=rho_port2.';

5425

rho_port2=rho_port2.';

5019

end

5426

end

5020

RIL_f=squeeze(RIL_struct.freq);

5427

RIL_f=squeeze(RIL_struct.freq);

5021

if iscolumn(RIL_f)

5428

if iscolumn(RIL_f)

5022

RIL_f=RIL_f.';

5429

RIL_f=RIL_f.';

5023

end

5430

end

5024

5431

5025

%---start. Calculate the reflection and re-reflection noise

5432

%---start. Calculate the reflection and re-reflection noise

5026

number_of_echos= 1e3;

5433

number_of_echos= 1e3;

5027

fmin= 1e9;%<-------------

5434

fmin= 1e9;%<-------------

5028

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5435

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5029

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5436

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5030

for m= 1:number_of_echos

5437

for m= 1:number_of_echos

5031

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);

5438

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);

5032

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);

5439

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);

5033

end

5440

end

5034

5441

5035

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5442

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5036

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5443

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5037

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5444

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5038

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5445

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5039

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5446

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5040

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5447

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5041

5448

5042

% clear RIL RIL_f rho_port1 rho_port2

5449

% clear RIL RIL_f rho_port1 rho_port2

5043

% clear fmin m

5450

% clear fmin m

5044

%---end. Calculate the reflection and re-reflection noise

5451

%---end. Calculate the reflection and re-reflection noise

5045

5452

5046

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) ];

5453

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) ];

5047

warning('off','MATLAB:nearlySingularMatrix');

5454

warning('off','MATLAB:nearlySingularMatrix');

5048

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5455

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5049

LGw=transpose(sdd21.*unwraplog);

5456

LGw=transpose(sdd21.*unwraplog);

5050

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5457

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5051

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5458

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5052

FIT=transpose(exp(transpose(efit_C)));

5459

FIT=transpose(exp(transpose(efit_C)));

5053

efit=db(abs(FIT));

5460

efit=db(abs(FIT));

5054

ILN = db(sdd21)-efit;

5461

ILN = db(sdd21)-efit;

5055

5462

5056

5463

5057

OP.impulse_response_truncation_threshold =1e-7;

5464

OP.impulse_response_truncation_threshold =1e-7;

5058

5465

5059

print_for_codereview=0;

5466

print_for_codereview=0;

5060

if exist('OP','var')

5467

if exist('OP','var')

5061

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5468

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5062

H_bw=Butterworth_Filter(param,faxis_f2,1);

5469

H_bw=Butterworth_Filter(param,faxis_f2,1);

5063

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5470

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5064

H_tw=Tukey_Window(faxis_f2,param);

5471

H_tw=Tukey_Window(faxis_f2,param);

5065

H_tw=ones(1,length(faxis_f2) );

5472

H_tw=ones(1,length(faxis_f2) );

5066

[RILN_TD_struct.REF.FIR, ...

5473

[RILN_TD_struct.REF.FIR, ...

5067

RILN_TD_struct.REF.t, ...

5474

RILN_TD_struct.REF.t, ...

5068

RILN_TD_struct.REF.causality_correction_dB, ...

5475

RILN_TD_struct.REF.causality_correction_dB, ...

5069

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5476

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5070

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5477

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5071

5478

5072

5479

5073

[RILN_TD_struct.FIT.FIR, ...

5480

[RILN_TD_struct.FIT.FIR, ...

5074

RILN_TD_struct.FIT.t, ...

5481

RILN_TD_struct.FIT.t, ...

5075

RILN_TD_struct.FIT.causality_correction_dB, ...

5482

RILN_TD_struct.FIT.causality_correction_dB, ...

5076

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5483

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5077

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5484

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5078

5485

5079

5486

5080

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5487

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5081

H_bw=Butterworth_Filter(param,RIL_f,1);

5488

H_bw=Butterworth_Filter(param,RIL_f,1);

5082

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5489

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5083

H_tw=Tukey_Window(RIL_f,param);

5490

H_tw=Tukey_Window(RIL_f,param);

5084

H_tw=ones(1,length(RIL_f) );

5491

H_tw=ones(1,length(RIL_f) );

5085

[RILN_TD_struct.RIL.FIR, ...

5492

[RILN_TD_struct.RIL.FIR, ...

5086

RILN_TD_struct.RIL.t, ...

5493

RILN_TD_struct.RIL.t, ...

5087

RILN_TD_struct.RIL.causality_correction_dB, ...

5494

RILN_TD_struct.RIL.causality_correction_dB, ...

5088

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5495

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5089

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5496

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5090

5497

5091

5498

5092

%---start. Calculate the channel delay

5499

%---start. Calculate the channel delay

5093

try

5500

try

5094

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5501

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5095

catch

5502

catch

5096

end

5503

end

5097

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5504

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5098

clear delay_sec delay_idx

5505

clear delay_sec delay_idx

5099

%---end. Calculate the channel delay

5506

%---end. Calculate the channel delay

5100

5507

5101

5508

5102

5509

5103

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5510

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5104

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5511

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5105

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5512

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5106

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5513

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5107

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5514

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5108

[RILN_TD_struct.REF_noise.FIR, ...

5515

[RILN_TD_struct.REF_noise.FIR, ...

5109

RILN_TD_struct.REF_noise.t, ...

5516

RILN_TD_struct.REF_noise.t, ...

5110

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5517

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5111

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) ;

5518

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) ;

5112

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5519

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5113

5520

5114

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5521

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5115

% NrangeUI=1000;

5522

% NrangeUI=1000;

5116

% 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);

5523

% 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);

5117

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5524

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5118

range=ipeak:range_end;

5525

range=ipeak:range_end;

5119

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5526

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5120

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5527

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5121

RILN_TD_struct.FOM=-inf;

5528

RILN_TD_struct.FOM=-inf;

5122

RILN_TD_struct.FOM_PDF=-inf;

5529

RILN_TD_struct.FOM_PDF=-inf;

5123

rms_fom=-inf;

5530

rms_fom=-inf;

5124

for im=1:param.samples_per_ui

5531

for im=1:param.samples_per_ui

5125

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5532

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5126

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5533

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5127

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5534

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5128

cdf=pdf; cdf.y=cumsum(pdf.y);

5535

cdf=pdf; cdf.y=cumsum(pdf.y);

5129

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5536

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5130

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5537

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5131

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5538

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5132

if print_for_codereview % remove once all checked out

5539

if print_for_codereview % remove once all checked out

5133

h=figure(190);set(gcf,'Tag','COM');

5540

h=figure(190);set(gcf,'Tag','COM');

5134

semilogy(-cdf.x,cdf.y);

5541

semilogy(-cdf.x,cdf.y);

5135

% xlim ([0,-cdf.x(1)])

5542

% xlim ([0,-cdf.x(1)])

5136

ylim([param.specBER 1]);title ('CDF of ILN')

5543

ylim([param.specBER 1]);title ('CDF of ILN')

5137

hold on

5544

hold on

5138

end

5545

end

5139

if rms>rms_fom

5546

if rms>rms_fom

5140

rms_fom=rms;

5547

rms_fom=rms;

5141

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5548

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5142

RILN_TD_struct.PDF=pdf;

5549

RILN_TD_struct.PDF=pdf;

5143

end

5550

end

5144

end

5551

end

5145

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5552

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5146

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5553

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5147

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5554

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5148

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5555

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5149

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5556

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5150

if print_for_codereview % remove once all checked out

5557

if print_for_codereview % remove once all checked out

5151

figure(9000);set(gcf,'Tag','COM');

5558

figure(9000);set(gcf,'Tag','COM');

5152

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5559

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5153

hold on

5560

hold on

5154

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5561

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5155

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5562

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5156

yyaxis right

5563

yyaxis right

5157

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5564

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5158

hold off

5565

hold off

5159

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)

5566

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)

5160

figure(9002);set(gcf,'Tag','COM');

5567

figure(9002);set(gcf,'Tag','COM');

5161

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5568

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5162

hold on

5569

hold on

5163

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5570

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5164

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5571

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5165

grid on

5572

grid on

5166

legend('show')

5573

legend('show')

5167

end

5574

end

5168

end

5575

end

5169

function result=get_StepR(ir,param,cb_step,ZT)

5576

function result=get_StepR(ir,param,cb_step,ZT)

5170

%ir = impulse response

5577

%ir = impulse response

5171

%t_base=time array with equal time steps

5578

%t_base=time array with equal time steps

5172

%samp_UI = number of samples per UI for ir

5579

%samp_UI = number of samples per UI for ir

5173

% result.SBR

5580

% result.SBR

5174

% t for debug

5581

% t for debug

5175

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5582

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5176

5583

5177

if cb_step

5584

if cb_step

5178

Ag=1;

5585

Ag=1;

5179

dt=1/param.fb/param.samples_per_ui;

5586

dt=1/param.fb/param.samples_per_ui;

5180

edge_time=param.TR_TDR*1e-9;

5587

edge_time=param.TR_TDR*1e-9;

5181

fedge=1/edge_time;

5588

fedge=1/edge_time;

5182

tedge=0:dt:edge_time*2;

5589

tedge=0:dt:edge_time*2;

5183

%

5590

%

5184

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5591

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5185

drive_pulse=[edge ones(1,param.samples_per_ui)];

5592

drive_pulse=[edge ones(1,param.samples_per_ui)];

5186

%pulse=filter(UI_ones,1,ir);

5593

%pulse=filter(UI_ones,1,ir);

5187

5594

5188

pulse=filter(drive_pulse,1,ir);

5595

pulse=filter(drive_pulse,1,ir);

5189

else

5596

else

5190

pulse=cumsum(ir);

5597

pulse=cumsum(ir);

5191

end

5598

end

5192

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5599

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5193

result.ZSR=TDR_response;

5600

result.ZSR=TDR_response;

5194

result.pulse=pulse;

5601

result.pulse=pulse;

5195

5602

5196

5603

5197

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5604

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5198

% sdd is differential s-parameters structure (2 port assumed)

5605

% sdd is differential s-parameters structure (2 port assumed)

5199

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5606

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5200

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5607

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5201

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5608

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5202

% TDR_results.t starting at t=0

5609

% TDR_results.t starting at t=0

5203

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5610

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5204

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5611

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5205

% TDR_results.f frequency for filter and s parameters

5612

% TDR_results.f frequency for filter and s parameters

5206

% TDR_results.ptdr_RL reflection waveform from the pulse

5613

% TDR_results.ptdr_RL reflection waveform from the pulse

5207

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5614

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5208

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5615

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5209

% TDR_results.ERL reported effective return loss

5616

% TDR_results.ERL reported effective return loss

5210

%

5617

%

5211

db = @(x) 20*log10(abs(x));

5618

db = @(x) 20*log10(abs(x));

5212

rms =@(x) norm(x)/sqrt(length(x));

5619

rms =@(x) norm(x)/sqrt(length(x));

5213

if isfield(OP,'TDR_duration')

5620

if isfield(OP,'TDR_duration')

5214

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5621

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5215

else

5622

else

5216

TDR_duration=5;

5623

TDR_duration=5;

5217

end

5624

end

5218

if ~isfield(OP,'DISPLAY_WINDOW')

5625

if ~isfield(OP,'DISPLAY_WINDOW')

5219

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5626

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5220

end

5627

end

5221

f=sdd.Frequencies;

5628

f=sdd.Frequencies;

5222

TDR_results.f=f;

5629

TDR_results.f=f;

5223

% OP.Zt_adj=2;

5630

% OP.Zt_adj=2;

5224

if param.FLAG.S2P == 0

5631

if param.FLAG.S2P == 0

5225

5632

5226

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5633

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5227

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);

5634

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);

5228

5635

5229

if param.RL_sel==1, other_port=2;end

5636

if param.RL_sel==1, other_port=2;end

5230

if param.RL_sel==2, other_port=1;end

5637

if param.RL_sel==2, other_port=1;end

5231

for i = 1:length(sdd.Frequencies)

5638

for i = 1:length(sdd.Frequencies)

5232

if size(sdd.Parameters,2) ==1 % for s2p files

5639

if size(sdd.Parameters,2) ==1 % for s2p files

5233

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) );

5640

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) );

5234

else

5641

else

5235

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) );

5642

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) );

5236

end

5643

end

5237

end

5644

end

5238

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5645

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5239

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5646

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5240

% Z_t=ZT;

5647

% Z_t=ZT;

5241

% zref=sdd.Impedance/2;

5648

% zref=sdd.Impedance/2;

5242

% if Z_t > zref

5649

% if Z_t > zref

5243

% radjust= (zref-Z_t);

5650

% radjust= (zref-Z_t);

5244

% S11adjust= radjust./(radjust + 2*zref);

5651

% S11adjust= radjust./(radjust + 2*zref);

5245

% RL=RL +S11adjust;

5652

% RL=RL +S11adjust;

5246

% elseif Z_t < zref

5653

% elseif Z_t < zref

5247

% rpad=-Z_t*zref/(Z_t-zref);

5654

% rpad=-Z_t*zref/(Z_t-zref);

5248

% S11adjust=zref/(rpad*(zref/rpad + 2));

5655

% S11adjust=zref/(rpad*(zref/rpad + 2));

5249

% RL=RL + S11adjust;

5656

% RL=RL + S11adjust;

5250

% else

5657

% else

5251

% RL=RL;

5658

% RL=RL;

5252

% end

5659

% end

5253

else

5660

else

5254

for i = 1:length(sdd.Frequencies)

5661

for i = 1:length(sdd.Frequencies)

5255

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5662

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5256

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5663

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5257

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5664

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5258

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5665

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5259

end

5666

end

5260

end

5667

end

5261

5668

5262

% end

5669

% end

5263

RL=squeeze(RL);

5670

RL=squeeze(RL);

5264

f9=f/1e9;

5671

f9=f/1e9;

5265

tr=param.TR_TDR;

5672

tr=param.TR_TDR;

5266

TDR_results.delay=500e-12 ;

5673

TDR_results.delay=500e-12 ;

5267

% determine max time from thue

5674

% determine max time from thue

5268

% if sdd.NumPorts==1

5675

% if sdd.NumPorts==1

5269

% try

5676

% try

5270

% maxtime=OP.N*param.ui;

5677

% maxtime=OP.N*param.ui;

5271

% catch

5678

% catch

5272

% maxtime=2e-9;

5679

% maxtime=2e-9;

5273

% end

5680

% end

5274

% pix=1;

5681

% pix=1;

5275

% else

5682

% else

5276

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5683

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5277

% pix=find(fir4del==max(fir4del),1);

5684

% pix=find(fir4del==max(fir4del),1);

5278

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5685

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5279

% if maxtime > tu(end); maxtime=tu(end);end

5686

% if maxtime > tu(end); maxtime=tu(end);end

5280

% endS

5687

% endS

5281

5688

5282

try

5689

try

5283

maxtime=OP.N*param.ui;

5690

maxtime=OP.N*param.ui;

5284

catch

5691

catch

5285

maxtime=2e-9;

5692

maxtime=2e-9;

5286

end

5693

end

5287

if OP.N==0

5694

if OP.N==0

5288

if sdd.NumPorts==1

5695

if sdd.NumPorts==1

5289

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5696

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5290

else

5697

else

5291

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5698

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5292

pix=find(fir4del==max(fir4del),1);

5699

pix=find(fir4del==max(fir4del),1);

5293

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5700

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5294

if maxtime > tu(end); maxtime=tu(end);end

5701

if maxtime > tu(end); maxtime=tu(end);end

5295

end

5702

end

5296

end

5703

end

5297

5704

5298

5705

5299

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5706

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5300

% (makes gausian edge somewhat causal)

5707

% (makes gausian edge somewhat causal)

5301

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);

5708

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);

5302

if ~isfield(OP,'cb_Guassian')

5709

if ~isfield(OP,'cb_Guassian')

5303

Use_gaussian=1;

5710

Use_gaussian=1;

5304

else

5711

else

5305

Use_gaussian=OP.cb_Guassian;

5712

Use_gaussian=OP.cb_Guassian;

5306

end

5713

end

5307

if Use_gaussian

5714

if Use_gaussian

5308

if iscolumn(H_t), H_t=H_t.'; end

5715

if iscolumn(H_t), H_t=H_t.'; end

5309

RLf=RL(:).'.*H_t;

5716

RLf=RL(:).'.*H_t;

5310

else % add extra 3x tr delay for causality

5717

else % add extra 3x tr delay for causality

5311

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5718

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5312

end

5719

end

5313

5720

5314

%Bessesl-Thomson turned off here (3rd input=0)

5721

%Bessesl-Thomson turned off here (3rd input=0)

5315

OP.TDR_Bessel_Thomson=0;

5316

H_bt=Bessel_Thomson_Filter(param,f,OP.TDR_Bessel_Thomson);

5722

H_bt=Bessel_Thomson_Filter(param,f,0);

5317

5723

5318

if isfield(OP,'TDR_Butterworth')

5724

if isfield(OP,'TDR_Butterworth')

5319

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5725

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5320

else

5726

else

5321

H_bw=ones(1,length(f));

5727

H_bw=ones(1,length(f));

5322

end

5728

end

5323

5729

5324

5730

5325

if param.Tukey_Window ~= 0

5731

if param.Tukey_Window ~= 0

5326

H_tw= Tukey_Window(f,param);

5732

H_tw= Tukey_Window(f,param);

5327

else

5733

else

5328

H_tw=ones(1,length(f));

5734

H_tw=ones(1,length(f));

5329

end

5735

end

5330

5736

5331

5737

5332

if iscolumn(H_tw), H_tw=H_tw.';end

5738

if iscolumn(H_tw), H_tw=H_tw.';end

5333

if iscolumn(H_bt), H_bt=H_bt.';end

5739

if iscolumn(H_bt), H_bt=H_bt.';end

5334

if iscolumn(H_bw), H_bw=H_bw.';end

5740

if iscolumn(H_bw), H_bw=H_bw.';end

5335

if iscolumn(RLf), RLf=RLf.';end

5741

if iscolumn(RLf), RLf=RLf.';end

5336

5742

5337

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5743

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5338

RLf=RLf.*TDR_results.Rx_filter;

5744

RLf=RLf.*TDR_results.Rx_filter;

5339

TDR_results.tx_filter=H_t;

5745

TDR_results.tx_filter=H_t;

5340

5746

5341

5747

5342

[IR, t, causality_correction_dB, truncation_dB] = ...

5748

[IR, t, causality_correction_dB, truncation_dB] = ...

5343

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5749

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5344

5750

5345

5751

5346

%

5752

%

5347

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5753

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5348

tfx=param.tfx(np); % use fixture delay for port (np)

5754

tfx=param.tfx(np); % use fixture delay for port (np)

5349

5755

5350

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5756

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5351

5757

5352

t = t-TDR_results.delay;

5758

t = t-TDR_results.delay;

5353

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5759

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5354

if isempty(tend), tend=length(t); end

5760

if isempty(tend), tend=length(t); end

5355

IR=IR(1:tend);

5761

IR=IR(1:tend);

5356

t=t(1:tend);

5762

t=t(1:tend);

5357

if isempty(tend), tend=length(t); end

5763

if isempty(tend), tend=length(t); end

5358

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5764

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5359

if isempty(tstart), tstart=1;end

5765

if isempty(tstart), tstart=1;end

5360

if isempty(tend) || tstart >= tend

5766

if isempty(tend) || tstart >= tend

5361

if isempty(tend) || tstart >= tend

5767

if isempty(tend) || tstart >= tend

5362

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5768

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5363

end

5769

end

5364

tend=length(t);

5770

tend=length(t);

5365

tstart=1;

5771

tstart=1;

5366

end

5772

end

5367

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5773

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5368

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5774

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5369

TDR_results.tdr= ch.ZSR;

5775

TDR_results.tdr= ch.ZSR;

5370

TDR_results.t = t(tstart:tend);

5776

TDR_results.t = t(tstart:tend);

5371

5777

5372

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5778

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5373

if OP.TDR || OP.PTDR % determin average impededance with

5779

if OP.TDR || OP.PTDR % determin average impededance with

5374

try

5780

try

5375

tfstart=find(t>=3*tr*1e-9,1);

5781

tfstart=find(t>=3*tr*1e-9,1);

5376

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5782

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5377

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5783

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5378

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5784

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5379

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5785

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5380

catch

5786

catch

5381

TDR_results.avgZport=0;

5787

TDR_results.avgZport=0;

5382

fit=zeros(1,1);

5788

fit=zeros(1,1);

5383

p=[0 0 0 0 ];

5789

p=[0 0 0 0 ];

5384

end

5790

end

5385

TDR_results.RL=RL;

5791

TDR_results.RL=RL;

5386

end

5792

end

5387

if OP.PTDR

5793

if OP.PTDR

5388

% param.N_bx=param.ndfe;

5794

% param.N_bx=param.ndfe;

5389

RL_equiv=-inf;

5795

RL_equiv=-inf;

5390

L=param.levels;

5796

L=param.levels;

5391

BinSize=OP.BinSize;

5797

BinSize=OP.BinSize;

5392

% param.specBER=1e-5;

5798

% param.specBER=1e-5;

5393

if OP.DISPLAY_WINDOW

5799

if OP.DISPLAY_WINDOW

5394

hwaitbar=waitbar(0);

5800

hwaitbar=waitbar(0);

5395

else

5801

else

5396

fprintf('Worst ERL searching');

5802

fprintf('Worst ERL searching');

5397

end

5803

end

5398

% adjust PTDR for NDFE

5804

% adjust PTDR for NDFE

5399

% ---------------------- 2.7 code

5805

% ---------------------- 2.7 code

5400

% ntx=find(TDR_results.t >= tfx,1,'first');

5806

% ntx=find(TDR_results.t >= tfx,1,'first');

5401

% % gatestartt=TDR_results.t(ntx);

5807

% % gatestartt=TDR_results.t(ntx);

5402

% % gatestartV=PTDR.pulse(ntx);

5808

% % gatestartV=PTDR.pulse(ntx);

5403

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5809

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5404

% tk=param.ui*1*(param.N_bx+1)+tfx;

5810

% tk=param.ui*1*(param.N_bx+1)+tfx;

5405

% -------------------

5811

% -------------------

5406

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5812

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5407

% time filter.

5813

% time filter.

5408

% ntx=find(TDR_results.t >= tfx,1,'first');

5814

% ntx=find(TDR_results.t >= tfx,1,'first');

5409

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5815

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5410

% gatestartt=TDR_results.t(ntx);

5816

% gatestartt=TDR_results.t(ntx);

5411

% gatestartV=PTDR.pulse(ntx);

5817

% gatestartV=PTDR.pulse(ntx);

5412

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5818

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5413

% tk=param.ui*1*(param.N_bx+1)+tfx;

5819

% tk=param.ui*1*(param.N_bx+1)+tfx;

5414

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5820

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5415

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5821

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5416

% [ahealey] End of modifications.

5822

% [ahealey] End of modifications.

5417

if isempty(ndfex), ndfex=length(TDR_results.t); end

5823

if isempty(ndfex), ndfex=length(TDR_results.t); end

5418

PTDR.pulse_orig=PTDR.pulse;

5824

PTDR.pulse_orig=PTDR.pulse;

5419

5825

5420

switch param.Grr

5826

switch param.Grr

5421

case 0 % pre .3cd release

5827

case 0 % pre .3cd release

5422

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5828

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5423

case 1 % .3cd release

5829

case 1 % .3cd release

5424

fctrx(1:length(PTDR.pulse_orig))=1;

5830

fctrx(1:length(PTDR.pulse_orig))=1;

5425

case 2 % .3ck working

5831

case 2 % .3ck working

5426

fctrx(1:length(PTDR.pulse_orig))=1;

5832

fctrx(1:length(PTDR.pulse_orig))=1;

5427

end

5833

end

5428

Gloss(1:length(TDR_results.t))=1;

5834

Gloss(1:length(TDR_results.t))=1;

5429

Grr(1:length(TDR_results.t))=1;

5835

Grr(1:length(TDR_results.t))=1;

5430

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5836

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5431

5837

5432

for ii=ntx:ndfex

5838

for ii=ntx:ndfex

5433

% adjust for near end loss

5839

% adjust for near end loss

5434

if param.N_bx>0 && param.beta_x~=0;

5840

if param.N_bx>0 && param.beta_x~=0;

5435

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5841

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5436

else

5842

else

5437

Gloss(ii)=1;

5843

Gloss(ii)=1;

5438

end

5844

end

5439

% ---------------------- 2.7 code

5845

% ---------------------- 2.7 code

5440

% x=(TDR_results.t(ii)-tfx)/param.ui;

5846

% x=(TDR_results.t(ii)-tfx)/param.ui;

5441

% ----------------------

5847

% ----------------------

5442

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5848

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5443

% rise time filter.

5849

% rise time filter.

5444

% x=(TDR_results.t(ii)-tfx)/param.ui;

5850

% x=(TDR_results.t(ii)-tfx)/param.ui;

5445

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5851

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5446

% determine how much of the return loss to use base on expected

5852

% determine how much of the return loss to use base on expected

5447

% missing reflections

5853

% missing reflections

5448

switch param.Grr

5854

switch param.Grr

5449

case 0 % pre .3cd release

5855

case 0 % pre .3cd release

5450

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5856

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5451

case 1 % .3cd release

5857

case 1 % .3cd release

5452

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5858

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5453

case 2 % .3ck working

5859

case 2 % .3ck working

5454

Grr(ii)= param.rho_x ;

5860

Grr(ii)= param.rho_x ;

5455

end

5861

end

5456

fctrx(ii)=Gloss(ii).*Grr(ii);

5862

fctrx(ii)=Gloss(ii).*Grr(ii);

5457

end

5863

end

5458

5864

5459

if isrow(fctrx), fctrx=fctrx(:);end

5865

if isrow(fctrx), fctrx=fctrx(:);end

5460

PTDR.pulse=PTDR.pulse.*fctrx;

5866

PTDR.pulse=PTDR.pulse.*fctrx;

5461

if 0

5867

if 0

5462

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5868

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5463

s1=subplot(2,1,1);

5869

s1=subplot(2,1,1);

5464

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5870

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5465

hold on

5871

hold on

5466

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5872

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5467

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5873

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5468

grid on

5874

grid on

5469

ylim([ 0 1.2])

5875

ylim([ 0 1.2])

5470

s2=subplot(2,1,2);

5876

s2=subplot(2,1,2);

5471

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5877

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5472

grid on

5878

grid on

5473

linkaxes([s1,s2],'x')

5879

linkaxes([s1,s2],'x')

5474

xlabel 'UI'

5880

xlabel 'UI'

5475

xlim ([ 1 200])

5881

xlim ([ 1 200])

5476

end

5882

end

5477

5883

5478

FAST_NOISE_CONV=0;

5884

FAST_NOISE_CONV=0;

5479

ERLRMS=rms(PTDR.pulse);

5885

ERLRMS=rms(PTDR.pulse);

5480

for ki=1:param.samples_per_ui

5886

for ki=1:param.samples_per_ui

5481

progress = ki/param.samples_per_ui;

5887

progress = ki/param.samples_per_ui;

5482

if OP.DISPLAY_WINDOW

5888

if OP.DISPLAY_WINDOW

5483

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5889

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5484

else

5890

else

5485

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5891

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5486

end

5892

end

5487

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5893

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5488

if OP.RL_norm_test

5894

if OP.RL_norm_test

5489

rl_fom=(norm(tps));

5895

rl_fom=(norm(tps));

5490

else

5896

else

5491

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5897

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5492

cdf_test=cumsum(testpdf.y);

5898

cdf_test=cumsum(testpdf.y);

5493

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5899

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5494

rl_fom=rl_test;

5900

rl_fom=rl_test;

5495

end

5901

end

5496

if rl_fom > RL_equiv

5902

if rl_fom > RL_equiv

5497

RL_equiv=rl_fom;

5903

RL_equiv=rl_fom;

5498

best_ki=ki;

5904

best_ki=ki;

5499

end

5905

end

5500

if ~OP.RL_norm_test

5906

if ~OP.RL_norm_test

5501

best_erl=rl_test;

5907

best_erl=rl_test;

5502

best_pdf=testpdf;

5908

best_pdf=testpdf;

5503

best_cdf=cdf_test;

5909

best_cdf=cdf_test;

5504

end

5910

end

5505

5911

5506

end

5912

end

5507

if OP.RL_norm_test

5913

if OP.RL_norm_test

5508

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5914

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5509

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5915

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5510

cdf_test=cumsum(testpdf.y);

5916

cdf_test=cumsum(testpdf.y);

5511

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5917

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5512

end

5918

end

5513

5919

5514

fprintf('\n');

5920

fprintf('\n');

5515

try

5921

try

5516

close(hwaitbar)

5922

close(hwaitbar)

5517

catch

5923

catch

5518

end

5924

end

5519

if ~exist('best_ki','var'),best_ki=1;end

5925

if ~exist('best_ki','var'),best_ki=1;end

5520

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5926

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5521

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5927

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5522

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5928

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5523

TDR_results.ERL=-db(best_erl);

5929

TDR_results.ERL=-db(best_erl);

5524

TDR_results.ERLRMS=-db(ERLRMS);

5930

TDR_results.ERLRMS=-db(ERLRMS);

5525

5931

5526

end

5932

end

5527

5933

5528

5934

5529

% end get TDR

5935

% end get TDR

5530

%%

5936

%%

5531

5937

5532

5938

5533

5939

5534

5940

5535

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5941

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5536

% filename parsing and acquisition

5942

% filename parsing and acquisition

5537

%------------------------------------------------------------------

5943

%------------------------------------------------------------------

5538

%----------put files names into chdata structure ---------

5944

%----------put files names into chdata structure ---------

5539

% The thru file has the index of 1

5945

% The thru file has the index of 1

5540

% crosstalk file are indexed from 2

5946

% crosstalk file are indexed from 2

5541

% nxi is incremented each time a file is read in so that nxi will end

5947

% nxi is incremented each time a file is read in so that nxi will end

5542

filepath=[]; % path name for file

5948

filepath=[]; % path name for file

5543

nxi=0; % file index

5949

nxi=0; % file index

5544

% get the THRU file

5950

% get the THRU file

5545

if size(file_list,2) ~= 0

5951

if size(file_list,2) ~= 0

5546

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5952

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5547

[filepath, basename, fileext]=fileparts(file_list{1});

5953

[filepath, basename, fileext]=fileparts(file_list{1});

5548

5954

5549

else

5955

else

5550

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5956

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5551

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5957

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5552

movegui(h,'northeast')

5958

movegui(h,'northeast')

5553

end

5959

end

5554

dir=fullfile(filepath, '*.csv');

5960

dir=fullfile(filepath, '*.csv');

5555

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5961

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5556

if filepath == 0

5962

if filepath == 0

5557

error('No Thru file')

5963

error('No Thru file')

5558

end

5964

end

5559

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5965

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5560

end

5966

end

5561

nxi=nxi+1;

5967

nxi=nxi+1;

5562

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5968

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5563

chdata(nxi).ext = fileext;

5969

chdata(nxi).ext = fileext;

5564

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5970

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5565

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5971

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5566

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5972

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5567

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5973

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5568

chdata(nxi).type='THRU';

5974

chdata(nxi).type='THRU';

5569

chdata(nxi).ftr=param.fb*param.f_v;

5975

chdata(nxi).ftr=param.fb*param.f_v;

5570

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5976

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5571

5977

5572

% now get FEXT file names into chdata structure

5978

% now get FEXT file names into chdata structure

5573

kxi=nxi;

5979

kxi=nxi;

5574

for nxi=kxi+1:num_fext+kxi

5980

for nxi=kxi+1:num_fext+kxi

5575

lastfilepath=filepath;

5981

lastfilepath=filepath;

5576

if size(file_list,2) ~= 0

5982

if size(file_list,2) ~= 0

5577

[filepath, basename, fileext]=fileparts(file_list{nxi});

5983

[filepath, basename, fileext]=fileparts(file_list{nxi});

5578

else

5984

else

5579

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5985

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5580

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5986

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5581

movegui(h,'northeast')

5987

movegui(h,'northeast')

5582

end

5988

end

5583

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5989

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5584

dir=fullfile(filepath, '*.csv');

5990

dir=fullfile(filepath, '*.csv');

5585

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5991

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5586

if filepath==0

5992

if filepath==0

5587

error('Not enough NEXT files')

5993

error('Not enough NEXT files')

5588

end

5994

end

5589

else

5995

else

5590

dir=fullfile(filepath, '*.csv');

5996

dir=fullfile(filepath, '*.csv');

5591

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5997

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5592

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5998

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5593

else

5999

else

5594

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

6000

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5595

end

6001

end

5596

if filepath==0

6002

if filepath==0

5597

error('Not enough NEXT files')

6003

error('Not enough NEXT files')

5598

end

6004

end

5599

end

6005

end

5600

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6006

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5601

end

6007

end

5602

if isempty( filepath), filepath=lastfilepath; end

6008

if isempty( filepath), filepath=lastfilepath; end

5603

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6009

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5604

chdata(nxi).ext = fileext;

6010

chdata(nxi).ext = fileext;

5605

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6011

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5606

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6012

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5607

% chdata(nxi).A=param.a_fext;

6013

% chdata(nxi).A=param.a_fext;

5608

chdata(nxi).ftr=param.fb*param.f_f;

6014

chdata(nxi).ftr=param.fb*param.f_f;

5609

chdata(nxi).type='FEXT';

6015

chdata(nxi).type='FEXT';

5610

end

6016

end

5611

% now get NEXT file names into chdata structure

6017

% now get NEXT file names into chdata structure

5612

kxi=num_fext+kxi;

6018

kxi=num_fext+kxi;

5613

for nxi=kxi+1:num_next+kxi

6019

for nxi=kxi+1:num_next+kxi

5614

lastfilepath=filepath;

6020

lastfilepath=filepath;

5615

if size(file_list,2) ~= 0

6021

if size(file_list,2) ~= 0

5616

[filepath, basename, fileext]=fileparts(file_list{nxi});

6022

[filepath, basename, fileext]=fileparts(file_list{nxi});

5617

else

6023

else

5618

dir=fullfile(filepath, '*.csv');

6024

dir=fullfile(filepath, '*.csv');

5619

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

6025

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5620

if filepath==0

6026

if filepath==0

5621

error('Not enough NEXT files')

6027

error('Not enough NEXT files')

5622

end

6028

end

5623

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6029

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5624

end

6030

end

5625

if isempty( filepath), filepath=lastfilepath; end

6031

if isempty( filepath), filepath=lastfilepath; end

5626

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6032

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5627

chdata(nxi).ext = fileext;

6033

chdata(nxi).ext = fileext;

5628

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6034

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5629

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6035

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5630

% chdata(nxi).A=param.A_next;

6036

% chdata(nxi).A=param.A_next;

5631

chdata(nxi).ftr=param.fb*param.f_n;

6037

chdata(nxi).ftr=param.fb*param.f_n;

5632

chdata(nxi).type='NEXT';

6038

chdata(nxi).type='NEXT';

5633

end

6039

end

5634

function half_UI=get_center_of_UI(samples_per_UI)

6040

function half_UI=get_center_of_UI(samples_per_UI)

5635

6041

5636

%half_UI reveals which value to use for the center of the UI. For eye

6042

%half_UI reveals which value to use for the center of the UI. For eye

5637

%width calculations, it is necessary to place the cursor in the center of the

6043

%width calculations, it is necessary to place the cursor in the center of the

5638

%UI window to ensure a 0 crossing on both left/right inside the window.

6044

%UI window to ensure a 0 crossing on both left/right inside the window.

5639

%This function was written in order to support even and odd samples_per_UI

6045

%This function was written in order to support even and odd samples_per_UI

5640

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

6046

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

5641

6047

5642

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

6048

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

5643

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

6049

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

5644

%the center of the UI is sample closest to 0.5

6050

%the center of the UI is sample closest to 0.5

5645

[temp_diff,half_UI]=min(abs(UI_window-0.5));

6051

[temp_diff,half_UI]=min(abs(UI_window-0.5));

5646

function results= get_cm_noise(M,PR,L,BER,OP)

6052

function results= get_cm_noise(M,PR,L,BER,OP)

5647

6053

5648

if ~exist('OP')

6054

if ~exist('OP')

5649

OP.DC_norm_test=0;

6055

OP.DC_norm_test=0;

5650

OP.DISPLAY_WINDOW=1;

6056

OP.DISPLAY_WINDOW=1;

5651

end

6057

end

5652

param.BinSize=1e-5;

6058

param.BinSize=1e-5;

5653

PR_test=-inf;

6059

PR_test=-inf;

5654

PR_fom_best=-inf;

6060

PR_fom_best=-inf;

5655

% hwaitbar=waitbar(0);

6061

% hwaitbar=waitbar(0);

5656

for ki=1:M

6062

for ki=1:M

5657

progress = ki/M;

6063

progress = ki/M;

5658

% if OP.DISPLAY_WINDOW

6064

% if OP.DISPLAY_WINDOW

5659

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

6065

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

5660

% else

6066

% else

5661

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

6067

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5662

% end

6068

% end

5663

tps=PR(ki:M:end);

6069

tps=PR(ki:M:end);

5664

if OP.DC_norm_test

6070

if OP.DC_norm_test

5665

PR_fom=(norm(tps));

6071

PR_fom=(norm(tps));

5666

else

6072

else

5667

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

6073

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

5668

cdf_test=cumsum(testpdf.y);

6074

cdf_test=cumsum(testpdf.y);

5669

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

6075

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

5670

PR_fom=PRn_test;

6076

PR_fom=PRn_test;

5671

end

6077

end

5672

if PR_fom > PR_fom_best

6078

if PR_fom > PR_fom_best

5673

PR_fom_best=PR_fom;

6079

PR_fom_best=PR_fom;

5674

best_ki=ki;

6080

best_ki=ki;

5675

end

6081

end

5676

if ~OP.DC_norm_test

6082

if ~OP.DC_norm_test

5677

results.DCn=PR_fom_best;

6083

results.DCn=PR_fom_best;

5678

results.DCn_pdf=testpdf;

6084

results.DCn_pdf=testpdf;

5679

results.DCn_cdf=cdf_test;

6085

results.DCn_cdf=cdf_test;

5680

else

6086

else

5681

results.DCn=PR_fom_best;

6087

results.DCn=PR_fom_best;

5682

end

6088

end

5683

results.DCn_p2p=max(PR)-min(PR);

6089

results.DCn_p2p=max(PR)-min(PR);

5684

end

6090

end

5685

6091

5686

6092

5687

6093

5688

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

6094

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

5689

SBR=chdata.eq_pulse_response(:)'; % row vector

6095

SBR=chdata.eq_pulse_response(:)'; % row vector

5690

type=chdata.type;

6096

type=chdata.type;

5691

samp_UI=param.samples_per_ui;

6097

samp_UI=param.samples_per_ui;

5692

residual_response = SBR;

6098

residual_response = SBR;

5693

6099

5694

if isequal(type, 'THRU')

6100

if isequal(type, 'THRU')

5695

% for thru pulse response:

6101

% for thru pulse response:

5696

% remove the cursor and the DFE postcursors (up to their limit), since

6102

% remove the cursor and the DFE postcursors (up to their limit), since

5697

% we only care about the residuals.

6103

% we only care about the residuals.

5698

6104

5699

if ~param.Floating_DFE

6105

if ~param.Floating_DFE

5700

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

6106

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

5701

else

6107

else

5702

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

6108

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

5703

end

6109

end

5704

if param.dfe_delta ~= 0

6110

if param.dfe_delta ~= 0

5705

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);

6111

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);

5706

else

6112

else

5707

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

6113

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5708

end

6114

end

5709

6115

5710

%AJG021820

6116

%AJG021820

5711

if ~param.Floating_DFE

6117

if ~param.Floating_DFE

5712

bmax_vec=residual_response(t_s)*[1,param.bmax];

6118

bmax_vec=residual_response(t_s)*[1,param.bmax];

5713

bmin_vec=residual_response(t_s)*[1,param.bmin];

6119

bmin_vec=residual_response(t_s)*[1,param.bmin];

5714

else

6120

else

5715

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

6121

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

5716

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

6122

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

5717

end

6123

end

5718

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6124

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5719

6125

5720

6126

5721

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

6127

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

5722

dfetaps=effective_cancelled_cursors/SBR(t_s);

6128

dfetaps=effective_cancelled_cursors/SBR(t_s);

5723

6129

5724

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6130

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5725

% really needed for COM, but helps debugging. May be factored out in future revisions.

6131

% really needed for COM, but helps debugging. May be factored out in future revisions.

5726

start_cancel = t_s-param.samples_per_ui/2;

6132

start_cancel = t_s-param.samples_per_ui/2;

5727

if ~param.Floating_DFE

6133

if ~param.Floating_DFE

5728

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

6134

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

5729

else

6135

else

5730

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

6136

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

5731

end

6137

end

5732

residual_response(start_cancel:end_cancel) = ...

6138

residual_response(start_cancel:end_cancel) = ...

5733

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6139

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5734

%else

6140

%else

5735

% for crosstalk pulse responses, nothing is cancelled, and all phases

6141

% for crosstalk pulse responses, nothing is cancelled, and all phases

5736

% are equally important.

6142

% are equally important.

5737

end

6143

end

5738

6144

5739

nui=round(length(residual_response)/param.samples_per_ui);

6145

nui=round(length(residual_response)/param.samples_per_ui);

5740

6146

5741

vs=zeros(nui-2, param.samples_per_ui);

6147

vs=zeros(nui-2, param.samples_per_ui);

5742

for i=1:param.samples_per_ui

6148

for i=1:param.samples_per_ui

5743

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

6149

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

5744

end

6150

end

5745

6151

5746

if OP.DISPLAY_WINDOW,

6152

if OP.DISPLAY_WINDOW,

5747

hwaitbar=waitbar(0);

6153

hwaitbar=waitbar(0);

5748

end

6154

end

5749

6155

5750

% determine which pdf to use

6156

% determine which pdf to use

5751

if isequal(type, 'THRU')

6157

if isequal(type, 'THRU')

5752

% one phase is interesting for thru

6158

% one phase is interesting for thru

5753

phases = mod(t_s,param.samples_per_ui);

6159

phases = mod(t_s,param.samples_per_ui);

5754

if phases==0, phases = param.samples_per_ui; end

6160

if phases==0, phases = param.samples_per_ui; end

5755

else

6161

else

5756

phases=1:samp_UI;

6162

phases=1:samp_UI;

5757

end

6163

end

5758

6164

5759

mxV = zeros(size(phases));

6165

mxV = zeros(size(phases));

5760

% we already found the phase in the PSD process for MMSE

6166

% we already found the phase in the PSD process for MMSE

5761

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

6167

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

5762

if isequal(type, 'THRU')

6168

if isequal(type, 'THRU')

5763

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

6169

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

5764

else

6170

else

5765

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

6171

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

5766

end

6172

end

5767

else

6173

else

5768

for k=phases

6174

for k=phases

5769

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

6175

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

5770

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6176

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

5771

progress = k/length(phases);

6177

progress = k/length(phases);

5772

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6178

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

5773

end

6179

end

5774

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

6180

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

5775

pdf=pdf_samples(pxi);

6181

pdf=pdf_samples(pxi);

5776

end

6182

end

5777

6183

5778

6184

5779

6185

5780

if OP.DISPLAY_WINDOW

6186

if OP.DISPLAY_WINDOW

5781

close(hwaitbar);

6187

close(hwaitbar);

5782

end

6188

end

5783

6189

5784

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

6190

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

5785

% Create PDF from interference vector using successive delta-set convolutions.

6191

% Create PDF from interference vector using successive delta-set convolutions.

5786

% input_vector = list of values of samples

6192

% input_vector = list of values of samples

5787

% return

6193

% return

5788

% pdf.x

6194

% pdf.x

5789

% pdf.y

6195

% pdf.y

5790

% pdf.vec

6196

% pdf.vec

5791

% pdf.bin

6197

% pdf.bin

5792

if ~exist('FAST_NOISE_CONV','var')

6198

if ~exist('FAST_NOISE_CONV','var')

5793

FAST_NOISE_CONV=0;

6199

FAST_NOISE_CONV=0;

5794

end

6200

end

5795

if max(input_vector) > BinSize

6201

if max(input_vector) > BinSize

5796

input_vector=input_vector(abs(input_vector)>BinSize);

6202

input_vector=input_vector(abs(input_vector)>BinSize);

5797

end

6203

end

5798

% for i = 1:length(input_vector)

6204

% for i = 1:length(input_vector)

5799

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

6205

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

5800

%end

6206

%end

5801

6207

5802

input_vector(abs(input_vector)<BinSize) = 0;

6208

input_vector(abs(input_vector)<BinSize) = 0;

5803

b=sign(input_vector);

6209

b=sign(input_vector);

5804

[input_vector,index]=sort(abs(input_vector),'descend');

6210

[input_vector,index]=sort(abs(input_vector),'descend');

5805

input_vector=input_vector.*b(index);

6211

input_vector=input_vector.*b(index);

5806

if FAST_NOISE_CONV

6212

if FAST_NOISE_CONV

5807

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

6213

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

5808

res_pdf= normal_dist(sig_res,5,BinSize);

6214

res_pdf= normal_dist(sig_res,5,BinSize);

5809

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

6215

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

5810

end

6216

end

5811

%% Equation 93A-39 %%

6217

%% Equation 93A-39 %%

5812

values = 2*(0:L-1)/(L-1)-1;

6218

values = 2*(0:L-1)/(L-1)-1;

5813

prob = ones(1,L)/L;

6219

prob = ones(1,L)/L;

5814

6220

5815

%% Initialize pdf to delta at 0

6221

%% Initialize pdf to delta at 0

5816

pdf=d_cpdf(BinSize, 0, 1);

6222

pdf=d_cpdf(BinSize, 0, 1);

5817

empty_pdf=pdf;

6223

empty_pdf=pdf;

5818

for k = 1:length(input_vector)

6224

for k = 1:length(input_vector)

5819

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

6225

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

5820

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

6226

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

5821

pdf=conv_fct(pdf, pdfn);

6227

pdf=conv_fct(pdf, pdfn);

5822

end

6228

end

5823

if FAST_NOISE_CONV

6229

if FAST_NOISE_CONV

5824

% pdf=conv_fct(pdf,res_pdf);

6230

% pdf=conv_fct(pdf,res_pdf);

5825

pdf=conv_fct_TEST(pdf,res_pdf);

6231

pdf=conv_fct_TEST(pdf,res_pdf);

5826

end

6232

end

5827

6233

5828

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

6234

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

5829

t_s_orig=t_s;

6235

t_s_orig=t_s;

5830

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

6236

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

5831

type=chdata.type;

6237

type=chdata.type;

5832

6238

5833

pulse_orig=chdata.eq_pulse_response(:)';

6239

pulse_orig=chdata.eq_pulse_response(:)';

5834

%build arbitrary time axis with step size = 1/samples per ui

6240

%build arbitrary time axis with step size = 1/samples per ui

5835

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

6241

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

5836

%force t_s at time =0 (makes the other things below easy)

6242

%force t_s at time =0 (makes the other things below easy)

5837

original_sample_time=old_time(t_s_orig);

6243

original_sample_time=old_time(t_s_orig);

5838

old_time=old_time-original_sample_time;

6244

old_time=old_time-original_sample_time;

5839

%build new time axis that forces time=0 to be in the axis

6245

%build new time axis that forces time=0 to be in the axis

5840

%unless the new/old samples per UI are integer ratios, time 0 will not be

6246

%unless the new/old samples per UI are integer ratios, time 0 will not be

5841

%there by default

6247

%there by default

5842

samp_UI=param.samples_for_C2M;

6248

samp_UI=param.samples_for_C2M;

5843

new_timea=[0:-1/samp_UI:min(old_time)];

6249

new_timea=[0:-1/samp_UI:min(old_time)];

5844

new_timeb=[0:1/samp_UI:max(old_time)];

6250

new_timeb=[0:1/samp_UI:max(old_time)];

5845

new_time=[fliplr(new_timea) new_timeb(2:end)];

6251

new_time=[fliplr(new_timea) new_timeb(2:end)];

5846

SBR=interp1(old_time,pulse_orig,new_time);

6252

SBR=interp1(old_time,pulse_orig,new_time);

5847

%new sample time is simply the point where new_time = 0

6253

%new sample time is simply the point where new_time = 0

5848

[tmp,t_s]=min(abs(new_time));

6254

[tmp,t_s]=min(abs(new_time));

5849

6255

5850

residual_response = SBR;

6256

residual_response = SBR;

5851

6257

5852

half_UI=get_center_of_UI(samp_UI);

6258

half_UI=get_center_of_UI(samp_UI);

5853

6259

5854

if isequal(type, 'THRU')

6260

if isequal(type, 'THRU')

5855

% for thru pulse response:

6261

% for thru pulse response:

5856

% remove the cursor and the DFE postcursors (up to their limit), since

6262

% remove the cursor and the DFE postcursors (up to their limit), since

5857

% we only care about the residuals.

6263

% we only care about the residuals.

5858

6264

5859

%AJG021820

6265

%AJG021820

5860

if ~param.Floating_DFE

6266

if ~param.Floating_DFE

5861

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

6267

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

5862

else

6268

else

5863

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

6269

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

5864

end

6270

end

5865

if param.dfe_delta ~= 0

6271

if param.dfe_delta ~= 0

5866

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);

6272

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);

5867

else

6273

else

5868

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

6274

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5869

end

6275

end

5870

6276

5871

if ~param.Floating_DFE

6277

if ~param.Floating_DFE

5872

bmax_vec=residual_response(t_s)*[param.bmax];

6278

bmax_vec=residual_response(t_s)*[param.bmax];

5873

bmin_vec=residual_response(t_s)*[param.bmin];

6279

bmin_vec=residual_response(t_s)*[param.bmin];

5874

else

6280

else

5875

bmax_vec=residual_response(t_s)*[param.use_bmax];

6281

bmax_vec=residual_response(t_s)*[param.use_bmax];

5876

bmin_vec=residual_response(t_s)*[param.use_bmin];

6282

bmin_vec=residual_response(t_s)*[param.use_bmin];

5877

end

6283

end

5878

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6284

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5879

6285

5880

6286

5881

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

6287

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

5882

dfetaps=effective_cancelled_cursors/SBR(t_s);

6288

dfetaps=effective_cancelled_cursors/SBR(t_s);

5883

6289

5884

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6290

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5885

% really needed for COM, but helps debugging. May be factored out in future revisions.

6291

% really needed for COM, but helps debugging. May be factored out in future revisions.

5886

6292

5887

%avoid dividing samp_UI by 2 in case it is not even

6293

%avoid dividing samp_UI by 2 in case it is not even

5888

start_cancel=t_s-half_UI+1+samp_UI;

6294

start_cancel=t_s-half_UI+1+samp_UI;

5889

%AJG021820

6295

%AJG021820

5890

if ~param.Floating_DFE

6296

if ~param.Floating_DFE

5891

end_cancel=start_cancel+param.ndfe*samp_UI-1;

6297

end_cancel=start_cancel+param.ndfe*samp_UI-1;

5892

else

6298

else

5893

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

6299

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

5894

end

6300

end

5895

residual_response(start_cancel:end_cancel) = ...

6301

residual_response(start_cancel:end_cancel) = ...

5896

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6302

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5897

%else

6303

%else

5898

% for crosstalk pulse responses, nothing is cancelled, and all phases

6304

% for crosstalk pulse responses, nothing is cancelled, and all phases

5899

% are equally important.

6305

% are equally important.

5900

6306

5901

%remove entire cursor UI

6307

%remove entire cursor UI

5902

uiv_start=start_cancel-samp_UI;

6308

uiv_start=start_cancel-samp_UI;

5903

uiv_end=uiv_start+samp_UI-1;

6309

uiv_end=uiv_start+samp_UI-1;

5904

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

6310

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

5905

residual_response(uiv_start:uiv_end)=0;

6311

residual_response(uiv_start:uiv_end)=0;

5906

end

6312

end

5907

6313

5908

nui=round(length(residual_response)/samp_UI);

6314

nui=round(length(residual_response)/samp_UI);

5909

6315

5910

6316

5911

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6317

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5912

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

6318

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

5913

%response without DFE included. (Can't include DFE for jitter calc)

6319

%response without DFE included. (Can't include DFE for jitter calc)

5914

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6320

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5915

6321

5916

% if OP.DISPLAY_WINDOW,

6322

% if OP.DISPLAY_WINDOW,

5917

% hwaitbar=waitbar(0);

6323

% hwaitbar=waitbar(0);

5918

% end

6324

% end

5919

6325

5920

% determine which pdf to use

6326

% determine which pdf to use

5921

if isequal(type, 'THRU')

6327

if isequal(type, 'THRU')

5922

% one phase is interesting for thru

6328

% one phase is interesting for thru

5923

phases = mod(t_s,samp_UI);

6329

phases = mod(t_s,samp_UI);

5924

if phases==0, phases = samp_UI; end

6330

if phases==0, phases = samp_UI; end

5925

else

6331

else

5926

phases=1:samp_UI;

6332

phases=1:samp_UI;

5927

end

6333

end

5928

6334

5929

mxV = zeros(size(phases));

6335

mxV = zeros(size(phases));

5930

6336

5931

%phases reveals the raw position in the UI window of the cursor.

6337

%phases reveals the raw position in the UI window of the cursor.

5932

%shift_amount is the amount to shift so that it aligns with half_UI

6338

%shift_amount is the amount to shift so that it aligns with half_UI

5933

shift_amount=half_UI-phases;

6339

shift_amount=half_UI-phases;

5934

%vs_shift puts the cursor at the center

6340

%vs_shift puts the cursor at the center

5935

vs_shift=circshift(vs,[0 shift_amount]);

6341

vs_shift=circshift(vs,[0 shift_amount]);

5936

L=size(vs_raw,1);

6342

L=size(vs_raw,1);

5937

%allow partial UI computation through pdf_range

6343

%allow partial UI computation through pdf_range

5938

%if pdf_range is empty, do full UI

6344

%if pdf_range is empty, do full UI

5939

if isempty(pdf_range)

6345

if isempty(pdf_range)

5940

pdf_range=1:samp_UI;

6346

pdf_range=1:samp_UI;

5941

else

6347

else

5942

pdf_range=min(pdf_range):max(pdf_range);

6348

pdf_range=min(pdf_range):max(pdf_range);

5943

end

6349

end

5944

h_j_full=zeros(L,samp_UI);

6350

h_j_full=zeros(L,samp_UI);

5945

for k=pdf_range

6351

for k=pdf_range

5946

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6352

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

5947

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6353

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

5948

%progress = k/length(phases);

6354

%progress = k/length(phases);

5949

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6355

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

5950

6356

5951

%build the circshift of h_j_full into the loop to support a reduced

6357

%build the circshift of h_j_full into the loop to support a reduced

5952

%range of sampling points. circshift at the end only works if doing the

6358

%range of sampling points. circshift at the end only works if doing the

5953

%full range of sampling points. And shifting before the loop will

6359

%full range of sampling points. And shifting before the loop will

5954

%yield the wrong answer at the edges of the UI

6360

%yield the wrong answer at the edges of the UI

5955

hk=k-shift_amount;

6361

hk=k-shift_amount;

5956

if hk<1

6362

if hk<1

5957

hk=hk+samp_UI;

6363

hk=hk+samp_UI;

5958

elseif hk>samp_UI

6364

elseif hk>samp_UI

5959

hk=hk-samp_UI;

6365

hk=hk-samp_UI;

5960

end

6366

end

5961

if hk==1

6367

if hk==1

5962

%when hk=1, the early UI is the last column

6368

%when hk=1, the early UI is the last column

5963

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6369

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

5964

elseif hk==samp_UI

6370

elseif hk==samp_UI

5965

%when hk=samp_UI, the late UI is the first column

6371

%when hk=samp_UI, the late UI is the first column

5966

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6372

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

5967

else

6373

else

5968

%for all other cases, do the normal late=+1, early = -1

6374

%for all other cases, do the normal late=+1, early = -1

5969

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6375

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

5970

end

6376

end

5971

end

6377

end

5972

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6378

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

5973

% filename parsing and acquisition

6379

% filename parsing and acquisition

5974

%------------------------------------------------------------------

6380

%------------------------------------------------------------------

5975

%----------put files names into chdata structure ---------

6381

%----------put files names into chdata structure ---------

5976

% The thru file has the index of 1

6382

% The thru file has the index of 1

5977

% crosstalk file are indexed from 2

6383

% crosstalk file are indexed from 2

5978

% nxi is incremented each time a file is read in so that nxi will end

6384

% nxi is incremented each time a file is read in so that nxi will end

5979

filepath=[]; % path name for file

6385

filepath=[]; % path name for file

5980

nxi=0; % file index

6386

nxi=0; % file index

5981

% get the THRU file

6387

% get the THRU file

5982

if size(file_list,2) ~= 0

6388

if size(file_list,2) ~= 0

5983

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6389

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5984

[filepath, basename, fileext]=fileparts(file_list{1});

6390

[filepath, basename, fileext]=fileparts(file_list{1});

5985

6391

5986

else

6392

else

5987

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6393

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5988

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6394

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5989

movegui(h,'northeast')

6395

movegui(h,'northeast')

5990

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6396

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

5991

end

6397

end

5992

if OP.ERL == 2

6398

if OP.ERL == 2

5993

dir=fullfile(filepath, '*.s2p');

6399

dir=fullfile(filepath, '*.s2p');

5994

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6400

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

5995

if filepath == 0

6401

if filepath == 0

5996

error('No RL measurement file')

6402

error('No RL measurement file')

5997

end

6403

end

5998

else

6404

else

5999

dir=fullfile(filepath, '*.s4p');

6405

dir=fullfile(filepath, '*.s4p');

6000

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6406

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6001

if filepath == 0

6407

if filepath == 0

6002

error('No Thru file')

6408

error('No Thru file')

6003

end

6409

end

6004

end

6410

end

6005

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6411

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6006

end

6412

end

6007

nxi=nxi+1;

6413

nxi=nxi+1;

6008

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6414

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6009

chdata(nxi).ext = fileext;

6415

chdata(nxi).ext = fileext;

6010

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6416

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6011

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6417

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6012

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6418

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6013

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6419

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6014

chdata(nxi).type='THRU';

6420

chdata(nxi).type='THRU';

6015

chdata(nxi).ftr=param.fb*param.f_v;

6421

chdata(nxi).ftr=param.fb*param.f_v;

6016

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6422

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6017

6423

6018

% now get FEXT file names into chdata structure

6424

% now get FEXT file names into chdata structure

6019

kxi=nxi;

6425

kxi=nxi;

6020

for nxi=kxi+1:num_fext+kxi

6426

for nxi=kxi+1:num_fext+kxi

6021

lastfilepath=filepath;

6427

lastfilepath=filepath;

6022

if size(file_list,2) ~= 0

6428

if size(file_list,2) ~= 0

6023

[filepath, basename, fileext]=fileparts(file_list{nxi});

6429

[filepath, basename, fileext]=fileparts(file_list{nxi});

6024

else

6430

else

6025

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6431

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6026

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6432

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6027

movegui(h,'northeast')

6433

movegui(h,'northeast')

6028

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6434

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6029

end

6435

end

6030

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6436

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6031

dir=fullfile(filepath, '*.s4p');

6437

dir=fullfile(filepath, '*.s4p');

6032

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6438

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6033

if filepath==0

6439

if filepath==0

6034

error('Not enough NEXT files')

6440

error('Not enough NEXT files')

6035

end

6441

end

6036

else

6442

else

6037

dir=fullfile(filepath, '*.s4p');

6443

dir=fullfile(filepath, '*.s4p');

6038

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6444

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6039

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6445

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6040

else

6446

else

6041

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6447

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6042

end

6448

end

6043

if filepath==0

6449

if filepath==0

6044

error('Not enough NEXT files')

6450

error('Not enough NEXT files')

6045

end

6451

end

6046

end

6452

end

6047

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6453

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6048

end

6454

end

6049

if isempty( filepath), filepath=lastfilepath; end

6455

if isempty( filepath), filepath=lastfilepath; end

6050

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6456

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6051

chdata(nxi).ext = fileext;

6457

chdata(nxi).ext = fileext;

6052

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6458

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6053

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6459

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6054

% chdata(nxi).A=param.a_fext;

6460

% chdata(nxi).A=param.a_fext;

6055

chdata(nxi).ftr=param.fb*param.f_f;

6461

chdata(nxi).ftr=param.fb*param.f_f;

6056

chdata(nxi).type='FEXT';

6462

chdata(nxi).type='FEXT';

6057

end

6463

end

6058

% now get NEXT file names into chdata structure

6464

% now get NEXT file names into chdata structure

6059

kxi=num_fext+kxi;

6465

kxi=num_fext+kxi;

6060

for nxi=kxi+1:num_next+kxi

6466

for nxi=kxi+1:num_next+kxi

6061

lastfilepath=filepath;

6467

lastfilepath=filepath;

6062

if size(file_list,2) ~= 0

6468

if size(file_list,2) ~= 0

6063

[filepath, basename, fileext]=fileparts(file_list{nxi});

6469

[filepath, basename, fileext]=fileparts(file_list{nxi});

6064

else

6470

else

6065

dir=fullfile(filepath, '*.s4p');

6471

dir=fullfile(filepath, '*.s4p');

6066

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6472

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6067

if filepath==0

6473

if filepath==0

6068

error('Not enough NEXT files')

6474

error('Not enough NEXT files')

6069

end

6475

end

6070

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6476

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6071

end

6477

end

6072

if isempty( filepath), filepath=lastfilepath; end

6478

if isempty( filepath), filepath=lastfilepath; end

6073

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6479

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6074

chdata(nxi).ext = fileext;

6480

chdata(nxi).ext = fileext;

6075

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6481

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6076

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6482

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6077

% chdata(nxi).A=param.A_next;

6483

% chdata(nxi).A=param.A_next;

6078

chdata(nxi).ftr=param.fb*param.f_n;

6484

chdata(nxi).ftr=param.fb*param.f_n;

6079

chdata(nxi).type='NEXT';

6485

chdata(nxi).type='NEXT';

6080

end

6486

end

6081

6487

6082

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6488

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6083

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6489

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6084

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6490

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6085

% H_r - receiver filter, Butterworth

6491

% H_r - receiver filter, Butterworth

6086

% H_ctf - total gain of CTLE and low freq filtering

6492

% H_ctf - total gain of CTLE and low freq filtering

6087

% H_dc - the common mode channel gain

6493

% H_dc - the common mode channel gain

6088

% param.eta_0 -input referred Rx noise

6494

% param.eta_0 -input referred Rx noise

6089

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6495

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6090

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6496

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6091

%% Equation 93A-35 - independent of FFE setting %%

6497

%% Equation 93A-35 - independent of FFE setting %%

6092

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

6498

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

6093

if sum(param.AC_CM_RMS) ~= 0

6499

if sum(param.AC_CM_RMS) ~= 0

6094

sigma_ACCM=0;

6500

sigma_ACCM=0;

6095

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6501

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6096

for i=1:length(chdata)

6502

for i=1:length(chdata)

6097

H_dc=abs(squeeze(chdata(i).sdc21));

6503

H_dc=abs(squeeze(chdata(i).sdc21));

6098

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) );

6504

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) );

6099

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6505

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6100

end

6506

end

6101

sigma_N=norm([sigma_N1,sigma_ACCM]);

6507

sigma_N=norm([sigma_N1,sigma_ACCM]);

6102

else

6508

else

6103

sigma_N=sigma_N1;

6509

sigma_N=sigma_N1;

6104

end

6510

end

6105

%%

6511

%%

6106

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6512

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6107

% for Rx calibratrion only

6513

% for Rx calibratrion only

6108

% the FEXT channel for calibration basically a DC connection unlike normal

6514

% the FEXT channel for calibration basically a DC connection unlike normal

6109

% FEXT channels which are nearly open at DC channels

6515

% FEXT channels which are nearly open at DC channels

6110

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6516

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6111

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6517

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6112

if size(chdata,2) >= 2

6518

if size(chdata,2) >= 2

6113

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6519

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6114

else

6520

else

6115

Hnoise_channel=1;

6521

Hnoise_channel=1;

6116

end

6522

end

6117

f=chdata(2).faxis;

6523

f=chdata(2).faxis;

6118

f_hp=param.f_hp;

6524

f_hp=param.f_hp;

6119

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6525

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6120

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6526

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6121

else

6527

else

6122

H_hp=ones(1,length(f));

6528

H_hp=ones(1,length(f));

6123

end

6529

end

6124

%% Equation 93A-47 or 162-12

6530

%% Equation 93A-47 or 162-12

6125

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6531

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6126

6532

6127

%% Equation 93A-48 or 162-14%%

6533

%% Equation 93A-48 or 162-14%%

6128

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6534

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6129

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6535

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6130

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6536

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6131

% Modified not to double count crosstalk: John Ewen 13/12/2018

6537

% Modified not to double count crosstalk: John Ewen 13/12/2018

6132

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6538

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6133

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6539

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6134

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6540

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6135

f=chdata(1).faxis;

6541

f=chdata(1).faxis;

6136

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6542

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6137

if(f(1)==0)

6543

if(f(1)==0)

6138

temp_angle(1)=1e-20;% we don't want to divide by zero

6544

temp_angle(1)=1e-20;% we don't want to divide by zero

6139

end

6545

end

6140

PWF_tx=ones(1,length(f));

6546

PWF_tx=ones(1,length(f));

6141

if max(upsampled_txffe) > 0

6547

if max(upsampled_txffe) > 0

6142

PWF_tx=zeros(1,length(f));

6548

PWF_tx=zeros(1,length(f));

6143

[mcur,icur] = max(upsampled_txffe);

6549

[mcur,icur] = max(upsampled_txffe);

6144

if exist('phase_memory','var') && ~isempty(phase_memory)

6550

if exist('phase_memory','var') && ~isempty(phase_memory)

6145

pre_calc=1;

6551

pre_calc=1;

6146

else

6552

else

6147

pre_calc=0;

6553

pre_calc=0;

6148

end

6554

end

6149

for ii=1:length(upsampled_txffe)

6555

for ii=1:length(upsampled_txffe)

6150

if upsampled_txffe(ii)==0

6556

if upsampled_txffe(ii)==0

6151

%speed up: skip cases when txffe=0

6557

%speed up: skip cases when txffe=0

6152

continue;

6558

continue;

6153

end

6559

end

6154

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6560

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6155

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6561

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6156

% that is needed

6562

% that is needed

6157

if ii==icur

6563

if ii==icur

6158

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6564

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6159

PWF_tx = PWF_tx + upsampled_txffe(ii);

6565

PWF_tx = PWF_tx + upsampled_txffe(ii);

6160

else

6566

else

6161

if pre_calc

6567

if pre_calc

6162

%speed up: avoid vector exp calculation by externally pre-calculating it

6568

%speed up: avoid vector exp calculation by externally pre-calculating it

6163

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6569

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6164

else

6570

else

6165

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6571

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6166

end

6572

end

6167

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6573

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6168

PWF_tx = PWF_tx + transpose(term_ii(:));

6574

PWF_tx = PWF_tx + transpose(term_ii(:));

6169

end

6575

end

6170

% /Adee

6576

% /Adee

6171

end

6577

end

6172

end

6578

end

6173

PWF_rx=ones(1,length(f));

6579

PWF_rx=ones(1,length(f));

6174

if exist('C','var')

6580

if exist('C','var')

6175

PWF_rx=zeros(1,length(f));

6581

PWF_rx=zeros(1,length(f));

6176

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6582

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6177

if C(ii+param.RxFFE_cmx+1)==0

6583

if C(ii+param.RxFFE_cmx+1)==0

6178

%speed up: skip cases when rxffe=0

6584

%speed up: skip cases when rxffe=0

6179

continue;

6585

continue;

6180

end

6586

end

6181

if ii+1==0

6587

if ii+1==0

6182

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6588

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6183

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6589

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6184

else

6590

else

6185

if pre_calc

6591

if pre_calc

6186

%speed up: avoid vector exp calculation by externally pre-calculating it

6592

%speed up: avoid vector exp calculation by externally pre-calculating it

6187

%The latter columns of phase_memory hold RXFFE shift vectors

6593

%The latter columns of phase_memory hold RXFFE shift vectors

6188

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6594

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6189

term_ii=transpose(term_ii);

6595

term_ii=transpose(term_ii);

6190

else

6596

else

6191

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6597

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6192

end

6598

end

6193

PWF_rx=PWF_rx+term_ii;

6599

PWF_rx=PWF_rx+term_ii;

6194

end

6600

end

6195

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6601

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6196

end

6602

end

6197

end

6603

end

6198

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6604

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6199

for ii=2:size(chdata,2)

6605

for ii=2:size(chdata,2)

6200

SINC = sin(temp_angle)./temp_angle;

6606

SINC = sin(temp_angle)./temp_angle;

6201

PWF_data=SINC.^2;

6607

PWF_data=SINC.^2;

6202

PWF=PWF_data.*PWF_rx; % power weight function

6608

PWF=PWF_data.*PWF_rx; % power weight function

6203

PWFnext=abs(PWF);

6609

PWFnext=abs(PWF);

6204

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6610

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6205

PWFfext=abs(PWF);

6611

PWFfext=abs(PWF);

6206

if isequal(chdata(ii).type, 'FEXT')

6612

if isequal(chdata(ii).type, 'FEXT')

6207

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6613

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6208

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

6614

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

6209

elseif isequal(chdata(ii).type, 'NEXT')

6615

elseif isequal(chdata(ii).type, 'NEXT')

6210

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6616

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6211

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

6617

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

6212

end

6618

end

6213

end

6619

end

6214

if nargout == 1 && isequal(type,'NEXT')

6620

if nargout == 1 && isequal(type,'NEXT')

6215

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6621

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6216

elseif nargout == 1 && isequal(type,'FEXT')

6622

elseif nargout == 1 && isequal(type,'FEXT')

6217

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6623

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6218

elseif nargout == 3

6624

elseif nargout == 3

6219

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6625

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6220

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6626

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6221

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6627

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6222

end

6628

end

6223

6629

6224

function out=hrem(h,index,N_bf,bmaxg)

6630

function out=hrem(h,index,N_bf,bmaxg)

6225

6631

6226

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) ];

6632

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) ];

6227

% faster than single line function

6633

% faster than single line function

6228

% hrem =@(h,index,N_bf,bmaxg) ...

6634

% hrem =@(h,index,N_bf,bmaxg) ...

6229

% [ h(1:index-1) ...

6635

% [ h(1:index-1) ...

6230

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6636

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6231

% h(index+N_bf:end) ]...

6637

% h(index+N_bf:end) ]...

6232

% ;

6638

% ;

6233

6639

6234

%% floating DFE taps

6640

%% floating DFE taps

6235

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6641

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6236

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6642

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6237

% Sout = interp_Sparam(Sin,fin,fout)

6643

% Sout = interp_Sparam(Sin,fin,fout)

6238

%

6644

%

6239

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6645

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6240

% fout.

6646

% fout.

6241

6647

6242

if ( fin(end)<fout(end) )

6648

if ( fin(end)<fout(end) )

6243

% warning('Channel high frequencies extrapolation might be inaccurate!');

6649

% warning('Channel high frequencies extrapolation might be inaccurate!');

6244

end

6650

end

6245

6651

6246

H_mag = abs(Sin);

6652

H_mag = abs(Sin);

6247

H_mag(H_mag<eps)=eps; % handle ill cases...

6653

H_mag(H_mag<eps)=eps; % handle ill cases...

6248

H_ph = unwrap(angle(Sin));

6654

H_ph = unwrap(angle(Sin));

6249

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6655

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6250

% user ignore that.

6656

% user ignore that.

6251

if mean(diff(H_ph))>0

6657

if mean(diff(H_ph))>0

6252

if OP.DEBUG

6658

if OP.DEBUG

6253

warning('Anti-causal response found. Finer frequency step is required for this channel');

6659

warning('Anti-causal response found. Finer frequency step is required for this channel');

6254

else

6660

else

6255

error('Anti-causal response found. Finer frequency step is required for this channel');

6661

error('Anti-causal response found. Finer frequency step is required for this channel');

6256

end

6662

end

6257

end

6663

end

6258

6664

6259

%opt_interp_Sparam_mag='linear_trend_to_DC';

6665

%opt_interp_Sparam_mag='linear_trend_to_DC';

6260

switch opt_interp_Sparam_mag

6666

switch opt_interp_Sparam_mag

6261

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6667

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6262

if -iscolumn(H_mag), H_mag=H_mag.';end

6668

if -iscolumn(H_mag), H_mag=H_mag.';end

6263

if -iscolumn(fin), fin=fin.';end

6669

if -iscolumn(fin), fin=fin.';end

6264

fin_x=fin;

6670

fin_x=fin;

6265

H_mag_x=H_mag(:);

6671

H_mag_x=H_mag(:);

6266

if fin(1)>0

6672

if fin(1)>0

6267

p=polyfit(fin(1:10), H_mag(1:10), 1);

6673

p=polyfit(fin(1:10), H_mag(1:10), 1);

6268

dc_trend_val=polyval(p, 0);

6674

dc_trend_val=polyval(p, 0);

6269

fin_x=[0, fin_x];

6675

fin_x=[0, fin_x];

6270

H_mag_x = [dc_trend_val; H_mag_x];

6676

H_mag_x = [dc_trend_val; H_mag_x];

6271

end

6677

end

6272

if fin(end)<fout(end)

6678

if fin(end)<fout(end)

6273

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6679

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6274

mid_freq_ind=round(length(fin)/2);

6680

mid_freq_ind=round(length(fin)/2);

6275

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6681

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6276

warning(warn_state);

6682

warning(warn_state);

6277

hf_trend_val=polyval(p, fout(end));

6683

hf_trend_val=polyval(p, fout(end));

6278

if hf_trend_val>H_mag(end)

6684

if hf_trend_val>H_mag(end)

6279

hf_trend_val=H_mag(end);

6685

hf_trend_val=H_mag(end);

6280

hf_logtrend_val = H_mag(end);

6686

hf_logtrend_val = H_mag(end);

6281

elseif hf_trend_val<eps

6687

elseif hf_trend_val<eps

6282

hf_trend_val=eps;

6688

hf_trend_val=eps;

6283

hf_logtrend_val = realmin;

6689

hf_logtrend_val = realmin;

6284

end

6690

end

6285

fin_x=[fin_x, fout(end)];

6691

fin_x=[fin_x, fout(end)];

6286

H_mag_x = [H_mag_x; hf_trend_val];

6692

H_mag_x = [H_mag_x; hf_trend_val];

6287

end

6693

end

6288

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6694

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6289

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6695

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6290

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6696

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6291

indx = find(fout > fin(end),1,'first');

6697

indx = find(fout > fin(end),1,'first');

6292

H_mag_i(indx:end) = H_logmag_i(indx:end);

6698

H_mag_i(indx:end) = H_logmag_i(indx:end);

6293

end

6699

end

6294

case 'trend_to_DC'

6700

case 'trend_to_DC'

6295

% extrapolate to trend value at DC.

6701

% extrapolate to trend value at DC.

6296

if -iscolumn(H_mag), H_mag=H_mag.';end

6702

if -iscolumn(H_mag), H_mag=H_mag.';end

6297

if -iscolumn(fin), fin=fin.';end

6703

if -iscolumn(fin), fin=fin.';end

6298

fin_x=fin;

6704

fin_x=fin;

6299

H_mag_x=H_mag;

6705

H_mag_x=H_mag;

6300

if fin(1)>0

6706

if fin(1)>0

6301

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6707

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6302

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6708

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6303

dc_trend_val=10^polyval(p, 0);

6709

dc_trend_val=10^polyval(p, 0);

6304

fin_x=[0, fin_x];

6710

fin_x=[0, fin_x];

6305

H_mag_x = [dc_trend_val H_mag_x];

6711

H_mag_x = [dc_trend_val H_mag_x];

6306

end

6712

end

6307

if fin(end)<fout(end)

6713

if fin(end)<fout(end)

6308

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6714

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6309

mid_freq_ind=round(length(fin)/2);

6715

mid_freq_ind=round(length(fin)/2);

6310

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6716

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6311

warning(warn_state);

6717

warning(warn_state);

6312

hf_trend_val=10^polyval(p, fout(end));

6718

hf_trend_val=10^polyval(p, fout(end));

6313

if hf_trend_val>H_mag(end)

6719

if hf_trend_val>H_mag(end)

6314

hf_trend_val=H_mag(end);

6720

hf_trend_val=H_mag(end);

6315

end

6721

end

6316

fin_x=[fin_x, fout(end)];

6722

fin_x=[fin_x, fout(end)];

6317

H_mag_x = [H_mag_x hf_trend_val];

6723

H_mag_x = [H_mag_x hf_trend_val];

6318

end

6724

end

6319

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6725

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6320

case 'extrap_to_DC_or_zero'

6726

case 'extrap_to_DC_or_zero'

6321

% same as extrap_to_DC but detect AC-coupled channels and

6727

% same as extrap_to_DC but detect AC-coupled channels and

6322

% extrapolate them to 0.

6728

% extrapolate them to 0.

6323

if fin(1)>0 && 20*log10(H_mag(1))<-20

6729

if fin(1)>0 && 20*log10(H_mag(1))<-20

6324

% assume AC coupling, with 0 at DC

6730

% assume AC coupling, with 0 at DC

6325

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6731

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6326

else

6732

else

6327

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6733

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6328

end

6734

end

6329

H_mag_i(fout>fin(end)) = H_mag(end);

6735

H_mag_i(fout>fin(end)) = H_mag(end);

6330

case 'extrap_to_DC'

6736

case 'extrap_to_DC'

6331

% first extrapolate down to DC, then use highest available frequency

6737

% first extrapolate down to DC, then use highest available frequency

6332

% for higher frequencies

6738

% for higher frequencies

6333

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6739

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6334

H_mag_i(fout>fin(end)) = H_mag(end);

6740

H_mag_i(fout>fin(end)) = H_mag(end);

6335

case 'old'

6741

case 'old'

6336

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6742

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6337

otherwise

6743

otherwise

6338

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6744

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6339

end

6745

end

6340

6746

6341

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6747

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6342

6748

6343

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6749

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6344

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6750

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6345

switch opt_interp_Sparam_phase

6751

switch opt_interp_Sparam_phase

6346

case 'old'

6752

case 'old'

6347

H_ph_i = H_ph_i-H_ph_i(1);

6753

H_ph_i = H_ph_i-H_ph_i(1);

6348

case 'zero_DC'

6754

case 'zero_DC'

6349

H_ph_i(1) = 0;

6755

H_ph_i(1) = 0;

6350

case 'interp_to_DC'

6756

case 'interp_to_DC'

6351

if fin(1) ~= 0

6757

if fin(1) ~= 0

6352

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6758

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6353

end

6759

end

6354

case 'extrap_cubic_to_dc_linear_to_inf'

6760

case 'extrap_cubic_to_dc_linear_to_inf'

6355

if fin(1) ~= 0

6761

if fin(1) ~= 0

6356

% estimate low frequency group delay

6762

% estimate low frequency group delay

6357

group_delay = -diff(H_ph(:))./diff(fin(:));

6763

group_delay = -diff(H_ph(:))./diff(fin(:));

6358

low_freq_gd = group_delay(1:50);

6764

low_freq_gd = group_delay(1:50);

6359

% calculate trend, throwing away outliers

6765

% calculate trend, throwing away outliers

6360

m = median(low_freq_gd); sigma = std(low_freq_gd);

6766

m = median(low_freq_gd); sigma = std(low_freq_gd);

6361

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6767

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6362

% correct outliers in first 10 phase samples

6768

% correct outliers in first 10 phase samples

6363

for k=10:-1:1

6769

for k=10:-1:1

6364

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6770

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6365

end

6771

end

6366

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6772

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6367

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6773

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6368

% modification - trend to inf

6774

% modification - trend to inf

6369

if (1)

6775

if (1)

6370

high_freq_gd = group_delay(end-50:end);

6776

high_freq_gd = group_delay(end-50:end);

6371

% calculate trend, throwing away outliers

6777

% calculate trend, throwing away outliers

6372

m = median(high_freq_gd); sigma = std(high_freq_gd);

6778

m = median(high_freq_gd); sigma = std(high_freq_gd);

6373

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6779

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6374

hf_extrap_range = find(fout>fin(end));

6780

hf_extrap_range = find(fout>fin(end));

6375

last_data_sample = hf_extrap_range(1)-1;

6781

last_data_sample = hf_extrap_range(1)-1;

6376

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6782

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6377

% for k=hf_range

6783

% for k=hf_range

6378

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6784

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6379

% end

6785

% end

6380

end

6786

end

6381

6787

6382

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6788

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6383

H_ph_i=H_ph_cubic;

6789

H_ph_i=H_ph_cubic;

6384

H_ph_i(indx:end) = H_ph_linear(indx:end);

6790

H_ph_i(indx:end) = H_ph_linear(indx:end);

6385

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6791

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6386

end

6792

end

6387

case 'interp_and_shift_to_DC'

6793

case 'interp_and_shift_to_DC'

6388

if fin(1) ~= 0

6794

if fin(1) ~= 0

6389

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6795

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6390

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6796

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6391

end

6797

end

6392

case 'trend_and_shift_to_DC'

6798

case 'trend_and_shift_to_DC'

6393

% estimate low frequency group delay

6799

% estimate low frequency group delay

6394

group_delay = -diff(H_ph(:))./diff(fin(:));

6800

group_delay = -diff(H_ph(:))./diff(fin(:));

6395

low_freq_gd = group_delay(1:50);

6801

low_freq_gd = group_delay(1:50);

6396

% calculate trend, throwing away outliers

6802

% calculate trend, throwing away outliers

6397

m = median(low_freq_gd); sigma = std(low_freq_gd);

6803

m = median(low_freq_gd); sigma = std(low_freq_gd);

6398

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6804

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6399

fin_x=fin;

6805

fin_x=fin;

6400

H_ph_x=H_ph(:);

6806

H_ph_x=H_ph(:);

6401

if fin(1) ~= 0

6807

if fin(1) ~= 0

6402

% correct outliers in first 10 phase samples

6808

% correct outliers in first 10 phase samples

6403

for k=10:-1:1

6809

for k=10:-1:1

6404

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6810

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6405

end

6811

end

6406

6812

6407

% shift all phase data so that DC extrapolation to 0 follows trend

6813

% shift all phase data so that DC extrapolation to 0 follows trend

6408

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6814

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6409

fin_x=[0, fin_x];

6815

fin_x=[0, fin_x];

6410

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6816

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6411

end

6817

end

6412

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6818

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6413

% the last two samples, so noise can create an inverted slope and

6819

% the last two samples, so noise can create an inverted slope and

6414

% non-causal response).

6820

% non-causal response).

6415

if fout(end)>fin(end)

6821

if fout(end)>fin(end)

6416

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6822

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6417

% p=polyfit(fin_x', H_ph_x, 1);

6823

% p=polyfit(fin_x', H_ph_x, 1);

6418

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6824

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6419

% hf_phase_trend=polyval(p,max(fout));

6825

% hf_phase_trend=polyval(p,max(fout));

6420

fin_x=[fin_x, fout(end)];

6826

fin_x=[fin_x, fout(end)];

6421

H_ph_x=[H_ph_x; hf_phase_trend];

6827

H_ph_x=[H_ph_x; hf_phase_trend];

6422

end

6828

end

6423

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6829

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6424

6830

6425

otherwise

6831

otherwise

6426

error('COM:Extrap:InvalidOption', ...

6832

error('COM:Extrap:InvalidOption', ...

6427

'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"');

6833

'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"');

6428

end

6834

end

6429

H_i = H_mag_i.*exp(1j*H_ph_i);

6835

H_i = H_mag_i.*exp(1j*H_ph_i);

6430

Sout=H_i;

6836

Sout=H_i;

6431

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6837

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6432

6838

6433

%This function makes the TX or RX package. The type input must be

6839

%This function makes the TX or RX package. The type input must be

6434

%'TX' or 'RX'

6840

%'TX' or 'RX'

6435

%If the mode argument is omitted, mode='dd' is assumed. Currently

6841

%If the mode argument is omitted, mode='dd' is assumed. Currently

6436

%mode='dc' is only used when making the TX package for AC CM noise

6842

%mode='dc' is only used when making the TX package for AC CM noise

6437

%inclusion. The Rx package for 'dc' mode is still generated using

6843

%inclusion. The Rx package for 'dc' mode is still generated using

6438

%the same parameters as 'dd' mode

6844

%the same parameters as 'dd' mode

6439

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6845

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6440

%

6846

%

6441

%One instance of package block looks like this (if no elements are set to 0):

6847

%One instance of package block looks like this (if no elements are set to 0):

6442

%-------------Lcomp----------Tline---------------

6848

%-------------Lcomp----------Tline---------------

6443

% | | |

6849

% | | |

6444

% Cpad Cbump Cball

6850

% Cpad Cbump Cball

6445

% | | |

6851

% | | |

6446

%------------------------------------------------

6852

%------------------------------------------------

6447

6853

6448

if nargin<6

6854

if nargin<6

6449

%optional input "include_die"=0 allows die parameters to be forced to 0

6855

%optional input "include_die"=0 allows die parameters to be forced to 0

6450

%this includes Cpad, Lcomp, and Cbump

6856

%this includes Cpad, Lcomp, and Cbump

6451

include_die=1;

6857

include_die=1;

6452

end

6858

end

6453

if nargin<5

6859

if nargin<5

6454

mode='dd';

6860

mode='dd';

6455

end

6861

end

6456

6862

6457

6863

6458

if ~isempty(param.PKG_NAME)

6864

if ~isempty(param.PKG_NAME)

6459

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6865

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6460

%so they are swapped in depending on if Tx or Rx is set for type

6866

%so they are swapped in depending on if Tx or Rx is set for type

6461

%Note that param is not returned from this function, so the swap does not persist

6867

%Note that param is not returned from this function, so the swap does not persist

6462

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6868

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6463

if strcmpi(type,'tx')

6869

if strcmpi(type,'tx')

6464

pkg_name = param.PKG_NAME{1};

6870

pkg_name = param.PKG_NAME{1};

6465

elseif strcmpi(type,'rx')

6871

elseif strcmpi(type,'rx')

6466

pkg_name = param.PKG_NAME{2};

6872

pkg_name = param.PKG_NAME{2};

6467

else

6873

else

6468

error('Pkg type must be Tx or Rx');

6874

error('Pkg type must be Tx or Rx');

6469

end

6875

end

6470

pkg_parameter_struct = param.PKG.(pkg_name);

6876

pkg_parameter_struct = param.PKG.(pkg_name);

6471

6877

6472

6878

6473

for j=1:length(swap_fields)

6879

for j=1:length(swap_fields)

6474

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6880

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6475

end

6881

end

6476

6882

6477

end

6883

end

6478

6884

6479

C_diepad = param.C_diepad;

6885

C_diepad = param.C_diepad;

6480

C_pkg_board = param.C_pkg_board;

6886

C_pkg_board = param.C_pkg_board;

6481

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6887

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6482

L_comp = param.L_comp;

6888

L_comp = param.L_comp;

6483

C_bump = param.C_bump;

6889

C_bump = param.C_bump;

6484

if ~include_die

6890

if ~include_die

6485

%best to multiply by 0. that way vectors maintain original size

6891

%best to multiply by 0. that way vectors maintain original size

6486

C_diepad=C_diepad*0;

6892

C_diepad=C_diepad*0;

6487

L_comp=L_comp*0;

6893

L_comp=L_comp*0;

6488

C_bump=C_bump*0;

6894

C_bump=C_bump*0;

6489

end

6895

end

6490

% [ahealey] End of modifications.

6896

% [ahealey] End of modifications.

6491

% generate TX package according to channel type.

6897

% generate TX package according to channel type.

6492

[ncases, mele]=size(param.z_p_next_cases);

6898

[ncases, mele]=size(param.z_p_next_cases);

6493

6899

6494

%Syntax update for C_diepad and L_comp

6900

%Syntax update for C_diepad and L_comp

6495

%Allow a chain of values to be entered as a matrix:

6901

%Allow a chain of values to be entered as a matrix:

6496

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6902

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6497

if isvector(C_diepad)

6903

if isvector(C_diepad)

6498

Cd_Tx=C_diepad(1);

6904

Cd_Tx=C_diepad(1);

6499

Cd_Rx=C_diepad(2);

6905

Cd_Rx=C_diepad(2);

6500

L_comp_Tx=L_comp(1);

6906

L_comp_Tx=L_comp(1);

6501

L_comp_Rx=L_comp(2);

6907

L_comp_Rx=L_comp(2);

6502

num_blocks=mele;

6908

num_blocks=mele;

6503

else

6909

else

6504

Cd_Tx=C_diepad(1,:);

6910

Cd_Tx=C_diepad(1,:);

6505

Cd_Rx=C_diepad(2,:);

6911

Cd_Rx=C_diepad(2,:);

6506

L_comp_Tx=L_comp(1,:);

6912

L_comp_Tx=L_comp(1,:);

6507

L_comp_Rx=L_comp(2,:);

6913

L_comp_Rx=L_comp(2,:);

6508

num_blocks=mele+length(Cd_Tx)-1;

6914

num_blocks=mele+length(Cd_Tx)-1;

6509

end

6915

end

6510

extra_LC=length(Cd_Tx)-1;

6916

extra_LC=length(Cd_Tx)-1;

6511

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6917

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6512

insert_zeros=zeros([1 extra_LC]);

6918

insert_zeros=zeros([1 extra_LC]);

6513

6919

6514

%Updated technique of building Tx/Rx packages

6920

%Updated technique of building Tx/Rx packages

6515

%each index corresponds to the package segment

6921

%each index corresponds to the package segment

6516

switch type

6922

switch type

6517

case 'TX'

6923

case 'TX'

6518

switch mele

6924

switch mele

6519

case 1

6925

case 1

6520

Cpad=Cd_Tx;

6926

Cpad=Cd_Tx;

6521

Lcomp=L_comp_Tx;

6927

Lcomp=L_comp_Tx;

6522

Cbump=C_bump(1);

6928

Cbump=C_bump(1);

6523

Cball=C_pkg_board(1);

6929

Cball=C_pkg_board(1);

6524

Zpkg=param.pkg_Z_c(1);

6930

Zpkg=param.pkg_Z_c(1);

6525

case 4

6931

case 4

6526

Cpad=[Cd_Tx 0 0 0];

6932

Cpad=[Cd_Tx 0 0 0];

6527

Lcomp=[L_comp_Tx 0 0 0];

6933

Lcomp=[L_comp_Tx 0 0 0];

6528

Cbump=[C_bump(1) 0 0 0];

6934

Cbump=[C_bump(1) 0 0 0];

6529

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6935

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6530

Zpkg=param.pkg_Z_c(1,:);

6936

Zpkg=param.pkg_Z_c(1,:);

6531

otherwise

6937

otherwise

6532

error('package syntax error')

6938

error('package syntax error')

6533

end

6939

end

6534

switch upper(channel_type)

6940

switch upper(channel_type)

6535

case 'THRU'

6941

case 'THRU'

6536

Len=param.Pkg_len_TX;

6942

Len=param.Pkg_len_TX;

6537

case 'NEXT'

6943

case 'NEXT'

6538

Len=param.Pkg_len_NEXT;

6944

Len=param.Pkg_len_NEXT;

6539

case 'FEXT'

6945

case 'FEXT'

6540

Len=param.Pkg_len_FEXT;

6946

Len=param.Pkg_len_FEXT;

6541

end

6947

end

6542

case 'RX'

6948

case 'RX'

6543

switch mele

6949

switch mele

6544

case 1

6950

case 1

6545

Cpad=Cd_Rx;

6951

Cpad=Cd_Rx;

6546

Lcomp=L_comp_Rx;

6952

Lcomp=L_comp_Rx;

6547

Cbump=C_bump(2);

6953

Cbump=C_bump(2);

6548

Cball=C_pkg_board(2);

6954

Cball=C_pkg_board(2);

6549

Zpkg=param.pkg_Z_c(2);

6955

Zpkg=param.pkg_Z_c(2);

6550

case 4

6956

case 4

6551

Cpad=[Cd_Rx 0 0 0];

6957

Cpad=[Cd_Rx 0 0 0];

6552

Lcomp=[L_comp_Rx 0 0 0];

6958

Lcomp=[L_comp_Rx 0 0 0];

6553

Cbump=[C_bump(2) 0 0 0];

6959

Cbump=[C_bump(2) 0 0 0];

6554

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6960

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6555

Zpkg=param.pkg_Z_c(2,:);

6961

Zpkg=param.pkg_Z_c(2,:);

6556

otherwise

6962

otherwise

6557

error('package syntax error')

6963

error('package syntax error')

6558

end

6964

end

6559

switch upper(channel_type)

6965

switch upper(channel_type)

6560

case 'THRU'

6966

case 'THRU'

6561

Len=param.Pkg_len_RX;

6967

Len=param.Pkg_len_RX;

6562

case 'NEXT'

6968

case 'NEXT'

6563

Len=param.Pkg_len_RX;

6969

Len=param.Pkg_len_RX;

6564

case 'FEXT'

6970

case 'FEXT'

6565

Len=param.Pkg_len_RX;

6971

Len=param.Pkg_len_RX;

6566

end

6972

end

6567

end

6973

end

6568

6974

6569

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6975

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6570

Cball=[insert_zeros Cball];

6976

Cball=[insert_zeros Cball];

6571

Cbump=[insert_zeros Cbump];

6977

Cbump=[insert_zeros Cbump];

6572

Len=[insert_zeros Len];

6978

Len=[insert_zeros Len];

6573

Zpkg=[insert_zeros Zpkg];

6979

Zpkg=[insert_zeros Zpkg];

6574

6980

6575

% debug_string='';

6981

% debug_string='';

6576

% for j=1:length(Zpkg)

6982

% for j=1:length(Zpkg)

6577

% if Cpad(j)~=0

6983

% if Cpad(j)~=0

6578

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6984

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6579

% end

6985

% end

6580

% if Lcomp(j)~=0

6986

% if Lcomp(j)~=0

6581

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6987

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6582

% end

6988

% end

6583

% if Cbump(j)~=0

6989

% if Cbump(j)~=0

6584

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6990

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6585

% end

6991

% end

6586

% if Len(j)~=0

6992

% if Len(j)~=0

6587

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6993

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6588

% end

6994

% end

6589

% if Cball(j)~=0

6995

% if Cball(j)~=0

6590

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6996

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6591

% end

6997

% end

6592

% end

6998

% end

6593

% if length(debug_string)>2

6999

% if length(debug_string)>2

6594

% debug_string=debug_string(3:end);

7000

% debug_string=debug_string(3:end);

6595

% end

7001

% end

6596

7002

6597

% tx package

7003

% tx package

6598

pkg_param=param;

7004

pkg_param=param;

6599

if strcmpi(mode,'dc')

7005

if strcmpi(mode,'dc')

6600

% change tx package to CC mode

7006

% change tx package to CC mode

6601

pkg_param.Z0=pkg_param.Z0/2;

7007

pkg_param.Z0=pkg_param.Z0/2;

6602

Cpad=Cpad*2;

7008

Cpad=Cpad*2;

6603

Cball=Cball*2;

7009

Cball=Cball*2;

6604

Zpkg=Zpkg*2;

7010

Zpkg=Zpkg*2;

6605

Lcomp=Lcomp/2;

7011

Lcomp=Lcomp/2;

6606

Cbump=Cbump*2;

7012

Cbump=Cbump*2;

6607

end

7013

end

6608

switch num_blocks

7014

switch num_blocks

6609

case 1

7015

case 1

6610

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

7016

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6611

otherwise

7017

otherwise

6612

for j=1:num_blocks

7018

for j=1:num_blocks

6613

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

7019

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6614

if j==1

7020

if j==1

6615

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

7021

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6616

else

7022

else

6617

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

7023

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6618

end

7024

end

6619

end

7025

end

6620

end

7026

end

6621

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

7027

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6622

f(f<eps)=eps;

7028

f(f<eps)=eps;

6623

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

7029

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6624

%% Equation 93A-8

7030

%% Equation 93A-8

6625

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

7031

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6626

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

7032

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6627

7033

6628

% [ahealey] Add compensating L and shunt C (bump) when requested.

7034

% [ahealey] Add compensating L and shunt C (bump) when requested.

6629

s12pad = s21pad;

7035

s12pad = s21pad;

6630

s22pad = s11pad;

7036

s22pad = s11pad;

6631

if nargin > 6

7037

if nargin > 6

6632

lcomp = varargin{1};

7038

lcomp = varargin{1};

6633

if lcomp>0

7039

if lcomp>0

6634

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

7040

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6635

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

7041

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6636

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

7042

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6637

s11pad, s12pad, s21pad, s22pad, ...

7043

s11pad, s12pad, s21pad, s22pad, ...

6638

s11comp, s21comp, s21comp, s11comp);

7044

s11comp, s21comp, s21comp, s11comp);

6639

end

7045

end

6640

end

7046

end

6641

if nargin > 7

7047

if nargin > 7

6642

cbump = varargin{2};

7048

cbump = varargin{2};

6643

if cbump>0

7049

if cbump>0

6644

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

7050

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

6645

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

7051

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

6646

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

7052

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6647

s11pad, s12pad, s21pad, s22pad, ...

7053

s11pad, s12pad, s21pad, s22pad, ...

6648

s11bump, s21bump, s21bump, s11bump);

7054

s11bump, s21bump, s21bump, s11bump);

6649

end

7055

end

6650

end

7056

end

6651

% [ahealey] End of modifications.

7057

% [ahealey] End of modifications.

6652

7058

6653

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

7059

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

6654

% [ahealey] Symmetry cannot be assumed with more complex termination models.

7060

% [ahealey] Symmetry cannot be assumed with more complex termination models.

6655

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

7061

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

6656

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

7062

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

6657

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

7063

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

6658

s11pad, s12pad, s21pad, s22pad, ...

7064

s11pad, s12pad, s21pad, s22pad, ...

6659

S11, S21, S21, S11);

7065

S11, S21, S21, S11);

6660

% [ahealey] End of modifications.

7066

% [ahealey] End of modifications.

6661

7067

6662

%% Equation 93A-8

7068

%% Equation 93A-8

6663

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

7069

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

6664

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

7070

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

6665

[ s11out, s12out, s21out, s22out ]= ...

7071

[ s11out, s12out, s21out, s22out ]= ...

6666

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

7072

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

6667

7073

6668

function missingParameter (parameterName)

7074

function missingParameter (parameterName)

6669

error( 'error:badParameterInformation', ...

7075

error( 'error:badParameterInformation', ...

6670

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

7076

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

6671

7077

6672

function pdf = normal_dist(sigma,nsigma,binsize)

7078

function pdf = normal_dist(sigma,nsigma,binsize)

6673

pdf.BinSize=binsize;

7079

pdf.BinSize=binsize;

6674

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

7080

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

6675

pdf.x=(pdf.Min:-pdf.Min)*binsize;

7081

pdf.x=(pdf.Min:-pdf.Min)*binsize;

6676

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

7082

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

6677

pdf.y=pdf.y/sum(pdf.y);

7083

pdf.y=pdf.y/sum(pdf.y);

6678

7084

6679

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

7085

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

6680

%% input

7086

%% input

6681

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

7087

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

6682

% baud_rate - baud rate in seconds

7088

% baud_rate - baud rate in seconds

6683

% param.samples_per_ui = samples per UI of IR

7089

% param.samples_per_ui = samples per UI of IR

6684

% param.max_ctle - maximum ac to dc gain in dB

7090

% param.max_ctle - maximum ac to dc gain in dB

6685

% param.tx_ffe(1) - maximum pre cursor (positive value)

7091

% param.tx_ffe(1) - maximum pre cursor (positive value)

6686

% param.tx_ffe(2) - maximum post cursor (positive value)

7092

% param.tx_ffe(2) - maximum post cursor (positive value)

6687

% param.tx_ffe_step - sweep step size for tx pre and post taps

7093

% param.tx_ffe_step - sweep step size for tx pre and post taps

6688

% param.ndfe - number of reference dfe taps

7094

% param.ndfe - number of reference dfe taps

6689

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

7095

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

6690

% output

7096

% output

6691

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

7097

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

6692

% result.eq.ctle - index of CTLE parameters in table

7098

% result.eq.ctle - index of CTLE parameters in table

6693

% result.IR - impulse response

7099

% result.IR - impulse response

6694

% result.avail_signal - maximum signal after equalization

7100

% result.avail_signal - maximum signal after equalization

6695

% result.avail_sig_index - index in result.IR of max signal

7101

% result.avail_sig_index - index in result.IR of max signal

6696

% result.best_FOM - best raw ISI

7102

% result.best_FOM - best raw ISI

6697

7103

6698

min_number_of_UI_in_response=40;

7104

min_number_of_UI_in_response=40;

6699

baud_rate=1/param.ui;

7105

baud_rate=1/param.ui;

6700

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

7106

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

6701

f=chdata(1).faxis;

7107

f=chdata(1).faxis;

6702

7108

6703

%Read user input of ts_sample_adj_range

7109

%Read user input of ts_sample_adj_range

6704

%if one value was entered, go from 0 to that value

7110

%if one value was entered, go from 0 to that value

6705

%if 2 values were entered, go from the 1st value to the 2nd value

7111

%if 2 values were entered, go from the 1st value to the 2nd value

6706

if length(param.ts_sample_adj_range)==1

7112

if length(param.ts_sample_adj_range)==1

6707

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

7113

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

6708

param.ts_sample_adj_range(1)=0;

7114

param.ts_sample_adj_range(1)=0;

6709

end

7115

end

6710

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

7116

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

6711

7117

6712

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

7118

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

6713

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

7119

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

6714

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7120

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

6715

% need to include H_RCos in noise and when computing the system ir for thru

7121

% need to include H_RCos in noise and when computing the system ir for thru

6716

% and crosstalk

7122

% and crosstalk

6717

H_r=H_bw.*H_bt.*H_RCos;

7123

H_r=H_bw.*H_bt.*H_RCos;

6718

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

7124

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

6719

% Get f vector from 0 to Fs/2-delta_f.

7125

% Get f vector from 0 to Fs/2-delta_f.

6720

N_fft_by2 = 512;

7126

N_fft_by2 = 512;

6721

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

7127

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

6722

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

7128

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

6723

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

7129

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

6724

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

7130

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

6725

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

7131

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

6726

%%

7132

%%

6727

7133

6728

% system noise H_sy PSD

7134

% system noise H_sy PSD

6729

if OP.USE_ETA0_PSD

7135

if OP.USE_ETA0_PSD

6730

fspike=1e9;

7136

fspike=1e9;

6731

% requires communication tool box if used

7137

% requires communication tool box if used

6732

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

7138

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

6733

else

7139

else

6734

H_sy=ones(1,length(chdata(1).faxis));

7140

H_sy=ones(1,length(chdata(1).faxis));

6735

end

7141

end

6736

7142

6737

%Build txffe values dynamically

7143

%Build txffe values dynamically

6738

%any param field that is "tx_ffe_cm<X>_values" is a precursor

7144

%any param field that is "tx_ffe_cm<X>_values" is a precursor

6739

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

7145

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

6740

%where <X> is any integer

7146

%where <X> is any integer

6741

param_fields=fieldnames(param);

7147

param_fields=fieldnames(param);

6742

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

7148

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

6743

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

7149

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

6744

num_taps=num_pre+num_post;

7150

num_taps=num_pre+num_post;

6745

cur=num_pre+1;

7151

cur=num_pre+1;

6746

%txffe_cell combines all the txffe values into a single cell array

7152

%txffe_cell combines all the txffe values into a single cell array

6747

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

7153

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

6748

txffe_cell=cell(1,num_taps);

7154

txffe_cell=cell(1,num_taps);

6749

for k=num_pre:-1:1

7155

for k=num_pre:-1:1

6750

idx=num_pre-k+1;

7156

idx=num_pre-k+1;

6751

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

7157

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

6752

txffe_cell{idx}=param.(this_tx_field);

7158

txffe_cell{idx}=param.(this_tx_field);

6753

end

7159

end

6754

for k=1:num_post

7160

for k=1:num_post

6755

idx=k+num_pre;

7161

idx=k+num_pre;

6756

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

7162

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

6757

txffe_cell{idx}=param.(this_tx_field);

7163

txffe_cell{idx}=param.(this_tx_field);

6758

end

7164

end

6759

%total number of txffe runs is the product of the lengths of each tap

7165

%total number of txffe runs is the product of the lengths of each tap

6760

txffe_lengths=cellfun('length',txffe_cell);

7166

txffe_lengths=cellfun('length',txffe_cell);

6761

if isempty(txffe_cell)

7167

if isempty(txffe_cell)

6762

num_txffe_runs=1;

7168

num_txffe_runs=1;

6763

else

7169

else

6764

num_txffe_runs=prod(txffe_lengths);

7170

num_txffe_runs=prod(txffe_lengths);

6765

end

7171

end

6766

%txffe_sweep_indices are used in the LOCAL_SEARCH block

7172

%txffe_sweep_indices are used in the LOCAL_SEARCH block

6767

%any tap with length=1 can be ignored

7173

%any tap with length=1 can be ignored

6768

%Also is statistically likely that taps with greater number of values

7174

%Also is statistically likely that taps with greater number of values

6769

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

7175

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

6770

txffe_sweep_indices=find(txffe_lengths>1);

7176

txffe_sweep_indices=find(txffe_lengths>1);

6771

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

7177

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

6772

txffe_sweep_indices=txffe_sweep_indices(length_sort);

7178

txffe_sweep_indices=txffe_sweep_indices(length_sort);

6773

num_txffe_sweep_indices=length(txffe_sweep_indices);

7179

num_txffe_sweep_indices=length(txffe_sweep_indices);

6774

7180

6775

gdc_values = param.ctle_gdc_values;

7181

gdc_values = param.ctle_gdc_values;

6776

Gffe_values = param.cursor_gain;

7182

Gffe_values = param.cursor_gain;

6777

switch param.CTLE_type

7183

switch param.CTLE_type

6778

case 'CL93'

7184

case 'CL93'

6779

case 'CL120d'

7185

case 'CL120d'

6780

g_DC_HP_values =param.g_DC_HP_values;

7186

g_DC_HP_values =param.g_DC_HP_values;

6781

case 'CL120e'

7187

case 'CL120e'

6782

f_HP_Z=param.f_HP_Z;

7188

f_HP_Z=param.f_HP_Z;

6783

f_HP_P=param.f_HP_P;

7189

f_HP_P=param.f_HP_P;

6784

7190

6785

end

7191

end

6786

best_ctle = [];

7192

best_ctle = [];

6787

best_FOM = -inf;

7193

best_FOM = -inf;

6788

best_txffe = [];

7194

best_txffe = [];

6789

delta_sbr = [];

7195

delta_sbr = [];

6790

PSD_results=[];

7196

PSD_results=[];

6791

MMSE_results=[];

7197

MMSE_results=[];

6792

best_bmax=param.bmax;

7198

best_bmax=param.bmax;

6793

%AJG021820

7199

%AJG021820

6794

best_bmin=param.bmin;

7200

best_bmin=param.bmin;

6795

h_J=[];

7201

h_J=[];

6796

pxi=0;

7202

pxi=0;

6797

if OP.DISPLAY_WINDOW

7203

if OP.DISPLAY_WINDOW

6798

hwaitbar=waitbar(0);

7204

hwaitbar=waitbar(0);

6799

else

7205

else

6800

fprintf('FOM search ');

7206

fprintf('FOM search ');

6801

end

7207

end

6802

FOM=0;

7208

FOM=0;

6803

if ~OP.RxFFE

7209

if ~OP.RxFFE

6804

Gffe_values=0;

7210

Gffe_values=0;

6805

end

7211

end

6806

param.ndfe_passed=param.ndfe;

7212

param.ndfe_passed=param.ndfe;

6807

old_loops=0;

7213

old_loops=0;

6808

new_loops=0;

7214

new_loops=0;

6809

7215

6810

%GDC Qual construction

7216

%GDC Qual construction

6811

gqual= param.gqual;

7217

gqual= param.gqual;

6812

g2qual=param.g2qual;

7218

g2qual=param.g2qual;

6813

if ~strcmp(param.CTLE_type,'CL120d')

7219

if ~strcmp(param.CTLE_type,'CL120d')

6814

qual=ones(1,length(gdc_values));

7220

qual=ones(1,length(gdc_values));

6815

else

7221

else

6816

if isempty(gqual) && isempty(g2qual)

7222

if isempty(gqual) && isempty(g2qual)

6817

qual=ones(length(g_DC_HP_values),length(gdc_values));

7223

qual=ones(length(g_DC_HP_values),length(gdc_values));

6818

else

7224

else

6819

qual=zeros(length(g_DC_HP_values),length(gdc_values));

7225

qual=zeros(length(g_DC_HP_values),length(gdc_values));

6820

7226

6821

%prepare gqual and g2qual

7227

%prepare gqual and g2qual

6822

[g2qual,si]=sort(g2qual,'descend');

7228

[g2qual,si]=sort(g2qual,'descend');

6823

gqual=gqual(si,:);

7229

gqual=gqual(si,:);

6824

tmp=g2qual;

7230

tmp=g2qual;

6825

g2qual=zeros(length(tmp),2);

7231

g2qual=zeros(length(tmp),2);

6826

for kk=1:length(tmp)

7232

for kk=1:length(tmp)

6827

if kk==1

7233

if kk==1

6828

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

7234

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

6829

else

7235

else

6830

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

7236

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

6831

end

7237

end

6832

gqual(kk,:)=sort(gqual(kk,:),'descend');

7238

gqual(kk,:)=sort(gqual(kk,:),'descend');

6833

end

7239

end

6834

7240

6835

%Qual Construction

7241

%Qual Construction

6836

for jj=1:length(g_DC_HP_values)

7242

for jj=1:length(g_DC_HP_values)

6837

for ii=1:length(gdc_values)

7243

for ii=1:length(gdc_values)

6838

for kk=1:size(gqual,1)

7244

for kk=1:size(gqual,1)

6839

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

7245

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

6840

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

7246

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

6841

qual(jj,ii)=1;

7247

qual(jj,ii)=1;

6842

break;

7248

break;

6843

end

7249

end

6844

end

7250

end

6845

end

7251

end

6846

end

7252

end

6847

end

7253

end

6848

end

7254

end

6849

end

7255

end

6850

7256

6851

progress_interval=0.025;

7257

progress_interval=0.025;

6852

if do_C2M

7258

if do_C2M

6853

loop_count=[1 2];

7259

loop_count=[1 2];

6854

T_O=floor((param.T_O/1000)*param.samples_per_ui);

7260

T_O=floor((param.T_O/1000)*param.samples_per_ui);

6855

T_O=max(0,T_O);

7261

T_O=max(0,T_O);

6856

else

7262

else

6857

loop_count=1;

7263

loop_count=1;

6858

T_O=0;

7264

T_O=0;

6859

end

7265

end

6860

switch param.CTLE_type

7266

switch param.CTLE_type

6861

case 'CL93'

7267

case 'CL93'

6862

lf_indx=1;

7268

lf_indx=1;

6863

case 'CL120d'

7269

case 'CL120d'

6864

lf_indx=length(g_DC_HP_values);

7270

lf_indx=length(g_DC_HP_values);

6865

case 'CL120e'

7271

case 'CL120e'

6866

lf_indx=1;

7272

lf_indx=1;

6867

end

7273

end

6868

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

7274

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

6869

if OP.Optimize_loop_speed_up == 1

7275

if OP.Optimize_loop_speed_up == 1

6870

OP.BinSize = 1e-4;

7276

OP.BinSize = 1e-4;

6871

OP.impulse_response_truncation_threshold = 1e-3;

7277

OP.impulse_response_truncation_threshold = 1e-3;

6872

end

7278

end

6873

7279

6874

%Used to speed up FFE by only performing circshift when necessary

7280

%Used to speed up FFE by only performing circshift when necessary

6875

pulse_struc(1).pulse_ctle_circshift=[];

7281

pulse_struc(1).pulse_ctle_circshift=[];

6876

ctle_response_updated=1;

7282

ctle_response_updated=1;

6877

7283

6878

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

7284

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

6879

calc_exp_phase=0;

7285

calc_exp_phase=0;

6880

7286

6881

%calculate cur index and pre/post indices outside of the loop

7287

%calculate cur index and pre/post indices outside of the loop

6882

cur_start=cur;

7288

cur_start=cur;

6883

precursor_indices=[];

7289

precursor_indices=[];

6884

postcursor_indices=[];

7290

postcursor_indices=[];

6885

auto_count_trigger=0;

7291

auto_count_trigger=0;

6886

for kv=1:num_taps

7292

for kv=1:num_taps

6887

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

7293

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

6888

%precursor values fill the beginning of the vector. Any empty precursor means

7294

%precursor values fill the beginning of the vector. Any empty precursor means

6889

%cursor position must be subtracted by 1

7295

%cursor position must be subtracted by 1

6890

if kv<cur_start

7296

if kv<cur_start

6891

cur=cur-1;

7297

cur=cur-1;

6892

end

7298

end

6893

else

7299

else

6894

%non empty value: add to precursor or postcursor indices depending on position

7300

%non empty value: add to precursor or postcursor indices depending on position

6895

%in the vector

7301

%in the vector

6896

if kv<cur_start

7302

if kv<cur_start

6897

auto_count_trigger=1;

7303

auto_count_trigger=1;

6898

precursor_indices=[precursor_indices kv];

7304

precursor_indices=[precursor_indices kv];

6899

else

7305

else

6900

auto_count_trigger=0;

7306

auto_count_trigger=0;

6901

postcursor_indices=[postcursor_indices kv];

7307

postcursor_indices=[postcursor_indices kv];

6902

end

7308

end

6903

end

7309

end

6904

end

7310

end

6905

if ~isempty(postcursor_indices)

7311

if ~isempty(postcursor_indices)

6906

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

7312

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

6907

end

7313

end

6908

7314

6909

%Calculate the full grid matrix of all txffe combinations

7315

%Calculate the full grid matrix of all txffe combinations

6910

if isempty(txffe_cell)

7316

if isempty(txffe_cell)

6911

TXFFE_grid=0;

7317

TXFFE_grid=0;

6912

FULL_tx_index_vector=1;

7318

FULL_tx_index_vector=1;

6913

else

7319

else

6914

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

7320

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

6915

%Also calculate the full grid matrix for the index used in each txffe combination

7321

%Also calculate the full grid matrix for the index used in each txffe combination

6916

%(the index is used in the LOCAL SEARCH block)

7322

%(the index is used in the LOCAL SEARCH block)

6917

for k=1:num_taps

7323

for k=1:num_taps

6918

txffe_index_cell{k}=1:txffe_lengths(k);

7324

txffe_index_cell{k}=1:txffe_lengths(k);

6919

end

7325

end

6920

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

7326

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

6921

end

7327

end

6922

7328

6923

%pre-calculate cursor to save time

7329

%pre-calculate cursor to save time

6924

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

7330

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

6925

7331

6926

%pre-calculate full txffe for each iteration to save time

7332

%pre-calculate full txffe for each iteration to save time

6927

precursor_matrix=TXFFE_grid(:,precursor_indices);

7333

precursor_matrix=TXFFE_grid(:,precursor_indices);

6928

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7334

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

6929

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7335

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

6930

7336

6931

if OP.TDMODE

7337

if OP.TDMODE

6932

uneq_field='uneq_pulse_response';

7338

uneq_field='uneq_pulse_response';

6933

ctle_field='ctle_pulse_response';

7339

ctle_field='ctle_pulse_response';

6934

else

7340

else

6935

uneq_field='uneq_imp_response';

7341

uneq_field='uneq_imp_response';

6936

ctle_field='ctle_imp_response';

7342

ctle_field='ctle_imp_response';

6937

end

7343

end

6938

7344

6939

%Speed up search for max(sbr)

7345

%Speed up search for max(sbr)

6940

if OP.TDMODE

7346

if OP.TDMODE

6941

[~,init_max]=max(chdata(1).uneq_pulse_response);

7347

[~,init_max]=max(chdata(1).uneq_pulse_response);

6942

else

7348

else

6943

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7349

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

6944

end

7350

end

6945

UI_max_window=20;

7351

UI_max_window=20;

6946

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7352

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

6947

if start_max_idx<1

7353

if start_max_idx<1

6948

start_max_idx=1;

7354

start_max_idx=1;

6949

end

7355

end

6950

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7356

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

6951

if end_max_idx>length(chdata(1).(uneq_field))

7357

if end_max_idx>length(chdata(1).(uneq_field))

6952

end_max_idx=length(chdata(1).(uneq_field));

7358

end_max_idx=length(chdata(1).(uneq_field));

6953

end

7359

end

6954

7360

6955

itick_skips=0;

7361

itick_skips=0;

6956

itick_cases=0;

7362

itick_cases=0;

6957

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7363

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

6958

for i=loop_count

7364

for i=loop_count

6959

7365

6960

for Gffe_index=1:length(Gffe_values)

7366

for Gffe_index=1:length(Gffe_values)

6961

param.current_ffegain=Gffe_values(Gffe_index);

7367

param.current_ffegain=Gffe_values(Gffe_index);

6962

for ctle_index=1:length(gdc_values)

7368

for ctle_index=1:length(gdc_values)

6963

g_dc = gdc_values(ctle_index);

7369

g_dc = gdc_values(ctle_index);

6964

kacdc = 10^(g_dc/20);

7370

kacdc = 10^(g_dc/20);

6965

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7371

CTLE_fp1 = param.CTLE_fp1(ctle_index);

6966

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7372

CTLE_fp2 = param.CTLE_fp2(ctle_index);

6967

CTLE_fz = param.CTLE_fz(ctle_index);

7373

CTLE_fz = param.CTLE_fz(ctle_index);

6968

switch param.CTLE_type

7374

switch param.CTLE_type

6969

case 'CL93'

7375

case 'CL93'

6970

%

7376

%

6971

case 'CL120d'

7377

case 'CL120d'

6972

%

7378

%

6973

case 'CL120e'

7379

case 'CL120e'

6974

HP_Z = param.f_HP_Z(ctle_index);

7380

HP_Z = param.f_HP_Z(ctle_index);

6975

HP_P = param.f_HP_P(ctle_index);

7381

HP_P = param.f_HP_P(ctle_index);

6976

end

7382

end

6977

%% HF Boost

7383

%% HF Boost

6978

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7384

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

6979

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7385

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

6980

%% Mid Frequency Boost

7386

%% Mid Frequency Boost

6981

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7387

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

6982

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7388

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

6983

for g_LP_index=1:lf_indx

7389

for g_LP_index=1:lf_indx

6984

7390

6985

%GDC Qual Check

7391

%GDC Qual Check

6986

if qual(g_LP_index,ctle_index)==0

7392

if qual(g_LP_index,ctle_index)==0

6987

pxi=pxi+num_txffe_runs;

7393

pxi=pxi+num_txffe_runs;

6988

continue;

7394

continue;

6989

end

7395

end

6990

7396

6991

switch param.CTLE_type

7397

switch param.CTLE_type

6992

case 'CL93'

7398

case 'CL93'

6993

H_low=1;

7399

H_low=1;

6994

kacde_DC_low=1;

7400

kacde_DC_low=1;

6995

case 'CL120d'

7401

case 'CL120d'

6996

g_DC_low = g_DC_HP_values(g_LP_index);

7402

g_DC_low = g_DC_HP_values(g_LP_index);

6997

f_HP=param.f_HP(g_LP_index);

7403

f_HP=param.f_HP(g_LP_index);

6998

kacde_DC_low = 10^(g_DC_low/20);

7404

kacde_DC_low = 10^(g_DC_low/20);

6999

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7405

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7000

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7406

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7001

case 'CL120e' % z1 has been adusted on read in

7407

case 'CL120e' % z1 has been adusted on read in

7002

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7408

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7003

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7409

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7004

end

7410

end

7005

H_ctf=H_low.*ctle_gain;

7411

H_ctf=H_low.*ctle_gain;

7006

switch upper(OP.FFE_OPT_METHOD)

7412

switch upper(OP.FFE_OPT_METHOD)

7007

case 'WIENER-HOPF'

7413

case 'WIENER-HOPF'

7008

%% Bill Kirkland

7414

%% Bill Kirkland

7009

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7415

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7010

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7416

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7011

% use Fourier Transform pair for correlation as we have to

7417

% use Fourier Transform pair for correlation as we have to

7012

% take ifft of H_r anyways.

7418

% take ifft of H_r anyways.

7013

% onesided and two sided responses - tricky, tricky, tricky

7419

% onesided and two sided responses - tricky, tricky, tricky

7014

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7420

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7015

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7421

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7016

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7422

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7017

7423

7018

if OP.Do_White_Noise

7424

if OP.Do_White_Noise

7019

Noise_XC = Noise_XC(1);

7425

Noise_XC = Noise_XC(1);

7020

end

7426

end

7021

otherwise

7427

otherwise

7022

Noise_XC=[];

7428

Noise_XC=[];

7023

end

7429

end

7024

7430

7025

7431

7026

7432

7027

if OP.INCLUDE_CTLE==1

7433

if OP.INCLUDE_CTLE==1

7028

for k=1:param.num_s4p_files

7434

for k=1:param.num_s4p_files

7029

ir_peak = max(abs(chdata(k).(uneq_field)));

7435

ir_peak = max(abs(chdata(k).(uneq_field)));

7030

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7436

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7031

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7437

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7032

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7438

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7033

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7439

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7034

switch param.CTLE_type

7440

switch param.CTLE_type

7035

case 'CL93'

7441

case 'CL93'

7036

case 'CL120d'

7442

case 'CL120d'

7037

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7443

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7038

case 'CL120e' % z1 has been adusted on read in

7444

case 'CL120e' % z1 has been adusted on read in

7039

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7445

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7040

end

7446

end

7041

end

7447

end

7042

%set the flag to show ctle response was updated

7448

%set the flag to show ctle response was updated

7043

ctle_response_updated=1;

7449

ctle_response_updated=1;

7044

else

7450

else

7045

for k=1:param.num_s4p_files

7451

for k=1:param.num_s4p_files

7046

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7452

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7047

end

7453

end

7048

end

7454

end

7049

for k=1:param.num_s4p_files

7455

for k=1:param.num_s4p_files

7050

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7456

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7051

end

7457

end

7052

%% Equation 93A-22 %%

7458

%% Equation 93A-22 %%

7053

% figure(1000)

7459

% figure(1000)

7054

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7460

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7055

% hold on

7461

% hold on

7056

if OP.RX_CALIBRATION

7462

if OP.RX_CALIBRATION

7057

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7463

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7058

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7464

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7059

switch param.CTLE_type

7465

switch param.CTLE_type

7060

case 'CL93'

7466

case 'CL93'

7061

H_low2=1;

7467

H_low2=1;

7062

case 'CL120d'

7468

case 'CL120d'

7063

g_DC_low = g_DC_HP_values(g_LP_index);

7469

g_DC_low = g_DC_HP_values(g_LP_index);

7064

f_HP=param.f_HP(g_LP_index);

7470

f_HP=param.f_HP(g_LP_index);

7065

kacde_DC_low = 10^(g_DC_low/20);

7471

kacde_DC_low = 10^(g_DC_low/20);

7066

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7472

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7067

case 'CL120e' % z1 has been adusted on read in

7473

case 'CL120e' % z1 has been adusted on read in

7068

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7474

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7069

end

7475

end

7070

H_ctf2=H_low2.*ctle_gain2;

7476

H_ctf2=H_low2.*ctle_gain2;

7071

end

7477

end

7072

% RIM 11-30-2020 moved to a subfunction

7478

% RIM 11-30-2020 moved to a subfunction

7073

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7479

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7074

if OP.RX_CALIBRATION

7480

if OP.RX_CALIBRATION

7075

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7481

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7076

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

7482

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

7077

else

7483

else

7078

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7484

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7079

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7485

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7080

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7486

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7081

sigma_ne=0;

7487

sigma_ne=0;

7082

end

7488

end

7083

7489

7084

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7490

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7085

pxi=pxi+num_txffe_runs;

7491

pxi=pxi+num_txffe_runs;

7086

continue; % change per 0.3k draft 2.3

7492

continue; % change per 0.3k draft 2.3

7087

end

7493

end

7088

%%

7494

%%

7089

PSD_results=[];

7495

PSD_results=[];

7090

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7496

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7091

OP.WO_TXFFE=1;

7497

OP.WO_TXFFE=1;

7092

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7498

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7093

end

7499

end

7094

%TXFFE Loop

7500

%TXFFE Loop

7095

%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

7501

%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

7096

for TK=1:size(TXFFE_grid,1)

7502

for TK=1:size(TXFFE_grid,1)

7097

7503

7098

pxi=pxi+1;

7504

pxi=pxi+1;

7099

progress = pxi/runs;

7505

progress = pxi/runs;

7100

if OP.DISPLAY_WINDOW

7506

if OP.DISPLAY_WINDOW

7101

if ~mod(pxi,floor(runs*progress_interval))

7507

if ~mod(pxi,floor(runs*progress_interval))

7102

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7508

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7103

end

7509

end

7104

else

7510

else

7105

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7511

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7106

end

7512

end

7107

7513

7108

%get the cursor for this iteration

7514

%get the cursor for this iteration

7109

txffe_cur=txffe_cursor_vector(TK);

7515

txffe_cur=txffe_cursor_vector(TK);

7110

7516

7111

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7517

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7112

if txffe_cur<param.tx_ffe_c0_min

7518

if txffe_cur<param.tx_ffe_c0_min

7113

continue;

7519

continue;

7114

end

7520

end

7115

old_loops=old_loops+1;

7521

old_loops=old_loops+1;

7116

7522

7117

%get the index used for each tap on this iteration

7523

%get the index used for each tap on this iteration

7118

%this is needed for the LOCAL SEARCH block

7524

%this is needed for the LOCAL SEARCH block

7119

tx_index_vector=FULL_tx_index_vector(TK,:);

7525

tx_index_vector=FULL_tx_index_vector(TK,:);

7120

7526

7121

%Original LOCAL SEARCH Block:

7527

%Original LOCAL SEARCH Block:

7122

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7528

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7123

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7529

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7124

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7530

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7125

% % skip configurations more than

7531

% % skip configurations more than

7126

% % 2 steps away from current "best" point on any grid direction

7532

% % 2 steps away from current "best" point on any grid direction

7127

% % Matt Brown 11/19/2021 for cp2 and cp3

7533

% % Matt Brown 11/19/2021 for cp2 and cp3

7128

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7534

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7129

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7535

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7130

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7536

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7131

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7537

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7132

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7538

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7133

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7539

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7134

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7540

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7135

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7541

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7136

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7542

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7137

%

7543

%

7138

% continue;

7544

% continue;

7139

% end

7545

% end

7140

7546

7141

%Modular LOCAL_SEARCH block:

7547

%Modular LOCAL_SEARCH block:

7142

% speedup "local search" heuristic - Adee Ran 03-17-2020

7548

% speedup "local search" heuristic - Adee Ran 03-17-2020

7143

% skip configurations more than 2 steps away from current "best" point on any grid direction

7549

% skip configurations more than 2 steps away from current "best" point on any grid direction

7144

skip_it=0;

7550

skip_it=0;

7145

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7551

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7146

%instead of looping across all taps, only loop across

7552

%instead of looping across all taps, only loop across

7147

%those with length>1 (txffe_sweep_indices).

7553

%those with length>1 (txffe_sweep_indices).

7148

%It saves time since this block is encountered so often

7554

%It saves time since this block is encountered so often

7149

for kj=1:num_txffe_sweep_indices

7555

for kj=1:num_txffe_sweep_indices

7150

kv=txffe_sweep_indices(kj);

7556

kv=txffe_sweep_indices(kj);

7151

if kv==1

7557

if kv==1

7152

previous_loop_val=g_LP_index;

7558

previous_loop_val=g_LP_index;

7153

else

7559

else

7154

previous_loop_val=tx_index_vector(kv-1);

7560

previous_loop_val=tx_index_vector(kv-1);

7155

end

7561

end

7156

if previous_loop_val>1

7562

if previous_loop_val>1

7157

best_index_this_tap=best_txffe_index(kv);

7563

best_index_this_tap=best_txffe_index(kv);

7158

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7564

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7159

skip_it=1;

7565

skip_it=1;

7160

break;

7566

break;

7161

end

7567

end

7162

end

7568

end

7163

end

7569

end

7164

7570

7165

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7571

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7166

skip_it=1;

7572

skip_it=1;

7167

end

7573

end

7168

end

7574

end

7169

if skip_it

7575

if skip_it

7170

continue;

7576

continue;

7171

end

7577

end

7172

%End Modular LOCAL SEARCH block

7578

%End Modular LOCAL SEARCH block

7173

7579

7174

new_loops=new_loops+1;

7580

new_loops=new_loops+1;

7175

7581

7176

%fetch txffe for this iteration

7582

%fetch txffe for this iteration

7177

txffe=txffe_matrix(TK,:);

7583

txffe=txffe_matrix(TK,:);

7178

7584

7179

%The phase shift exponentials used in get_xtlk_noise are independent of

7585

%The phase shift exponentials used in get_xtlk_noise are independent of

7180

%everything except number of taps and cursor position

7586

%everything except number of taps and cursor position

7181

%So it can be calculated 1 time here to avoid thousands of re-calcs

7587

%So it can be calculated 1 time here to avoid thousands of re-calcs

7182

if ~calc_exp_phase

7588

if ~calc_exp_phase

7183

calc_exp_phase=1;

7589

calc_exp_phase=1;

7184

for k=1:length(txffe)

7590

for k=1:length(txffe)

7185

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7591

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7186

end

7592

end

7187

if OP.RxFFE

7593

if OP.RxFFE

7188

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7594

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7189

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7595

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7190

end

7596

end

7191

phase_memory=[phase_memory phase_memoryRXFFE];

7597

phase_memory=[phase_memory phase_memoryRXFFE];

7192

end

7598

end

7193

end

7599

end

7194

7600

7195

%% Unequalized Pulse Reponse & circshift for FFE

7601

%% Unequalized Pulse Reponse & circshift for FFE

7196

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7602

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7197

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7603

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7198

if ctle_response_updated

7604

if ctle_response_updated

7199

ctle_response_updated=0;

7605

ctle_response_updated=0;

7200

num_pre=cur-1;

7606

num_pre=cur-1;

7201

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7607

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7202

%Calculating here reduces number of convolutions by thousands

7608

%Calculating here reduces number of convolutions by thousands

7203

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7609

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7204

ich=1;

7610

ich=1;

7205

else

7611

else

7206

ich=param.num_s4p_files;

7612

ich=param.num_s4p_files;

7207

end

7613

end

7208

for ii=1:ich

7614

for ii=1:ich

7209

if OP.TDMODE

7615

if OP.TDMODE

7210

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7616

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7211

else

7617

else

7212

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7618

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7213

%"conv2" is faster than filter. Just need to chop off extra points at the end

7619

%"conv2" is faster than filter. Just need to chop off extra points at the end

7214

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7620

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7215

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7621

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7216

end

7622

end

7217

for k=1:length(txffe)

7623

for k=1:length(txffe)

7218

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7624

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7219

end

7625

end

7220

end

7626

end

7221

end

7627

end

7222

7628

7223

%% Apply TXFFE to pre-shifted pulse response

7629

%% Apply TXFFE to pre-shifted pulse response

7224

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7630

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7225

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7631

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7226

sbr_from_txffe=sbr;

7632

sbr_from_txffe=sbr;

7227

for ii=1:ich

7633

for ii=1:ich

7228

% this is sbr when ii=1; to be used in get_PSDs

7634

% this is sbr when ii=1; to be used in get_PSDs

7229

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7635

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7230

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7636

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7231

else

7637

else

7232

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7638

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7233

end

7639

end

7234

end

7640

end

7235

7641

7236

%% Find Sample Location

7642

%% Find Sample Location

7237

% If RXFFE is included, the sample location will be found again below

7643

% If RXFFE is included, the sample location will be found again below

7238

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7644

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7239

if param.ts_anchor==0

7645

if param.ts_anchor==0

7240

%keep MM

7646

%keep MM

7241

elseif param.ts_anchor==1

7647

elseif param.ts_anchor==1

7242

%peak sample

7648

%peak sample

7243

cursor_i=sbr_peak_i;

7649

cursor_i=sbr_peak_i;

7244

no_zero_crossing=0;

7650

no_zero_crossing=0;

7245

elseif param.ts_anchor==2

7651

elseif param.ts_anchor==2

7246

%max DV

7652

%max DV

7247

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7653

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7248

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7654

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7249

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7655

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7250

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7656

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7251

no_zero_crossing=0;

7657

no_zero_crossing=0;

7252

else

7658

else

7253

error('ts_anchor parameter must be 0, 1, or 2');

7659

error('ts_anchor parameter must be 0, 1, or 2');

7254

end

7660

end

7255

if no_zero_crossing

7661

if no_zero_crossing

7256

continue;

7662

continue;

7257

end

7663

end

7258

raw_cursor_i=cursor_i;

7664

raw_cursor_i=cursor_i;

7259

7665

7260

%%%%%%%%%%

7666

%%%%%%%%%%

7261

%%%%%%%%%%

7667

%%%%%%%%%%

7262

%%%%%%%%%%

7668

%%%%%%%%%%

7263

%NEW ITICK LOOP (not indenting everything yet)

7669

%NEW ITICK LOOP (not indenting everything yet)

7264

[~,si]=sort(abs(full_sample_range));

7670

[~,si]=sort(abs(full_sample_range));

7265

best_positive_itick_FOM=-inf;

7671

best_positive_itick_FOM=-inf;

7266

best_negative_itick_FOM=-inf;

7672

best_negative_itick_FOM=-inf;

7267

best_positive_itick_in_loop=[];

7673

best_positive_itick_in_loop=[];

7268

best_negative_itick_in_loop=[];

7674

best_negative_itick_in_loop=[];

7269

best_itick_FOM=-inf;

7675

best_itick_FOM=-inf;

7270

best_itick_in_cluster=[];

7676

best_itick_in_cluster=[];

7271

best_cluster=[];

7677

best_cluster=[];

7272

7678

7273

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7679

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7274

%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)

7680

%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)

7275

% Commit request4p4_7 healey_3dj_COM_01_240416

7681

% Commit request4p4_7 healey_3dj_COM_01_240416

7276

%box_search=0;

7682

%box_search=0;

7277

%middle_search=1;% should set 0 so all Ts sample points are used

7683

%middle_search=1;% should set 0 so all Ts sample points are used

7278

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7684

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7279

case 'full-sweep'

7685

case 'full-sweep'

7280

box_search=0;

7686

box_search=0;

7281

middle_search=0;

7687

middle_search=0;

7282

case 'middle'

7688

case 'middle'

7283

box_search=0;

7689

box_search=0;

7284

middle_search=1;

7690

middle_search=1;

7285

otherwise

7691

otherwise

7286

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7692

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7287

end

7693

end

7288

if box_search

7694

if box_search

7289

box_size=5;

7695

box_size=5;

7290

box_mid=floor(box_size/2);

7696

box_mid=floor(box_size/2);

7291

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7697

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7292

CL=length(cluster);

7698

CL=length(cluster);

7293

loop_range=1:CL+box_mid*2;

7699

loop_range=1:CL+box_mid*2;

7294

elseif middle_search

7700

elseif middle_search

7295

loop_range=si;

7701

loop_range=si;

7296

else

7702

else

7297

loop_range=1:length(full_sample_range);

7703

loop_range=1:length(full_sample_range);

7298

end

7704

end

7299

7705

7300

for itickn=loop_range

7706

for itickn=loop_range

7301

if box_search

7707

if box_search

7302

if itickn<=CL

7708

if itickn<=CL

7303

itick=cluster(itickn);

7709

itick=cluster(itickn);

7304

else

7710

else

7305

if itickn==CL+1

7711

if itickn==CL+1

7306

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7712

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7307

end

7713

end

7308

if isempty(best_cluster)

7714

if isempty(best_cluster)

7309

continue;

7715

continue;

7310

end

7716

end

7311

itick=best_cluster(itickn-CL);

7717

itick=best_cluster(itickn-CL);

7312

end

7718

end

7313

else

7719

else

7314

itick=full_sample_range(itickn);

7720

itick=full_sample_range(itickn);

7315

end

7721

end

7316

7722

7317

itick_cases=itick_cases+1;

7723

itick_cases=itick_cases+1;

7318

7724

7319

sbr=sbr_from_txffe;

7725

sbr=sbr_from_txffe;

7320

cursor_i = raw_cursor_i+itick;

7726

cursor_i = raw_cursor_i+itick;

7321

7727

7322

%Local Search for +/- itick sweep

7728

%Local Search for +/- itick sweep

7323

if middle_search && param.LOCAL_SEARCH>0

7729

if middle_search && param.LOCAL_SEARCH>0

7324

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7730

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7325

itick_skips=itick_skips+1;

7731

itick_skips=itick_skips+1;

7326

continue;

7732

continue;

7327

end

7733

end

7328

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7734

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7329

itick_skips=itick_skips+1;

7735

itick_skips=itick_skips+1;

7330

continue;

7736

continue;

7331

end

7737

end

7332

end

7738

end

7333

7739

7334

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7740

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7335

if min_number_of_UI_in_response < triple_transit_time

7741

if min_number_of_UI_in_response < triple_transit_time

7336

min_number_of_UI_in_response = triple_transit_time;

7742

min_number_of_UI_in_response = triple_transit_time;

7337

end

7743

end

7338

7744

7339

cursor = sbr(cursor_i);

7745

cursor = sbr(cursor_i);

7340

7746

7341

%% RXFFE

7747

%% RXFFE

7342

if OP.RxFFE

7748

if OP.RxFFE

7343

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7749

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7344

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7750

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7345

%if isrow(sbr), sbr=sbr';end

7751

%if isrow(sbr), sbr=sbr';end

7346

7752

7347

%AJG: do not return sbr here (run time improvement)

7753

%AJG: do not return sbr here (run time improvement)

7348

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7754

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7349

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7755

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7350

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7756

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7351

% sbr at this point include the current setting

7757

% sbr at this point include the current setting

7352

% under consideration of txffe h21 ctf and fr

7758

% under consideration of txffe h21 ctf and fr

7353

switch upper(OP.FFE_OPT_METHOD)

7759

switch upper(OP.FFE_OPT_METHOD)

7354

case 'MMSE'

7760

case 'MMSE'

7355

OP.WO_TXFFE=0;

7761

OP.WO_TXFFE=0;

7356

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7762

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7357

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn;

7763

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn;

7358

if 0 % for debug

7764

if 0 % for debug

7359

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7765

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7360

hold on

7766

hold on

7361

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7767

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7362

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7768

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7363

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7769

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7364

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7770

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7365

xlim([0 0.5])

7771

xlim([0 0.5])

7366

% ylim([-190 -160])

7772

% ylim([-190 -160])

7367

set(gcf,'defaulttextinterpreter','none')

7773

set(gcf,'defaulttextinterpreter','none')

7368

xlabel('Normalized Frequency')

7774

xlabel('Normalized Frequency')

7369

ylabel('PSD dBm/Hz')

7775

ylabel('PSD dBm/Hz')

7370

hold on

7776

hold on

7371

grid on

7777

grid on

7372

legend show

7778

legend show

7373

title('PSD')

7779

title('PSD')

7374

end

7780

end

7375

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7781

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7376

% floating_tap_locations=MMSE_results.MLSE_results;

7782

% floating_tap_locations=MMSE_results.MLSE_results;

7377

C=MMSE_results.C;

7783

C=MMSE_results.C;

7378

FOM=MMSE_results.FOM;

7784

FOM=MMSE_results.FOM;

7379

floating_tap_locations=MMSE_results.floating_tap_locations;

7785

floating_tap_locations=MMSE_results.floating_tap_locations;

7380

otherwise

7786

otherwise

7381

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7787

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7382

end

7788

end

7383

%Now there is a stand alone function for determining if RXFFE taps are illegal

7789

%Now there is a stand alone function for determining if RXFFE taps are illegal

7384

%This is because the "force" function will also do a legality check when "backoff" is enabled

7790

%This is because the "force" function will also do a legality check when "backoff" is enabled

7385

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7791

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7386

if RXFFE_Illegal(C,param)

7792

if RXFFE_Illegal(C,param)

7387

continue;

7793

continue;

7388

end

7794

end

7389

end

7795

end

7390

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7796

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7391

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7797

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7392

if isrow(sbr), sbr=sbr';end

7798

if isrow(sbr), sbr=sbr';end

7393

7799

7394

%% second guess at cursor location (t_s) - based on approximate zero crossing

7800

%% second guess at cursor location (t_s) - based on approximate zero crossing

7395

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7801

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7396

%UPDATE: NOT RESAMPLING AFTER RXFFE

7802

%UPDATE: NOT RESAMPLING AFTER RXFFE

7397

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7803

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7398

% if no_zero_crossing

7804

% if no_zero_crossing

7399

% continue;

7805

% continue;

7400

% end

7806

% end

7401

7807

7402

cursor = sbr(cursor_i);

7808

cursor = sbr(cursor_i);

7403

end

7809

end

7404

A_p=sbr(sbr_peak_i);

7810

A_p=sbr(sbr_peak_i);

7405

%% 93A.1.6 step c defines A_s %%

7811

%% 93A.1.6 step c defines A_s %%

7406

A_s = param.R_LM*cursor/(param.levels-1);

7812

A_s = param.R_LM*cursor/(param.levels-1);

7407

if isempty(delta_sbr)

7813

if isempty(delta_sbr)

7408

delta_sbr = sbr;

7814

delta_sbr = sbr;

7409

end

7815

end

7410

sbr=sbr(:);

7816

sbr=sbr(:);

7411

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7817

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7412

7818

7413

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7819

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7414

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7820

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7415

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)))*...

7821

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)))*...

7416

param.ui/param.samples_per_ui;

7822

param.ui/param.samples_per_ui;

7417

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7823

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7418

precursors = precursors(end:-1:1);

7824

precursors = precursors(end:-1:1);

7419

7825

7420

% % Error message if the sbr is not long enough for the specified range of Nb

7826

% % Error message if the sbr is not long enough for the specified range of Nb

7421

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7827

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7422

% close(hwaitbar);

7828

% close(hwaitbar);

7423

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7829

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7424

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7830

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7425

% end

7831

% end

7426

7832

7427

7833

7428

7834

7429

%% skip this case if FOM has no chance of beating old FOM

7835

%% skip this case if FOM has no chance of beating old FOM

7430

%this is also done below but with excess_dfe_cursors included.

7836

%this is also done below but with excess_dfe_cursors included.

7431

%excess_dfe_cursors requires the floating DFE computation which is

7837

%excess_dfe_cursors requires the floating DFE computation which is

7432

%time consuming, so checking here can have significant run time improvements

7838

%time consuming, so checking here can have significant run time improvements

7433

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7839

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7434

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7840

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7435

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7841

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7436

continue

7842

continue

7437

end

7843

end

7438

end

7844

end

7439

7845

7440

%% Equation 93A-27, when 1<=n<=N_b

7846

%% Equation 93A-27, when 1<=n<=N_b

7441

%required length = cursor + all DFE UI + 1 additional UI

7847

%required length = cursor + all DFE UI + 1 additional UI

7442

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7848

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7443

if length(sbr)<sbr_required_length

7849

if length(sbr)<sbr_required_length

7444

sbr(end+1:sbr_required_length)=0;

7850

sbr(end+1:sbr_required_length)=0;

7445

end

7851

end

7446

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7852

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7447

if param.dfe_delta ~= 0

7853

if param.dfe_delta ~= 0

7448

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7854

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7449

7855

7450

else

7856

else

7451

dfecursors_q=dfecursors;

7857

dfecursors_q=dfecursors;

7452

end

7858

end

7453

if param.Floating_DFE

7859

if param.Floating_DFE

7454

%% floating taps

7860

%% floating taps

7455

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7861

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7456

7862

7457

[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 );

7863

[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 );

7458

7864

7459

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7865

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7460

param.use_bmax=newbmax;

7866

param.use_bmax=newbmax;

7461

%AJG021820

7867

%AJG021820

7462

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7868

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7463

else

7869

else

7464

param.use_bmax=param.bmax;

7870

param.use_bmax=param.bmax;

7465

%AJG021820

7871

%AJG021820

7466

param.use_bmin=param.bmin;

7872

param.use_bmin=param.bmin;

7467

end

7873

end

7468

7874

7469

%AJG021820

7875

%AJG021820

7470

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7876

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7471

if do_C2M

7877

if do_C2M

7472

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);

7878

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);

7473

% readjust SBR

7879

% readjust SBR

7474

if 0

7880

if 0

7475

%PR_DFE_center not currently used, so this is in "if 0" statement

7881

%PR_DFE_center not currently used, so this is in "if 0" statement

7476

PR_DFE_center=sbr;

7882

PR_DFE_center=sbr;

7477

for n=1:param.ndfe

7883

for n=1:param.ndfe

7478

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7884

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7479

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7885

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7480

% dper=sbr(i_sample)- actual_dfecursors(n);

7886

% dper=sbr(i_sample)- actual_dfecursors(n);

7481

% PR_DFE_center(i_sample)=dper;

7887

% PR_DFE_center(i_sample)=dper;

7482

% end

7888

% end

7483

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7889

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7484

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7890

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7485

end

7891

end

7486

end

7892

end

7487

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7893

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7488

else

7894

else

7489

excess_dfe_cursors=dfecursors-actual_dfecursors;

7895

excess_dfe_cursors=dfecursors-actual_dfecursors;

7490

end

7896

end

7491

dfetaps=actual_dfecursors/sbr(cursor_i);

7897

dfetaps=actual_dfecursors/sbr(cursor_i);

7492

7898

7493

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7899

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7494

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7900

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7495

if tail_RSS ~= 0

7901

if tail_RSS ~= 0

7496

if tail_RSS >= param.B_float_RSS_MAX

7902

if tail_RSS >= param.B_float_RSS_MAX

7497

param.use_bmax(param.N_tail_start:end)= ...

7903

param.use_bmax(param.N_tail_start:end)= ...

7498

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7904

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7499

%AJG021820

7905

%AJG021820

7500

param.use_bmin(param.N_tail_start:end)= ...

7906

param.use_bmin(param.N_tail_start:end)= ...

7501

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7907

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7502

end

7908

end

7503

end

7909

end

7504

7910

7505

%AJG021820

7911

%AJG021820

7506

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7912

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7507

if do_C2M

7913

if do_C2M

7508

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7914

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7509

else

7915

else

7510

excess_dfe_cursors=dfecursors-actual_dfecursors;

7916

excess_dfe_cursors=dfecursors-actual_dfecursors;

7511

end

7917

end

7512

dfetaps=actual_dfecursors/sbr(cursor_i);

7918

dfetaps=actual_dfecursors/sbr(cursor_i);

7513

7919

7514

else

7920

else

7515

tail_RSS=0;

7921

tail_RSS=0;

7516

end

7922

end

7517

%% Eq. 93A-28 %%

7923

%% Eq. 93A-28 %%

7518

sampling_offset = mod(cursor_i, param.samples_per_ui);

7924

sampling_offset = mod(cursor_i, param.samples_per_ui);

7519

%ensure we can take early sample

7925

%ensure we can take early sample

7520

if sampling_offset<=1

7926

if sampling_offset<=1

7521

sampling_offset=sampling_offset+param.samples_per_ui;

7927

sampling_offset=sampling_offset+param.samples_per_ui;

7522

end

7928

end

7523

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7929

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7524

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7930

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7525

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7931

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7526

else

7932

else

7527

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7933

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7528

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7934

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7529

end

7935

end

7530

% ensure lengths are equal

7936

% ensure lengths are equal

7531

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7937

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7532

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7938

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7533

if ~OP.SNR_TXwC0

7939

if ~OP.SNR_TXwC0

7534

%% Equation 93A-30 %%

7940

%% Equation 93A-30 %%

7535

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7941

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7536

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7942

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7537

else

7943

else

7538

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7944

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7539

end

7945

end

7540

%% Equation 93A-31 %%

7946

%% Equation 93A-31 %%

7541

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7947

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7542

ISI_N=param.sigma_X*norm( far_cursors);

7948

ISI_N=param.sigma_X*norm( far_cursors);

7543

%% break if FOM has no chance of beating old e

7949

%% break if FOM has no chance of beating old e

7544

OP.exe_mode=1;

7950

OP.exe_mode=1;

7545

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7951

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7546

switch OP.EXE_MODE

7952

switch OP.EXE_MODE

7547

case 0

7953

case 0

7548

case 1

7954

case 1

7549

if (20*log10(A_s/sigma_ISI) < best_FOM)

7955

if (20*log10(A_s/sigma_ISI) < best_FOM)

7550

continue

7956

continue

7551

end

7957

end

7552

case 2

7958

case 2

7553

if (20*log10(A_s/sigma_ISI) < best_FOM)

7959

if (20*log10(A_s/sigma_ISI) < best_FOM)

7554

break

7960

break

7555

end

7961

end

7556

end

7962

end

7557

end

7963

end

7558

%% Equation 93A-32 %%

7964

%% Equation 93A-32 %%

7559

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7965

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7560

7966

7561

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7967

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7562

if OP.RX_CALIBRATION

7968

if OP.RX_CALIBRATION

7563

sigma_XT=0;

7969

sigma_XT=0;

7564

else

7970

else

7565

if ~OP.RxFFE

7971

if ~OP.RxFFE

7566

[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

7972

[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

7567

%% Equation 93A-36 denominator (actually its sqrt)

7973

%% Equation 93A-36 denominator (actually its sqrt)

7568

else % John Ewen: 13/12/20018

7974

else % John Ewen: 13/12/20018

7569

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7975

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7570

[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

7976

[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

7571

else % use results from get_PSDs RIM 3/28/2024

7977

else % use results from get_PSDs RIM 3/28/2024

7572

sigma_XT=PSD_results.S_xn_rms;

7978

sigma_XT=PSD_results.S_xn_rms;

7573

end

7979

end

7574

end

7980

end

7575

end

7981

end

7576

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7982

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7577

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7983

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7578

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7984

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7579

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7985

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7580

f=chdata(1).faxis;

7986

f=chdata(1).faxis;

7581

H_Rx_FFE=zeros(1,length(f));

7987

H_Rx_FFE=zeros(1,length(f));

7582

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7988

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7583

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7989

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7584

if C(ii+param.RxFFE_cmx+1)==0

7990

if C(ii+param.RxFFE_cmx+1)==0

7585

%speed up: skip cases when rxffe=0

7991

%speed up: skip cases when rxffe=0

7586

continue;

7992

continue;

7587

end

7993

end

7588

if ii+1==0

7994

if ii+1==0

7589

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7995

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7590

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7996

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7591

else

7997

else

7592

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7998

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7593

end

7999

end

7594

end

8000

end

7595

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

8001

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

7596

end

8002

end

7597

end

8003

end

7598

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

8004

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7599

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

8005

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7600

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

8006

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7601

else

8007

else

7602

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

8008

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7603

end

8009

end

7604

if do_C2M

8010

if do_C2M

7605

if param.Noise_Crest_Factor == 0

8011

if param.Noise_Crest_Factor == 0

7606

ber_q = sqrt(2)*erfcinv(2*param.specBER);

8012

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7607

else

8013

else

7608

ber_q=param.Noise_Crest_Factor;

8014

ber_q=param.Noise_Crest_Factor;

7609

end

8015

end

7610

if OP.force_pdf_bin_size

8016

if OP.force_pdf_bin_size

7611

delta_y = OP.BinSize;

8017

delta_y = OP.BinSize;

7612

else

8018

else

7613

delta_y = min(A_s/1000, OP.BinSize);

8019

delta_y = min(A_s/1000, OP.BinSize);

7614

end

8020

end

7615

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

8021

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7616

cci_pdf = normal_dist(0, ber_q, delta_y);

8022

cci_pdf = normal_dist(0, ber_q, delta_y);

7617

chdata(1).eq_pulse_response=sbr;

8023

chdata(1).eq_pulse_response=sbr;

7618

tmp_result.t_s= cursor_i;

8024

tmp_result.t_s= cursor_i;

7619

tmp_result.A_s=A_s;

8025

tmp_result.A_s=A_s;

7620

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

8026

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7621

if EH_1st <= param.Min_VEO_Test/1000 -.001

8027

if EH_1st <= param.Min_VEO_Test/1000 -.001

7622

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

8028

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7623

continue

8029

continue

7624

else

8030

else

7625

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

8031

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7626

end

8032

end

7627

Struct_Noise.sigma_N=sigma_N;

8033

Struct_Noise.sigma_N=sigma_N;

7628

Struct_Noise.sigma_TX=sigma_TX;

8034

Struct_Noise.sigma_TX=sigma_TX;

7629

Struct_Noise.cci_pdf=cci_pdf;

8035

Struct_Noise.cci_pdf=cci_pdf;

7630

Struct_Noise.ber_q=ber_q;

8036

Struct_Noise.ber_q=ber_q;

7631

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

8037

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7632

[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);

8038

[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);

7633

EH=EH_T_C2M-EH_B_C2M;

8039

EH=EH_T_C2M-EH_B_C2M;

7634

N_i=(A_s*2-EH)/2;

8040

N_i=(A_s*2-EH)/2;

7635

if EH <= param.Min_VEO_Test/1000

8041

if EH <= param.Min_VEO_Test/1000

7636

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

8042

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7637

continue

8043

continue

7638

else

8044

else

7639

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

8045

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

7640

end

8046

end

7641

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

8047

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7642

FOM =20*log10(A_s/N_i);

8048

FOM =20*log10(A_s/N_i);

7643

end

8049

end

7644

else

8050

else

7645

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

8051

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7646

FOM = 20*log10(A_s/total_noise_rms);

8052

FOM = 20*log10(A_s/total_noise_rms);

7647

end

8053

end

7648

% if strfind(param.CTLE_type,'CL120e')

8054

% if strfind(param.CTLE_type,'CL120e')

7649

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

8055

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

7650

end

8056

end

7651

if 0 % for loop analysis

8057

if 0 % for loop analysis

7652

result.FOM_array(new_loops)=FOM;

8058

result.FOM_array(new_loops)=FOM;

7653

end

8059

end

7654

8060

7655

if FOM>best_itick_FOM

8061

if FOM>best_itick_FOM

7656

best_itick_FOM=FOM;

8062

best_itick_FOM=FOM;

7657

best_itick_in_cluster=itick;

8063

best_itick_in_cluster=itick;

7658

end

8064

end

7659

8065

7660

if itick>=0 && FOM>best_positive_itick_FOM

8066

if itick>=0 && FOM>best_positive_itick_FOM

7661

best_positive_itick_FOM=FOM;

8067

best_positive_itick_FOM=FOM;

7662

best_positive_itick_in_loop=itick;

8068

best_positive_itick_in_loop=itick;

7663

end

8069

end

7664

if itick<=0 && FOM>best_negative_itick_FOM

8070

if itick<=0 && FOM>best_negative_itick_FOM

7665

best_negative_itick_FOM=FOM;

8071

best_negative_itick_FOM=FOM;

7666

best_negative_itick_in_loop=itick;

8072

best_negative_itick_in_loop=itick;

7667

end

8073

end

7668

8074

7669

itick_index=find(itick==full_sample_range);

8075

itick_index=find(itick==full_sample_range);

7670

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

8076

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

7671

8077

7672

if (FOM > best_FOM)

8078

if (FOM > best_FOM)

7673

best_current_ffegain=param.current_ffegain;

8079

best_current_ffegain=param.current_ffegain;

7674

best_txffe = txffe;

8080

best_txffe = txffe;

7675

%along with best_txffe, save the indices of the best_txffe

8081

%along with best_txffe, save the indices of the best_txffe

7676

%(saves time in LOCAL SEARCH block)

8082

%(saves time in LOCAL SEARCH block)

7677

best_txffe_index=tx_index_vector;

8083

best_txffe_index=tx_index_vector;

7678

best_sbr = sbr;

8084

best_sbr = sbr;

7679

best_ctle = ctle_index;

8085

best_ctle = ctle_index;

7680

best_G_high_pass =g_LP_index;

8086

best_G_high_pass =g_LP_index;

7681

best_FOM = FOM;

8087

best_FOM = FOM;

7682

best_cursor_i = cursor_i;

8088

best_cursor_i = cursor_i;

7683

best_itick = itick;

8089

best_itick = itick;

7684

if ~OP.TDMODE

8090

if ~OP.TDMODE

7685

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

8091

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7686

best_IR=effective_channel;

8092

best_IR=effective_channel;

7687

end

8093

end

7688

best_sigma_N = sigma_N;

8094

best_sigma_N = sigma_N;

7689

best_h_J = h_J;

8095

best_h_J = h_J;

7690

best_A_s=A_s;

8096

best_A_s=A_s;

7691

best_A_p=A_p;

8097

best_A_p=A_p;

7692

best_ISI=ISI_N;

8098

best_ISI=ISI_N;

7693

best_bmax=param.use_bmax;

8099

best_bmax=param.use_bmax;

7694

%AJG021820

8100

%AJG021820

7695

best_bmin=param.use_bmin;

8101

best_bmin=param.use_bmin;

7696

best_tail_RSS=tail_RSS;

8102

best_tail_RSS=tail_RSS;

7697

best_dfetaps=dfetaps;

8103

best_dfetaps=dfetaps;

7698

if param.Floating_DFE

8104

if param.Floating_DFE

7699

best_floating_tap_locations=floating_tap_locations;

8105

best_floating_tap_locations=floating_tap_locations;

7700

best_floating_tap_coef=floating_tap_coef;

8106

best_floating_tap_coef=floating_tap_coef;

7701

end

8107

end

7702

if param.Floating_RXFFE

8108

if param.Floating_RXFFE

7703

best_floating_tap_locations=floating_tap_locations;

8109

best_floating_tap_locations=floating_tap_locations;

7704

% best_floating_tap_coef=floating_tap_coef;

8110

% best_floating_tap_coef=floating_tap_coef;

7705

end

8111

end

7706

if OP.RxFFE

8112

if OP.RxFFE

7707

best_RxFFE=C;

8113

best_RxFFE=C;

7708

best_PSD_results=PSD_results;

8114

best_PSD_results=PSD_results;

7709

best_MMSE_results=MMSE_results;

8115

best_MMSE_results=MMSE_results;

7710

end

8116

end

7711

end

8117

end

7712

end

8118

end

7713

end

8119

end

7714

8120

7715

end

8121

end

7716

end

8122

end

7717

end

8123

end

7718

if do_C2M

8124

if do_C2M

7719

if best_FOM == -inf

8125

if best_FOM == -inf

7720

param.Min_VEO_Test=0;

8126

param.Min_VEO_Test=0;

7721

else

8127

else

7722

break

8128

break

7723

end

8129

end

7724

end

8130

end

7725

end

8131

end

7726

if 0

8132

if 0

7727

fprintf('old loops = %d\n',old_loops);

8133

fprintf('old loops = %d\n',old_loops);

7728

fprintf('new loops = %d\n',new_loops);

8134

fprintf('new loops = %d\n',new_loops);

7729

display(sprintf('\n :loops = %g',pxi))

8135

display(sprintf('\n :loops = %g',pxi))

7730

end

8136

end

7731

8137

7732

%turn this on to review if FOM changes sign more than once in an itick loop

8138

%turn this on to review if FOM changes sign more than once in an itick loop

7733

if 0

8139

if 0

7734

DIR_CHANGE={};

8140

DIR_CHANGE={};

7735

for m=1:length(Gffe_values)

8141

for m=1:length(Gffe_values)

7736

for n=1:length(gdc_values)

8142

for n=1:length(gdc_values)

7737

for k=1:lf_indx

8143

for k=1:lf_indx

7738

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

8144

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

7739

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

8145

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

7740

%1 = goes up, -1=goes down

8146

%1 = goes up, -1=goes down

7741

x=sign(diff(FOM_this_mat')');

8147

x=sign(diff(FOM_this_mat')');

7742

%y = change in sign on x. the location of a "2" is where FOM changes direction

8148

%y = change in sign on x. the location of a "2" is where FOM changes direction

7743

y=abs(diff(x'))';

8149

y=abs(diff(x'))';

7744

%the goal is the FOM only changes direction once. so count the occurences of the 2

8150

%the goal is the FOM only changes direction once. so count the occurences of the 2

7745

for j=1:size(FOM_this_mat,1)

8151

for j=1:size(FOM_this_mat,1)

7746

z{j}=find(y(j,:)==2);

8152

z{j}=find(y(j,:)==2);

7747

end

8153

end

7748

zL=cellfun('length',z);

8154

zL=cellfun('length',z);

7749

%return any row where FOM changed direction more than once

8155

%return any row where FOM changed direction more than once

7750

DIR_CHANGE{j,k}=find(zL>1);

8156

DIR_CHANGE{j,k}=find(zL>1);

7751

end

8157

end

7752

end

8158

end

7753

end

8159

end

7754

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

8160

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

7755

end

8161

end

7756

8162

7757

if ~exist('best_cursor_i', 'var')% take last setting

8163

if ~exist('best_cursor_i', 'var')% take last setting

7758

result.eq_failed=true;

8164

result.eq_failed=true;

7759

display('equalization failed')

8165

display('equalization failed')

7760

best_bmax=param.bmax;

8166

best_bmax=param.bmax;

7761

%AJG021820

8167

%AJG021820

7762

best_bmin=param.bmin;

8168

best_bmin=param.bmin;

7763

best_tail_RSS=0;

8169

best_tail_RSS=0;

7764

best_current_ffegain=0;

8170

best_current_ffegain=0;

7765

best_txffe = txffe;

8171

best_txffe = txffe;

7766

best_sbr = sbr;

8172

best_sbr = sbr;

7767

best_ctle = ctle_index;

8173

best_ctle = ctle_index;

7768

if OP.RxFFE

8174

if OP.RxFFE

7769

best_PSD_results=PSD_results;

8175

best_PSD_results=PSD_results;

7770

best_MMSE_results=MMSE_results;

8176

best_MMSE_results=MMSE_results;

7771

best_RxFFE=C;

8177

best_RxFFE=C;

7772

end

8178

end

7773

best_G_high_pass =g_LP_index;

8179

best_G_high_pass =g_LP_index;

7774

best_FOM = FOM;

8180

best_FOM = FOM;

7775

%if this block is reached, the last encountered EQ parameters are used

8181

%if this block is reached, the last encountered EQ parameters are used

7776

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

8182

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

7777

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

8183

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

7778

if isempty(cursor_i)

8184

if isempty(cursor_i)

7779

[~,cursor_i]=max(sbr);

8185

[~,cursor_i]=max(sbr);

7780

end

8186

end

7781

best_cursor_i = cursor_i;

8187

best_cursor_i = cursor_i;

7782

best_itick = itick;

8188

best_itick = itick;

7783

if ~OP.TDMODE

8189

if ~OP.TDMODE

7784

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

8190

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7785

best_IR=effective_channel;

8191

best_IR=effective_channel;

7786

end

8192

end

7787

best_sigma_N = sigma_N;

8193

best_sigma_N = sigma_N;

7788

best_h_J = h_J;

8194

best_h_J = h_J;

7789

best_A_p=max(sbr);

8195

best_A_p=max(sbr);

7790

best_ISI=1;

8196

best_ISI=1;

7791

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) ;

8197

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) ;

7792

best_A_s= sbr( cursor_i);

8198

best_A_s= sbr( cursor_i);

7793

if param.Floating_DFE

8199

if param.Floating_DFE

7794

best_floating_tap_locations=[];

8200

best_floating_tap_locations=[];

7795

best_floating_tap_coef=[];

8201

best_floating_tap_coef=[];

7796

end

8202

end

7797

if do_C2M

8203

if do_C2M

7798

return

8204

return

7799

end

8205

end

7800

% return

8206

% return

7801

else

8207

else

7802

result.eq_failed=false; % RIM 12/30/2023

8208

result.eq_failed=false; % RIM 12/30/2023

7803

end

8209

end

7804

8210

7805

best_cursor = best_sbr(best_cursor_i);

8211

best_cursor = best_sbr(best_cursor_i);

7806

% report during debug

8212

% report during debug

7807

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

8213

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

7808

%If sbr was zero padded, then PRin needs to do so as well)

8214

%If sbr was zero padded, then PRin needs to do so as well)

7809

if length(PRin)<length(best_sbr)

8215

if length(PRin)<length(best_sbr)

7810

PRin(end+1:length(best_sbr))=0;

8216

PRin(end+1:length(best_sbr))=0;

7811

end

8217

end

7812

f=1e8:1e8:100e9;

8218

f=1e8:1e8:100e9;

7813

8219

7814

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

8220

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

7815

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

8221

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

7816

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

8222

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7817

% need to include H_RCos in noise and when computing the system ir for thru

8223

% need to include H_RCos in noise and when computing the system ir for thru

7818

% and crosstalk

8224

% and crosstalk

7819

H_r=H_bw.*H_bt.*H_RCos;

8225

H_r=H_bw.*H_bt.*H_RCos;

7820

8226

7821

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

8227

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

7822

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

8228

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

7823

8229

7824

switch param.CTLE_type

8230

switch param.CTLE_type

7825

case 'CL93'

8231

case 'CL93'

7826

H_low=1;

8232

H_low=1;

7827

case 'CL120d'

8233

case 'CL120d'

7828

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));

8234

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));

7829

case 'CL120e'

8235

case 'CL120e'

7830

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

8236

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

7831

end

8237

end

7832

ctle_gain=H_low.*ctle_gain1.*H_r;

8238

ctle_gain=H_low.*ctle_gain1.*H_r;

7833

8239

7834

8240

7835

8241

7836

%lsbr=length(sbr);

8242

%lsbr=length(sbr);

7837

%use length of best_sbr in case zero padding was performed

8243

%use length of best_sbr in case zero padding was performed

7838

%check "sbr_required_length" variable

8244

%check "sbr_required_length" variable

7839

lsbr=length(best_sbr);

8245

lsbr=length(best_sbr);

7840

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

8246

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

7841

8247

7842

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

8248

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

7843

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

8249

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

7844

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

8250

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

7845

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

8251

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

7846

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

8252

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

7847

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

8253

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

7848

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

8254

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

7849

if param.Floating_DFE

8255

if param.Floating_DFE

7850

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

8256

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

7851

end

8257

end

7852

% apply max tap value constraint

8258

% apply max tap value constraint

7853

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

8259

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

7854

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

8260

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

7855

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

8261

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

7856

8262

7857

%AJG021820

8263

%AJG021820

7858

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

8264

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

7859

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

8265

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

7860

if param.Floating_DFE

8266

if param.Floating_DFE

7861

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

8267

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

7862

end

8268

end

7863

8269

7864

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

8270

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

7865

Symbol_Adj = (param.levels-1);% 3A.1.6

8271

Symbol_Adj = (param.levels-1);% 3A.1.6

7866

if OP.DEBUG ~=0

8272

if OP.DEBUG ~=0

7867

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

8273

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

7868

% display pulse responses in one axis per test case.

8274

% display pulse responses in one axis per test case.

7869

switch upper(OP.TIME_AXIS)

8275

switch upper(OP.TIME_AXIS)

7870

case 'S' % RIM 11-13-2023 added user selectable xaxis

8276

case 'S' % RIM 11-13-2023 added user selectable xaxis

7871

xnorm=1;

8277

xnorm=1;

7872

xaxis_label='seconds';

8278

xaxis_label='seconds';

7873

offset=0;

8279

offset=0;

7874

case 'UI'

8280

case 'UI'

7875

xnorm=param.ui;

8281

xnorm=param.ui;

7876

xaxis_label='UI';

8282

xaxis_label='UI';

7877

offset=t(best_cursor_i)/xnorm;

8283

offset=t(best_cursor_i)/xnorm;

7878

otherwise

8284

otherwise

7879

xnorm=1;

8285

xnorm=1;

7880

xaxis_label='seconds';

8286

xaxis_label='seconds';

7881

offset=0;

8287

offset=0;

7882

end

8288

end

7883

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

8289

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

7884

fig=findobj('Name', figure_name);

8290

fig=findobj('Name', figure_name);

7885

if isempty(fig), fig=figure('Name', figure_name); end

8291

if isempty(fig), fig=figure('Name', figure_name); end

7886

figure(fig);set(gcf,'Tag','COM');

8292

figure(fig);set(gcf,'Tag','COM');

7887

movegui(fig,'north')

8293

movegui(fig,'north')

7888

%figure(fig.Number);

8294

%figure(fig.Number);

7889

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

8295

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

7890

if OP.RxFFE

8296

if OP.RxFFE

7891

ax1=subplot(2,1,1);

8297

ax1=subplot(2,1,1);

7892

end

8298

end

7893

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

8299

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

7894

hold on

8300

hold on

7895

8301

7896

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

8302

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

7897

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

8303

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

7898

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

8304

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

7899

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

8305

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

7900

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

8306

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

7901

ylabel('volts')

8307

ylabel('volts')

7902

xlabel(xaxis_label)

8308

xlabel(xaxis_label)

7903

grid on

8309

grid on

7904

legend show

8310

legend show

7905

legend( 'Location', 'best')

8311

legend( 'Location', 'best')

7906

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

8312

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

7907

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

8313

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

7908

if param.ndfe_passed ~=0

8314

if param.ndfe_passed ~=0

7909

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');

8315

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');

7910

end

8316

end

7911

if param.Floating_DFE

8317

if param.Floating_DFE

7912

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');

8318

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');

7913

end

8319

end

7914

if OP.RxFFE

8320

if OP.RxFFE

7915

ax2=subplot(2,1,2);

8321

ax2=subplot(2,1,2);

7916

if param.Floating_RXFFE

8322

if param.Floating_RXFFE

7917

%AJG: floating tap x-axis location needs offset by -(RxFFE_cmx+1) because the floating tap indices include precursor indices

8323

%AJG: floating tap x-axis location needs offset by -(RxFFE_cmx+1) because the floating tap indices include precursor indices

7918

stem((t(best_cursor_i+(best_floating_tap_locations-param.RxFFE_cmx-1)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

8324

stem((t(best_cursor_i+(best_floating_tap_locations-param.RxFFE_cmx-1)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

7919

,'filled','disp','RxFFE floating FFE taps')

8325

,'filled','disp','RxFFE floating FFE taps')

7920

hold on

8326

hold on

7921

end

8327

end

7922

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)...

8328

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)...

7923

,'filled','disp','RxFFE fixted FFE taps')

8329

,'filled','disp','RxFFE fixted FFE taps')

7924

legend show

8330

legend show

7925

zoom xon

8331

zoom xon

7926

linkaxes([ax1 ax2],'x')

8332

linkaxes([ax1 ax2],'x')

7927

end

8333

end

7928

8334

7929

8335

7930

grid on

8336

grid on

7931

legend show

8337

legend show

7932

legend( 'Location', 'best')

8338

legend( 'Location', 'best')

7933

zoom xon

8339

zoom xon

7934

% set(hax, 'tag', 'EQE');

8340

% set(hax, 'tag', 'EQE');

7935

%

8341

%

7936

figure(110);set(gcf,'Tag','COM');

8342

figure(110);set(gcf,'Tag','COM');

7937

set(gcf, 'Name', 'CTLE selection');

8343

set(gcf, 'Name', 'CTLE selection');

7938

movegui(gcf, 'southeast');

8344

movegui(gcf, 'southeast');

7939

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8345

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

7940

hold on

8346

hold on

7941

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8347

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

7942

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8348

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

7943

fbaud_tick=find(f >= baud_rate, 1);

8349

fbaud_tick=find(f >= baud_rate, 1);

7944

fnq_tick=find(f >= baud_rate/2, 1);

8350

fnq_tick=find(f >= baud_rate/2, 1);

7945

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8351

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

7946

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8352

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

7947

recolor_plots(gca);

8353

recolor_plots(gca);

7948

title('CTF/w Rx Filter Response')

8354

title('CTF/w Rx Filter Response')

7949

ylabel('dB')

8355

ylabel('dB')

7950

xlabel('Hz')

8356

xlabel('Hz')

7951

legend show

8357

legend show

7952

end

8358

end

7953

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8359

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

7954

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8360

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

7955

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8361

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

7956

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8362

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

7957

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8363

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

7958

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8364

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

7959

end

8365

end

7960

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

8366

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

7961

eqe_axes = findobj('tag', 'EQE');

8367

eqe_axes = findobj('tag', 'EQE');

7962

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8368

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

7963

end

8369

end

7964

if OP.DISPLAY_WINDOW

8370

if OP.DISPLAY_WINDOW

7965

close(hwaitbar);

8371

close(hwaitbar);

7966

else

8372

else

7967

fprintf('\n');

8373

fprintf('\n');

7968

end

8374

end

7969

8375

7970

% % eq_data

8376

% % eq_data

7971

result.cur=cur;

8377

result.cur=cur;

7972

result.txffe = best_txffe;

8378

result.txffe = best_txffe;

7973

result.ctle = best_ctle;

8379

result.ctle = best_ctle;

7974

result.best_G_high_pass=best_G_high_pass;

8380

result.best_G_high_pass=best_G_high_pass;

7975

result.DFE_taps = best_dfetaps; %relative

8381

result.DFE_taps = best_dfetaps; %relative

7976

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8382

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

7977

if param.Floating_DFE

8383

if param.Floating_DFE

7978

result.floating_tap_locations=best_floating_tap_locations;

8384

result.floating_tap_locations=best_floating_tap_locations;

7979

result.floating_tap_coef=best_floating_tap_coef;

8385

result.floating_tap_coef=best_floating_tap_coef;

7980

end

8386

end

7981

if param.Floating_RXFFE

8387

if param.Floating_RXFFE

7982

result.floating_tap_locations=best_floating_tap_locations;

8388

result.floating_tap_locations=best_floating_tap_locations;

7983

end

8389

end

7984

result.A_s = best_A_s;

8390

result.A_s = best_A_s;

7985

result.t_s = best_cursor_i;

8391

result.t_s = best_cursor_i;

7986

result.itick = best_itick;

8392

result.itick = best_itick;

7987

result.sigma_N = best_sigma_N;

8393

result.sigma_N = best_sigma_N;

7988

result.h_J = best_h_J;

8394

result.h_J = best_h_J;

7989

result.FOM = best_FOM;

8395

result.FOM = best_FOM;

7990

if ~OP.TDMODE

8396

if ~OP.TDMODE

7991

%If sbr was zero padded, then best_IR needs to do so as well)

8397

%If sbr was zero padded, then best_IR needs to do so as well)

7992

if length(best_IR)<length(best_sbr)

8398

if length(best_IR)<length(best_sbr)

7993

best_IR(end+1:length(best_sbr))=0;

8399

best_IR(end+1:length(best_sbr))=0;

7994

end

8400

end

7995

result.IR = best_IR;

8401

result.IR = best_IR;

7996

end

8402

end

7997

result.t=t;

8403

result.t=t;

7998

result.sbr=best_sbr;

8404

result.sbr=best_sbr;

7999

if OP.RxFFE

8405

if OP.RxFFE

8000

result.RxFFE=best_RxFFE;

8406

result.RxFFE=best_RxFFE;

8001

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8407

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8002

result.PSD_results=best_PSD_results;

8408

result.PSD_results=best_PSD_results;

8003

result.MMSE_results=best_MMSE_results;

8409

result.MMSE_results=best_MMSE_results;

8004

end

8410

end

8005

end

8411

end

8006

8412

8007

8413

8008

8414

8009

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8415

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8010

% updated RIM 12/17/2021

8416

% updated RIM 12/17/2021

8011

result.A_p = max(chdata(1).uneq_pulse_response);

8417

result.A_p = max(chdata(1).uneq_pulse_response);

8012

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8418

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8013

PR=chdata(1).uneq_pulse_response;

8419

PR=chdata(1).uneq_pulse_response;

8014

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8420

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8015

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8421

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8016

if iend >= length(PR)

8422

if iend >= length(PR)

8017

iend = length (PR);

8423

iend = length (PR);

8018

end

8424

end

8019

if ibeg < 1

8425

if ibeg < 1

8020

ibeg = 1;

8426

ibeg = 1;

8021

end

8427

end

8022

PR=PR(ibeg:iend);

8428

PR=PR(ibeg:iend);

8023

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8429

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8024

SRn=PR;

8430

SRn=PR;

8025

for ik=1:floor(length(PR)/param.samples_per_ui)

8431

for ik=1:floor(length(PR)/param.samples_per_ui)

8026

SPR=circshift(PR,param.samples_per_ui*ik);

8432

SPR=circshift(PR,param.samples_per_ui*ik);

8027

SPR(1:ik*param.samples_per_ui)=0;

8433

SPR(1:ik*param.samples_per_ui)=0;

8028

SRn=SRn+ SPR;

8434

SRn=SRn+ SPR;

8029

end

8435

end

8030

codedebug=0;

8436

codedebug=0;

8031

if codedebug

8437

if codedebug

8032

fig=figure('Name', 'step and pulse response for code debug');

8438

fig=figure('Name', 'step and pulse response for code debug');

8033

figure(fig);set(gcf,'Tag','COM');

8439

figure(fig);set(gcf,'Tag','COM');

8034

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8440

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8035

plot(UI,SRn)

8441

plot(UI,SRn)

8036

hold on

8442

hold on

8037

plot(UI,PR)

8443

plot(UI,PR)

8038

xlim([-param.D_p param.N_v])

8444

xlim([-param.D_p param.N_v])

8039

grid on;hold off;

8445

grid on;hold off;

8040

result.step=SRn;

8446

result.step=SRn;

8041

end

8447

end

8042

i20=find(SRn>=0.20*result.A_f,1,'first');

8448

i20=find(SRn>=0.20*result.A_f,1,'first');

8043

i80=find(SRn>=0.80*result.A_f,1,'first');

8449

i80=find(SRn>=0.80*result.A_f,1,'first');

8044

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8450

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8045

result.Pmax_by_Vf=result.A_p/result.A_f;

8451

result.Pmax_by_Vf=result.A_p/result.A_f;

8046

result.ISI =best_ISI;

8452

result.ISI =best_ISI;

8047

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8453

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8048

result.best_current_ffegain=best_current_ffegain;

8454

result.best_current_ffegain=best_current_ffegain;

8049

result.best_bmax=best_bmax;

8455

result.best_bmax=best_bmax;

8050

%AJG021820

8456

%AJG021820

8051

result.best_bmin=best_bmin;

8457

result.best_bmin=best_bmin;

8052

result.tail_RSS=best_tail_RSS;

8458

result.tail_RSS=best_tail_RSS;

8053

function param=parameter_size_adjustment(param,OP)

8459

function param=parameter_size_adjustment(param,OP)

8054

8460

8055

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'};

8461

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'};

8056

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8462

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8057

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8463

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8058

make_length_DCHP={'f_HP'};

8464

make_length_DCHP={'f_HP'};

8059

make_length_ncases={'AC_CM_RMS'};

8465

make_length_ncases={'AC_CM_RMS'};

8060

8466

8061

%ncases used by make_length_ncases fields

8467

%ncases used by make_length_ncases fields

8062

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8468

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8063

8469

8064

%PORTZ_mult used by make_length_WCPORTZ fields

8470

%PORTZ_mult used by make_length_WCPORTZ fields

8065

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8471

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8066

if OP.WC_PORTZ

8472

if OP.WC_PORTZ

8067

PORTZ_mult=[1 1];

8473

PORTZ_mult=[1 1];

8068

else

8474

else

8069

PORTZ_mult=pkg_sel_vec;

8475

PORTZ_mult=pkg_sel_vec;

8070

end

8476

end

8071

8477

8072

%Parameters that have length = 2

8478

%Parameters that have length = 2

8073

for j=1:length(make_length2)

8479

for j=1:length(make_length2)

8074

if numel(param.(make_length2{j}))==1

8480

if numel(param.(make_length2{j}))==1

8075

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8481

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8076

end

8482

end

8077

end

8483

end

8078

8484

8079

%Parameters that have length = ncases

8485

%Parameters that have length = ncases

8080

for j=1:length(make_length_ncases)

8486

for j=1:length(make_length_ncases)

8081

if numel(param.(make_length_ncases{j}))==1

8487

if numel(param.(make_length_ncases{j}))==1

8082

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8488

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8083

end

8489

end

8084

end

8490

end

8085

8491

8086

%Parameters that have length = length(ctle_gdc_values)

8492

%Parameters that have length = length(ctle_gdc_values)

8087

for j=1:length(make_length_GDC)

8493

for j=1:length(make_length_GDC)

8088

if numel(param.(make_length_GDC{j}))==1

8494

if numel(param.(make_length_GDC{j}))==1

8089

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8495

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8090

end

8496

end

8091

end

8497

end

8092

8498

8093

%Parameters that have length = length(g_DC_HP_values)

8499

%Parameters that have length = length(g_DC_HP_values)

8094

for j=1:length(make_length_DCHP)

8500

for j=1:length(make_length_DCHP)

8095

if numel(param.(make_length_DCHP{j}))==1

8501

if numel(param.(make_length_DCHP{j}))==1

8096

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8502

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8097

end

8503

end

8098

end

8504

end

8099

8505

8100

%Parameters that have length associated with PORTZ_mult

8506

%Parameters that have length associated with PORTZ_mult

8101

for j=1:length(make_length_WCPORTZ)

8507

for j=1:length(make_length_WCPORTZ)

8102

if numel(param.(make_length_WCPORTZ{j}))==1

8508

if numel(param.(make_length_WCPORTZ{j}))==1

8103

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8509

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8104

end

8510

end

8105

end

8511

end

8106

function sgm = pdf2sgm(pdf)

8512

function sgm = pdf2sgm(pdf)

8107

avg = sum(pdf.x .* pdf.y);

8513

avg = sum(pdf.x .* pdf.y);

8108

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8514

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8109

% end yasuo patch

8515

% end yasuo patch

8110

8516

8111

8517

8112

%% adding tx packgage

8518

%% adding tx packgage

8113

function cdf=pdf_to_cdf(pdf)

8519

function cdf=pdf_to_cdf(pdf)

8114

8520

8115

%Transform PDF to CDF

8521

%Transform PDF to CDF

8116

%The CDF is natively calculated from negative-to-positive voltage.

8522

%The CDF is natively calculated from negative-to-positive voltage.

8117

%This only gives BER calculation for bottom eye. Need to also

8523

%This only gives BER calculation for bottom eye. Need to also

8118

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8524

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8119

%min of top and bottom CDF values.

8525

%min of top and bottom CDF values.

8120

%If only interested in one side, a simple cumsum on y is all that is needed.

8526

%If only interested in one side, a simple cumsum on y is all that is needed.

8121

8527

8122

cdf.yB=cumsum(pdf.y);

8528

cdf.yB=cumsum(pdf.y);

8123

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8529

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8124

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8530

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8125

cdf.x=pdf.x;

8531

cdf.x=pdf.x;

8126

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)

8532

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)

8127

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8533

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8128

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8534

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8129

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8535

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8130

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8536

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8131

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8537

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8132

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8538

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8133

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8539

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8134

%% Added by Bill Kirkland, June 14, 2017

8540

%% Added by Bill Kirkland, June 14, 2017

8135

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8541

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8136

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8542

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8137

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8543

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8138

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8544

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8139

8545

8140

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8546

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8141

hold on

8547

hold on

8142

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8548

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8143

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8549

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8144

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)

8550

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)

8145

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8551

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8146

8552

8147

%% Added by Bill Kirkland, June 14, 2017

8553

%% Added by Bill Kirkland, June 14, 2017

8148

% modification allows bathtub curves to cross over and hence one can

8554

% modification allows bathtub curves to cross over and hence one can

8149

% directly read the noise component.

8555

% directly read the noise component.

8150

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8556

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8151

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8557

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8152

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8558

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8153

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8559

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8154

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8560

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8155

8561

8156

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8562

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8157

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8563

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8158

8564

8159

ylabel(hax, 'Probability')

8565

ylabel(hax, 'Probability')

8160

xlabel(hax, 'volts')

8566

xlabel(hax, 'volts')

8161

legend(hax, 'show')

8567

legend(hax, 'show')

8162

% testing code

8568

% testing code

8163

if 0

8569

if 0

8164

figure_name = 'COM curves';

8570

figure_name = 'COM curves';

8165

fig=findobj('Name', figure_name);

8571

fig=findobj('Name', figure_name);

8166

if isempty(fig), fig=figure('Name', figure_name); end

8572

if isempty(fig), fig=figure('Name', figure_name); end

8167

figure(fig);set(gcf,'Tag','COM');

8573

figure(fig);set(gcf,'Tag','COM');

8168

grid on

8574

grid on

8169

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8575

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8170

hold on

8576

hold on

8171

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8577

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8172

ylim([ 1e-6 0.25])

8578

ylim([ 1e-6 0.25])

8173

xlim([0 30])

8579

xlim([0 30])

8174

grid on

8580

grid on

8175

end

8581

end

8176

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)

8582

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)

8177

BER=param.specBER;

8583

BER=param.specBER;

8178

delta_dB=param.delta_IL;

8584

delta_dB=param.delta_IL;

8179

8585

8180

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8586

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8181

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8587

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8182

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8588

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8183

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8589

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8184

8590

8185

8591

8186

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8592

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8187

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8593

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8188

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8594

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8189

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8595

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8190

8596

8191

COM=20*log10(max_signal/maxn_tot);

8597

COM=20*log10(max_signal/maxn_tot);

8192

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8598

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8193

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8599

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8194

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8600

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8195

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8601

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8196

8602

8197

pfctr=exp(-0.09054*delta_dB);% less loss

8603

pfctr=exp(-0.09054*delta_dB);% less loss

8198

mfctr=exp(0.09054*delta_dB); % more loss

8604

mfctr=exp(0.09054*delta_dB); % more loss

8199

8605

8200

%less loss

8606

%less loss

8201

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8607

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8202

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8608

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8203

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8609

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8204

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8610

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8205

plus_maxn_tot=norm(plus_maxn);

8611

plus_maxn_tot=norm(plus_maxn);

8206

8612

8207

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8613

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8208

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8614

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8209

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8615

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8210

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8616

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8211

minus_maxn_tot=norm(minus_maxn);

8617

minus_maxn_tot=norm(minus_maxn);

8212

8618

8213

% more loss

8619

% more loss

8214

COMp=20*log10(max_signal*pfctr/maxn_tot);

8620

COMp=20*log10(max_signal*pfctr/maxn_tot);

8215

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8621

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8216

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8622

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8217

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8623

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8218

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8624

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8219

% less loss

8625

% less loss

8220

COMm=20*log10(max_signal*mfctr/maxn_tot);

8626

COMm=20*log10(max_signal*mfctr/maxn_tot);

8221

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8627

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8222

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8628

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8223

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8629

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8224

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8630

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8225

8631

8226

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8632

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8227

8633

8228

8634

8229

if(COM<0)

8635

if(COM<0)

8230

return

8636

return

8231

end

8637

end

8232

8638

8233

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8639

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8234

8640

8235

% pie(COM_per_noise,labels)

8641

% pie(COM_per_noise,labels)

8236

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8642

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8237

% legend('show','Location','bestoutside')

8643

% legend('show','Location','bestoutside')

8238

nullbar= [ 0 0 0 ];

8644

nullbar= [ 0 0 0 ];

8239

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8645

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8240

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8646

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8241

hold on

8647

hold on

8242

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8648

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8243

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8649

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8244

8650

8245

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8651

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8246

% ax=gca;

8652

% ax=gca;

8247

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8653

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8248

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8654

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8249

grid on

8655

grid on

8250

legend(labels,'Location','north')

8656

legend(labels,'Location','north')

8251

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8657

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8252

ylabel('COM (dB)')

8658

ylabel('COM (dB)')

8253

hold off

8659

hold off

8254

8660

8255

8661

8256

8662

8257

8663

8258

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8664

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8259

num_files=length(chdata);

8665

num_files=length(chdata);

8260

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8666

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8261

for i=1:num_files

8667

for i=1:num_files

8262

if param.package_testcase_i==1 && i==1

8668

if param.package_testcase_i==1 && i==1

8263

if OP.TDR && i==1

8669

if OP.TDR && i==1

8264

S.Frequencies=chdata(i).faxis;

8670

S.Frequencies=chdata(i).faxis;

8265

S.Impedance=100;

8671

S.Impedance=100;

8266

if ~OP.SHOW_BRD

8672

if ~OP.SHOW_BRD

8267

Sfield='_orig';

8673

Sfield='_orig';

8268

else

8674

else

8269

Sfield='_raw';

8675

Sfield='_raw';

8270

end

8676

end

8271

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8677

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8272

if ~param.FLAG.S2P

8678

if ~param.FLAG.S2P

8273

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8679

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8274

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8680

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8275

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8681

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8276

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8682

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8277

else

8683

else

8278

S.NumPorts=1;

8684

S.NumPorts=1;

8279

end

8685

end

8280

if OP.TDR_W_TXPKG

8686

if OP.TDR_W_TXPKG

8281

if OP.ERL == 2

8687

if OP.ERL == 2

8282

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8688

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8283

end

8689

end

8284

R_diepad = param.R_diepad;

8690

R_diepad = param.R_diepad;

8285

% RX package length is assumed to be the same for all

8691

% RX package length is assumed to be the same for all

8286

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8692

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8287

% for Rx pkg

8693

% for Rx pkg

8288

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8694

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8289

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8695

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8290

combines4p( s11in, s12in, s21in, s22in, ...

8696

combines4p( s11in, s12in, s21in, s22in, ...

8291

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8697

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8292

% S=sparameters(S.Parameters,S.Frequencies,100);

8698

% S=sparameters(S.Parameters,S.Frequencies,100);

8293

S=SL(S,S.Frequencies,R_diepad(1)*2);

8699

S=SL(S,S.Frequencies,R_diepad(1)*2);

8294

chdata(i).TX_RL=S.Parameters(2,2,:);

8700

chdata(i).TX_RL=S.Parameters(2,2,:);

8295

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8701

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8296

end

8702

end

8297

8703

8298

% need to combine S wiht is page and channel

8704

% need to combine S wiht is page and channel

8299

if param.FLAG.S2P

8705

if param.FLAG.S2P

8300

port_sel=1;

8706

port_sel=1;

8301

else

8707

else

8302

port_sel=[1 2];

8708

port_sel=[1 2];

8303

if OP.AUTO_TFX

8709

if OP.AUTO_TFX

8304

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8710

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8305

pix=find(fir4del==max(fir4del),1);

8711

pix=find(fir4del==max(fir4del),1);

8306

param.tfx(2)=2*tu(pix);

8712

param.tfx(2)=2*tu(pix);

8307

end

8713

end

8308

end

8714

end

8309

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8715

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8310

for ipsl=1:length(port_sel) % do for both port if s4p

8716

for ipsl=1:length(port_sel) % do for both port if s4p

8311

for izt=1:length(param.Z_t) % do for all tdr impedances

8717

for izt=1:length(param.Z_t) % do for all tdr impedances

8312

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8718

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8313

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8719

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8314

% OP.interp_sparam_mag='trend_to_DC';

8720

% OP.interp_sparam_mag='trend_to_DC';

8315

OP.interp_sparam_mag='linear_trend_to_DC';

8721

OP.interp_sparam_mag='linear_trend_to_DC';

8316

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8722

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8317

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8723

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8318

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8724

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8319

if ipsl ==1

8725

if ipsl ==1

8320

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8726

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8321

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8727

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8322

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8728

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8323

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8729

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8324

else

8730

else

8325

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8731

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8326

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8732

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8327

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8733

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8328

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8734

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8329

end

8735

end

8330

if OP.PTDR && i==1

8736

if OP.PTDR && i==1

8331

if ipsl ==1

8737

if ipsl ==1

8332

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8738

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8333

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8739

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8334

else

8740

else

8335

if ~param.FLAG.S2P

8741

if ~param.FLAG.S2P

8336

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8742

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8337

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8743

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8338

else

8744

else

8339

chdata(i).TDR22(izt).ERL=[];

8745

chdata(i).TDR22(izt).ERL=[];

8340

chdata(i).TDR22(izt).ERLRMS=[];

8746

chdata(i).TDR22(izt).ERLRMS=[];

8341

end

8747

end

8342

end

8748

end

8343

else

8749

else

8344

chdata(i).TDR11(izt).ERL=[];

8750

chdata(i).TDR11(izt).ERL=[];

8345

chdata(i).TDR22(izt).ERL=[];

8751

chdata(i).TDR22(izt).ERL=[];

8346

chdata(i).TDR11(izt).ERLRMS=[];

8752

chdata(i).TDR11(izt).ERLRMS=[];

8347

chdata(i).TDR22(izt).ERLRMS=[];

8753

chdata(i).TDR22(izt).ERLRMS=[];

8348

end

8754

end

8349

end

8755

end

8350

end

8756

end

8351

end

8757

end

8352

8758

8353

end

8759

end

8354

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8760

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8355

h=figure(180);set(gcf,'Tag','COM');

8761

h=figure(180);set(gcf,'Tag','COM');

8356

if param.package_testcase_i==1 && i == 1

8762

if param.package_testcase_i==1 && i == 1

8357

if i==1

8763

if i==1

8358

htabgroup = uitabgroup(h);

8764

htabgroup = uitabgroup(h);

8359

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8765

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8360

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8766

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8361

hax1 = axes('Parent', htab1);

8767

hax1 = axes('Parent', htab1);

8362

hax3 = axes('Parent', htab3);

8768

hax3 = axes('Parent', htab3);

8363

if ~param.FLAG.S2P

8769

if ~param.FLAG.S2P

8364

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8770

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8365

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8771

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8366

hax2 = axes('Parent', htab2);

8772

hax2 = axes('Parent', htab2);

8367

hax4 = axes('Parent', htab4);

8773

hax4 = axes('Parent', htab4);

8368

end

8774

end

8369

end

8775

end

8370

set(h,'CurrentAxes',hax1)

8776

set(h,'CurrentAxes',hax1)

8371

hold on

8777

hold on

8372

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8778

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8373

hold off

8779

hold off

8374

legend (hax1, 'off');grid on;zoom xon;

8780

legend (hax1, 'off');grid on;zoom xon;

8375

set(legend (hax1, 'show'), 'interp', 'none');

8781

set(legend (hax1, 'show'), 'interp', 'none');

8376

8782

8377

if ~param.FLAG.S2P

8783

if ~param.FLAG.S2P

8378

set(h,'CurrentAxes',hax2)

8784

set(h,'CurrentAxes',hax2)

8379

hold on

8785

hold on

8380

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8786

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8381

hold off

8787

hold off

8382

legend (hax2, 'off');grid on;zoom xon;

8788

legend (hax2, 'off');grid on;zoom xon;

8383

set(legend (hax2, 'show'), 'interp', 'none');

8789

set(legend (hax2, 'show'), 'interp', 'none');

8384

end

8790

end

8385

8791

8386

set(h,'CurrentAxes',hax3)

8792

set(h,'CurrentAxes',hax3)

8387

hold on

8793

hold on

8388

if OP.PTDR

8794

if OP.PTDR

8389

for izt=1:length(param.Z_t)

8795

for izt=1:length(param.Z_t)

8390

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8796

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8391

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8797

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8392

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8798

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8393

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8799

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8394

end

8800

end

8395

end

8801

end

8396

hold off

8802

hold off

8397

legend (hax3, 'off');grid on;zoom xon;

8803

legend (hax3, 'off');grid on;zoom xon;

8398

set(legend (hax3, 'show'), 'interp', 'none');

8804

set(legend (hax3, 'show'), 'interp', 'none');

8399

if ~param.FLAG.S2P

8805

if ~param.FLAG.S2P

8400

set(h,'CurrentAxes',hax4)

8806

set(h,'CurrentAxes',hax4)

8401

hold on

8807

hold on

8402

if OP.PTDR

8808

if OP.PTDR

8403

for izt=1:length(param.Z_t)

8809

for izt=1:length(param.Z_t)

8404

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8810

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8405

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8811

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8406

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8812

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8407

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8813

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8408

end

8814

end

8409

end

8815

end

8410

hold off

8816

hold off

8411

legend (hax4, 'off');grid on;zoom xon;

8817

legend (hax4, 'off');grid on;zoom xon;

8412

set(legend (hax4, 'show'), 'interp', 'none');

8818

set(legend (hax4, 'show'), 'interp', 'none');

8413

end

8819

end

8414

end

8820

end

8415

end

8821

end

8416

if param.FLAG.S2P, return; end

8822

if param.FLAG.S2P, return; end

8417

end

8823

end

8418

function S =r_parrelell2(zref,f,rpad)

8824

function S =r_parrelell2(zref,f,rpad)

8419

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8825

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8420

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8826

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8421

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8827

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8422

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8828

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8423

% Sm=sparameters(S.Parameters,f,zref);

8829

% Sm=sparameters(S.Parameters,f,zref);

8424

8830

8425

8831

8426

8832

8427

8833

8428

8834

8429

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8835

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8430

8836

8431

%touchstone_file: .sNp touchstone file to read

8837

%touchstone_file: .sNp touchstone file to read

8432

%port_order: port reorder vector

8838

%port_order: port reorder vector

8433

%

8839

%

8434

%sch: sparameter matrix

8840

%sch: sparameter matrix

8435

%schFreqAxis: frequency axis

8841

%schFreqAxis: frequency axis

8436

8842

8437

[file_path,root_name,extension]=fileparts(touchstone_file);

8843

[file_path,root_name,extension]=fileparts(touchstone_file);

8438

fid=fopen(touchstone_file);

8844

fid=fopen(touchstone_file);

8439

8845

8440

%fetch number of ports from extension

8846

%fetch number of ports from extension

8441

num_ports=str2num(char(regexp(extension,'\d*','match')));

8847

num_ports=str2num(char(regexp(extension,'\d*','match')));

8442

8848

8443

%Get option line

8849

%Get option line

8444

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8850

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8445

optcell=textscan(optstr{1}{1},'%s');

8851

optcell=textscan(optstr{1}{1},'%s');

8446

optcell=optcell{1};

8852

optcell=optcell{1};

8447

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8853

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8448

%Some touchstone files need this. can't remember why now. maybe lines

8854

%Some touchstone files need this. can't remember why now. maybe lines

8449

%with whitespace but not empty but not commented

8855

%with whitespace but not empty but not commented

8450

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8856

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8451

optcell=textscan(optstr{1}{1},'%s');

8857

optcell=textscan(optstr{1}{1},'%s');

8452

optcell=optcell{1};

8858

optcell=optcell{1};

8453

end

8859

end

8454

8860

8455

%read the entire file

8861

%read the entire file

8456

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8862

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8457

raw_column_data=raw_read_data{1};

8863

raw_column_data=raw_read_data{1};

8458

fclose(fid);

8864

fclose(fid);

8459

8865

8460

%number of columns for 2D matrix

8866

%number of columns for 2D matrix

8461

columns=num_ports*num_ports*2+1;

8867

columns=num_ports*num_ports*2+1;

8462

8868

8463

%find the frequency lines by searching for the right number of NaN

8869

%find the frequency lines by searching for the right number of NaN

8464

a=sum(isnan(raw_column_data),2);

8870

a=sum(isnan(raw_column_data),2);

8465

if num_ports==3

8871

if num_ports==3

8466

b=find(a==2);

8872

b=find(a==2);

8467

elseif num_ports==1

8873

elseif num_ports==1

8468

b=find(a==6);

8874

b=find(a==6);

8469

else

8875

else

8470

b=find(a==0);

8876

b=find(a==0);

8471

end

8877

end

8472

8878

8473

num_freq=length(b);

8879

num_freq=length(b);

8474

8880

8475

%toss out the NaN and reshape into a 2D matrix

8881

%toss out the NaN and reshape into a 2D matrix

8476

raw_input = raw_column_data.';

8882

raw_input = raw_column_data.';

8477

raw_input = raw_input(~isnan(raw_input));

8883

raw_input = raw_input(~isnan(raw_input));

8478

raw_input = reshape(raw_input,columns,num_freq).';

8884

raw_input = reshape(raw_input,columns,num_freq).';

8479

8885

8480

%get the frequency mult

8886

%get the frequency mult

8481

frequency_mult_text=optcell{2};

8887

frequency_mult_text=optcell{2};

8482

if(strcmpi(frequency_mult_text,'hz'))

8888

if(strcmpi(frequency_mult_text,'hz'))

8483

frequency_mult=1;

8889

frequency_mult=1;

8484

elseif(strcmpi(frequency_mult_text,'khz'))

8890

elseif(strcmpi(frequency_mult_text,'khz'))

8485

frequency_mult=1e3;

8891

frequency_mult=1e3;

8486

elseif(strcmpi(frequency_mult_text,'mhz'))

8892

elseif(strcmpi(frequency_mult_text,'mhz'))

8487

frequency_mult=1e6;

8893

frequency_mult=1e6;

8488

elseif(strcmpi(frequency_mult_text,'ghz'))

8894

elseif(strcmpi(frequency_mult_text,'ghz'))

8489

frequency_mult=1e9;

8895

frequency_mult=1e9;

8490

else

8896

else

8491

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8897

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8492

end

8898

end

8493

8899

8494

%get the RI/MA/DB format

8900

%get the RI/MA/DB format

8495

format=optcell{4};

8901

format=optcell{4};

8496

%get Z0

8902

%get Z0

8497

port_impedance=str2double(optcell(6:end))';

8903

port_impedance=str2double(optcell(6:end))';

8498

8904

8499

8905

8500

%grab frequency

8906

%grab frequency

8501

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8907

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8502

Spar.F=raw_input(:,1);

8908

Spar.F=raw_input(:,1);

8503

Spar.F=transpose(Spar.F(:));

8909

Spar.F=transpose(Spar.F(:));

8504

8910

8505

8911

8506

%transform data to real imaginary

8912

%transform data to real imaginary

8507

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8913

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8508

if(strcmpi(format,'ri'))

8914

if(strcmpi(format,'ri'))

8509

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8915

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8510

elseif(strcmpi(format,'ma'))

8916

elseif(strcmpi(format,'ma'))

8511

mag_data=raw_input(:,2:2:end);

8917

mag_data=raw_input(:,2:2:end);

8512

rad_data=raw_input(:,3:2:end)*pi/180;

8918

rad_data=raw_input(:,3:2:end)*pi/180;

8513

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8919

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8514

elseif(strcmpi(format,'db'))

8920

elseif(strcmpi(format,'db'))

8515

mag_data=10.^(raw_input(:,2:2:end)/20);

8921

mag_data=10.^(raw_input(:,2:2:end)/20);

8516

rad_data=raw_input(:,3:2:end)*pi/180;

8922

rad_data=raw_input(:,3:2:end)*pi/180;

8517

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8923

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8518

else

8924

else

8519

error('Format %s is not supported. Use RI MA or DB',format);

8925

error('Format %s is not supported. Use RI MA or DB',format);

8520

end

8926

end

8521

8927

8522

8928

8523

8929

8524

%transform to 3D

8930

%transform to 3D

8525

%allow for upper/lower matrix specification for touchstone 2.0 support

8931

%allow for upper/lower matrix specification for touchstone 2.0 support

8526

matrix_format=0;

8932

matrix_format=0;

8527

if(matrix_format==0)

8933

if(matrix_format==0)

8528

%full

8934

%full

8529

for j=1:num_ports

8935

for j=1:num_ports

8530

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8936

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8531

end

8937

end

8532

elseif(matrix_format==1)

8938

elseif(matrix_format==1)

8533

%upper

8939

%upper

8534

used_ports=0;

8940

used_ports=0;

8535

for j=1:num_ports

8941

for j=1:num_ports

8536

stated_ports=num_ports-j+1;

8942

stated_ports=num_ports-j+1;

8537

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8943

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8538

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8944

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8539

used_ports=used_ports+stated_ports;

8945

used_ports=used_ports+stated_ports;

8540

end

8946

end

8541

elseif(matrix_format==2)

8947

elseif(matrix_format==2)

8542

%lower

8948

%lower

8543

used_ports=0;

8949

used_ports=0;

8544

for j=1:num_ports

8950

for j=1:num_ports

8545

stated_ports=j;

8951

stated_ports=j;

8546

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8952

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8547

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8953

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8548

used_ports=used_ports+stated_ports;

8954

used_ports=used_ports+stated_ports;

8549

end

8955

end

8550

else

8956

else

8551

error('Matrix format is not supported. Use Full, Lower, or Upper');

8957

error('Matrix format is not supported. Use Full, Lower, or Upper');

8552

end

8958

end

8553

8959

8554

8960

8555

%check for swapping the 2 port matrix (required on 1.x spec)

8961

%check for swapping the 2 port matrix (required on 1.x spec)

8556

two_port_swap=1;

8962

two_port_swap=1;

8557

if(num_ports==2 && two_port_swap==1)

8963

if(num_ports==2 && two_port_swap==1)

8558

temp=pre_out.sp(1,2,:);

8964

temp=pre_out.sp(1,2,:);

8559

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8965

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8560

pre_out.sp(2,1,:)=temp;

8966

pre_out.sp(2,1,:)=temp;

8561

end

8967

end

8562

8968

8563

Spar.S=pre_out.sp;

8969

Spar.S=pre_out.sp;

8564

Spar.Z0=transpose(port_impedance(:));

8970

Spar.Z0=transpose(port_impedance(:));

8565

8971

8566

if length(Spar.Z0)>1

8972

if length(Spar.Z0)>1

8567

error('Each port must have the same reference impedance');

8973

error('Each port must have the same reference impedance');

8568

end

8974

end

8569

if ~isequal(Spar.Z0,50)

8975

if ~isequal(Spar.Z0,50)

8570

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8976

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8571

%Renormalize to 50 ohms

8977

%Renormalize to 50 ohms

8572

rho=(50-Spar.Z0)/(50+Spar.Z0);

8978

rho=(50-Spar.Z0)/(50+Spar.Z0);

8573

p=num_ports;

8979

p=num_ports;

8574

s_old=Spar.S;

8980

s_old=Spar.S;

8575

for k=1:num_freq

8981

for k=1:num_freq

8576

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8982

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8577

end

8983

end

8578

end

8984

end

8579

8985

8580

%These operations sync up with COM style Spar matrix

8986

%These operations sync up with COM style Spar matrix

8581

%1: put frequency as first dimension

8987

%1: put frequency as first dimension

8582

sch=shiftdim(Spar.S,2);

8988

sch=shiftdim(Spar.S,2);

8583

%2: reorder ports according to "ports" input

8989

%2: reorder ports according to "ports" input

8584

sch=sch(:,port_order,port_order);

8990

sch=sch(:,port_order,port_order);

8585

schFreqAxis=Spar.F;

8991

schFreqAxis=Spar.F;

8586

function [chdata, param] = read_PR_files(param, OP, chdata)

8992

function [chdata, param] = read_PR_files(param, OP, chdata)

8587

%% Read in pulse response

8993

%% Read in pulse response

8588

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8994

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8589

num_files=length(chdata);

8995

num_files=length(chdata);

8590

M=param.samples_per_ui;

8996

M=param.samples_per_ui;

8591

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8997

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8592

for i=1:num_files

8998

for i=1:num_files

8593

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8999

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8594

progress = i/num_files;

9000

progress = i/num_files;

8595

if OP.DISPLAY_WINDOW

9001

if OP.DISPLAY_WINDOW

8596

[~,a]=fileparts(chdata(i).filename);

9002

[~,a]=fileparts(chdata(i).filename);

8597

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9003

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8598

else

9004

else

8599

fprintf('%i ',i);

9005

fprintf('%i ',i);

8600

end

9006

end

8601

switch chdata(i).ext

9007

switch chdata(i).ext

8602

case '.csv'

9008

case '.csv'

8603

vt=load(chdata(i).filename);

9009

vt=load(chdata(i).filename);

8604

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

9010

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8605

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

9011

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8606

dt=vt(2,1)-vt(1,1);

9012

dt=vt(2,1)-vt(1,1);

8607

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

9013

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8608

9014

8609

9015

8610

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

9016

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8611

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

9017

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8612

Vf=step_response(end);

9018

Vf=step_response(end);

8613

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

9019

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8614

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

9020

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8615

9021

8616

end

9022

end

8617

end

9023

end

8618

function [param,OP]= read_ParamConfigFile(paramFile,OP)

9024

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8619

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

9025

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8620

[filepath,name,ext] = fileparts(paramFile);

9026

[filepath,name,ext] = fileparts(paramFile);

8621

if ~isempty(filepath)

9027

if ~isempty(filepath)

8622

filepath=[filepath '\'];

9028

filepath=[filepath '\'];

8623

end

9029

end

8624

matcongfile=[filepath name '.mat'];

9030

matcongfile=[filepath name '.mat'];

8625

try

9031

try

8626

switch upper(ext)

9032

switch upper(ext)

8627

case upper('.mat')

9033

case upper('.mat')

8628

load(matcongfile)

9034

load(matcongfile)

8629

case upper('.csv')

9035

case upper('.csv')

8630

[na1, na2, parameter] = xlsread(paramFile);

9036

[na1, na2, parameter] = xlsread(paramFile);

8631

otherwise

9037

otherwise

8632

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

9038

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8633

end

9039

end

8634

9040

8635

catch ME %#ok<NASGU>

9041

catch ME %#ok<NASGU>

8636

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

9042

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8637

switch upper(ext)

9043

switch upper(ext)

8638

case upper('.mat')

9044

case upper('.mat')

8639

load(matcongfile)

9045

load(matcongfile)

8640

case upper('.csv')

9046

case upper('.csv')

8641

[na1, na2, parameter] = xlsread(paramFile);

9047

[na1, na2, parameter] = xlsread(paramFile);

8642

otherwise

9048

otherwise

8643

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

9049

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8644

end

9050

end

8645

end

9051

end

8646

9052

8647

%% New section to parse .START package data

9053

%% New section to parse .START package data

8648

first_column_data = parameter(:,1);

9054

first_column_data = parameter(:,1);

8649

start_data_rows = find(strcmp(first_column_data,'.START'));

9055

start_data_rows = find(strcmp(first_column_data,'.START'));

8650

if ~isempty(start_data_rows)

9056

if ~isempty(start_data_rows)

8651

end_data_rows = find(strcmp(first_column_data,'.END'));

9057

end_data_rows = find(strcmp(first_column_data,'.END'));

8652

if length(start_data_rows) ~= length(end_data_rows)

9058

if length(start_data_rows) ~= length(end_data_rows)

8653

error('Number of .START and .END must be the same');

9059

error('Number of .START and .END must be the same');

8654

end

9060

end

8655

first_start_row = start_data_rows(1);

9061

first_start_row = start_data_rows(1);

8656

special_parameter = parameter;

9062

special_parameter = parameter;

8657

parameter = parameter(1:first_start_row-1,:);

9063

parameter = parameter(1:first_start_row-1,:);

8658

for j=1:length(start_data_rows)

9064

for j=1:length(start_data_rows)

8659

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

9065

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

8660

pkg_name = special_parameter{start_data_rows(j),2};

9066

pkg_name = special_parameter{start_data_rows(j),2};

8661

9067

8662

%Read all the parameters that make up a package

9068

%Read all the parameters that make up a package

8663

PKG_param = read_package_parameters(this_block);

9069

PKG_param = read_package_parameters(this_block);

8664

9070

8665

%save the data in a field revealed by pkg_name

9071

%save the data in a field revealed by pkg_name

8666

param.PKG.(pkg_name) = PKG_param;

9072

param.PKG.(pkg_name) = PKG_param;

8667

9073

8668

9074

8669

end

9075

end

8670

end

9076

end

8671

%Allow specification of TX and RX package section through PKG_NAME keyword

9077

%Allow specification of TX and RX package section through PKG_NAME keyword

8672

%the values must match package blocks specified in .START sections

9078

%the values must match package blocks specified in .START sections

8673

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

9079

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

8674

if isnan(param.PKG_NAME)

9080

if isnan(param.PKG_NAME)

8675

param.PKG_NAME = '';

9081

param.PKG_NAME = '';

8676

end

9082

end

8677

if isempty(param.PKG_NAME)

9083

if isempty(param.PKG_NAME)

8678

param.PKG_NAME = {};

9084

param.PKG_NAME = {};

8679

else

9085

else

8680

param.PKG_NAME = strsplit(param.PKG_NAME);

9086

param.PKG_NAME = strsplit(param.PKG_NAME);

8681

end

9087

end

8682

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

9088

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

8683

error('PKG_NAME can only be used if .START blocks for package parameters are used');

9089

error('PKG_NAME can only be used if .START blocks for package parameters are used');

8684

end

9090

end

8685

for j=1:length(param.PKG_NAME)

9091

for j=1:length(param.PKG_NAME)

8686

if ~isfield(param.PKG,param.PKG_NAME{j})

9092

if ~isfield(param.PKG,param.PKG_NAME{j})

8687

error('Package Block "%s" not found',param.PKG_NAME{j});

9093

error('Package Block "%s" not found',param.PKG_NAME{j});

8688

end

9094

end

8689

end

9095

end

8690

9096

8691

%%

9097

%%

8692

% just need to define so we can pass

9098

% just need to define so we can pass

8693

param.c=[.4e-12 .4e-12];

9099

param.c=[.4e-12 .4e-12];

8694

param.alen=[ 20 30 550 ];

9100

param.alen=[ 20 30 550 ];

8695

param.az=[100 120 100];

9101

param.az=[100 120 100];

8696

9102

8697

% make control for package/channel reflection control

9103

% make control for package/channel reflection control

8698

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

9104

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

8699

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

9105

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

8700

9106

8701

% make compatible with presentation of kappa

9107

% make compatible with presentation of kappa

8702

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

9108

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

8703

9109

8704

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

9110

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

8705

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

9111

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

8706

9112

8707

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

9113

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

8708

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

9114

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

8709

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

9115

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

8710

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

9116

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

8711

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

9117

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

8712

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

9118

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

8713

9119

8714

if OP.dynamic_txffe

9120

if OP.dynamic_txffe

8715

found_pre=1;

9121

found_pre=1;

8716

pre_count=1;

9122

pre_count=1;

8717

while found_pre

9123

while found_pre

8718

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

9124

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

8719

if found_pre

9125

if found_pre

8720

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

9126

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

8721

param.(field_name)=p;

9127

param.(field_name)=p;

8722

pre_count=pre_count+1;

9128

pre_count=pre_count+1;

8723

end

9129

end

8724

end

9130

end

8725

found_post=1;

9131

found_post=1;

8726

post_count=1;

9132

post_count=1;

8727

while found_post

9133

while found_post

8728

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

9134

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

8729

if found_post

9135

if found_post

8730

field_name=sprintf('tx_ffe_cp%d_values',post_count);

9136

field_name=sprintf('tx_ffe_cp%d_values',post_count);

8731

param.(field_name)=p;

9137

param.(field_name)=p;

8732

post_count=post_count+1;

9138

post_count=post_count+1;

8733

end

9139

end

8734

end

9140

end

8735

else

9141

else

8736

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

9142

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

8737

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

9143

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

8738

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

9144

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

8739

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

9145

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

8740

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

9146

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

8741

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

9147

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

8742

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

9148

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

8743

end

9149

end

8744

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

9150

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

8745

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

9151

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

8746

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

9152

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

8747

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

9153

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

8748

% support for floating taps

9154

% support for floating taps

8749

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

9155

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

8750

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

9156

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

8751

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

9157

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

8752

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

9158

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

8753

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

9159

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

8754

if param.N_bg == 0, param.N_bmax=param.ndfe; end

9160

if param.N_bg == 0, param.N_bmax=param.ndfe; end

8755

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

9161

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

8756

9162

8757

% support for tail tap power limitations

9163

% support for tail tap power limitations

8758

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

9164

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

8759

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

9165

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

8760

%

9166

%

8761

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

9167

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

8762

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

9168

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

8763

param.RxFFE_cmx=param.ffe_pre_tap_len;

9169

param.RxFFE_cmx=param.ffe_pre_tap_len;

8764

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

9170

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

8765

param.RxFFE_cpx=param.ffe_post_tap_len;

9171

param.RxFFE_cpx=param.ffe_post_tap_len;

8766

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

9172

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

8767

param.RxFFE_stepz=param.ffe_tap_step_size;

9173

param.RxFFE_stepz=param.ffe_tap_step_size;

8768

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

9174

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

8769

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

9175

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

8770

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

9176

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

8771

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

9177

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

8772

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

9178

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

8773

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

9179

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

8774

OP.RxFFE= true;

9180

OP.RxFFE= true;

8775

else

9181

else

8776

OP.RxFFE=false;

9182

OP.RxFFE=false;

8777

end

9183

end

8778

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

9184

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

8779

9185

8780

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

9186

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

8781

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

9187

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

8782

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

9188

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

8783

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

9189

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

8784

9190

8785

9191

8786

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

9192

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

8787

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

9193

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

8788

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)

9194

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)

8789

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

9195

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

8790

9196

8791

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)

9197

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)

8792

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

9198

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

8793

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

9199

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

8794

% always read in main ctle values. They would be interpreted different baseed

9200

% always read in main ctle values. They would be interpreted different baseed

8795

% on the clause they apply because of different CTF equations

9201

% on the clause they apply because of different CTF equations

8796

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

9202

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

8797

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9203

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8798

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9204

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8799

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9205

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8800

% the contex of the poles an zeros are determined by the clause

9206

% the contex of the poles an zeros are determined by the clause

8801

switch param.CTLE_type

9207

switch param.CTLE_type

8802

case 'CL93'

9208

case 'CL93'

8803

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

9209

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

8804

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9210

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8805

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9211

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8806

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9212

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8807

case 'CL120d'

9213

case 'CL120d'

8808

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

9214

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

8809

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

9215

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

8810

case 'CL120e'

9216

case 'CL120e'

8811

% re adjust to get TD_CTLE to work with C:120e equation without

9217

% re adjust to get TD_CTLE to work with C:120e equation without

8812

% changing TD_CTLE code

9218

% changing TD_CTLE code

8813

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

9219

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

8814

end

9220

end

8815

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

9221

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

8816

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

9222

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

8817

%% addd default to support multiple packages

9223

%% addd default to support multiple packages

8818

param.a_thru = xls_parameter(parameter, 'A_v', true, 0.5); % Victim differential peak source output voltage (half of peak to peak)

9224

param.a_thru = xls_parameter(parameter, 'A_v', true, 0.5); % Victim differential peak source output voltage (half of peak to peak)

8819

param.a_fext = xls_parameter(parameter, 'A_fe', true,0.5); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9225

param.a_fext = xls_parameter(parameter, 'A_fe', true,0.5); % FEXT aggressor differential peak source output voltage (half of peak to peak)

8820

param.a_next = xls_parameter(parameter, 'A_ne', true,0.5); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9226

param.a_next = xls_parameter(parameter, 'A_ne', true,0.5); % NEXT aggressor differential peak source output voltage (half of peak to peak)

8821

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

9227

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

8822

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

9228

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

8823

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

9229

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

8824

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

9230

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

8825

param.DER_CDR = xls_parameter(parameter, 'DER_CDR',true,1e-2); % min DER required for a CDR

9231

param.DER_CDR = xls_parameter(parameter, 'DER_CDR',true,1e-2); % min DER required for a CDR

8826

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

9232

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

8827

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

9233

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

8828

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

9234

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

8829

9235

8830

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

9236

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

8831

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

9237

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

8832

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

9238

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

8833

% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

9239

% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

8834

param.trunc = xls_parameter(parameter, 'trunc', true, 128); % MLSE sequence truncation length

9240

param.trunc = xls_parameter(parameter, 'trunc', true, 128); % MLSE sequence truncation length

8835

param.trunc = xls_parameter(parameter, 'N_tc', true, param.trunc); % MLSE sequence truncation length

9241

param.trunc = xls_parameter(parameter, 'N_tc', true, param.trunc); % MLSE sequence truncation length

8836

9242

8837

% healey_3dj_01a_2407 adjust MLSE for COM_DFE

9243

% healey_3dj_01a_2407 adjust MLSE for COM_DFE

8838

param.Q_budget_adj = xls_parameter(parameter, 'Q_budget_adj', true, 0); % MLSE sequence truncation length

9244

param.Q_budget_adj = xls_parameter(parameter, 'Q_budget_adj', true, 0); % MLSE sequence truncation length

8839

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

9245

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

8840

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

9246

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

8841

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

9247

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

8842

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

9248

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

8843

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)

9249

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)

8844

% This will keep bmax length 0 if Nb=0

9250

% This will keep bmax length 0 if Nb=0

8845

9251

8846

%AJG021820

9252

%AJG021820

8847

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

9253

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

8848

if isempty(param.bmax)

9254

if isempty(param.bmax)

8849

param.bmin=param.bmax;

9255

param.bmin=param.bmax;

8850

else

9256

else

8851

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.

9257

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.

8852

9258

8853

end

9259

end

8854

if param.ndfe >= 2

9260

if param.ndfe >= 2

8855

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

9261

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

8856

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)

9262

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)

8857

end

9263

end

8858

9264

8859

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)

9265

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)

8860

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

9266

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

8861

%verify gqual and gqual2 input

9267

%verify gqual and gqual2 input

8862

if ~isempty(param.gqual) || ~isempty(param.g2qual)

9268

if ~isempty(param.gqual) || ~isempty(param.g2qual)

8863

if size(param.gqual,1)~=length(param.g2qual)

9269

if size(param.gqual,1)~=length(param.g2qual)

8864

error('gqual and g2qual size mismatch');

9270

error('gqual and g2qual size mismatch');

8865

end

9271

end

8866

if size(param.gqual,2)~=2

9272

if size(param.gqual,2)~=2

8867

error('gqual must be Nx2 matrix');

9273

error('gqual must be Nx2 matrix');

8868

end

9274

end

8869

end

9275

end

8870

9276

8871

9277

8872

% eval if string for all three - can use different for TX and RX

9278

% eval if string for all three - can use different for TX and RX

8873

param.C_pkg_board = xls_parameter(parameter, 'C_p', true,0)*1e-9; % C_p in nF (single sided)

9279

param.C_pkg_board = xls_parameter(parameter, 'C_p', true,0)*1e-9; % C_p in nF (single sided)

8874

param.C_diepad = xls_parameter(parameter, 'C_d', true,0)*1e-9; % C_d in nF (single sided)

9280

param.C_diepad = xls_parameter(parameter, 'C_d', true,0)*1e-9; % C_d in nF (single sided)

8875

% [ahealey] Read values for optional compensating L and "bump" C

9281

% [ahealey] Read values for optional compensating L and "bump" C

8876

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

9282

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

8877

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

9283

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

8878

% [ahealey] End of modification

9284

% [ahealey] End of modification

8879

% added default to support multiple packages

9285

% added default to support multiple packages

8880

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

9286

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

8881

param.R_diepad = xls_parameter(parameter, 'R_d', true, [50,50]); % Die source termination resistance (single sided)

9287

param.R_diepad = xls_parameter(parameter, 'R_d', true, [50,50]); % Die source termination resistance (single sided)

8882

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

9288

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

8883

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

9289

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

8884

9290

8885

9291

8886

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

9292

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

8887

% added default to support multiple packages

9293

% added default to support multiple packages

8888

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of victim transmitter package trace lengths in mm, one per case

9294

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of victim transmitter package trace lengths in mm, one per case

8889

[ncases, mele]=size(param.z_p_tx_cases);

9295

[ncases, mele]=size(param.z_p_tx_cases);

8890

if mele ==2

9296

if mele ==2

8891

param.flex=2;

9297

param.flex=2;

8892

elseif mele==4

9298

elseif mele==4

8893

param.flex=4;

9299

param.flex=4;

8894

elseif mele==1

9300

elseif mele==1

8895

param.flex=1;

9301

param.flex=1;

8896

else

9302

else

8897

error(sprintf('config file syntax error'))

9303

error(sprintf('config file syntax error'))

8898

end

9304

end

8899

9305

8900

% board parameters

9306

% board parameters

8901

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

9307

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

8902

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

9308

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

8903

% added default to support multiple packages

9309

% added default to support multiple packages

8904

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of NEXT transmitter package trace lengths in mm, one per case

9310

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of NEXT transmitter package trace lengths in mm, one per case

8905

[ncases1, mele1]=size(param.z_p_next_cases);

9311

[ncases1, mele1]=size(param.z_p_next_cases);

8906

if ncases ~= ncases1 || mele ~= mele1

9312

if ncases ~= ncases1 || mele ~= mele1

8907

error('All TX, NEXT, FEXT, Rx cases must agree');

9313

error('All TX, NEXT, FEXT, Rx cases must agree');

8908

else

9314

else

8909

end

9315

end

8910

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of FEXT transmitter package trace lengths in mm, one per case

9316

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of FEXT transmitter package trace lengths in mm, one per case

8911

[ncases1, mele1]=size(param.z_p_fext_cases);

9317

[ncases1, mele1]=size(param.z_p_fext_cases);

8912

if ncases ~= ncases1 || mele ~= mele1

9318

if ncases ~= ncases1 || mele ~= mele1

8913

error('All TX, NEXT, FEXT, Rx cases must agree');

9319

error('All TX, NEXT, FEXT, Rx cases must agree');

8914

else

9320

else

8915

end

9321

end

8916

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of FEXT receiver package trace lengths in mm, one per case

9322

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of FEXT receiver package trace lengths in mm, one per case

8917

[ncases1, mele1]=size(param.z_p_rx_cases);

9323

[ncases1, mele1]=size(param.z_p_rx_cases);

8918

if ncases ~= ncases1 || mele ~= mele1

9324

if ncases ~= ncases1 || mele ~= mele1

8919

error('All TX, NEXT, FEXT, Rx cases must agree');

9325

error('All TX, NEXT, FEXT, Rx cases must agree');

8920

else

9326

else

8921

end

9327

end

8922

% Table 93A-3 parameters

9328

% Table 93A-3 parameters

8923

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.

9329

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.

8924

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9330

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

8925

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, '[92 92 ; 70 70; 80 80; 100 100]').';% Package model transmission line characteristic impedance [ Tx , Rx ]

9331

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, '[92 92 ; 70 70; 80 80; 100 100]').';% Package model transmission line characteristic impedance [ Tx , Rx ]

8926

[ ncases1, mele1]=size(param.pkg_Z_c);%

9332

[ ncases1, mele1]=size(param.pkg_Z_c);%

8927

if mele ~= mele1

9333

if mele ~= mele1

8928

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9334

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

8929

else

9335

else

8930

end

9336

end

8931

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9337

if mele1==2 % fuill in a array if only a 2 element flex package is specified

8932

for ii=1:ncases

9338

for ii=1:ncases

8933

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9339

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

8934

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9340

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

8935

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9341

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

8936

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9342

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

8937

end

9343

end

8938

param.z_p_fext_cases = param.z_p_fext_casesx;

9344

param.z_p_fext_cases = param.z_p_fext_casesx;

8939

param.z_p_next_cases= param.z_p_next_casesx;

9345

param.z_p_next_cases= param.z_p_next_casesx;

8940

param.z_p_tx_cases= param.z_p_tx_casesx;

9346

param.z_p_tx_cases= param.z_p_tx_casesx;

8941

param.z_p_rx_cases= param.z_p_rx_casesx;

9347

param.z_p_rx_cases= param.z_p_rx_casesx;

8942

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9348

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

8943

end

9349

end

8944

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9350

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

8945

9351

8946

% Table 92-12 parameters

9352

% Table 92-12 parameters

8947

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.

9353

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.

8948

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9354

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

8949

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9355

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

8950

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9356

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

8951

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9357

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

8952

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9358

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

8953

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9359

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

8954

9360

8955

% Unofficial parameters

9361

% Unofficial parameters

8956

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9362

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

8957

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9363

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

8958

% Deprecated parameters - affect only frequency domain analysis.

9364

% Deprecated parameters - affect only frequency domain analysis.

8959

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

9365

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

8960

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

9366

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

8961

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

9367

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

8962

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

9368

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

8963

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

9369

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

8964

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9370

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

8965

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9371

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

8966

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9372

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

8967

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9373

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

8968

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9374

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

8969

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9375

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

8970

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9376

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

8971

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9377

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

8972

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9378

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

8973

switch param.Gx

9379

switch param.Gx

8974

case 0

9380

case 0

8975

param.Grr=param.Grr; % just use older Grr ir gx not specified

9381

param.Grr=param.Grr; % just use older Grr ir gx not specified

8976

case 1

9382

case 1

8977

param.Grr=2; % use newer Grr

9383

param.Grr=2; % use newer Grr

8978

end

9384

end

8979

9385

8980

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

9386

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

8981

% Operational control variables

9387

% Operational control variables

8982

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9388

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

8983

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9389

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

8984

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

9390

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

8985

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

9391

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

8986

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9392

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

8987

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.

9393

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.

8988

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.

9394

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.

8989

9395

8990

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9396

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

8991

9397

8992

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)

9398

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)

8993

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9399

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

8994

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9400

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

8995

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

9401

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

8996

9402

8997

%%

9403

%%

8998

9404

8999

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9405

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9000

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9406

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9001

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9407

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9002

param.awgn_mv=param.AC_CM_RMS;

9408

param.awgn_mv=param.AC_CM_RMS;

9003

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9409

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9004

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

9410

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

9005

param.Q=xls_parameter(parameter, 'Q', true, 0 ); % Implementation penalty for MLSE in EQ 178a-36

9411

param.Q=xls_parameter(parameter, 'Q', true, 0 ); % Implementation penalty for MLSE in EQ 178a-36

9006

9412

9007

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9413

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9008

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9414

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9009

param.Floating_RXFFE=false;

9415

param.Floating_RXFFE=false;

9010

param.Floating_DFE=false;

9416

param.Floating_DFE=false;

9011

if param.N_bg > 0

9417

if param.N_bg > 0

9012

param.Floating_DFE=true;

9418

param.Floating_DFE=true;

9013

end

9419

end

9014

if OP.RxFFE

9420

if OP.RxFFE

9015

param.Floating_DFE=false;

9421

param.Floating_DFE=false;

9016

if param.N_bg > 0

9422

if param.N_bg > 0

9017

param.Floating_RXFFE=true;

9423

param.Floating_RXFFE=true;

9018

end

9424

end

9019

end

9425

end

9020

%% for introducing Tx or Rx skew on p leg or n leg

9426

%% for introducing Tx or Rx skew on p leg or n leg

9021

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9427

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9022

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9428

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9023

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9429

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9024

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9430

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9025

9431

9026

%%

9432

%%

9027

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9433

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9028

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9434

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9029

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9435

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9030

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9436

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9031

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9437

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9032

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9438

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9033

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9439

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9034

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9440

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9035

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9441

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9036

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

9442

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

9037

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9443

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9038

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9444

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9039

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9445

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9040

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

9446

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

9041

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

9447

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

9042

if ~OP.INC_PACKAGE

9448

if ~OP.INC_PACKAGE

9043

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');

9449

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');

9044

end

9450

end

9045

9451

9046

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9452

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9047

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9453

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9048

if OP.IDEAL_TX_TERM

9454

if OP.IDEAL_TX_TERM

9049

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9455

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9050

end

9456

end

9051

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9457

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9052

if OP.IDEAL_RX_TERM

9458

if OP.IDEAL_RX_TERM

9053

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9459

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9054

end

9460

end

9055

9461

9056

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.

9462

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.

9057

9463

9058

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9464

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9059

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9465

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9060

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9466

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9061

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

9467

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

9062

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9468

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9063

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

9469

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

9064

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9470

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9065

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

9471

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

9066

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

9472

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

9067

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

9473

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

9068

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9474

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9069

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9475

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9070

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

9476

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

9071

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.

9477

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.

9072

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9478

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9073

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9479

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9074

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9480

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9075

9481

9076

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9482

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9077

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9483

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9078

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.

9484

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.

9079

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9485

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9080

% compatibility

9486

% compatibility

9081

if OP.FORCE_TR

9487

if OP.FORCE_TR

9082

OP.T_r_meas_point=0;

9488

OP.T_r_meas_point=0;

9083

OP.T_r_filter_type=1;

9489

OP.T_r_filter_type=1;

9084

end

9490

end

9085

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9491

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9086

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.

9492

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.

9087

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9493

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9088

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9494

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9089

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.

9495

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.

9090

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9496

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9091

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9497

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9092

if OP.ERL

9498

if OP.ERL

9093

OP.PTDR=1;

9499

OP.PTDR=1;

9094

else

9500

else

9095

OP.PTDR=0;

9501

OP.PTDR=0;

9096

end % ERL needs to do a TDR

9502

end % ERL needs to do a TDR

9097

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9503

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9098

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9504

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9099

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9505

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9100

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9506

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9101

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9507

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9102

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9508

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9103

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9509

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9104

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9510

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9105

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.

9511

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.

9106

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9512

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9107

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9513

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9108

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.

9514

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.

9109

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9515

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9110

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9516

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9111

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9517

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9112

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9518

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9113

if strcmpi(OP.PHY,'C2M')

9519

if strcmpi(OP.PHY,'C2M')

9114

OP.EW=true;

9520

OP.EW=true;

9115

else

9521

else

9116

param.T_O=0; % make sure when c2c that sample is at Ts

9522

param.T_O=0; % make sure when c2c that sample is at Ts

9117

end

9523

end

9118

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9524

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9119

OP.PHY='C2Mcom';

9525

OP.PHY='C2Mcom';

9120

end

9526

end

9121

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9527

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9122

switch lower(OP.TDECQ)

9528

switch lower(OP.TDECQ)

9123

case {false 'none' 'vma'}

9529

case {false 'none' 'vma'}

9124

otherwise

9530

otherwise

9125

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9531

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9126

end

9532

end

9127

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9533

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9128

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9534

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9129

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9535

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9130

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9536

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9131

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

9537

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

9132

% Parameters for error burst probability calculation. Not officially used

9538

% Parameters for error burst probability calculation. Not officially used

9133

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9539

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9134

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9540

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9135

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9541

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9136

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.

9542

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.

9137

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.

9543

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.

9138

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9544

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9139

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.

9545

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.

9140

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9546

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9141

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9547

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9142

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9548

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9143

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9549

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9144

OP.MLSD = xls_parameter(parameter, 'MLSD', false, 0); % not 0 or missing means use MLSD

9550

OP.MLSE = xls_parameter(parameter, 'MLSE', false, 0); % MLSE 0,1,2, 3 (no MLSE, U1 MLSE, experimetal MLSE, U3 MLSE)

9145

OP.MLSE = xls_parameter(parameter, 'MLSE', false, OP.MLSD ); % MSLD Synonym support

9146

if OP.MLSE ~=0

9147

if param.T_O ~= 0

9148

error('MLSD nnot presently no supported for VEC')

9149

end

9150

if OP.COM_CONTRIBUTION_CURVES ~=0

9151

warning("COM_CONTRIBUTION_CURVES not functional yet with MLSE")

9152

OP.COM_CONTRIBUTION_CURVES=0;

9153

end

9154

end

9155

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9551

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9156

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9552

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9157

if OP.MLSE && param.ndfe==0

9553

if OP.MLSE && param.ndfe==0

9158

error('At least DFE 1 must be set to use MLSE');

9554

error('At least DFE 1 must be set to use MLSE');

9159

end

9555

end

9160

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9556

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9161

% MNSE parameters

9557

% MNSE parameters

9162

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9558

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9163

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9559

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9164

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9560

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9165

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9561

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9166

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9562

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9167

% Commit request 4p4_7, healey_3dj_COM_01_240416

9563

% Commit request 4p4_7, healey_3dj_COM_01_240416

9168

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

9564

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

9169

% need to make sure TD mode does not invoke FD operations

9565

% need to make sure TD mode does not invoke FD operations

9170

if OP.TDMODE % need to set GET_FD false of TDMODE

9566

if OP.TDMODE % need to set GET_FD false of TDMODE

9171

OP.GET_FD=false;

9567

OP.GET_FD=false;

9172

OP.ERL_ONLY=0;

9568

OP.ERL_ONLY=0;

9173

OP.ERL=0;

9569

OP.ERL=0;

9174

OP.PTDR=0;

9570

OP.PTDR=0;

9175

OP.TDR=0;

9571

OP.TDR=0;

9176

OP.RX_CALIBRATION=0;

9572

OP.RX_CALIBRATION=0;

9177

end

9573

end

9178

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9574

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9179

save(matcongfile ,'parameter');

9575

save(matcongfile ,'parameter');

9180

end

9576

end

9181

9577

9182

9578

9183

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9579

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9184

if ~isempty(param.PKG_NAME)

9580

if ~isempty(param.PKG_NAME)

9185

if length(param.PKG_NAME) == 1

9581

if length(param.PKG_NAME) == 1

9186

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9582

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9187

end

9583

end

9188

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9584

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9189

tx_rx_fields_matrix = {'pkg_Z_c'};

9585

tx_rx_fields_matrix = {'pkg_Z_c'};

9190

tx_fields = {'z_p_tx_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9586

tx_fields = {'z_p_tx_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9191

rx_fields = {'z_p_rx_cases' 'a_next' 'z_p_next_cases'};

9587

rx_fields = {'z_p_rx_cases' 'a_next' 'z_p_next_cases'};

9192

tx_pkg_name=param.PKG_NAME{1};

9588

tx_pkg_name=param.PKG_NAME{1};

9193

rx_pkg_name=param.PKG_NAME{2};

9589

rx_pkg_name=param.PKG_NAME{2};

9194

tx_pkg_struct=param.PKG.(tx_pkg_name);

9590

tx_pkg_struct=param.PKG.(tx_pkg_name);

9195

rx_pkg_struct=param.PKG.(rx_pkg_name);

9591

rx_pkg_struct=param.PKG.(rx_pkg_name);

9196

9592

9197

%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

9593

%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

9198

for j=1:length(tx_rx_fields)

9594

for j=1:length(tx_rx_fields)

9199

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9595

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9200

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9596

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9201

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9597

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9202

end

9598

end

9203

9599

9204

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9600

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9205

for j=1:length(tx_rx_fields_matrix)

9601

for j=1:length(tx_rx_fields_matrix)

9206

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9602

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9207

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9603

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9208

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9604

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9209

end

9605

end

9210

9606

9211

%tx_fields: use only the tx package values

9607

%tx_fields: use only the tx package values

9212

for j=1:length(tx_fields)

9608

for j=1:length(tx_fields)

9213

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9609

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9214

end

9610

end

9215

9611

9216

%rx_fields: use only the rx package values

9612

%rx_fields: use only the rx package values

9217

for j=1:length(rx_fields)

9613

for j=1:length(rx_fields)

9218

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9614

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9219

end

9615

end

9220

9616

9221

end

9617

end

9222

9618

9223

9619

9224

%%

9620

%%

9225

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9621

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9226

%% FUNCTION :: read_sp4_sparams

9622

%% FUNCTION :: read_sp4_sparams

9227

%

9623

%

9228

% Description

9624

% Description

9229

% Read the fid of single-ended 4-port complex S-parameters

9625

% Read the fid of single-ended 4-port complex S-parameters

9230

% in Touchstone format 'file' and convert to the internal

9626

% in Touchstone format 'file' and convert to the internal

9231

% format using the port transform 'ports'

9627

% format using the port transform 'ports'

9232

%

9628

%

9233

% Created by Mike Y. He

9629

% Created by Mike Y. He

9234

% April 22, 2005

9630

% April 22, 2005

9235

%

9631

%

9236

% Reused some code from

9632

% Reused some code from

9237

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9633

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9238

% for touchstone 4-port S-matrix import.

9634

% for touchstone 4-port S-matrix import.

9239

%

9635

%

9240

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9636

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9241

% optimized for quicker parameter matching and parsing. also, separated out

9637

% optimized for quicker parameter matching and parsing. also, separated out

9242

% the plotting algorithms into their own sub-function routines

9638

% the plotting algorithms into their own sub-function routines

9243

%

9639

%

9244

% Modified December 2021 to use read_Nport_touchstone

9640

% Modified December 2021 to use read_Nport_touchstone

9245

% This is faster reader that is capable of reading touchstone with any number of ports

9641

% This is faster reader that is capable of reading touchstone with any number of ports

9246

%

9642

%

9247

% Input Variables (required)

9643

% Input Variables (required)

9248

% infile -- The s4p file to be read and converted

9644

% infile -- The s4p file to be read and converted

9249

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9645

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9250

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9646

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9251

% ports -- Re-order the port layout

9647

% ports -- Re-order the port layout

9252

%

9648

%

9253

% Output/Return Variables

9649

% Output/Return Variables

9254

% data -- structure containing network parameter data points and frequency axis

9650

% data -- structure containing network parameter data points and frequency axis

9255

% sdc -- the differential in/common-mode out s-parameter data matrix

9651

% sdc -- the differential in/common-mode out s-parameter data matrix

9256

% sdd -- the differential in/differential out s-parameter data matrix

9652

% sdd -- the differential in/differential out s-parameter data matrix

9257

%

9653

%

9258

9654

9259

9655

9260

% backwards compatibility settings. can be removed in updated code.

9656

% backwards compatibility settings. can be removed in updated code.

9261

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9657

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9262

if isempty(ports); ports = [1 2]; end % default order normally used.

9658

if isempty(ports); ports = [1 2]; end % default order normally used.

9263

ports = [1 2];

9659

ports = [1 2];

9264

9660

9265

9661

9266

if OP.DISPLAY_WINDOW

9662

if OP.DISPLAY_WINDOW

9267

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9663

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9268

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9664

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9269

end

9665

end

9270

9666

9271

%AJG: fast touchstone read for any number of ports

9667

%AJG: fast touchstone read for any number of ports

9272

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9668

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9273

9669

9274

9670

9275

9671

9276

D=NaN(size(sch));

9672

D=NaN(size(sch));

9277

% calculate differential s parameter matrix from single ended

9673

% calculate differential s parameter matrix from single ended

9278

for i=1:size(sch,1)

9674

for i=1:size(sch,1)

9279

S(:,:) = sch(i,:,:);

9675

S(:,:) = sch(i,:,:);

9280

T = [1 1 ; 1 -1 ];

9676

T = [1 1 ; 1 -1 ];

9281

W = T * (S / T);

9677

W = T * (S / T);

9282

D(i,:,:) = W(:,:);

9678

D(i,:,:) = W(:,:);

9283

end

9679

end

9284

9680

9285

% D matrix should be

9681

% D matrix should be

9286

% Scc11 Scd11 Scc12 Scd21

9682

% Scc11 Scd11 Scc12 Scd21

9287

% Sdc11 Sdd11 Sdc12 Sdd12

9683

% Sdc11 Sdd11 Sdc12 Sdd12

9288

% Scc21 Scd21 Scc22 Scd22

9684

% Scc21 Scd21 Scc22 Scd22

9289

% Sdc21 Sdd21 Sdc22 Sdd22

9685

% Sdc21 Sdd21 Sdc22 Sdd22

9290

9686

9291

% proper values

9687

% proper values

9292

%AJG: matrix can be properly referenced after fixing mapping

9688

%AJG: matrix can be properly referenced after fixing mapping

9293

SDD(:,1,1) = D(:,2,2);

9689

SDD(:,1,1) = D(:,2,2);

9294

SDC(:,1,1)= D(:,2,1);

9690

SDC(:,1,1)= D(:,2,1);

9295

SCC(:,1,1)= D(:,1,1);

9691

SCC(:,1,1)= D(:,1,1);

9296

SCD(:,1,1)= D(:,1,2);

9692

SCD(:,1,1)= D(:,1,2);

9297

9693

9298

9694

9299

9695

9300

% backwards compatibility output variables

9696

% backwards compatibility output variables

9301

data.m = sch;

9697

data.m = sch;

9302

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9698

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9303

data.freq = schFreqAxis;

9699

data.freq = schFreqAxis;

9304

colors = 'rgbk';

9700

colors = 'rgbk';

9305

9701

9306

if (plot_ini_s_params == 1)

9702

if (plot_ini_s_params == 1)

9307

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9703

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9308

for mj=1:4

9704

for mj=1:4

9309

% subplot(2,2,mj);

9705

% subplot(2,2,mj);

9310

for mi=1:4

9706

for mi=1:4

9311

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9707

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9312

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9708

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9313

hold on

9709

hold on

9314

end

9710

end

9315

xlabel('Frequency (Hz)');

9711

xlabel('Frequency (Hz)');

9316

ylabel('Magnitude (dB)');

9712

ylabel('Magnitude (dB)');

9317

legend show

9713

legend show

9318

grid on

9714

grid on

9319

title(sprintf('Output port %d', mj));

9715

title(sprintf('Output port %d', mj));

9320

end

9716

end

9321

end

9717

end

9322

plot_dif_s_params =0;

9718

plot_dif_s_params =0;

9323

if (plot_dif_s_params == 1)

9719

if (plot_dif_s_params == 1)

9324

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9720

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9325

% subplot(2,1,1);

9721

% subplot(2,1,1);

9326

for mj=1:1

9722

for mj=1:1

9327

for mi=1:1

9723

for mi=1:1

9328

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9724

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9329

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9725

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9330

hold on

9726

hold on

9331

end

9727

end

9332

end

9728

end

9333

xlabel('Frequency (Hz)');

9729

xlabel('Frequency (Hz)');

9334

ylabel('Magnitude (dB)');

9730

ylabel('Magnitude (dB)');

9335

legend show

9731

legend show

9336

grid on

9732

grid on

9337

title(infile);

9733

title(infile);

9338

9734

9339

% subplot(2,1,2);

9735

% subplot(2,1,2);

9340

% for mj=1:2

9736

% for mj=1:2

9341

% for mi=1:2

9737

% for mi=1:2

9342

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9738

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9343

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9739

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9344

% hold on

9740

% hold on

9345

% end

9741

% end

9346

% end

9742

% end

9347

% xlabel('Frequency (Hz)');

9743

% xlabel('Frequency (Hz)');

9348

% ylabel('Magnitude (dB)');

9744

% ylabel('Magnitude (dB)');

9349

% legend show

9745

% legend show

9350

% grid on

9746

% grid on

9351

end

9747

end

9352

9748

9353

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9749

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9354

% end read_sp2_sparam

9750

% end read_sp2_sparam

9355

9751

9356

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9752

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9357

%% FUNCTION :: read_sp4_sparams

9753

%% FUNCTION :: read_sp4_sparams

9358

%

9754

%

9359

% Description

9755

% Description

9360

% Read the fid of single-ended 4-port complex S-parameters

9756

% Read the fid of single-ended 4-port complex S-parameters

9361

% in Touchstone format 'file' and convert to the internal

9757

% in Touchstone format 'file' and convert to the internal

9362

% format using the port transform 'ports'

9758

% format using the port transform 'ports'

9363

%

9759

%

9364

% Created by Mike Y. He

9760

% Created by Mike Y. He

9365

% April 22, 2005

9761

% April 22, 2005

9366

%

9762

%

9367

% Reused some code from

9763

% Reused some code from

9368

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9764

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9369

% for touchstone 4-port S-matrix import.

9765

% for touchstone 4-port S-matrix import.

9370

%

9766

%

9371

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9767

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9372

% optimized for quicker parameter matching and parsing. also, separated out

9768

% optimized for quicker parameter matching and parsing. also, separated out

9373

% the plotting algorithms into their own sub-function routines

9769

% the plotting algorithms into their own sub-function routines

9374

%

9770

%

9375

% Modified December 2021 to use read_Nport_touchstone

9771

% Modified December 2021 to use read_Nport_touchstone

9376

% This is faster reader that is capable of reading touchstone with any number of ports

9772

% This is faster reader that is capable of reading touchstone with any number of ports

9377

%

9773

%

9378

% Input Variables (required)

9774

% Input Variables (required)

9379

% infile -- The s4p file to be read and converted

9775

% infile -- The s4p file to be read and converted

9380

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9776

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9381

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9777

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9382

% ports -- Re-order the port layout

9778

% ports -- Re-order the port layout

9383

% OP

9779

% OP

9384

% param

9780

% param

9385

% Output/Return Variables

9781

% Output/Return Variables

9386

% data -- structure containing network parameter data points and frequency axis

9782

% data -- structure containing network parameter data points and frequency axis

9387

% sdd -- the differential in/differential out s-parameter data matrix

9783

% sdd -- the differential in/differential out s-parameter data matrix

9388

% sdc -- the differential in/common-mode out s-parameter data matrix

9784

% sdc -- the differential in/common-mode out s-parameter data matrix

9389

% scc -- the common mode in/common-mode out s-parameter data matrix

9785

% scc -- the common mode in/common-mode out s-parameter data matrix

9390

%

9786

%

9391

%

9787

%

9392

9788

9393

9789

9394

% backwards compatibility settings. can be removed in updated code.

9790

% backwards compatibility settings. can be removed in updated code.

9395

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9791

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9396

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9792

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9397

9793

9398

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9794

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9399

% pair is reversed.

9795

% pair is reversed.

9400

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9796

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9401

9797

9402

if OP.DISPLAY_WINDOW

9798

if OP.DISPLAY_WINDOW

9403

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9799

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9404

end

9800

end

9405

9801

9406

%AJG: fast touchstone read for any number of ports

9802

%AJG: fast touchstone read for any number of ports

9407

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9803

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9408

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9804

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9409

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9805

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9410

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9806

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9411

Sigfct = ...

9807

Sigfct = ...

9412

@(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]);

9808

@(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]);

9413

D=NaN(size(sch));

9809

D=NaN(size(sch));

9414

% calculate differential s parameter matrix from single ended

9810

% calculate differential s parameter matrix from single ended

9415

% skew added RIM 12/29/2023

9811

% skew added RIM 12/29/2023

9416

for i=1:size(sch,1)

9812

for i=1:size(sch,1)

9417

f=schFreqAxis(i);

9813

f=schFreqAxis(i);

9418

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) );

9814

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) );

9419

S(:,:) = sch(i,:,:);

9815

S(:,:) = sch(i,:,:);

9420

Snew=sigma_matrix.*S;

9816

Snew=sigma_matrix.*S;

9421

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9817

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9422

W = T * (Snew / T);

9818

W = T * (Snew / T);

9423

D(i,:,:) = W(:,:);

9819

D(i,:,:) = W(:,:);

9424

end

9820

end

9425

9821

9426

% D matrix should be

9822

% D matrix should be

9427

% Scc11 Scd11 Scc12 Scd21

9823

% Scc11 Scd11 Scc12 Scd21

9428

% Sdc11 Sdd11 Sdc12 Sdd12

9824

% Sdc11 Sdd11 Sdc12 Sdd12

9429

% Scc21 Scd21 Scc22 Scd22

9825

% Scc21 Scd21 Scc22 Scd22

9430

% Sdc21 Sdd21 Sdc22 Sdd22

9826

% Sdc21 Sdd21 Sdc22 Sdd22

9431

9827

9432

% proper values

9828

% proper values

9433

SDD(:,1,1) = D(:,2,2);

9829

SDD(:,1,1) = D(:,2,2);

9434

SDD(:,2,2) = D(:,4,4);

9830

SDD(:,2,2) = D(:,4,4);

9435

SDD(:,1,2) = D(:,2,4);

9831

SDD(:,1,2) = D(:,2,4);

9436

SDD(:,2,1) = D(:,4,2);

9832

SDD(:,2,1) = D(:,4,2);

9437

9833

9438

SDC(:,1,1) = D(:,2,1);

9834

SDC(:,1,1) = D(:,2,1);

9439

SDC(:,2,2) = D(:,4,3);

9835

SDC(:,2,2) = D(:,4,3);

9440

SDC(:,1,2) = D(:,2,3);

9836

SDC(:,1,2) = D(:,2,3);

9441

SDC(:,2,1) = D(:,4,1);

9837

SDC(:,2,1) = D(:,4,1);

9442

9838

9443

SCC(:,1,1) = D(:,1,1);

9839

SCC(:,1,1) = D(:,1,1);

9444

SCC(:,2,2) = D(:,3,3);

9840

SCC(:,2,2) = D(:,3,3);

9445

SCC(:,1,2) = D(:,1,3);

9841

SCC(:,1,2) = D(:,1,3);

9446

SCC(:,2,1) = D(:,3,1);

9842

SCC(:,2,1) = D(:,3,1);

9447

9843

9448

% backwards compatibility output variables

9844

% backwards compatibility output variables

9449

data.m = sch;

9845

data.m = sch;

9450

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9846

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9451

data.freq = schFreqAxis;

9847

data.freq = schFreqAxis;

9452

colors = 'rgbk';

9848

colors = 'rgbk';

9453

9849

9454

if (plot_ini_s_params == 1)

9850

if (plot_ini_s_params == 1)

9455

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9851

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9456

for mj=1:4

9852

for mj=1:4

9457

subplot(2,2,mj);

9853

subplot(2,2,mj);

9458

for mi=1:4

9854

for mi=1:4

9459

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9855

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9460

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9856

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9461

hold on

9857

hold on

9462

end

9858

end

9463

xlabel('Frequency (Hz)');

9859

xlabel('Frequency (Hz)');

9464

ylabel('Magnitude (dB)');

9860

ylabel('Magnitude (dB)');

9465

legend show

9861

legend show

9466

grid on

9862

grid on

9467

title(sprintf('Output port %d', mj));

9863

title(sprintf('Output port %d', mj));

9468

end

9864

end

9469

end

9865

end

9470

plot_dif_s_params =0;

9866

plot_dif_s_params =0;

9471

if (plot_dif_s_params == 1)

9867

if (plot_dif_s_params == 1)

9472

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9868

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9473

% subplot(2,1,1);

9869

% subplot(2,1,1);

9474

for mj=1:2

9870

for mj=1:2

9475

for mi=1:2

9871

for mi=1:2

9476

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9872

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9477

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9873

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9478

hold on

9874

hold on

9479

end

9875

end

9480

end

9876

end

9481

xlabel('Frequency (Hz)');

9877

xlabel('Frequency (Hz)');

9482

ylabel('Magnitude (dB)');

9878

ylabel('Magnitude (dB)');

9483

legend show

9879

legend show

9484

grid on

9880

grid on

9485

title(infile);

9881

title(infile);

9486

%

9882

%

9487

% subplot(2,1,2);

9883

% subplot(2,1,2);

9488

% for mj=1:2

9884

% for mj=1:2

9489

% for mi=1:2

9885

% for mi=1:2

9490

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9886

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9491

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9887

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9492

% hold on

9888

% hold on

9493

% end

9889

% end

9494

% end

9890

% end

9495

% xlabel('Frequency (Hz)');

9891

% xlabel('Frequency (Hz)');

9496

% ylabel('Magnitude (dB)');

9892

% ylabel('Magnitude (dB)');

9497

% legend show

9893

% legend show

9498

% grid on

9894

% grid on

9499

end

9895

end

9500

9896

9501

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9897

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9502

% end read_sp4_sparam

9898

% end read_sp4_sparam

9503

function param_struct = read_package_parameters(parameter,param_struct)

9899

function param_struct = read_package_parameters(parameter,param_struct)

9504

9900

9505

%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

9901

%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

9506

%This block should eventually replace what is in read_ParamConfigFile

9902

%This block should eventually replace what is in read_ParamConfigFile

9507

%It can be called as: param = read_package_parameters(parameter, param)

9903

%It can be called as: param = read_package_parameters(parameter, param)

9508

9904

9509

if nargin<2

9905

if nargin<2

9510

%param_struct doesn't need to be passed when building a new package structure

9906

%param_struct doesn't need to be passed when building a new package structure

9511

%it is only needed when appending to regular param structure

9907

%it is only needed when appending to regular param structure

9512

param_struct=struct;

9908

param_struct=struct;

9513

end

9909

end

9514

9910

9515

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9911

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9516

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9912

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9517

9913

9518

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9914

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9519

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9915

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9520

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9916

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9521

9917

9522

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

9918

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

9523

[ncases, mele]=size(param_struct.z_p_tx_cases);

9919

[ncases, mele]=size(param_struct.z_p_tx_cases);

9524

if mele ==2

9920

if mele ==2

9525

param_struct.flex=2;

9921

param_struct.flex=2;

9526

elseif mele==4

9922

elseif mele==4

9527

param_struct.flex=4;

9923

param_struct.flex=4;

9528

elseif mele==1

9924

elseif mele==1

9529

param_struct.flex=1;

9925

param_struct.flex=1;

9530

else

9926

else

9531

error('config file syntax error')

9927

error('config file syntax error')

9532

end

9928

end

9533

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

9929

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

9534

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9930

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9535

if ncases ~= ncases1 || mele ~= mele1

9931

if ncases ~= ncases1 || mele ~= mele1

9536

error('All TX, NEXT, FEXT, Rx cases must agree');

9932

error('All TX, NEXT, FEXT, Rx cases must agree');

9537

else

9933

else

9538

end

9934

end

9539

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

9935

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

9540

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9936

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9541

if ncases ~= ncases1 || mele ~= mele1

9937

if ncases ~= ncases1 || mele ~= mele1

9542

error('All TX, NEXT, FEXT, Rx cases must agree');

9938

error('All TX, NEXT, FEXT, Rx cases must agree');

9543

else

9939

else

9544

end

9940

end

9545

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

9941

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

9546

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9942

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9547

if ncases ~= ncases1 || mele ~= mele1

9943

if ncases ~= ncases1 || mele ~= mele1

9548

error('All TX, NEXT, FEXT, Rx cases must agree');

9944

error('All TX, NEXT, FEXT, Rx cases must agree');

9549

else

9945

else

9550

end

9946

end

9551

% Table 93A-3 parameters

9947

% Table 93A-3 parameters

9552

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.

9948

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.

9553

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9949

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9554

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9950

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9555

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9951

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9556

if mele ~= mele1

9952

if mele ~= mele1

9557

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9953

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9558

else

9954

else

9559

end

9955

end

9560

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9956

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9561

for ii=1:ncases

9957

for ii=1:ncases

9562

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9958

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9563

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9959

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9564

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9960

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9565

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9961

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9566

end

9962

end

9567

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9963

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9568

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9964

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9569

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9965

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9570

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9966

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9571

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9967

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9572

end

9968

end

9573

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9969

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9574

%% extract s-parameter and convert to differential mode

9970

%% extract s-parameter and convert to differential mode

9575

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9971

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9576

num_files=length(chdata);

9972

num_files=length(chdata);

9577

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9973

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9578

for i=1:num_files

9974

for i=1:num_files

9579

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9975

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9580

progress = i/num_files;

9976

progress = i/num_files;

9581

if OP.DISPLAY_WINDOW

9977

if OP.DISPLAY_WINDOW

9582

[~,a]=fileparts(chdata(i).filename);

9978

[~,a]=fileparts(chdata(i).filename);

9583

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9979

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9584

else

9980

else

9585

fprintf('%i ',i);

9981

fprintf('%i ',i);

9586

end

9982

end

9587

9983

9588

% Skip reading file if it was already read (multiple test cases)

9984

% Skip reading file if it was already read (multiple test cases)

9589

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9985

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9590

switch lower(chdata(i).ext)

9986

switch lower(chdata(i).ext)

9591

case '.s2p' % for differential return loss

9987

case '.s2p' % for differential return loss

9592

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9988

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9593

chdata(i).fmaxi = length(Sch.freq);

9989

chdata(i).fmaxi = length(Sch.freq);

9594

chdata(i).faxis = Sch.freq;

9990

chdata(i).faxis = Sch.freq;

9595

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9991

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9596

SDDp2p(i)=NaN;

9992

SDDp2p(i)=NaN;

9597

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9993

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9598

chdata(i).sdd11=chdata(i).sdd11_raw;

9994

chdata(i).sdd11=chdata(i).sdd11_raw;

9599

case '.s4p'

9995

case '.s4p'

9600

if length(param.snpPortsOrder) ~= 4

9996

if length(param.snpPortsOrder) ~= 4

9601

error( 'warning:sNpFilePortMismatch', ...

9997

error( 'warning:sNpFilePortMismatch', ...

9602

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9998

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9603

length(param.snpPortsOrder), ...

9999

length(param.snpPortsOrder), ...

9604

chdata(i).ext ...

10000

chdata(i).ext ...

9605

);

10001

);

9606

end

10002

end

9607

% read function returns differnetial mode parameters

10003

% read function returns differnetial mode parameters

9608

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

10004

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9609

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

10005

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9610

% param.holdsdata(i).Sch= Sch;

10006

% param.holdsdata(i).Sch= Sch;

9611

% param.holdsdata(i).SDDch= SDDch;

10007

% param.holdsdata(i).SDDch= SDDch;

9612

% param.holdsdata(i).SDCch= SDCch;

10008

% param.holdsdata(i).SDCch= SDCch;

9613

else

10009

else

9614

error('If this line is reached, there is a logic error');

10010

error('If this line is reached, there is a logic error');

9615

% Sch=param.holdsdata(i).Sch;

10011

% Sch=param.holdsdata(i).Sch;

9616

% SDDch=param.holdsdata(i).SDDch;

10012

% SDDch=param.holdsdata(i).SDDch;

9617

% SDCch=param.holdsdata(i).SDCch;

10013

% SDCch=param.holdsdata(i).SDCch;

9618

end

10014

end

9619

chdata(i).fmaxi = length(Sch.freq);

10015

chdata(i).fmaxi = length(Sch.freq);

9620

10016

9621

10017

9622

if Sch.freq(chdata(i).fmaxi) < param.fb

10018

if Sch.freq(chdata(i).fmaxi) < param.fb

9623

warning('COM:read_s4p:MaxFreqTooLow', ...

10019

warning('COM:read_s4p:MaxFreqTooLow', ...

9624

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

10020

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9625

chdata(i).filename, Sch.freq(end), param.fb);

10021

chdata(i).filename, Sch.freq(end), param.fb);

9626

end

10022

end

9627

if Sch.freq(1) > param.max_start_freq

10023

if Sch.freq(1) > param.max_start_freq

9628

warning('COM:read_s4p:StartFreqTooHigh', ...

10024

warning('COM:read_s4p:StartFreqTooHigh', ...

9629

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

10025

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9630

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

10026

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9631

end

10027

end

9632

freqstep=diff(Sch.freq);

10028

freqstep=diff(Sch.freq);

9633

% ignore frequency differences up to 1 Hz - possible numerical artifacts

10029

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9634

if max(freqstep)-min(freqstep) > 1

10030

if max(freqstep)-min(freqstep) > 1

9635

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

10031

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9636

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

10032

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9637

end

10033

end

9638

if max(freqstep) - param.max_freq_step > 1

10034

if max(freqstep) - param.max_freq_step > 1

9639

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

10035

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9640

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

10036

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9641

end

10037

end

9642

10038

9643

chdata(i).faxis = Sch.freq;

10039

chdata(i).faxis = Sch.freq;

9644

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

10040

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9645

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

10041

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9646

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

10042

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9647

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

10043

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9648

% mode conversion

10044

% mode conversion

9649

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

10045

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9650

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

10046

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9651

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

10047

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9652

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

10048

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9653

%save original and add board (if required)

10049

%save original and add board (if required)

9654

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

10050

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9655

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

10051

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

9656

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

10052

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

9657

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

10053

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

9658

if OP.include_pcb

10054

if OP.include_pcb

9659

% add boards to sdd

10055

% add boards to sdd

9660

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

10056

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

9661

10057

9662

end

10058

end

9663

%save final return loss (after the boards were included)

10059

%save final return loss (after the boards were included)

9664

chdata(i).sdd11=chdata(i).sdd11_raw;

10060

chdata(i).sdd11=chdata(i).sdd11_raw;

9665

chdata(i).sdd22=chdata(i).sdd22_raw;

10061

chdata(i).sdd22=chdata(i).sdd22_raw;

9666

otherwise

10062

otherwise

9667

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

10063

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

9668

end

10064

end

9669

10065

9670

%Crosstalk frequency axis must be the same as Thru

10066

%Crosstalk frequency axis must be the same as Thru

9671

if i>1

10067

if i>1

9672

%error on length difference

10068

%error on length difference

9673

if length(chdata(i).faxis)~=length(chdata(1).faxis)

10069

if length(chdata(i).faxis)~=length(chdata(1).faxis)

9674

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

10070

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

9675

end

10071

end

9676

%error if any value > 1Hz (don't want to check for exact

10072

%error if any value > 1Hz (don't want to check for exact

9677

%equality in case of floating point error)

10073

%equality in case of floating point error)

9678

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

10074

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

9679

if max(Fdiff)>1

10075

if max(Fdiff)>1

9680

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

10076

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

9681

end

10077

end

9682

end

10078

end

9683

else

10079

else

9684

SDDch(:,1,2)=chdata(i).sdd12_raw;

10080

SDDch(:,1,2)=chdata(i).sdd12_raw;

9685

SDDch(:,2,1)=chdata(i).sdd21_raw;

10081

SDDch(:,2,1)=chdata(i).sdd21_raw;

9686

SDDch(:,1,1)=chdata(i).sdd11_raw;

10082

SDDch(:,1,1)=chdata(i).sdd11_raw;

9687

SDDch(:,2,2)=chdata(i).sdd22_raw;

10083

SDDch(:,2,2)=chdata(i).sdd22_raw;

9688

end

10084

end

9689

chdata(i).sigma_ACCM_at_tp0=0;

10085

chdata(i).sigma_ACCM_at_tp0=0;

9690

if ~param.FLAG.S2P

10086

if ~param.FLAG.S2P

9691

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

10087

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

9692

if (OP.RX_CALIBRATION == 1 && i==2)

10088

if (OP.RX_CALIBRATION == 1 && i==2)

9693

chdata(i).sdd21=chdata(i).sdd21_raw;

10089

chdata(i).sdd21=chdata(i).sdd21_raw;

9694

else

10090

else

9695

%updated package construction with single function for both DD and DC

10091

%updated package construction with single function for both DD and DC

9696

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

10092

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

9697

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

10093

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

9698

chdata(i).sdd21=chdata(i).sdd21p;

10094

chdata(i).sdd21=chdata(i).sdd21p;

9699

if 1 % for AC CM noise inclusion

10095

if 1 % for AC CM noise inclusion

9700

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

10096

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

9701

chdata(i).sdc21=chdata(i).sdc21p;

10097

chdata(i).sdc21=chdata(i).sdc21p;

9702

end

10098

end

9703

end

10099

end

9704

else

10100

else

9705

chdata(i).sdd21=chdata(i).sdd21_raw;

10101

chdata(i).sdd21=chdata(i).sdd21_raw;

9706

end

10102

end

9707

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

10103

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

9708

end

10104

end

9709

end

10105

end

9710

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

10106

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

9711

10107

9712

function result = readdataSnPx(filename, nport)

10108

function result = readdataSnPx(filename, nport)

9713

%function [freq, cs] = readdataSnPx(filename, nport)

10109

%function [freq, cs] = readdataSnPx(filename, nport)

9714

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

10110

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

9715

%

10111

%

9716

% Read Touchstone file with frequencies in units of Hertz

10112

% Read Touchstone file with frequencies in units of Hertz

9717

%

10113

%

9718

% Input:

10114

% Input:

9719

% ======

10115

% ======

9720

% filename: Name of the Touchstone/SnP file

10116

% filename: Name of the Touchstone/SnP file

9721

% nport: Number of ports

10117

% nport: Number of ports

9722

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

10118

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

9723

% Touchstone file)

10119

% Touchstone file)

9724

% nheader: Number of header lines (comment lines plus option line in the

10120

% nheader: Number of header lines (comment lines plus option line in the

9725

% Touchstone file)

10121

% Touchstone file)

9726

%

10122

%

9727

% Output:

10123

% Output:

9728

% =======

10124

% =======

9729

% freq: Vector of frequencies [Hz]

10125

% freq: Vector of frequencies [Hz]

9730

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

10126

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

9731

% at frequency freq(k)

10127

% at frequency freq(k)

9732

%

10128

%

9733

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

10129

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

9734

% frequencies appropriately after reading the data.

10130

% frequencies appropriately after reading the data.

9735

%

10131

%

9736

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

10132

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

9737

% EIA/IBIS Open Forum, 2002.

10133

% EIA/IBIS Open Forum, 2002.

9738

%

10134

%

9739

% Written by Henning Braunisch, September 2004.

10135

% Written by Henning Braunisch, September 2004.

9740

% Updated by Steven Krooswyk, April 2006.

10136

% Updated by Steven Krooswyk, April 2006.

9741

10137

9742

10138

9743

fid = fopen(filename, 'r');

10139

fid = fopen(filename, 'r');

9744

10140

9745

10141

9746

% Skip header lines

10142

% Skip header lines

9747

str = ' ';

10143

str = ' ';

9748

n = 0;

10144

n = 0;

9749

while ~strcmp(str(1),'#')

10145

while ~strcmp(str(1),'#')

9750

str = fgetl(fid);

10146

str = fgetl(fid);

9751

if isempty(str)

10147

if isempty(str)

9752

str=' ' ;

10148

str=' ' ;

9753

if n > 1000

10149

if n > 1000

9754

display('error: could not find config line (#)')

10150

display('error: could not find config line (#)')

9755

break

10151

break

9756

end

10152

end

9757

end

10153

end

9758

n = n + 1;

10154

n = n + 1;

9759

end

10155

end

9760

10156

9761

% parse configuration line

10157

% parse configuration line

9762

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

10158

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

9763

p = find(A=='S'); %position of 'S'

10159

p = find(A=='S'); %position of 'S'

9764

units = lower(A(2:p-1)); %units before 'S'

10160

units = lower(A(2:p-1)); %units before 'S'

9765

format = A(p+1:p+2); %format after 'S'

10161

format = A(p+1:p+2); %format after 'S'

9766

10162

9767

% skip any more header lines

10163

% skip any more header lines

9768

%while ~str

10164

%while ~str

9769

10165

9770

nk = 0; % frequency counter

10166

nk = 0; % frequency counter

9771

while 1

10167

while 1

9772

10168

9773

[temp, count] = fscanf(fid, '%f', 1);

10169

[temp, count] = fscanf(fid, '%f', 1);

9774

if count == 0

10170

if count == 0

9775

temp2 = fscanf(fid, '%s', 1);

10171

temp2 = fscanf(fid, '%s', 1);

9776

if ~isempty(temp2), fgetl(fid); continue, end;

10172

if ~isempty(temp2), fgetl(fid); continue, end;

9777

break

10173

break

9778

end

10174

end

9779

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

10175

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

9780

for ni = 1:nport

10176

for ni = 1:nport

9781

for nj = 1:nport

10177

for nj = 1:nport

9782

switch lower(format)

10178

switch lower(format)

9783

case 'ma'

10179

case 'ma'

9784

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10180

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9785

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

10181

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

9786

case 'ri'

10182

case 'ri'

9787

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

10183

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

9788

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10184

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9789

case 'db'

10185

case 'db'

9790

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10186

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9791

M = 10^(db/20);

10187

M = 10^(db/20);

9792

%re = M*cos(ang);

10188

%re = M*cos(ang);

9793

%im = M*sin(ang);

10189

%im = M*sin(ang);

9794

re = M*cos(ang * pi / 180);

10190

re = M*cos(ang * pi / 180);

9795

im = M*sin(ang * pi / 180);

10191

im = M*sin(ang * pi / 180);

9796

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10192

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9797

otherwise

10193

otherwise

9798

error('readdataSnP: Unknown data format');

10194

error('readdataSnP: Unknown data format');

9799

end

10195

end

9800

end

10196

end

9801

end

10197

end

9802

end

10198

end

9803

10199

9804

fclose(fid);

10200

fclose(fid);

9805

10201

9806

% If 2-port then swap S_12 and S_21 per Touchstone spec

10202

% If 2-port then swap S_12 and S_21 per Touchstone spec

9807

if nport == 2

10203

if nport == 2

9808

temp = cs(2,1,:);

10204

temp = cs(2,1,:);

9809

cs(2,1,:) = cs(1,2,:);

10205

cs(2,1,:) = cs(1,2,:);

9810

cs(1,2,:) = temp;

10206

cs(1,2,:) = temp;

9811

end

10207

end

9812

10208

9813

% Update freq units to Hz

10209

% Update freq units to Hz

9814

switch lower(units)

10210

switch lower(units)

9815

case 'hz'

10211

case 'hz'

9816

10212

9817

case 'khz'

10213

case 'khz'

9818

freq=freq.*1e3;

10214

freq=freq.*1e3;

9819

case 'mhz'

10215

case 'mhz'

9820

freq=freq.*1e6;

10216

freq=freq.*1e6;

9821

case 'ghz'

10217

case 'ghz'

9822

freq=freq.*1e9;

10218

freq=freq.*1e9;

9823

end

10219

end

9824

10220

9825

% passivity check

10221

% passivity check

9826

result.freq = freq;

10222

result.freq = freq;

9827

result.cs = cs;

10223

result.cs = cs;

9828

10224

9829

function recolor_plots(ax)

10225

function recolor_plots(ax)

9830

10226

9831

if ~verLessThan('matlab', '8.4.0')

10227

if ~verLessThan('matlab', '8.4.0')

9832

return

10228

return

9833

end

10229

end

9834

colors='brgcmk';

10230

colors='brgcmk';

9835

ch=flipud(get(ax, 'children'));

10231

ch=flipud(get(ax, 'children'));

9836

10232

9837

for k=1:length(ch)

10233

for k=1:length(ch)

9838

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

10234

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

9839

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

10235

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

9840

end

10236

end

9841

legend (ax, 'off');

10237

legend (ax, 'off');

9842

warning('off', 'MATLAB:legend:PlotEmpty');

10238

warning('off', 'MATLAB:legend:PlotEmpty');

9843

set(legend (ax, 'show'), 'interp', 'none');

10239

set(legend (ax, 'show'), 'interp', 'none');

9844

10240

9845

function result = reduce(var1)

10241

function result = reduce(var1)

9846

% --- Reduce 1x1xn array to 1xn (aka squeeze)

10242

% --- Reduce 1x1xn array to 1xn (aka squeeze)

9847

out = zeros(1,length(var1));

10243

out = zeros(1,length(var1));

9848

out(1,:) = var1(1,1,:);

10244

out(1,:) = var1(1,1,:);

9849

result=out;

10245

result=out;

9850

10246

9851

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

10247

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

9852

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

10248

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

9853

% faxis is the frequency array

10249

% faxis is the frequency array

9854

% s21, s11, s22 are the corresponding array of differential parameters

10250

% s21, s11, s22 are the corresponding array of differential parameters

9855

% s21p includes the VFT and Tx filter if include_die=1

10251

% s21p includes the VFT and Tx filter if include_die=1

9856

if nargin<6

10252

if nargin<6

9857

include_die=1;

10253

include_die=1;

9858

end

10254

end

9859

if nargin<5

10255

if nargin<5

9860

mode='dd';

10256

mode='dd';

9861

end

10257

end

9862

10258

9863

s21=chdata.(['s' mode '21_raw']);

10259

s21=chdata.(['s' mode '21_raw']);

9864

s12=chdata.(['s' mode '12_raw']);

10260

s12=chdata.(['s' mode '12_raw']);

9865

s11=chdata.(['s' mode '11_raw']);

10261

s11=chdata.(['s' mode '11_raw']);

9866

s22=chdata.(['s' mode '22_raw']);

10262

s22=chdata.(['s' mode '22_raw']);

9867

faxis=chdata.faxis;

10263

faxis=chdata.faxis;

9868

channel_type=chdata.type;

10264

channel_type=chdata.type;

9869

10265

9870

if strcmpi(mode,'dd')

10266

if strcmpi(mode,'dd')

9871

s11=s11*param.kappa1;

10267

s11=s11*param.kappa1;

9872

s22=s22*param.kappa2;

10268

s22=s22*param.kappa2;

9873

end

10269

end

9874

10270

9875

10271

9876

Z0=param.Z0;

10272

Z0=param.Z0;

9877

%sigma_ACCM_at_tp0 is only used when mode=DC

10273

%sigma_ACCM_at_tp0 is only used when mode=DC

9878

sigma_ACCM_at_tp0=0;

10274

sigma_ACCM_at_tp0=0;

9879

10275

9880

% The following three parameters have possibly different valuesF for TX and

10276

% The following three parameters have possibly different valuesF for TX and

9881

% RX (so can be 2-element vectors).

10277

% RX (so can be 2-element vectors).

9882

R_diepad = param.R_diepad;

10278

R_diepad = param.R_diepad;

9883

10279

9884

%Make TX Package

10280

%Make TX Package

9885

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

10281

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

9886

10282

9887

%Make RX Package

10283

%Make RX Package

9888

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

10284

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

9889

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

10285

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

9890

10286

9891

10287

9892

% p(1 ,1, :)=s11in;

10288

% p(1 ,1, :)=s11in;

9893

% p(2 ,2, :)=s22in;

10289

% p(2 ,2, :)=s22in;

9894

% p(1 ,2, :)=s12in;

10290

% p(1 ,2, :)=s12in;

9895

% p(2 ,1, :)=s21in;

10291

% p(2 ,1, :)=s21in;

9896

%

10292

%

9897

% S=sparameters(p,faxis);

10293

% S=sparameters(p,faxis);

9898

% rfwrite(S,'temp.s4p');

10294

% rfwrite(S,'temp.s4p');

9899

10295

9900

if strcmpi(mode,'dc')

10296

if strcmpi(mode,'dc')

9901

RTX=R_diepad(param.Tx_rd_sel)/2;

10297

RTX=R_diepad(param.Tx_rd_sel)/2;

9902

RRX=R_diepad(param.Rx_rd_sel)/2;

10298

RRX=R_diepad(param.Rx_rd_sel)/2;

9903

Z0gamma=Z0/2;

10299

Z0gamma=Z0/2;

9904

else

10300

else

9905

RTX=R_diepad(param.Tx_rd_sel);

10301

RTX=R_diepad(param.Tx_rd_sel);

9906

RRX=R_diepad(param.Rx_rd_sel);

10302

RRX=R_diepad(param.Rx_rd_sel);

9907

Z0gamma=Z0;

10303

Z0gamma=Z0;

9908

end

10304

end

9909

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

10305

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

9910

gamma_tx=0;

10306

gamma_tx=0;

9911

else

10307

else

9912

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

10308

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

9913

end

10309

end

9914

if OP.IDEAL_RX_TERM

10310

if OP.IDEAL_RX_TERM

9915

gamma_rx=0;

10311

gamma_rx=0;

9916

else

10312

else

9917

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

10313

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

9918

end

10314

end

9919

10315

9920

if OP.INC_PACKAGE==0

10316

if OP.INC_PACKAGE==0

9921

s21p= s21;

10317

s21p= s21;

9922

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

10318

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

9923

else

10319

else

9924

if OP.RX_CALIBRATION == 1 && channel_number == 2

10320

if OP.RX_CALIBRATION == 1 && channel_number == 2

9925

% for calibration do not include the transmitter package

10321

% for calibration do not include the transmitter package

9926

[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

10322

[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

9927

SCH.Frequencies=faxis;

10323

SCH.Frequencies=faxis;

9928

SCH.Parameters(1,1,:)=s11out_rx;

10324

SCH.Parameters(1,1,:)=s11out_rx;

9929

SCH.Parameters(2,2,:)=s22out_rx;

10325

SCH.Parameters(2,2,:)=s22out_rx;

9930

SCH.Parameters(1,2,:)=s12out_rx;

10326

SCH.Parameters(1,2,:)=s12out_rx;

9931

SCH.Parameters(2,1,:)=s21out_rx;

10327

SCH.Parameters(2,1,:)=s21out_rx;

9932

SCH.NumPorts=2;

10328

SCH.NumPorts=2;

9933

SCH.Impedance=100;

10329

SCH.Impedance=100;

9934

%% Equation 93A-18

10330

%% Equation 93A-18

9935

if include_die

10331

if include_die

9936

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);

10332

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);

9937

else

10333

else

9938

s21p=s21out_rx; % if no die we do not want a VTF

10334

s21p=s21out_rx; % if no die we do not want a VTF

9939

end

10335

end

9940

else

10336

else

9941

%% Equations 93A-4 to 93A-7

10337

%% Equations 93A-4 to 93A-7

9942

if ~OP.IDEAL_TX_TERM

10338

if ~OP.IDEAL_TX_TERM

9943

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10339

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

9944

end

10340

end

9945

H_t=ones(1,length(faxis)); % .3bj compatibility

10341

H_t=ones(1,length(faxis)); % .3bj compatibility

9946

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10342

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

9947

% for RITT testing with good termination as in some instruments

10343

% for RITT testing with good termination as in some instruments

9948

% and tx filter when required

10344

% and tx filter when required

9949

if OP.T_r_filter_type==0

10345

if OP.T_r_filter_type==0

9950

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10346

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

9951

else

10347

else

9952

tr=OP.transmitter_transition_time;

10348

tr=OP.transmitter_transition_time;

9953

f9=faxis/1e9;

10349

f9=faxis/1e9;

9954

if OP.T_r_meas_point == 1

10350

if OP.T_r_meas_point == 1

9955

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10351

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

9956

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);

10352

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);

9957

else

10353

else

9958

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10354

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

9959

end

10355

end

9960

10356

9961

end

10357

end

9962

end

10358

end

9963

if strcmpi(mode,'dc')

10359

if strcmpi(mode,'dc')

9964

% 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?

10360

% 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?

9965

end

10361

end

9966

if ~OP.IDEAL_RX_TERM

10362

if ~OP.IDEAL_RX_TERM

9967

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10363

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

9968

else

10364

else

9969

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10365

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

9970

end

10366

end

9971

%% 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 )

10367

%% 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 )

9972

if include_die

10368

if include_die

9973

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);

10369

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);

9974

else

10370

else

9975

s21p=s21; % if no die we do not want a VTF

10371

s21p=s21; % if no die we do not want a VTF

9976

end

10372

end

9977

end

10373

end

9978

10374

9979

if strcmpi(mode,'dc')

10375

if strcmpi(mode,'dc')

9980

% compute AC_CM_RMS at tp0

10376

% compute AC_CM_RMS at tp0

9981

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10377

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

9982

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10378

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

9983

if channel_number == 1

10379

if channel_number == 1

9984

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10380

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

9985

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10381

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

9986

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)) ;

10382

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)) ;

9987

% S=sparameters(p,faxis);

10383

% S=sparameters(p,faxis);

9988

% rfwrite(S,'temp.s4p');

10384

% rfwrite(S,'temp.s4p');

9989

end

10385

end

9990

end

10386

end

9991

10387

9992

SCH.Frequencies=faxis;

10388

SCH.Frequencies=faxis;

9993

SCH.Parameters(1,1,:)=s11;

10389

SCH.Parameters(1,1,:)=s11;

9994

SCH.Parameters(2,2,:)=s22;

10390

SCH.Parameters(2,2,:)=s22;

9995

SCH.Parameters(1,2,:)=s12;

10391

SCH.Parameters(1,2,:)=s12;

9996

SCH.Parameters(2,1,:)=s21;

10392

SCH.Parameters(2,1,:)=s21;

9997

SCH.NumPorts=2;

10393

SCH.NumPorts=2;

9998

if strcmpi(mode,'dc')

10394

if strcmpi(mode,'dc')

9999

SCH.Impedance=25;

10395

SCH.Impedance=25;

10000

else

10396

else

10001

SCH.Impedance=100;

10397

SCH.Impedance=100;

10002

end

10398

end

10003

10399

10004

end

10400

end

10005

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10401

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10006

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10402

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10007

% Creates a time-domain impulse response from frequency-domain IL data.

10403

% Creates a time-domain impulse response from frequency-domain IL data.

10008

% IL does not need to have DC but a corresponding frequency array

10404

% IL does not need to have DC but a corresponding frequency array

10009

% (freq_array) is required.

10405

% (freq_array) is required.

10010

%

10406

%

10011

% Causality is imposed using the Alternating Projections Method. See also:

10407

% Causality is imposed using the Alternating Projections Method. See also:

10012

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10408

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10013

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10409

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10014

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10410

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10015

10411

10016

ILin=IL;

10412

ILin=IL;

10017

fmax=1/time_step/2;

10413

fmax=1/time_step/2;

10018

freq_step=(freq_array(3)-freq_array(2))/1;

10414

freq_step=(freq_array(3)-freq_array(2))/1;

10019

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10415

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10020

if all(IL==0)

10416

if all(IL==0)

10021

%response with all zeros is problematic. set to all eps and avoid interp function

10417

%response with all zeros is problematic. set to all eps and avoid interp function

10022

IL=ones(1,length(fout))*eps;

10418

IL=ones(1,length(fout))*eps;

10023

else

10419

else

10024

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10420

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10025

IL_nan = find(isnan(IL));

10421

IL_nan = find(isnan(IL));

10026

for in=IL_nan

10422

for in=IL_nan

10027

IL(in)=IL(in-1);

10423

IL(in)=IL(in-1);

10028

end

10424

end

10029

end

10425

end

10030

IL = IL(:);

10426

IL = IL(:);

10031

% add padding for time steps

10427

% add padding for time steps

10032

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10428

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10033

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10429

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10034

impulse_response = real(ifft(IL_symmetric));

10430

impulse_response = real(ifft(IL_symmetric));

10035

L = length(impulse_response);

10431

L = length(impulse_response);

10036

t_base = (0:L-1)/(freq_step*L);

10432

t_base = (0:L-1)/(freq_step*L);

10037

10433

10038

original_impulse_response=impulse_response;

10434

original_impulse_response=impulse_response;

10039

% Correct non-causal effects frequently caused by extrapolation of IL

10435

% Correct non-causal effects frequently caused by extrapolation of IL

10040

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10436

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10041

abs_ir=abs(impulse_response);

10437

abs_ir=abs(impulse_response);

10042

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10438

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10043

start_ind = a(1);

10439

start_ind = a(1);

10044

10440

10045

err=inf;

10441

err=inf;

10046

while ~all(impulse_response==0)

10442

while ~all(impulse_response==0)

10047

impulse_response(1:start_ind)=0;

10443

impulse_response(1:start_ind)=0;

10048

impulse_response(floor(L/2):end)=0;

10444

impulse_response(floor(L/2):end)=0;

10049

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10445

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10050

ir_modified = real(ifft(IL_modified));

10446

ir_modified = real(ifft(IL_modified));

10051

delta = abs(impulse_response-ir_modified);

10447

delta = abs(impulse_response-ir_modified);

10052

10448

10053

err_prev = err;

10449

err_prev = err;

10054

err=max(delta)/max(impulse_response);

10450

err=max(delta)/max(impulse_response);

10055

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10451

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10056

break;

10452

break;

10057

end

10453

end

10058

10454

10059

impulse_response=ir_modified;

10455

impulse_response=ir_modified;

10060

end

10456

end

10061

10457

10062

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10458

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10063

10459

10064

if ~OP.ENFORCE_CAUSALITY

10460

if ~OP.ENFORCE_CAUSALITY

10065

impulse_response = original_impulse_response;

10461

impulse_response = original_impulse_response;

10066

end

10462

end

10067

% truncate final samples smaller than 1e-3 of the peak

10463

% truncate final samples smaller than 1e-3 of the peak

10068

ir_peak = max(abs(impulse_response));

10464

ir_peak = max(abs(impulse_response));

10069

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10465

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10070

10466

10071

voltage = impulse_response(1:ir_last);

10467

voltage = impulse_response(1:ir_last);

10072

t_base = t_base(1:ir_last);

10468

t_base = t_base(1:ir_last);

10073

10469

10074

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10470

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10075

10471

10076

function S =s_for_c2(zref,f,cpad)

10472

function S =s_for_c2(zref,f,cpad)

10077

% S is 2 port s parameters out

10473

% S is 2 port s parameters out

10078

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10474

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10079

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10475

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10080

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10476

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10081

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10477

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10082

S=sparameters(S_Parameters,f,zref);

10478

S=sparameters(S_Parameters,f,zref);

10083

10479

10084

function S =s_for_c4(zref,f,cpad)

10480

function S =s_for_c4(zref,f,cpad)

10085

10481

10086

S2 = s_for_c2(zref,f,cpad);

10482

S2 = s_for_c2(zref,f,cpad);

10087

S4P=s2_to_s4(S2.Parameters);

10483

S4P=s2_to_s4(S2.Parameters);

10088

S=sparameters(S4P,f,zref);

10484

S=sparameters(S4P,f,zref);

10089

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10485

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10090

10486

10091

10487

10092

10488

10093

10489

10094

%%

10490

%%

10095

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10491

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10096

% save commmend string

10492

% save commmend string

10097

% for saving from interactive queries

10493

% for saving from interactive queries

10098

10494

10099

10495

10100

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10496

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10101

for i=1:num_next+num_fext

10497

for i=1:num_next+num_fext

10102

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10498

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10103

end

10499

end

10104

cmd_str= [ cmd_str ')'];

10500

cmd_str= [ cmd_str ')'];

10105

10501

10106

10502

10107

%%%%% require the RF tool box

10503

%%%%% require the RF tool box

10108

%%

10504

%%

10109

function [ h ] = savefigs( param, OP )

10505

function [ h ] = savefigs( param, OP )

10110

10506

10111

%% find the figures

10507

%% find the figures

10112

hw = waitbar(0,'Saving figures...');

10508

hw = waitbar(0,'Saving figures...');

10113

h = findobj(0, 'Type', 'figure');

10509

h = findobj(0, 'Type', 'figure');

10114

for ii=1:length(h)

10510

for ii=1:length(h)

10115

10511

10116

figname= get(h(ii), 'Name'); % use the figure name as file name

10512

figname= get(h(ii), 'Name'); % use the figure name as file name

10117

if isempty(strfind(figname,param.base))

10513

if isempty(strfind(figname,param.base))

10118

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10514

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10119

end

10515

end

10120

if verLessThan('matlab', '8.4.0')

10516

if verLessThan('matlab', '8.4.0')

10121

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10517

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10122

else

10518

else

10123

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10519

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10124

end

10520

end

10125

figname = strrep(figname,':','-');

10521

figname = strrep(figname,':','-');

10126

figname = strrep(figname,' ','_');

10522

figname = strrep(figname,' ','_');

10127

if OP.SAVE_FIGURES==1

10523

if OP.SAVE_FIGURES==1

10128

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10524

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10129

end

10525

end

10130

%% get x y data

10526

%% get x y data

10131

if OP.SAVE_FIGURE_to_CSV==1

10527

if OP.SAVE_FIGURE_to_CSV==1

10132

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10528

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10133

M=[]; %ncol=1;

10529

M=[]; %ncol=1;

10134

for nk=1:length(h_L)

10530

for nk=1:length(h_L)

10135

% get x and data for a line.

10531

% get x and data for a line.

10136

x_data=get(h_L(nk),'xdata')';

10532

x_data=get(h_L(nk),'xdata')';

10137

y_data=get(h_L(nk),'ydata')';

10533

y_data=get(h_L(nk),'ydata')';

10138

% .........>> need to get data in the line structure (legend or label) for headers

10534

% .........>> need to get data in the line structure (legend or label) for headers

10139

M=[M; x_data; y_data]; %#ok<AGROW>

10535

M=[M; x_data; y_data]; %#ok<AGROW>

10140

end

10536

end

10141

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10537

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10142

% clear M y x header h_L

10538

% clear M y x header h_L

10143

end

10539

end

10144

waitbar(ii/length(h),hw)

10540

waitbar(ii/length(h),hw)

10145

10541

10146

end

10542

end

10147

10543

10148

close(hw)

10544

close(hw)

10149

10545

10150

%%

10546

%%

10151

function [ h ] = savefigs_png( param, OP )

10547

function [ h ] = savefigs_png( param, OP )

10152

10548

10153

%% find the figures

10549

%% find the figures

10154

hw = waitbar(0,'Saving figures...');

10550

hw = waitbar(0,'Saving figures...');

10155

h = findobj(0, 'Type', 'figure');

10551

h = findobj(0, 'Type', 'figure');

10156

for ii=1:length(h)

10552

for ii=1:length(h)

10157

10553

10158

figname= get(h(ii), 'Name'); % use the figure name as file name

10554

figname= get(h(ii), 'Name'); % use the figure name as file name

10159

if isempty(strfind(figname,param.base))

10555

if isempty(strfind(figname,param.base))

10160

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10556

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10161

end

10557

end

10162

if verLessThan('matlab', '8.4.0')

10558

if verLessThan('matlab', '8.4.0')

10163

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10559

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10164

else

10560

else

10165

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10561

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10166

end

10562

end

10167

figname = strrep(figname,':','-');

10563

figname = strrep(figname,':','-');

10168

figname = strrep(figname,' ','_');

10564

figname = strrep(figname,' ','_');

10169

if OP.SAVE_FIGURES==1

10565

if OP.SAVE_FIGURES==1

10170

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10566

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10171

end

10567

end

10172

%% get x y data

10568

%% get x y data

10173

if OP.SAVE_FIGURE_to_CSV==1

10569

if OP.SAVE_FIGURE_to_CSV==1

10174

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10570

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10175

M=[]; %ncol=1;

10571

M=[]; %ncol=1;

10176

for nk=1:length(h_L)

10572

for nk=1:length(h_L)

10177

% get x and data for a line.

10573

% get x and data for a line.

10178

x_data=get(h_L(nk),'xdata')';

10574

x_data=get(h_L(nk),'xdata')';

10179

y_data=get(h_L(nk),'ydata')';

10575

y_data=get(h_L(nk),'ydata')';

10180

% .........>> need to get data in the line structure (legend or label) for headers

10576

% .........>> need to get data in the line structure (legend or label) for headers

10181

M=[M; x_data; y_data]; %#ok<AGROW>

10577

M=[M; x_data; y_data]; %#ok<AGROW>

10182

end

10578

end

10183

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10579

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10184

% clear M y x header h_L

10580

% clear M y x header h_L

10185

end

10581

end

10186

waitbar(ii/length(h),hw)

10582

waitbar(ii/length(h),hw)

10187

10583

10188

end

10584

end

10189

10585

10190

close(hw)

10586

close(hw)

10191

10587

10192

%%

10588

%%

10193

function [pdf_out, cdf_out, scale_factor] = scaleCDF(pdf,delta_com,DER0,A_s)

10194

% scale CDF at DER0 to delta_com

10195

pdf_out=pdf;

10196

P=cumsum(pdf.y);

10197

ider0=find(P>=DER0,1,'first');

10198

anias=pdf.x(ider0)/A_s; % ani/as

10199

new_db = 20*log10(-1/anias)-delta_com;

10200

new_value = -1*1/10^(new_db/20);

10201

scale_factor=1/10^(-delta_com/20);

10202

pdf_out=scalePDF(pdf,scale_factor);

10203

cdf_out=cumsum(pdf_out.y);

10204

function pdf_out = scalePDF(pdf,scale_factor)

10589

function pdf_out = scalePDF(pdf,scale_factor)

10205

pdf_out=pdf;

10590

pdf_out=pdf;

10206

pdf_out.Min=floor(pdf.Min*scale_factor);

10591

pdf_out.Min=floor(pdf.Min*scale_factor);

10207

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10592

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10208

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10593

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10209

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10594

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10210

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10595

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10211

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10596

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10212

function t_params = stot(s_params)

10597

function t_params = stot(s_params)

10213

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10598

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10214

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10599

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10215

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10600

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10216

delta = (s11.*s22-s12.*s21);

10601

delta = (s11.*s22-s12.*s21);

10217

s21(s21==0)=eps;

10602

s21(s21==0)=eps;

10218

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10603

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10219

10604

10220

function csv_string = str2csv(c)

10605

function csv_string = str2csv(c)

10221

% convert a cell array of strings to a csv string

10606

% convert a cell array of strings to a csv string

10222

cell_tmp = cell(2, length(c));

10607

cell_tmp = cell(2, length(c));

10223

cell_tmp(1,:)=c;

10608

cell_tmp(1,:)=c;

10224

cell_tmp(2,:) = {','};

10609

cell_tmp(2,:) = {','};

10225

cell_tmp{2,end} = '';

10610

cell_tmp{2,end} = '';

10226

csv_string=strcat(cell_tmp{:});

10611

csv_string=strcat(cell_tmp{:});

10227

10612

10228

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10613

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10229

f_GHz=f/1e9;

10614

f_GHz=f/1e9;

10230

%% Equation 93A-10 %%

10615

%% Equation 93A-10 %%

10231

gamma_1 = gamma_coeff(2)*(1+1i);

10616

gamma_1 = gamma_coeff(2)*(1+1i);

10232

%% Equation 93A-11 %%

10617

%% Equation 93A-11 %%

10233

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10618

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10234

%% Equation 93A-9 %%

10619

%% Equation 93A-9 %%

10235

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10620

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10236

gamma(f_GHz==0) = gamma_coeff(1);

10621

gamma(f_GHz==0) = gamma_coeff(1);

10237

10622

10238

%% Equation 93A-12 %%

10623

%% Equation 93A-12 %%

10239

if d==0

10624

if d==0

10240

%force matched impedance if length is 0

10625

%force matched impedance if length is 0

10241

%otherwise divide by zero can occur if Z_c=0

10626

%otherwise divide by zero can occur if Z_c=0

10242

rho_rl=0;

10627

rho_rl=0;

10243

else

10628

else

10244

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10629

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10245

end

10630

end

10246

10631

10247

exp_gamma_d = exp(-d*gamma);

10632

exp_gamma_d = exp(-d*gamma);

10248

%% Equations 93A-13 and 93A-14 %%

10633

%% Equations 93A-13 and 93A-14 %%

10249

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10634

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10250

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10635

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10251

s12 = s21;

10636

s12 = s21;

10252

s22 = s11;

10637

s22 = s11;

10253

10638

10254

function s_params = ttos(t_params)

10639

function s_params = ttos(t_params)

10255

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10640

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10256

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10641

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10257

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10642

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10258

delta = t11.*t22-t21.*t12;

10643

delta = t11.*t22-t21.*t12;

10259

t11(t11==0)=eps;

10644

t11(t11==0)=eps;

10260

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10645

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10261

10646

10262

function [out_var,varg_out]=varargin_extractor(varargin)

10647

function [out_var,varg_out]=varargin_extractor(varargin)

10263

10648

10264

if isempty(varargin)

10649

if isempty(varargin)

10265

out_var=[];

10650

out_var=[];

10266

varg_out={};

10651

varg_out={};

10267

else

10652

else

10268

out_var=varargin{1};

10653

out_var=varargin{1};

10269

varg_out=varargin;

10654

varg_out=varargin;

10270

varg_out(1)=[];

10655

varg_out(1)=[];

10271

end

10656

end

10272

10657

10273

10658

10274

function results= vma(PR, M)

10659

function results= vma(PR, M)

10275

% PR=sbr.Data;

10660

% PR=sbr.Data;

10276

% M=32;

10661

% M=32;

10277

% PR is the pulse response

10662

% PR is the pulse response

10278

% M is samples per UI

10663

% M is samples per UI

10279

[ seq, syms, syms_nrz ] = PRBS13Q( );

10664

[ seq, syms, syms_nrz ] = PRBS13Q( );

10280

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10665

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10281

symbols=seq;

10666

symbols=seq;

10282

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10667

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10283

% start end symbols index for 7 3's and 6 0's

10668

% start end symbols index for 7 3's and 6 0's

10284

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10669

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10285

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10670

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10286

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10671

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10287

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10672

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10288

% superposition code

10673

% superposition code

10289

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10674

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10290

Bit_stream_response=filter(PR,1, shifting_vector);

10675

Bit_stream_response=filter(PR,1, shifting_vector);

10291

% find center of 3's and 0's

10676

% find center of 3's and 0's

10292

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10677

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10293

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10678

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10294

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10679

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10295

% hold on

10680

% hold on

10296

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10681

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10297

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10682

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10298

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10683

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10299

VMA= P_3 - P_0;

10684

VMA= P_3 - P_0;

10300

results.P_3=P_3;

10685

results.P_3=P_3;

10301

results.P_0=P_0;

10686

results.P_0=P_0;

10302

results.VMA=VMA;

10687

results.VMA=VMA;

10303

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10688

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10304

10689

10305

%slope of the 2 sample points around vref crossing

10690

%slope of the 2 sample points around vref crossing

10306

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10691

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10307

%x-intercept for the line

10692

%x-intercept for the line

10308

b1=eye_contour(x_in,1)-m1*x_in;

10693

b1=eye_contour(x_in,1)-m1*x_in;

10309

% drawing a horizontal line through vref so slope = 0

10694

% drawing a horizontal line through vref so slope = 0

10310

m2=0;

10695

m2=0;

10311

%special case for horizontal line, b=y

10696

%special case for horizontal line, b=y

10312

b2=vref;

10697

b2=vref;

10313

%the x-value of line intersection = (b2-b1)/(m1-m2)

10698

%the x-value of line intersection = (b2-b1)/(m1-m2)

10314

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10699

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10315

%And usually vref is 0, so it further reduces to -b1/m1

10700

%And usually vref is 0, so it further reduces to -b1/m1

10316

line_intersection=(b2-b1)/(m1-m2);

10701

line_intersection=(b2-b1)/(m1-m2);

10317

10702

10318

10703

10319

10704

10320

10705

10321

10706

10322

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10707

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10323

% helper function to read parameter values from XLS file. Uses names to find values.

10708

% helper function to read parameter values from XLS file. Uses names to find values.

10324

if nargin<3, eval_if_string=0; end

10709

if nargin<3, eval_if_string=0; end

10325

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10710

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10326

if numel(row)*numel(col)==0

10711

if numel(row)*numel(col)==0

10327

if nargin<4

10712

if nargin<4

10328

missingParameter(param_name);

10713

missingParameter(param_name);

10329

else

10714

else

10330

p = default_value;

10715

p = default_value;

10331

end

10716

end

10332

elseif numel(row)*numel(col)>1

10717

elseif numel(row)*numel(col)>1

10333

% if there are several occurrences, use the first, but warn

10718

% if there are several occurrences, use the first, but warn

10334

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10719

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10335

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10720

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10336

error('COM:XLS_parameter:MultipleOccurrence', ...

10721

error('COM:XLS_parameter:MultipleOccurrence', ...

10337

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10722

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10338

p=param_sheet{row(1), col(1)+1};

10723

p=param_sheet{row(1), col(1)+1};

10339

else

10724

else

10340

p=param_sheet{row, col+1};

10725

p=param_sheet{row, col+1};

10341

end

10726

end

10342

if ischar(p) && eval_if_string

10727

if ischar(p) && eval_if_string

10343

p=eval(p);

10728

p=eval(p);

10344

end

10729

end

10345

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10730

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10346

if OP.SAVE_KEYWORD_FILE

10731

if OP.SAVE_KEYWORD_FILE

10347

10732

10348

if nargin<3 || ~exist('default_value','var')

10733

if nargin<3 || ~exist('default_value','var')

10349

default_value=p;

10734

default_value=p;

10350

end

10735

end

10351

if isempty(default_value)

10736

if isempty(default_value)

10352

default_value='-';

10737

default_value='-';

10353

end

10738

end

10354

%%

10739

%%

10355

% Get call-stack info:

10740

% Get call-stack info:

10356

stDebug = dbstack;

10741

stDebug = dbstack;

10357

callerFileName = stDebug(2).file;

10742

callerFileName = stDebug(2).file;

10358

callerLineNumber = stDebug(2).line;

10743

callerLineNumber = stDebug(2).line;

10359

% Open caller file:

10744

% Open caller file:

10360

fCaller = fopen(callerFileName);

10745

fCaller = fopen(callerFileName);

10361

% Iterate through lines to get to desired line number:

10746

% Iterate through lines to get to desired line number:

10362

for iLine = 1 : callerLineNumber

10747

for iLine = 1 : callerLineNumber

10363

% Read current line of text:

10748

% Read current line of text:

10364

currLine = fgetl(fCaller);

10749

currLine = fgetl(fCaller);

10365

end

10750

end

10366

% (currLine) now reflects calling desired code: display this code:

10751

% (currLine) now reflects calling desired code: display this code:

10367

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10752

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10368

% Close caller file:

10753

% Close caller file:

10369

left_side=currLine(1:strfind(currLine,'=')-1);

10754

left_side=currLine(1:strfind(currLine,'=')-1);

10370

cmt_side=currLine(strfind(currLine,'%')+1:end);

10755

cmt_side=currLine(strfind(currLine,'%')+1:end);

10371

if isempty(cmt_side), cmt_side=' ';end

10756

if isempty(cmt_side), cmt_side=' ';end

10372

fclose(fCaller);

10757

fclose(fCaller);

10373

10758

10374

if ~ischar(default_value)

10759

if ~ischar(default_value)

10375

default_str=sprintf('%g ',default_value);

10760

default_str=sprintf('%g ',default_value);

10376

else

10761

else

10377

default_str=default_value;

10762

default_str=default_value;

10378

end

10763

end

10379

if ~isfile('keyworklog.mat')

10764

if ~isfile('keyworklog.mat')

10380

save_p=param_name;

10765

save_p=param_name;

10381

save_d=default_str;

10766

save_d=default_str;

10382

save_r=left_side;

10767

save_r=left_side;

10383

save_c=cmt_side;

10768

save_c=cmt_side;

10384

param_name = {'keyword'};

10769

param_name = {'keyword'};

10385

default_str = {'default'};

10770

default_str = {'default'};

10386

left_side={'matlab variable'};

10771

left_side={'matlab variable'};

10387

cmt_side={'info'};

10772

cmt_side={'info'};

10388

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10773

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10389

param_name=save_p;

10774

param_name=save_p;

10390

default_str=save_d;

10775

default_str=save_d;

10391

left_side=save_r;

10776

left_side=save_r;

10392

cmt_side=save_c;

10777

cmt_side=save_c;

10393

data=load('keyworklog.mat');

10778

data=load('keyworklog.mat');

10394

else

10779

else

10395

load('keyworklog.mat');

10780

load('keyworklog.mat');

10396

end

10781

end

10397

data.left_side = [ data.left_side; left_side];

10782

data.left_side = [ data.left_side; left_side];

10398

data.param_name = [data.param_name; param_name];

10783

data.param_name = [data.param_name; param_name];

10399

data.default_str = [data.default_str; default_str ];

10784

data.default_str = [data.default_str; default_str ];

10400

data.cmt_side = [ data.cmt_side; cmt_side];

10785

data.cmt_side = [ data.cmt_side; cmt_side];

10401

if length(data.default_str)~=length(data.default_str)

10786

if length(data.default_str)~=length(data.default_str)

10402

a=1;

10787

a=1;

10403

end

10788

end

10404

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10789

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10405

save('keyworklog.mat','data');

10790

save('keyworklog.mat','data');

10406

writetable(T,[ 'keywords_' date '.csv' ]);

10791

writetable(T,[ 'keywords_' date '.csv' ]);

10407

end

10792

end

10408

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10793

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10409

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10794

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10410

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10795

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10411

10796

10412

found=1;

10797

found=1;

10413

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10798

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10414

if numel(row)*numel(col)==0

10799

if numel(row)*numel(col)==0

10415

p = 0;

10800

p = 0;

10416

found=0;

10801

found=0;

10417

elseif numel(row)*numel(col)>1

10802

elseif numel(row)*numel(col)>1

10418

% if there are several occurrences, use the first, but warn

10803

% if there are several occurrences, use the first, but warn

10419

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10804

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10420

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10805

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10421

error('COM:XLS_parameter:MultipleOccurrence', ...

10806

error('COM:XLS_parameter:MultipleOccurrence', ...

10422

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10807

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10423

p=param_sheet{row(1), col(1)+1};

10808

p=param_sheet{row(1), col(1)+1};

10424

else

10809

else

10425

p=param_sheet{row, col+1};

10810

p=param_sheet{row, col+1};

10426

end

10811

end

10427

if ischar(p)

10812

if ischar(p)

10428

p=eval(p);

10813

p=eval(p);

10429

end

10814

end

10430

function zzz_list_of_changes

10815

function zzz_list_of_changes

10431

% structures:

10816

% structures:

10432

% chdata(i)

10817

% chdata(i)

10433

% i= 1 --> THRU index

10818

% i= 1 --> THRU index

10434

% i= 2, num_fext+1 --> FEXT channel index

10819

% i= 2, num_fext+1 --> FEXT channel index

10435

% i= num_fext+2, num_next+num_fext+1

10820

% i= num_fext+2, num_next+num_fext+1

10436

% base: name of THRU file

10821

% base: name of THRU file

10437

% A: amplitude

10822

% A: amplitude

10438

% type: 'THRU', 'NEXT', or 'FEXT'

10823

% type: 'THRU', 'NEXT', or 'FEXT'

10439

% ftr: Rise time frequency

10824

% ftr: Rise time frequency

10440

% fmaxi: max number of frequency points

10825

% fmaxi: max number of frequency points

10441

% faxis: frequency array [Hz]

10826

% faxis: frequency array [Hz]

10442

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10827

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10443

% sdd22: differential RL

10828

% sdd22: differential RL

10444

% sdd11: differential RL

10829

% sdd11: differential RL

10445

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10830

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10446

% sdd21f: raw differential IL not filtered use for FD plots

10831

% sdd21f: raw differential IL not filtered use for FD plots

10447

% added output_args.peak_uneq_pulse_mV

10832

% added output_args.peak_uneq_pulse_mV

10448

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10833

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10449

% added: tap c(-2) c(2) and c(3)

10834

% added: tap c(-2) c(2) and c(3)

10450

% added: g_DC_HP and f_HP_PZ

10835

% added: g_DC_HP and f_HP_PZ

10451

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10836

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10452

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10837

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10453

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10838

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10454

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10839

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10455

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10840

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10456

% fixed INCLUDE_CTLE=0 to really remove from computation

10841

% fixed INCLUDE_CTLE=0 to really remove from computation

10457

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10842

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10458

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10843

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10459

% r162 tx and rx package impedance {Zc)

10844

% r162 tx and rx package impedance {Zc)

10460

% r162a Gaussian equation corrected

10845

% r162a Gaussian equation corrected

10461

% r163 cast snr_tx with package test case

10846

% r163 cast snr_tx with package test case

10462

% r164 fix pdf for very low noise and lo pass filter enhancements

10847

% r164 fix pdf for very low noise and lo pass filter enhancements

10463

% r164 add zero gain at nqyist CTLE as in CL12e

10848

% r164 add zero gain at nqyist CTLE as in CL12e

10464

% r165 add simpler congfig command called FORCE_TR (force risetime)

10849

% r165 add simpler congfig command called FORCE_TR (force risetime)

10465

% r200 cm3 and cm4 added cp3 removed

10850

% r200 cm3 and cm4 added cp3 removed

10466

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10851

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10467

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10852

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10468

% r200 improved phase interpolation for return loss time conversion

10853

% r200 improved phase interpolation for return loss time conversion

10469

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10854

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10470

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10855

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10471

% r200c missed on fix for interpolation

10856

% r200c missed on fix for interpolation

10472

% r210 new ERL with time gating function

10857

% r210 new ERL with time gating function

10473

% r224 update ERL with from D3.1

10858

% r224 update ERL with from D3.1

10474

% r226 fix s2p reading problem

10859

% r226 fix s2p reading problem

10475

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10860

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10476

% Fix Rx calibration issue

10861

% Fix Rx calibration issue

10477

% added ERL limit and Nd

10862

% added ERL limit and Nd

10478

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10863

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10479

% INC_PACKAGE=0 not fully supported message

10864

% INC_PACKAGE=0 not fully supported message

10480

% if N=0 use TDR_duration

10865

% if N=0 use TDR_duration

10481

% red display text for fail ERL and COM

10866

% red display text for fail ERL and COM

10482

% r228 fixed ERL pass fail report, default Grr_limit to 1

10867

% r228 fixed ERL pass fail report, default Grr_limit to 1

10483

% r230 add rx ffe

10868

% r230 add rx ffe

10484

% r231 change crosstalk noise to icn like to speed things up

10869

% r231 change crosstalk noise to icn like to speed things up

10485

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10870

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10486

% 1e-5mof-

10871

% 1e-5mof-

10487

% r232 fix default for Rx eq so old spead sheets work

10872

% r232 fix default for Rx eq so old spead sheets work

10488

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10873

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10489

% r235 adding dfe quantization changed to normalized DFE taps reported

10874

% r235 adding dfe quantization changed to normalized DFE taps reported

10490

% r236 adding ffe gain loop and resample after RxFFE

10875

% r236 adding ffe gain loop and resample after RxFFE

10491

% r240 added output for C2M and setting defaults for some FFE eq

10876

% r240 added output for C2M and setting defaults for some FFE eq

10492

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10877

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10493

% r250 adding more complex package

10878

% r250 adding more complex package

10494

% r251 post cursor fix for DFE in force() and ffe backoff

10879

% r251 post cursor fix for DFE in force() and ffe backoff

10495

% r251 remove TDR threshold noise filter

10880

% r251 remove TDR threshold noise filter

10496

% r252 add rx FFE filter to receiver noise filter

10881

% r252 add rx FFE filter to receiver noise filter

10497

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10882

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10498

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10883

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10499

% r254 precursor check fix in optimize_fom % mod fix in force

10884

% r254 precursor check fix in optimize_fom % mod fix in force

10500

% r254 help to align columns in csv file

10885

% r254 help to align columns in csv file

10501

% r254 accept syntax for 2 tline flex package model

10886

% r254 accept syntax for 2 tline flex package model

10502

% r256 speed up optimize FOM

10887

% r256 speed up optimize FOM

10503

% r256 fix problem reading in config file from q/a

10888

% r256 fix problem reading in config file from q/a

10504

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10889

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10505

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10890

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10506

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10891

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10507

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10892

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10508

% r258 CDR switch 'MM' or 'mod-MM'

10893

% r258 CDR switch 'MM' or 'mod-MM'

10509

% r258 correction for asymentirc tx/Rx packages

10894

% r258 correction for asymentirc tx/Rx packages

10510

% r258 revamped display results display window

10895

% r258 revamped display results display window

10511

% r259 fix problem if Min_VEO is set in spreadsheet.

10896

% r259 fix problem if Min_VEO is set in spreadsheet.

10512

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10897

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10513

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10898

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10514

% r259 putting COM_db and IL last in output to terminal

10899

% r259 putting COM_db and IL last in output to terminal

10515

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10900

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10516

% r259 use N_bx for ERL rather than Nb (ndfe))

10901

% r259 use N_bx for ERL rather than Nb (ndfe))

10517

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10902

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10518

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10903

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10519

% r260 used eta_0 PSD equation for sigma_n

10904

% r260 used eta_0 PSD equation for sigma_n

10520

% r260 fix IL graph legend to w/pkg and Tr

10905

% r260 fix IL graph legend to w/pkg and Tr

10521

% r260 define tfx for each port

10906

% r260 define tfx for each port

10522

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10907

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10523

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10908

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10524

% r262 reset on exit default text interpreter to tex

10909

% r262 reset on exit default text interpreter to tex

10525

% r262 localize run timer (John Buck 1/17/19)

10910

% r262 localize run timer (John Buck 1/17/19)

10526

% r262 set db as internal function in force to avoid tool box

10911

% r262 set db as internal function in force to avoid tool box

10527

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10912

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10528

% r263 added to output_args RL structure and report "struct" in csv file

10913

% r263 added to output_args RL structure and report "struct" in csv file

10529

% r264 added EW estimate

10914

% r264 added EW estimate

10530

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10915

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10531

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10916

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10532

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10917

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10533

% r269 changed param.N_bmax to param.N_f

10918

% r269 changed param.N_bmax to param.N_f

10534

% r270 implement JingBo Li's and Howard Heck's floating tap method

10919

% r270 implement JingBo Li's and Howard Heck's floating tap method

10535

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10920

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10536

% r270 added c_0 and c_1 for CA in add_brd

10921

% r270 added c_0 and c_1 for CA in add_brd

10537

% r272 fixed version syntax problem in output_args RL report

10922

% r272 fixed version syntax problem in output_args RL report

10538

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10923

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10539

% r272 removed eye width report if doing a Rx calibration

10924

% r272 removed eye width report if doing a Rx calibration

10540

% r273 better alignment and control for ICN reporting

10925

% r273 better alignment and control for ICN reporting

10541

% r273 fixed PSXTK graph

10926

% r273 fixed PSXTK graph

10542

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10927

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10543

% 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)

10928

% 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)

10544

% 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

10929

% 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

10545

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10930

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10546

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10931

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10547

% r276 C_1 was instantiated as C_0. This was fixed

10932

% r276 C_1 was instantiated as C_0. This was fixed

10548

% r276 fixed rounding problem in reporting of loss at f_nq

10933

% r276 fixed rounding problem in reporting of loss at f_nq

10549

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10934

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10550

% r277 added nv for deterining steady state voltage for fitting compatibility

10935

% r277 added nv for deterining steady state voltage for fitting compatibility

10551

% r278 added b_min to support asymmetric bmax

10936

% r278 added b_min to support asymmetric bmax

10552

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10937

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10553

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10938

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10554

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10939

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10555

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10940

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10556

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10941

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10557

% 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

10942

% 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

10558

% r292 H_t implemented in s21_pkg

10943

% r292 H_t implemented in s21_pkg

10559

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10944

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10560

% r292 add GDC_MIN to optimize_FOM

10945

% r292 add GDC_MIN to optimize_FOM

10561

% r293 fix if ndfe-0 and ERL only and s2p issue

10946

% r293 fix if ndfe-0 and ERL only and s2p issue

10562

% r293a investigate the Tukey filtering

10947

% r293a investigate the Tukey filtering

10563

% r293a if fix if bmin is missing

10948

% r293a if fix if bmin is missing

10564

% r294 fix problems reading s2p files for ERL computation

10949

% r294 fix problems reading s2p files for ERL computation

10565

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10950

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10566

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10951

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10567

% r294 add gdc and gdc2 range limitations

10952

% r294 add gdc and gdc2 range limitations

10568

% r295 add VEC Pass threshold

10953

% r295 add VEC Pass threshold

10569

% r295 removed close force all. Tagged all figures with "COM"

10954

% r295 removed close force all. Tagged all figures with "COM"

10570

% r295 consolidated print in new function "end_display_control"

10955

% r295 consolidated print in new function "end_display_control"

10571

% r295 report pre/pmax for Txffe

10956

% r295 report pre/pmax for Txffe

10572

% r295 speed up test cases by not re-reading in s4p files

10957

% r295 speed up test cases by not re-reading in s4p files

10573

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10958

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10574

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10959

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10575

% r310 refine VEC and EH for C2M from Adam Gregory in

10960

% r310 refine VEC and EH for C2M from Adam Gregory in

10576

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10961

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10577

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10962

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10578

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10963

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10579

% r311 added RILN

10964

% r311 added RILN

10580

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10965

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10581

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10966

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10582

% r316 remove DC computation for RX Calibration loops

10967

% r316 remove DC computation for RX Calibration loops

10583

% r317 for SAVE_TD to include EQ and unEQ FIR

10968

% r317 for SAVE_TD to include EQ and unEQ FIR

10584

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10969

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10585

% 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

10970

% 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

10586

% r320 fixed RX_CALIBRATION which was broken in r310

10971

% r320 fixed RX_CALIBRATION which was broken in r310

10587

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10972

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10588

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10973

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10589

% r320 removed external feature and replace with TDMODE

10974

% r320 removed external feature and replace with TDMODE

10590

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10975

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10591

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10976

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10592

% r335 fixed typo in when processing the bessel thompson filter option

10977

% r335 fixed typo in when processing the bessel thompson filter option

10593

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10978

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10594

% r335 compute and report CD_CM_RMS

10979

% r335 compute and report CD_CM_RMS

10595

% r335 fixed where output_arg is save i.e. move to end

10980

% r335 fixed where output_arg is save i.e. move to end

10596

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10981

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10597

% r335 change raw IL plot to not include boards

10982

% r335 change raw IL plot to not include boards

10598

% r335 set T_0 to zero if not C2M

10983

% r335 set T_0 to zero if not C2M

10599

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10984

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10600

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10985

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10601

% r335 TD_RILN changes from Hansel Dsilva

10986

% r335 TD_RILN changes from Hansel Dsilva

10602

% r335 Fixed sigma_N for RxFFE

10987

% r335 Fixed sigma_N for RxFFE

10603

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10988

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10604

% r335 added c(2) and C(3) back to read_ParamConfigFile

10989

% r335 added c(2) and C(3) back to read_ParamConfigFile

10605

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10990

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10606

% r335 corrected GDC_MIN per 0.3ck D2.3

10991

% r335 corrected GDC_MIN per 0.3ck D2.3

10607

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10992

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10608

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10993

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10609

% r370 speed up

10994

% r370 speed up

10610

% r370 fix for floating tap missing locations

10995

% r370 fix for floating tap missing locations

10611

% r370 variable Tx FFE taps

10996

% r370 variable Tx FFE taps

10612

% r370 package die load with ladder circuit

10997

% r370 package die load with ladder circuit

10613

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10998

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10614

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10999

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10615

% r380 added capabablity to enable a raised cosine Rx filter0

11000

% r380 added capabablity to enable a raised cosine Rx filter0

10616

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

11001

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10617

% r380 added plot for VTF

11002

% r380 added plot for VTF

10618

% r385 added capability for additional Tx FFE per package

11003

% r385 added capability for additional Tx FFE per package

10619

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

11004

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10620

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

11005

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10621

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

11006

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10622

% r389 Improvement by A. Ran for reporting loss at Nq

11007

% r389 Improvement by A. Ran for reporting loss at Nq

10623

% r389 Fixed typo: changed VIM to VMP

11008

% r389 Fixed typo: changed VIM to VMP

10624

% r400 fixed PR with zero pad extension

11009

% r400 fixed PR with zero pad extension

10625

% r400 keyword MLSE and SNRADJ_EQUA for future work

11010

% r400 keyword MLSE and SNRADJ_EQUA for future work

10626

% r400 replaced function db with instances of 20*log10(abs(...))

11011

% r400 replaced function db with instances of 20*log10(abs(...))

10627

% r410 widen voltage distriution for normal_dist doubled max Q

11012

% r410 widen voltage distriution for normal_dist doubled max Q

10628

% r410 improve reading in of config files

11013

% r410 improve reading in of config files

10629

% r410 renormalize s-parameter if not 50 ohm ref

11014

% r410 renormalize s-parameter if not 50 ohm ref

10630

% r410 reference for RXFFE changed to MM from UI+zero first precursor

11015

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10631

% r410 remove RL from output_args bc not need and too much storage allocation

11016

% r410 remove RL from output_args bc not need and too much storage allocation

10632

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

11017

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10633

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

11018

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10634

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

11019

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10635

% r420 updade force to account for pulse responces with short delays in force

11020

% r420 updade force to account for pulse responces with short delays in force

10636

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

11021

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10637

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

11022

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10638

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

11023

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10639

% r420 Wiener-Kofp MMSE optimization for RxFFE

11024

% r420 Wiener-Kofp MMSE optimization for RxFFE

10640

% r430 first pass at healey_3dj_01_2401

11025

% r430 first pass at healey_3dj_01_2401

10641

% r430 RxFFE fixed taps

11026

% r430 RxFFE fixed taps

10642

% r440 RxffE fixed tap index corrections and floating taps

11027

% r440 RxffE fixed tap index corrections and floating taps

10643

% r440 first pass implemenation of MLSE U3

11028

% r440 first pass implemenation of MLSE U3

10644

% r450 fix MLSE_FOM typos, sigma_e,and FOM.

11029

% r450 fix MLSE_FOM typos, sigma_e,and FOM.

10645

% r450 incude Hisi in PSD in get_PSDs

11030

% r450 incude Hisi in PSD in get_PSDs

10646

% r460 is working out reporting bug from RxFFE and package A,B invocations

11031

% r460 is working out reporting bug from RxFFE and package A,B invocations

10647

% r460 align package config Tx and Rx cases with selected casting 4p5_3

11032

% r460 align package config Tx and Rx cases with selected casting 4p5_3

10648

% r460 fix RxFFE floating taps display (indexing error) 4p5_4

11033

% r460 fix RxFFE floating taps display (indexing error) 4p5_4

10649

% r470 beta1 added MLSE truncation inclusion using N_tc

11034

% r470 beta1 added MLSE truncation inclusion using N_tc

10650

% r470 beta1 add MLSE Q_budget_adj

11035

% r470 beta1 add MLSE Q_budget_adj

10651

% r470 added parameter defaults to support multiple packages

11036

% r470 added parameter defaults to support multiple packages

10652

% r470 beta2 added MLSD proposal from healey_3dj_01_2409

10653

11037