File Comparison Report

C:\Users\richardm\OneDrive - Samtec\COM\COM\src\com_ieee8023_480.m vs. C:\Users\richardm\OneDrive - Samtec\COM\older_versions\com_ieee8023_93a_470.m

richardm

03-Mar-2025

Files

Left FileRight File
File namecom_ieee8023_480com_ieee8023_93a_470
File pathC:\Users\richardm\OneDrive - Samtec\COM\COM\srcC:\Users\richardm\OneDrive - Samtec\COM\older_versions
Last modified03-Mar-2025 11:23:0310-Jan-2025 11:34:41

Environment

MATLAB9.14 (R2023a)

Comparison Results

+

Insertion

Deletion

Modification
1

function results=com_ieee8023_(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 and/or 178A IEEE Std 802.3

3

%% Implementation example of annex 93A IEEE Std 802.3

4

%% This the main calling program

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

%pm

12

% This program is intended for the development of standard specifications

13

% and reflects activity which may be related to

14

% IEEE P802.3bj, .3by, .3bm, .3bs, .3cd, .3ck, 3dj

12

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

15

% found in Annex 93A or 178A IEEE Std 802.3™ and projects

13

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

16

% The original proposal for COM may be found at

14

% original proposal for COM may be found at

17

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

15

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

18

% from the following authors and affiliations in 2012.

16

% from the following authors and affiliations in 2012.

19

% Richard Mellitz, Intel Corporation

17

% Richard Mellitz, Intel Corporation

20

% Charles Moore, Avago Technologies

18

% Charles Moore, Avago Technologies

21

% Mike Dudek, QLogic Corporation

19

% Mike Dudek, QLogic Corporation

22

% Mike Peng Li, Altera Corporation

20

% Mike Peng Li, Altera Corporation

23

% Adee Ran, Intel Corporation

21

% Adee Ran, Intel Corporation

+22

%

23

% Some of the authors and Contributors:

24

% Adee Ran

25

% Richard Mellitz

26

% Yasuo Hidaka

27

% John Ewen

28

% Bill Kirkland

29

% Adam Gregory

30

% Howard Heck

31

% Jingbo Li

32

% Adam Healey

33

% Matt Brown

34

% Sameh Elnagar

35

% Hossein Shakiba

24

zzz_list_of_changes()

36

zzz_list_of_changes()

25

37

26

%% Opening Preface

38

%% Opening Preface

27

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

39

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

28

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

40

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

29

try % version number at end of call string

41

try % version number at end of call string

30

cmdfile=mfilename;

42

cmdfile=mfilename;

31

hindx=strfind(mfilename,'_');

43

hindx=strfind(mfilename,'_');

32

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

44

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

33

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

45

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

34

catch

46

catch

35

output_args.code_revision ='';

47

output_args.code_revision ='';

36

end

48

end

37

teststr='';

49

teststr='';

38

OP.TESTING=0;

50

OP.TESTING=0;

39

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

51

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

40

teststr='testing';

52

teststr='testing';

41

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

53

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

42

htest = msgbox(testmsg);

54

htest = msgbox(testmsg);

43

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

55

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

44

end

56

end

45

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

57

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

46

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

58

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

47

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

59

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

48

t0=tic;

60

t0=tic;

49

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

61

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

50

% reset to tex on exit

62

% reset to tex on exit

51

%% file_setup

63

%% file_setup

52

%%

64

%%

53

% need to see what happens for version 8

65

% need to see what happens for version 8

54

if verLessThan('matlab', '7.4.1')

66

if verLessThan('matlab', '7.4.1')

55

error('Matlab version 7.4 or higher required')

67

error('Matlab version 7.4 or higher required')

56

end

68

end

57

69

58

results=[];

70

results=[];

59

71

60

%% New Command Line parser

72

%% New Command Line parser

61

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

73

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

62

74

63

75

64

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

76

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

65

if isempty(config_file)

77

if isempty(config_file)

66

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

78

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

67

if isempty(config_file)

79

if isempty(config_file)

68

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

80

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

69

else

81

else

70

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

82

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

71

config_file=[cname cext];

83

config_file=[cname cext];

72

end

84

end

73

if config_file==0

85

if config_file==0

74

% cancel - exit gracefully

86

% cancel - exit gracefully

75

return;

87

return;

76

end

88

end

77

config_file = fullfile(config_file_path, config_file);

89

config_file = fullfile(config_file_path, config_file);

78

end

90

end

79

output_args.config_file = config_file;

91

output_args.config_file = config_file;

80

OP.SAVE_KEYWORD_FILE=0;

92

OP.SAVE_KEYWORD_FILE=0;

81

if OP.SAVE_KEYWORD_FILE

93

if OP.SAVE_KEYWORD_FILE

82

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

94

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

83

delete('keyworklog.mat');

95

delete('keyworklog.mat');

84

end

96

end

85

end

97

end

86

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

98

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

87

if OP.CONFIG2MAT_ONLY

99

if OP.CONFIG2MAT_ONLY

88

return;

100

return;

89

end

101

end

90

if isempty(num_fext)

102

if isempty(num_fext)

91

if OP.RX_CALIBRATION

103

if OP.RX_CALIBRATION

92

num_fext=1;

104

num_fext=1;

93

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

105

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

94

else

106

else

95

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

107

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

96

num_fext=1;

108

num_fext=1;

97

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

109

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

98

elseif ~OP.ERL_ONLY

110

elseif ~OP.ERL_ONLY

99

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

111

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

100

else

112

else

101

num_fext=0;

113

num_fext=0;

102

end

114

end

103

end

115

end

104

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

116

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

105

end

117

end

106

if isempty(num_next)

118

if isempty(num_next)

107

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

119

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

num_next=0;

120

num_next=0;

109

else

121

else

110

if OP.RX_CALIBRATION

122

if OP.RX_CALIBRATION

111

num_next=0;

123

num_next=0;

112

elseif ~OP.ERL_ONLY

124

elseif ~OP.ERL_ONLY

113

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

125

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

114

else

126

else

115

num_next=0;

127

num_next=0;

116

end

128

end

117

end

129

end

118

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

130

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

119

end

131

end

120

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

132

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

121

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

133

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

122

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

134

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

123

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

135

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

124

param.num_next=num_next;

136

param.num_next=num_next;

125

param.num_fext=num_fext;

137

param.num_fext=num_fext;

126

param.num_s4p_files=num_fext+num_next+1;

138

param.num_s4p_files=num_fext+num_next+1;

127

% checking for data when running for rx compliance BBN calibration

139

% checking for data when running for rx compliance BBN calibration

128

if OP.RX_CALIBRATION == 1

140

if OP.RX_CALIBRATION == 1

129

if num_fext ~=1

141

if num_fext ~=1

130

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

142

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

131

movegui(h,'northwest')

143

movegui(h,'northwest')

132

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

144

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

133

if OP.DEBUG ~= 1

145

if OP.DEBUG ~= 1

134

return

146

return

135

end

147

end

136

end

148

end

137

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

149

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

138

movegui(h,'southeast')

150

movegui(h,'southeast')

139

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

151

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

140

end

152

end

141

153

142

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

154

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

143

if num_fext ~=1

155

if num_fext ~=1

144

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

156

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

145

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

157

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

146

movegui(h,'northwest')

158

movegui(h,'northwest')

147

if OP.DEBUG ~= 1

159

if OP.DEBUG ~= 1

148

return

160

return

149

end

161

end

150

end

162

end

151

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

163

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

152

movegui(h,'southeast')

164

movegui(h,'southeast')

153

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

165

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

154

end

166

end

155

167

156

168

157

% create result directory if needed

169

% create result directory if needed

158

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

170

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

159

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

171

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

160

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

172

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

161

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

173

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

162

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

174

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

163

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

175

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

164

%OP.EXTERNAL = true;

176

%OP.EXTERNAL = true;

165

%OP.GET_FD = 0;

177

%OP.GET_FD = 0;

166

%ir1a= varargin(2);

178

%ir1a= varargin(2);

167

%ex_var = varargin(3);

179

%ex_var = varargin(3);

168

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

180

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

169

else

181

else

170

if OP.TDMODE

182

if OP.TDMODE

171

OP.GET_FD=false;

183

OP.GET_FD=false;

172

end

184

end

173

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

185

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

174

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

186

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

175

end

187

end

176

%% eveluate any extra arguments as possible modifications of parameters

188

%% eveluate any extra arguments as possible modifications of parameters

177

extra_args = varargin(xtk+2:end);

189

extra_args = varargin(xtk+2:end);

178

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

190

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

179

try

191

try

180

orig_value_is_str = 1;

192

orig_value_is_str = 1;

181

orig_value=eval(extra_args{k});

193

orig_value=eval(extra_args{k});

182

if ~ischar(orig_value)

194

if ~ischar(orig_value)

183

orig_value_is_str = 0;

195

orig_value_is_str = 0;

184

orig_value=mat2str(orig_value);

196

orig_value=mat2str(orig_value);

185

end

197

end

186

catch eval_err

198

catch eval_err

187

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

199

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

188

% trying to modify a nonexistent parameter - probably a

200

% trying to modify a nonexistent parameter - probably a

189

% typo. save the user from his error.

201

% typo. save the user from his error.

190

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

202

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

191

else

203

else

192

% unexpected condition

204

% unexpected condition

193

rethrow(eval_err);

205

rethrow(eval_err);

194

end

206

end

195

end

207

end

196

try

208

try

197

if orig_value_is_str

209

if orig_value_is_str

198

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

210

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

199

else

211

else

200

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

212

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

201

end

213

end

202

eval(mod_string);

214

eval(mod_string);

203

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

215

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

204

% begin yasuo patch 2/11/2018

216

% begin yasuo patch 2/11/2018

205

% output_args.(fname)=mod_string;

217

% output_args.(fname)=mod_string;

206

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

218

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

207

219

208

% re-patch yasuo 3/18/2019

220

% re-patch yasuo 3/18/2019

209

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

221

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

210

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

222

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

211

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

223

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

212

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

224

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

213

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

225

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

214

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

226

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

215

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

227

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

216

else

228

else

217

output_args.(fname)=mod_string;

229

output_args.(fname)=mod_string;

218

end

230

end

219

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

231

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

220

catch eval_err

232

catch eval_err

221

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

233

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

222

end

234

end

223

end

235

end

224

end

236

end

225

end

237

end

226

%% Parameters computationally defined by values from the settings files

238

%% Parameters computationally defined by values from the settings files

227

param.ui=1/param.fb;

239

param.ui=1/param.fb;

228

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

240

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

229

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

241

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

230

factor_3db=0.473037;

242

factor_3db=0.473037;

231

param.fb_BT_cutoff=factor_3db*param.f_r;

243

param.fb_BT_cutoff=factor_3db*param.f_r;

232

param.fb_BW_cutoff=param.f_r;

244

param.fb_BW_cutoff=param.f_r;

233

param.Tx_rd_sel=1;

245

param.Tx_rd_sel=1;

234

param.Rx_rd_sel=2;

246

param.Rx_rd_sel=2;

235

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

247

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

236

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

248

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

237

end

249

end

238

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

250

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

239

param=parameter_size_adjustment(param,OP);

251

param=parameter_size_adjustment(param,OP);

240

252

241

%% get input models

253

%% get input models

242

param.FLAG.S2P=0;

254

param.FLAG.S2P=0;

243

if OP.TDMODE

255

if OP.TDMODE

244

OP.FIXTURE_CALIBRATION= 0;

256

OP.FIXTURE_CALIBRATION= 0;

245

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

257

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

246

else

258

else

247

OP.FIXTURE_CALIBRATION= 0;

259

OP.FIXTURE_CALIBRATION= 0;

248

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

260

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

249

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

261

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

250

param.FLAG.S2P=1;

262

param.FLAG.S2P=1;

251

end

263

end

252

end

264

end

253

265

254

OP.SAVE_CMD_STR=1;

266

OP.SAVE_CMD_STR=1;

255

if OP.SAVE_CMD_STR

267

if OP.SAVE_CMD_STR

256

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

268

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

257

setappdata(0,'cmd_str',cmd_str);

269

setappdata(0,'cmd_str',cmd_str);

258

end

270

end

259

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

271

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

260

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

272

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

261

COM = inf;

273

COM = inf;

262

min_COM=inf; % reset COM prior to calibration

274

min_COM=inf; % reset COM prior to calibration

263

% min_VEO = inf;

275

% min_VEO = inf;

264

min_VEO_mV = inf;

276

min_VEO_mV = inf;

265

max_VEC_dB = -inf;

277

max_VEC_dB = -inf;

266

threshold_DER=inf;

278

threshold_DER=inf;

267

% begin yasuo patch 3/18/2019

279

% begin yasuo patch 3/18/2019

268

threshold_DER_max = 0; % reset worst DER

280

threshold_DER_max = 0; % reset worst DER

269

% end yasuo patch

281

% end yasuo patch

270

sigma_bn=0;

282

sigma_bn=0;

271

DO_ONCE=true;

283

DO_ONCE=true;

272

low_COM_found = 0;

284

low_COM_found = 0;

273

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

285

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

274

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

286

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

275

if ~DO_ONCE

287

if ~DO_ONCE

276

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

288

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

277

break;

289

break;

278

elseif min_COM > param.pass_threshold

290

elseif min_COM > param.pass_threshold

279

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

291

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

280

if low_COM_found

292

if low_COM_found

281

if OP.sigma_bn_STEP>0 % previous increase too small

293

if OP.sigma_bn_STEP>0 % previous increase too small

282

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

294

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

283

else % previously decrease too large

295

else % previously decrease too large

284

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

296

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

285

end

297

end

286

end

298

end

287

else % binary searchparam.Pkg_len_TX

299

else % binary searchparam.Pkg_len_TX

288

low_COM_found=1;

300

low_COM_found=1;

289

if OP.sigma_bn_STEP>0 % previous increase too large

301

if OP.sigma_bn_STEP>0 % previous increase too large

290

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

302

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

291

else % previously decrease too small

303

else % previously decrease too small

292

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

304

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

293

end

305

end

294

end

306

end

295

min_COM = inf; % ignore previous iterations

307

min_COM = inf; % ignore previous iterations

296

min_VEO_mV = inf;

308

min_VEO_mV = inf;

297

max_VEC_dB = -inf;

309

max_VEC_dB = -inf;

298

sigma_bn = sigma_bn + OP.sigma_bn_STEP;

310

sigma_bn = sigma_bn + OP.sigma_bn_STEP;

299

end

311

end

300

msgctr=1;

312

msgctr=1;

301

for package_testcase_i = 1:length(OP.pkg_len_select)

313

for package_testcase_i = 1:length(OP.pkg_len_select)

302

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

314

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

303

package_testcase=OP.pkg_len_select(package_testcase_i);

315

package_testcase=OP.pkg_len_select(package_testcase_i);

304

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

316

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

305

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

317

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

306

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

318

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

307

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

319

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

308

param.AC_CM_RMS_TX= param.AC_CM_RMS(package_testcase);

320

param.AC_CM_RMS_TX= param.AC_CM_RMS(package_testcase);

309

if param.PKG_Tx_FFE_preset ~=0

321

if param.PKG_Tx_FFE_preset ~=0

310

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

322

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

311

else

323

else

312

param.Pkg_TXFFE_preset=0;

324

param.Pkg_TXFFE_preset=0;

313

end

325

end

314

% ki=package_testcase;

326

% ki=package_testcase;

315

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

327

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

316

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

328

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

317

param.Pkg_Zc= param.pkg_Z_c;

329

param.Pkg_Zc= param.pkg_Z_c;

318

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

330

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

319

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

331

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

320

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

332

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

321

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

333

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

322

end

334

end

323

param.package_testcase_i = package_testcase_i;

335

param.package_testcase_i = package_testcase_i;

324

336

325

%% Fill in chdata

337

%% Fill in chdata

326

if OP.TDMODE

338

if OP.TDMODE

327

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

339

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

328

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

340

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

329

else

341

else

330

%fill in chada with s-parameters

342

%fill in chada with s-parameters

331

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

343

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

332

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

344

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

333

end

345

end

334

if OP.BREAD_CRUMBS

346

if OP.BREAD_CRUMBS

335

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

347

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

336

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

348

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

337

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

349

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

338

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

350

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

339

end

351

end

340

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

352

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

341

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

353

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

342

end

354

end

343

end

355

end

344

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

356

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

345

357

346

%% Process TDR & ERL

358

%% Process TDR & ERL

347

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

359

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

348

if OP.ERL_ONLY

360

if OP.ERL_ONLY

349

results = cell(1);

361

results = cell(1);

350

results{1} = output_args;

362

results{1} = output_args;

351

rt=toc(t0);

363

rt=toc(t0);

352

output_args.rtmin=rt/60;

364

output_args.rtmin=rt/60;

353

if 1

365

if 1

354

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

366

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

355

end

367

end

356

if OP.CSV_REPORT ==1

368

if OP.CSV_REPORT ==1

357

Write_CSV(output_args,CSV_FILE);

369

Write_CSV(output_args,CSV_FILE);

358

end

370

end

359

break;

371

break;

360

end

372

end

361

373

362

%% FD processing s-parameter

374

%% FD processing s-parameter

363

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

375

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

364

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

376

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

365

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

377

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

366

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

378

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

367

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

379

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

368

%most operations now wrapped into FD_Processing function

380

%most operations now wrapped into FD_Processing function

369

param.number_of_s4p_files=length(chdata);

381

param.number_of_s4p_files=length(chdata);

370

%ICN=0;

382

%ICN=0;

371

output_args.ICN_mV=0;

383

output_args.ICN_mV=0;

372

output_args.MDNEXT_ICN_92_46_mV=0;

384

output_args.MDNEXT_ICN_92_46_mV=0;

373

output_args.MDFEXT_ICN_92_47_mV=0;

385

output_args.MDFEXT_ICN_92_47_mV=0;

374

if OP.WC_PORTZ

386

if OP.WC_PORTZ

375

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

387

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

376

else

388

else

377

param.SNR_TX=param.SNDR(package_testcase);

389

param.SNR_TX=param.SNDR(package_testcase);

378

end

390

end

379

391

380

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

392

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

381

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

393

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

382

394

383

%% Convert from Frequency Domain to Time Domain

395

%% Convert from Frequency Domain to Time Domain

384

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

396

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

385

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

397

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

386

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

398

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

387

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

399

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

388

if DO_ONCE

400

if DO_ONCE

389

if ~OP.TDMODE

401

if ~OP.TDMODE

390

chdata=COM_FD_to_TD(chdata,param,OP);

402

chdata=COM_FD_to_TD(chdata,param,OP);

391

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

403

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

392

output_args.SCMR_dB=chdata(1).SCMR;

404

output_args.SCMR_dB=chdata(1).SCMR;

393

end

405

end

394

end

406

end

395

407

396

%% Determine equalization settings

408

%% Determine equalization settings

397

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

409

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

398

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

410

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

399

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

411

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

400

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

412

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

401

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

413

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

402

do_C2M=0;

414

do_C2M=0;

403

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

415

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

404

do_C2M=1;

416

do_C2M=1;

405

end

417

end

406

OP.COMPUTE_COM=false;

418

OP.COMPUTE_COM=false;

407

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

419

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

408

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

420

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

409

OP.COMPUTE_COM=true;

421

OP.COMPUTE_COM=true;

410

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

422

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

411

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

423

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

412

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

424

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

413

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

425

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

414

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

426

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

415

427

416

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

428

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

417

param.use_bmax=fom_result.best_bmax.';

429

param.use_bmax=fom_result.best_bmax.';

418

%AJG021820

430

%AJG021820

419

param.use_bmin=fom_result.best_bmin.';

431

param.use_bmin=fom_result.best_bmin.';

420

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

432

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

421

param.current_ffegain=fom_result.best_current_ffegain;

433

param.current_ffegain=fom_result.best_current_ffegain;

422

if OP.force_pdf_bin_size

434

if OP.force_pdf_bin_size

423

param.delta_y = OP.BinSize;

435

param.delta_y = OP.BinSize;

424

else

436

else

425

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

437

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

426

end

438

end

427

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

439

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

428

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

440

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

429

441

430

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

442

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

431

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

443

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

432

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

444

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

433

OP.WO_TXFFE=1;

445

OP.WO_TXFFE=1;

434

PSD_results.w=fom_result.RxFFE;

446

PSD_results.w=fom_result.RxFFE;

435

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

447

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

436

% well as CTLE (CTF) and tx FFE

448

% well as CTLE (CTF) and tx FFE

437

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

449

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

438

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

450

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

439

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

451

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

440

OP.WO_TXFFE=0;

452

OP.WO_TXFFE=0;

441

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

453

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

442

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

454

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

443

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

455

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

444

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

456

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

445

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

457

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

446

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

458

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

447

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

459

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

448

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

460

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

449

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

461

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

450

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

462

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

451

end

463

end

452

%% Create ISI PDF & Individual Crosstalk PDFs

464

%% Create ISI PDF & Individual Crosstalk PDFs

453

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

465

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

454

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

466

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

455

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

467

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

456

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

468

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

457

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

469

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

458

for i=1:param.number_of_s4p_files

470

for i=1:param.number_of_s4p_files

459

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

471

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

460

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

472

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

461

473

462

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

474

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

463

else

475

else

464

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

476

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

465

end

477

end

466

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

478

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

467

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

479

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

468

subplot(2,1,2);

480

subplot(2,1,2);

469

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

481

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

470

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

482

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

471

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

483

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

472

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

484

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

473

hold on; title('PDF')

485

hold on; title('PDF')

474

recolor_plots(gca);

486

recolor_plots(gca);

475

end

487

end

476

chdata(i).pdfr=pdf;

488

chdata(i).pdfr=pdf;

477

% reporting

489

% reporting

478

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

490

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

479

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

491

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

480

492

481

end

493

end

482

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

494

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

483

495

484

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

496

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

485

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

497

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

486

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

498

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

487

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

499

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

488

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

500

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

489

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

501

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

490

combined_interference_and_noise_pdf=PDF;

502

combined_interference_and_noise_pdf=PDF;

491

combined_interference_and_noise_cdf=CDF;

503

combined_interference_and_noise_cdf=CDF;

492

504

493

505

494

%% Calculate COM and other associated outputs

506

%% Calculate COM and other associated outputs

495

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

507

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

496

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

508

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

497

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

509

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

498

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

510

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

499

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

511

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

500

% that satisfies the relationship P(y0) = DER_0

512

% that satisfies the relationship P(y0) = DER_0

501

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

513

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

502

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

514

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

503

515

504

% begin yasuo patch 3/18/2019

516

% begin yasuo patch 3/18/2019

505

% estimate DER at threshold COM

517

% estimate DER at threshold COM

506

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

518

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

507

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

519

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

508

threshold_DER_max = max(threshold_DER_max, threshold_DER);

520

threshold_DER_max = max(threshold_DER_max, threshold_DER);

509

% end yasuo patch

521

% end yasuo patch

510

522

511

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

523

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

512

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

524

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

513

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

525

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

514

if OP.DISPLAY_WINDOW && OP.DEBUG

526

if OP.DISPLAY_WINDOW && OP.DEBUG

515

figure_name = 'Eye at DER0 estimate';

527

figure_name = 'Eye at DER0 estimate';

516

fig=findobj('Name', figure_name);

528

fig=findobj('Name', figure_name);

517

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

529

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

518

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

530

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

519

movegui(fig,'southwest')

531

movegui(fig,'southwest')

520

plot(eye_contour)

532

plot(eye_contour)

521

xlabel('UI %')

533

xlabel('UI %')

522

ylabel('V')

534

ylabel('V')

523

end

535

end

524

536

525

else

537

else

526

EW_UI=0;

538

EW_UI=0;

527

eye_contour=[];

539

eye_contour=[];

528

end

540

end

529

if OP.MLSE==0

541

if OP.MLSE==0

530

if param.T_O ~=0

542

if param.T_O ~=0

531

eye_opening=EH_T_C2M-EH_B_C2M;

543

eye_opening=EH_T_C2M-EH_B_C2M;

532

A_ni=2*A_s-eye_opening;

544

A_ni=2*A_s-eye_opening;

533

%eq 124E-4

545

%eq 124E-4

534

vec_arg=2*A_s/eye_opening;

546

vec_arg=2*A_s/eye_opening;

535

if vec_arg<eps

547

if vec_arg<eps

536

vec_arg=eps;

548

vec_arg=eps;

537

end

549

end

538

VEC_dB = 20*log10(vec_arg);

550

VEC_dB = 20*log10(vec_arg);

539

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

551

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

540

VEO_mV=eye_opening*1000;

552

VEO_mV=eye_opening*1000;

541

min_COM = min(min_COM, COM);

553

min_COM = min(min_COM, COM);

542

min_VEO_mV = min(min_VEO_mV,VEO_mV);

554

min_VEO_mV = min(min_VEO_mV,VEO_mV);

543

max_VEC_dB = max(max_VEC_dB, VEC_dB);

555

max_VEC_dB = max(max_VEC_dB, VEC_dB);

544

else

556

else

545

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

557

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

546

vec_arg=(A_s-A_ni)/A_s;

558

vec_arg=(A_s-A_ni)/A_s;

547

if vec_arg<eps

559

if vec_arg<eps

548

vec_arg=eps;

560

vec_arg=eps;

549

end

561

end

550

VEC_dB = -20*log10(vec_arg);

562

VEC_dB = -20*log10(vec_arg);

551

COM=20*log10(A_s/A_ni);

563

COM=20*log10(A_s/A_ni);

552

min_COM = min(min_COM, COM);

564

min_COM = min(min_COM, COM);

553

min_VEO_mV = min(min_VEO_mV,VEO_mV);

565

min_VEO_mV = min(min_VEO_mV,VEO_mV);

554

max_VEC_dB = max(max_VEC_dB, VEC_dB);

566

max_VEC_dB = max(max_VEC_dB, VEC_dB);

555

end

567

end

556

MLSE_results=struct;

568

MLSE_results=struct;

557

else

569

else

558

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

570

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

559

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

571

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

560

if param.T_O ~=0

572

if param.T_O ~=0

561

eye_opening=EH_T_C2M-EH_B_C2M;

573

eye_opening=EH_T_C2M-EH_B_C2M;

562

A_ni=2*A_s-eye_opening;

574

A_ni=2*A_s-eye_opening;

563

%eq 124E-4

575

%eq 124E-4

564

vec_arg=2*A_s/eye_opening;

576

vec_arg=2*A_s/eye_opening;

565

if vec_arg<eps

577

if vec_arg<eps

566

vec_arg=eps;

578

vec_arg=eps;

567

end

579

end

568

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

580

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

569

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

581

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

570

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

582

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

571

COM=MLSE_results.COM;

583

COM=MLSE_results.COM;

572

VEO_mV=eye_opening*1000;

584

VEO_mV=eye_opening*1000;

573

min_COM = min(min_COM, COM);

585

min_COM = min(min_COM, COM);

574

min_VEO_mV = min(min_VEO_mV,VEO_mV);

586

min_VEO_mV = min(min_VEO_mV,VEO_mV);

575

max_VEC_dB = max(max_VEC_dB, VEC_dB);

587

max_VEC_dB = max(max_VEC_dB, VEC_dB);

576

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

588

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

577

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

589

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

578

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

590

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

579

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

591

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

580

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

592

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

581

COM_SNR_Struct.VEC_dB=VEC_dB;

593

COM_SNR_Struct.VEC_dB=VEC_dB;

582

else

594

else

583

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

595

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

584

vec_arg=(A_s-A_ni)/A_s;

596

vec_arg=(A_s-A_ni)/A_s;

585

if vec_arg<eps

597

if vec_arg<eps

586

vec_arg=eps;

598

vec_arg=eps;

587

end

599

end

588

VEC_dB_orig = -20*log10(vec_arg);

600

VEC_dB_orig = -20*log10(vec_arg);

589

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

601

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

590

COM_orig=20*log10(A_s/A_ni);

602

COM_orig=20*log10(A_s/A_ni);

591

COM=MLSE_results.COM;

603

COM=MLSE_results.COM;

592

min_COM = min(min_COM, COM);

604

min_COM = min(min_COM, COM);

593

min_VEO_mV = min(min_VEO_mV,VEO_mV);

605

min_VEO_mV = min(min_VEO_mV,VEO_mV);

594

max_VEC_dB = max(max_VEC_dB, VEC_dB);

606

max_VEC_dB = max(max_VEC_dB, VEC_dB);

595

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

607

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

596

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

608

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

597

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

609

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

598

COM_SNR_Struct.VEC_dB=VEC_dB;

610

COM_SNR_Struct.VEC_dB=VEC_dB;

599

end

611

end

600

end

612

end

601

613

602

%% Create COM_SNR_Struct to hold the main COM outputs

614

%% Create COM_SNR_Struct to hold the main COM outputs

603

COM_SNR_Struct.A_s=A_s;

615

COM_SNR_Struct.A_s=A_s;

604

COM_SNR_Struct.A_ni=A_ni;

616

COM_SNR_Struct.A_ni=A_ni;

605

COM_SNR_Struct.threshold_DER=threshold_DER;

617

COM_SNR_Struct.threshold_DER=threshold_DER;

606

COM_SNR_Struct.EW_UI=EW_UI;

618

COM_SNR_Struct.EW_UI=EW_UI;

607

COM_SNR_Struct.COM=COM;

619

COM_SNR_Struct.COM=COM;

608

COM_SNR_Struct.VEC_dB=VEC_dB;

620

COM_SNR_Struct.VEC_dB=VEC_dB;

609

if OP.MLSE == 0

621

if OP.MLSE == 0

610

COM_SNR_Struct.COM_orig=[];

622

COM_SNR_Struct.COM_orig=[];

611

COM_SNR_Struct.VEC_dB_orig=[];

623

COM_SNR_Struct.VEC_dB_orig=[];

612

else

624

else

613

COM_SNR_Struct.COM_orig=COM_orig;

625

COM_SNR_Struct.COM_orig=COM_orig;

614

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

626

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

615

end

627

end

616

COM_SNR_Struct.VEO_mV=VEO_mV;

628

COM_SNR_Struct.VEO_mV=VEO_mV;

617

COM_SNR_Struct.combined_interference_and_noise_pdf=combined_interference_and_noise_pdf;

629

COM_SNR_Struct.combined_interference_and_noise_pdf=combined_interference_and_noise_pdf;

618

COM_SNR_Struct.combined_interference_and_noise_cdf=combined_interference_and_noise_cdf;

630

COM_SNR_Struct.combined_interference_and_noise_cdf=combined_interference_and_noise_cdf;

619

COM_SNR_Struct.eye_contour=eye_contour;

631

COM_SNR_Struct.eye_contour=eye_contour;

620

632

621

633

622

%% Save TD

634

%% Save TD

623

if OP.SAVE_TD

635

if OP.SAVE_TD

624

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

636

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

625

if ~OP.TDMODE

637

if ~OP.TDMODE

626

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

638

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

627

end

639

end

628

for i=1:param.number_of_s4p_files

640

for i=1:param.number_of_s4p_files

629

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

641

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

630

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

642

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

631

if ~OP.TDMODE

643

if ~OP.TDMODE

632

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

644

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

633

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

645

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

634

end

646

end

635

end

647

end

636

if OP.TDMODE

648

if OP.TDMODE

637

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

649

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

638

else

650

else

639

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

651

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

640

end

652

end

641

end

653

end

642

654

643

%% Bathtub/Contribution Plot

655

%% Bathtub/Contribution Plot

644

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

656

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

645

if OP.MLSE ~= 0

657

if OP.MLSE ~= 0

646

COM_SNR_Struct.combined_interference_and_noise_pdf=MLSE_results.PDF;

658

COM_SNR_Struct.combined_interference_and_noise_pdf=MLSE_results.PDF;

647

COM_SNR_Struct.combined_interference_and_noise_cdf=MLSE_results.CDF;

659

COM_SNR_Struct.combined_interference_and_noise_cdf=MLSE_results.CDF;

648

end

660

end

649

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

661

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

650

end

662

end

651

663

652

%% Msg management

664

%% Msg management

653

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

665

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

654

msg=[];

666

msg=[];

655

end

667

end

656

if OP.DEBUG

668

if OP.DEBUG

657

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

669

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

658

switch param.flex

670

switch param.flex

659

case 4

671

case 4

660

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

672

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

661

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

673

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

662

);

674

);

663

case 2

675

case 2

664

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

676

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

665

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

677

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

666

);

678

);

667

otherwise

679

otherwise

668

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

680

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

669

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

681

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

670

);

682

);

671

683

672

end

684

end

673

else

685

else

674

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

686

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

675

end

687

end

676

688

677

if OP.TDMODE

689

if OP.TDMODE

678

min_ERL=inf;

690

min_ERL=inf;

679

ERL=[inf inf];

691

ERL=[inf inf];

680

end

692

end

681

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

693

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

682

694

683

695

684

%% Output Args

696

%% Output Args

685

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

697

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

686

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

698

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

687

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

699

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

688

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

700

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

689

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

701

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

690

rt=toc(t0);

702

rt=toc(t0);

691

output_args.rtmin=rt/60;

703

output_args.rtmin=rt/60;

692

704

693

if OP.BREAD_CRUMBS

705

if OP.BREAD_CRUMBS

694

output_args.OP=OP;

706

output_args.OP=OP;

695

output_args.param=param;

707

output_args.param=param;

696

output_args.chdata=chdata;

708

output_args.chdata=chdata;

697

output_args.fom_result = fom_result;

709

output_args.fom_result = fom_result;

698

output_args.PDF=PDF; % for exploration

710

output_args.PDF=PDF; % for exploration

699

output_args.CDF=CDF; % for exploration

711

output_args.CDF=CDF; % for exploration

700

output_args.MLSE_results=MLSE_results;

712

output_args.MLSE_results=MLSE_results;

701

output_args.PSD_results=PSD_results;

713

output_args.PSD_results=PSD_results;

702

end

714

end

703

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

715

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

704

716

705

%% making csv file

717

%% making csv file

706

if OP.CSV_REPORT ==1

718

if OP.CSV_REPORT ==1

707

Write_CSV(output_args,CSV_FILE);

719

Write_CSV(output_args,CSV_FILE);

708

end

720

end

709

%% making mat file

721

%% making mat file

710

if(OP.DEBUG)

722

if(OP.DEBUG)

711

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

723

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

712

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

724

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

713

end

725

end

714

if 1

726

if 1

715

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

727

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

716

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

728

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

717

end

729

end

718

730

719

if nargout==0

731

if nargout==0

720

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

732

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

721

disp(output_args)

733

disp(output_args)

722

end

734

end

723

735

724

if OP.BREAD_CRUMBS

736

if OP.BREAD_CRUMBS

725

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

737

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

726

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

738

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

727

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

739

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

728

try

740

try

729

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

741

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

730

catch

742

catch

731

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

743

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

732

end

744

end

733

end

745

end

734

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

746

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

735

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

747

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

736

end

748

end

737

749

738

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

750

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

739

end

751

end

740

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

752

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

741

%%

753

%%

742

754

743

if OP.RX_CALIBRATION ==1

755

if OP.RX_CALIBRATION ==1

744

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

756

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

745

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

757

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

746

end

758

end

747

DO_ONCE=false;

759

DO_ONCE=false;

748

end

760

end

749

761

750

%% Final cleanup

762

%% Final cleanup

751

if OP.DISPLAY_WINDOW

763

if OP.DISPLAY_WINDOW

752

savefigs(param, OP);

764

savefigs(param, OP);

753

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

765

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

754

end

766

end

755

767

756

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

768

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

757

if ~param.f_hp==0

769

if ~param.f_hp==0

758

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

770

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

759

if OP.DISPLAY_WINDOW

771

if OP.DISPLAY_WINDOW

760

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

772

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

761

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

773

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

762

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

774

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

763

end

775

end

764

else

776

else

765

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

777

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

766

if OP.DISPLAY_WINDOW

778

if OP.DISPLAY_WINDOW

767

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

779

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

768

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

780

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

769

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

781

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

770

end

782

end

771

end

783

end

772

end

784

end

773

785

774

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

786

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

775

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

787

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

776

disp(redo_cmd_str);

788

disp(redo_cmd_str);

777

if isdeployed

789

if isdeployed

778

if OP.exit_if_deployed

790

if OP.exit_if_deployed

779

quit

791

quit

780

end

792

end

781

end

793

end

782

%%

794

%%

783

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

795

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

784

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

796

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

785

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

797

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

786

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

798

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

787

799

788

FB=param.fb;

800

FB=param.fb;

789

FZ=param.CTLE_fz(fom_result.ctle);

801

FZ=param.CTLE_fz(fom_result.ctle);

790

FP1=param.CTLE_fp1(fom_result.ctle);

802

FP1=param.CTLE_fp1(fom_result.ctle);

791

FP2=param.CTLE_fp2(fom_result.ctle);

803

FP2=param.CTLE_fp2(fom_result.ctle);

792

GDC=param.ctle_gdc_values(fom_result.ctle);

804

GDC=param.ctle_gdc_values(fom_result.ctle);

793

if ~isempty(param.f_HP)

805

if ~isempty(param.f_HP)

794

FHP=param.f_HP(fom_result.best_G_high_pass);

806

FHP=param.f_HP(fom_result.best_G_high_pass);

795

end

807

end

796

if ~isempty(param.g_DC_HP_values)

808

if ~isempty(param.g_DC_HP_values)

797

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

809

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

798

end

810

end

799

if ~isempty(param.f_HP_Z)

811

if ~isempty(param.f_HP_Z)

800

FHPZ=param.f_HP_Z(fom_result.ctle);

812

FHPZ=param.f_HP_Z(fom_result.ctle);

801

end

813

end

802

if ~isempty(param.f_HP_P)

814

if ~isempty(param.f_HP_P)

803

FHPP=param.f_HP_P(fom_result.ctle);

815

FHPP=param.f_HP_P(fom_result.ctle);

804

end

816

end

805

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

817

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

806

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

818

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

807

%length

819

%length

808

SBR_Len=length(fom_result.sbr);

820

SBR_Len=length(fom_result.sbr);

809

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

821

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

810

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

822

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

811

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

823

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

812

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

824

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

813

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

825

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

814

end

826

end

815

for i=1:param.number_of_s4p_files

827

for i=1:param.number_of_s4p_files

816

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

828

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

817

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

829

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

818

if OP.INCLUDE_CTLE==1

830

if OP.INCLUDE_CTLE==1

819

switch param.CTLE_type

831

switch param.CTLE_type

820

case 'CL93'

832

case 'CL93'

821

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

833

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

822

case 'CL120d'

834

case 'CL120d'

823

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

824

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

836

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

825

case 'CL120e' % z has been adjusted for gain

837

case 'CL120e' % z has been adjusted for gain

826

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

838

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

827

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

839

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

828

end

840

end

829

else

841

else

830

eq_ir=uneq_ir;

842

eq_ir=uneq_ir;

831

end

843

end

832

chdata(i).eq_imp_response=eq_ir;

844

chdata(i).eq_imp_response=eq_ir;

833

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

845

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

834

846

835

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

847

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

836

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

848

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

837

end

849

end

838

839

% Next 4 lines determine a pulse response required quantization,

840

% at the CTLE output with Tx_ffe

841

chdata(i).ctle_pulse = eq_pulse;

842

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

843

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

844

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

845

846

% chdata(i).ctle_imp_response

850

% chdata(i).ctle_imp_response

847

if OP.RxFFE

851

if OP.RxFFE

848

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

852

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

849

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

853

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

850

end

854

end

851

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

855

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

852

end

856

end

853

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

857

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

854

end

858

end

855

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

859

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

856

860

857

% display bathtub curves in one axis per test case.

861

% display bathtub curves in one axis per test case.

858

case_number=param.package_testcase_i;

862

case_number=param.package_testcase_i;

859

if ~OP.COM_CONTRIBUTION_CURVES

863

if ~OP.COM_CONTRIBUTION_CURVES

860

figure_name = 'Voltage bathtub curves';

864

figure_name = 'Voltage bathtub curves';

861

fig=findobj('Name', figure_name);

865

fig=findobj('Name', figure_name);

862

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

866

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

863

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

867

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

864

movegui(fig,'south')

868

movegui(fig,'south')

865

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

869

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

866

plot_bathtub_curves( hax ...

870

plot_bathtub_curves( hax ...

867

, COM_SNR_Struct.A_s ...

871

, COM_SNR_Struct.A_s ...

868

, Noise_Struct.sci_pdf ...

872

, Noise_Struct.sci_pdf ...

869

, Noise_Struct.cci_pdf ...

873

, Noise_Struct.cci_pdf ...

870

, Noise_Struct.isi_and_xtalk_pdf ...

874

, Noise_Struct.isi_and_xtalk_pdf ...

871

, Noise_Struct.noise_pdf ...

875

, Noise_Struct.noise_pdf ...

872

, Noise_Struct.jitt_pdf ...

876

, Noise_Struct.jitt_pdf ...

873

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

877

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

874

, param.delta_y ...

878

, param.delta_y ...

875

);

879

);

876

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

880

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

877

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

881

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

878

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

882

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

879

% show BER target line

883

% show BER target line

880

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

884

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

881

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

885

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

882

else

886

else

883

figure_name = 'COM Contributions (Rough Allocations)';

887

figure_name = 'COM Contributions (Rough Allocations)';

884

fig=findobj('Name', figure_name);

888

fig=findobj('Name', figure_name);

885

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

889

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

886

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

890

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

887

movegui(fig,'south')

891

movegui(fig,'south')

888

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

892

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

889

893

890

plot_pie_com( hax ...

894

plot_pie_com( hax ...

891

, COM_SNR_Struct.A_s ...

895

, COM_SNR_Struct.A_s ...

892

, Noise_Struct.sci_pdf ...

896

, Noise_Struct.sci_pdf ...

893

, Noise_Struct.cci_pdf ...

897

, Noise_Struct.cci_pdf ...

894

, Noise_Struct.isi_and_xtalk_pdf ...

898

, Noise_Struct.isi_and_xtalk_pdf ...

895

, Noise_Struct.noise_pdf ...

899

, Noise_Struct.noise_pdf ...

896

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

900

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

897

, param.delta_y, param...

901

, param.delta_y, param...

898

);

902

);

899

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

903

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

900

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

904

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

901

end

905

end

902

906

903

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

907

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

904

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

908

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

905

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

909

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

906

end

910

end

907

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

911

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

908

912

909

if use_BT

913

if use_BT

910

a = bessel( param.BTorder );

914

a = bessel( param.BTorder );

911

acoef=fliplr( a );

915

acoef=fliplr( a );

912

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

916

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

913

else

917

else

914

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

918

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

915

end

919

end

916

920

917

921

918

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

922

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

919

923

920

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

924

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

921

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

925

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

922

%All subsequent lines are field names in chdata

926

%All subsequent lines are field names in chdata

923

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

927

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

924

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

928

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

925

%

929

%

926

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

930

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

927

%#reduce

931

%#reduce

928

%sdd12_raw

932

%sdd12_raw

929

%sdd21_raw

933

%sdd21_raw

930

%sdd22_raw

934

%sdd22_raw

931

%sdd11_raw

935

%sdd11_raw

932

%

936

%

933

937

934

fid=fopen(fields_file,'r');

938

fid=fopen(fields_file,'r');

935

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

939

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

936

940

937

file_data=file_data{1};

941

file_data=file_data{1};

938

fclose(fid);

942

fclose(fid);

939

943

940

%remove blank lines

944

%remove blank lines

941

L=cellfun('length',file_data);

945

L=cellfun('length',file_data);

942

file_data=file_data(L~=0);

946

file_data=file_data(L~=0);

943

947

944

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

948

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

945

type=file_data{1};

949

type=file_data{1};

946

field_names=file_data(2:end);

950

field_names=file_data(2:end);

947

switch lower(type)

951

switch lower(type)

948

case '#reduce'

952

case '#reduce'

949

remove_fields=field_names;

953

remove_fields=field_names;

950

case '#include'

954

case '#include'

951

all_fields=fieldnames(chdata);

955

all_fields=fieldnames(chdata);

952

remove_fields=setdiff(all_fields,field_names);

956

remove_fields=setdiff(all_fields,field_names);

953

otherwise

957

otherwise

954

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

958

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

955

end

959

end

956

960

957

%remove the "remove_fields" from chdata

961

%remove the "remove_fields" from chdata

958

for j=1:length(remove_fields)

962

for j=1:length(remove_fields)

959

this_field=remove_fields{j};

963

this_field=remove_fields{j};

960

if isfield(chdata,this_field)

964

if isfield(chdata,this_field)

961

chdata=rmfield(chdata,this_field);

965

chdata=rmfield(chdata,this_field);

962

end

966

end

963

end

967

end

964

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

968

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

965

969

966

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

970

% 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

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

971

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

968

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

972

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

969

973

970

A_s=COM_SNR_Struct.A_s;

974

A_s=COM_SNR_Struct.A_s;

971

% initialize loop with uncorrelated noise and BER

975

% initialize loop with uncorrelated noise and BER

972

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

976

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

973

977

974

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

978

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

975

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

979

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

976

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

980

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

977

% below target BER).

981

% below target BER).

978

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

982

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

979

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

983

% 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

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

984

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

981

if isempty(x_error_propagation)

985

if isempty(x_error_propagation)

982

p_error_propagation(1) = 1e-20;

986

p_error_propagation(1) = 1e-20;

983

else

987

else

984

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

988

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

985

end

989

end

986

990

987

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

991

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

988

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

992

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

989

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

993

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

990

if OP.use_simple_EP_model

994

if OP.use_simple_EP_model

991

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>

995

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

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

996

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

993

else

997

else

994

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>

998

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

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

999

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

996

end

1000

end

997

1001

998

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

1002

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

999

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

1003

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

1000

if isempty(x_error_propagation)

1004

if isempty(x_error_propagation)

1001

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

1005

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

1002

else

1006

else

1003

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

1007

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

1004

end

1008

end

1005

end

1009

end

1006

1010

1007

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

1011

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

1008

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

1012

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

1009

% of this event by partial sum of the PDF.

1013

% of this event by partial sum of the PDF.

1010

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

1014

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

1011

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

1015

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

1012

1016

1013

% probability of bursts of different lengths

1017

% probability of bursts of different lengths

1014

p_burst = cumprod(p_error_propagation);

1018

p_burst = cumprod(p_error_propagation);

1015

function H_bw=Butterworth_Filter(param,f,use_BW)

1019

function H_bw=Butterworth_Filter(param,f,use_BW)

1016

1020

1017

if use_BW

1021

if use_BW

1018

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

1022

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

1019

else

1023

else

1020

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

1024

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

1021

end

1025

end

1022

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

1026

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

1023

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

1027

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

1024

CDF_ev=CDF(index);

1028

CDF_ev=CDF(index);

1025

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

1029

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

1026

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

1030

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

1027

if isempty(index)

1031

if isempty(index)

1028

CDF_inv_ev=PDF.x(end);

1032

CDF_inv_ev=PDF.x(end);

1029

else

1033

else

1030

CDF_inv_ev=PDF.x(index);

1034

CDF_inv_ev=PDF.x(index);

1031

end

1035

end

1032

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

1036

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

1033

1037

1034

1038

1035

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

1039

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

1036

Remember_keyword='Legacy';

1040

Remember_keyword='Legacy';

1037

OP.TDMODE=false;

1041

OP.TDMODE=false;

1038

OP.GET_FD=true;

1042

OP.GET_FD=true;

1039

OP.CONFIG2MAT_ONLY=false;

1043

OP.CONFIG2MAT_ONLY=false;

1040

config_file='';

1044

config_file='';

1041

num_fext=[];

1045

num_fext=[];

1042

num_next=[];

1046

num_next=[];

1043

if ~isempty(varargin)

1047

if ~isempty(varargin)

1044

if ~ischar(varargin{1})

1048

if ~ischar(varargin{1})

1045

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

1049

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

1046

end

1050

end

1047

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

1051

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

1048

if isempty(keyword_idx)

1052

if isempty(keyword_idx)

1049

%Legacy Mode

1053

%Legacy Mode

1050

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

1054

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

1051

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

1055

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

1052

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

1056

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

1053

else

1057

else

1054

%Keyword Mode

1058

%Keyword Mode

1055

my_keyword=varargin{1};

1059

my_keyword=varargin{1};

1056

Remember_keyword=my_keyword;

1060

Remember_keyword=my_keyword;

1057

varargin(1)=[];

1061

varargin(1)=[];

1058

switch my_keyword

1062

switch my_keyword

1059

1063

1060

case 'Legacy'

1064

case 'Legacy'

1061

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

1065

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

1062

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

1066

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

1063

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

1067

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

1064

case 'TD'

1068

case 'TD'

1065

OP.TDMODE=true;

1069

OP.TDMODE=true;

1066

OP.GET_FD=false;

1070

OP.GET_FD=false;

1067

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

1071

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

1068

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

1072

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

1069

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

1073

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

1070

case 'Config2Mat'

1074

case 'Config2Mat'

1071

OP.CONFIG2MAT_ONLY=true;

1075

OP.CONFIG2MAT_ONLY=true;

1072

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

1076

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

1073

end

1077

end

1074

end

1078

end

1075

end

1079

end

1076

function chdata=COM_FD_to_TD(chdata,param,OP)

1080

function chdata=COM_FD_to_TD(chdata,param,OP)

1077

1081

1078

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

1082

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

1079

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

1083

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

1080

case_number=param.package_testcase_i;

1084

case_number=param.package_testcase_i;

1081

for i=1:param.number_of_s4p_files

1085

for i=1:param.number_of_s4p_files

1082

% RIM 2-01-2023 moved to FD_Processing

1086

% RIM 2-01-2023 moved to FD_Processing

1083

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1087

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1084

% % Equation 93A-20 %%

1088

% % Equation 93A-20 %%

1085

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

1089

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

1086

% f=chdata(i).faxis;

1090

% f=chdata(i).faxis;

1087

% %

1091

% %

1088

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

1092

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

1089

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

1093

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

1090

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

1094

% 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_txffe= Tx_FFE_Filter(param,f,param.Pkg_TXFFE_preset); % RIM 08-18-2022 to add forced TX ffe per package case

1095

% 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_r=H_bw.*H_bt.*H_RCos.*H_txffe; % RIM 08-18-2022 to add forced TX ffe per package case

1096

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

1093

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

1097

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

1094

% if OP.DISPLAY_WINDOW

1098

% if OP.DISPLAY_WINDOW

1095

% if i==1

1099

% if i==1

1096

% figure(300+param.package_testcase_i);

1100

% figure(300+param.package_testcase_i);

1097

% subplot(3,1,1)

1101

% subplot(3,1,1)

1098

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

1102

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

1099

% try

1103

% try

1100

% legend('NumColumns',2)

1104

% legend('NumColumns',2)

1101

% legend('location','south')

1105

% legend('location','south')

1102

% catch

1106

% catch

1103

% end

1107

% end

1104

% end

1108

% end

1105

% end

1109

% end

1106

% end

1110

% end

1107

[chdata(i).uneq_imp_response, ...

1111

[chdata(i).uneq_imp_response, ...

1108

chdata(i).t, ...

1112

chdata(i).t, ...

1109

chdata(i).causality_correction_dB, ...

1113

chdata(i).causality_correction_dB, ...

1110

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

1114

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

1111

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

1115

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

1112

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

1116

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

1113

[chdata(i).uneq_CD_imp_response, ...

1117

[chdata(i).uneq_CD_imp_response, ...

1114

chdata(i).t_DC, ...

1118

chdata(i).t_DC, ...

1115

chdata(i).causality_correction_DC_dB, ...

1119

chdata(i).causality_correction_DC_dB, ...

1116

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

1120

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

1117

end

1121

end

1118

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

1122

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

1119

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

1123

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

1120

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

1124

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

1121

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

1125

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

1122

1126

1123

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

1127

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

1124

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

1128

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_CD_response=chdata(i).uneq_pulse_DC_response*chdata(i).A;

1129

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

1126

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

1130

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

1127

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

1131

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

1128

rss=-inf;

1132

rss=-inf;

1129

for im=1:param.samples_per_ui

1133

for im=1:param.samples_per_ui

1130

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

1134

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

1131

end

1135

end

1132

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

1136

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

1133

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

1137

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).SCMR=10*log10(max(chdata(1).uneq_pulse_response)^2/chdata(i).VCM_HF_struct.DCn^2);

1138

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

1135

end

1139

end

1136

if OP.DEBUG && OP.DISPLAY_WINDOW

1140

if OP.DEBUG && OP.DISPLAY_WINDOW

1137

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1141

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1138

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

1142

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

1139

screen_size=get(0,'ScreenSize');

1143

screen_size=get(0,'ScreenSize');

1140

pos = get(gcf, 'OuterPosition');

1144

pos = get(gcf, 'OuterPosition');

1141

set(gcf, 'OuterPosition', ...

1145

set(gcf, 'OuterPosition', ...

1142

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

1146

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

1143

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

1147

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

1144

%movegui(gcf,'northeast')

1148

%movegui(gcf,'northeast')

1145

1149

1146

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

1150

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

1147

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

1151

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

1148

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

1152

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

1149

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

1153

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

1150

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

1154

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

1151

end

1155

end

1152

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

1156

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

1153

% scale. thru is shown in another plot.

1157

% scale. thru is shown in another plot.

1154

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

1158

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

1155

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

1159

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

1156

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

1160

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

1157

end

1161

end

1158

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

1162

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

1159

ylabel('Volts')

1163

ylabel('Volts')

1160

xlabel('seconds')

1164

xlabel('seconds')

1161

1165

1162

recolor_plots(gca);

1166

recolor_plots(gca);

1163

else

1167

else

1164

if param.ndfe~=0

1168

if param.ndfe~=0

1165

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

1169

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

1166

end

1170

end

1167

end

1171

end

1168

1172

1169

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

1173

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

1170

if OP.ENFORCE_CAUSALITY

1174

if OP.ENFORCE_CAUSALITY

1171

fprintf('\n');

1175

fprintf('\n');

1172

else

1176

else

1173

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

1177

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

1174

end

1178

end

1175

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

1179

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

1176

1180

1177

end

1181

end

1178

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)

1182

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

1183

1180

1184

1181

debug_plot=0;

1185

debug_plot=0;

1182

1186

1183

1187

1184

samp_UI=param.samples_for_C2M;

1188

samp_UI=param.samples_for_C2M;

1185

half_UI=get_center_of_UI(samp_UI);

1189

half_UI=get_center_of_UI(samp_UI);

1186

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

1190

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

1187

start_sample=half_UI-T_O;

1191

start_sample=half_UI-T_O;

1188

end_sample=half_UI+T_O;

1192

end_sample=half_UI+T_O;

1189

1193

1190

1194

1191

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

1195

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

1192

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

1196

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

1193

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

1197

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

1194

if pdf_range_flag

1198

if pdf_range_flag

1195

pdf_range=[start_sample end_sample];

1199

pdf_range=[start_sample end_sample];

1196

else

1200

else

1197

pdf_range=[];

1201

pdf_range=[];

1198

end

1202

end

1199

1203

1200

%pdf_full is self ISI pdf for each sample point

1204

%pdf_full is self ISI pdf for each sample point

1201

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

1205

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

1202

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

1206

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

1203

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

1207

[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

1208

1205

1209

1206

1210

1207

if isempty(pdf_range)

1211

if isempty(pdf_range)

1208

pdf_range=1:samp_UI;

1212

pdf_range=1:samp_UI;

1209

else

1213

else

1210

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

1214

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

1211

end

1215

end

1212

1216

1213

%Test doing Level PDFs

1217

%Test doing Level PDFs

1214

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

1218

Levels = 2*(0:param.levels-1)/(param.levels-1)-1;

1215

%A_s_vec=A_s_vec*(param.levels-1)/param.R_LM;

1219

%A_s_vec=A_s_vec*(param.levels-1)/param.R_LM;

1216

A_s_vec=A_s_vec*(param.levels-1);

1220

A_s_vec=A_s_vec*(param.levels-1);

1217

1221

1218

%add signal vector into pdf

1222

%add signal vector into pdf

1219

for n=1:param.levels

1223

for n=1:param.levels

1220

pdf_full{n}=pdf_full_1;

1224

pdf_full{n}=pdf_full_1;

1221

for j=pdf_range

1225

for j=pdf_range

1222

pdf_full{n}(j).x=pdf_full{n}(j).x+A_s_vec(j)*Levels(n);

1226

pdf_full{n}(j).x=pdf_full{n}(j).x+A_s_vec(j)*Levels(n);

1223

pdf_full{n}(j).Min=pdf_full{n}(j).x(1)/pdf_full{n}(j).BinSize;

1227

pdf_full{n}(j).Min=pdf_full{n}(j).x(1)/pdf_full{n}(j).BinSize;

1224

end

1228

end

1225

end

1229

end

1226

1230

1227

1231

1228

% figure;

1232

% figure;

1229

% hold on;

1233

% hold on;

1230

%This loop builds the same PDF/CDF structures from regular COM, but it is

1234

%This loop builds the same PDF/CDF structures from regular COM, but it is

1231

%computed for every sample point

1235

%computed for every sample point

1232

for n=1:param.levels

1236

for n=1:param.levels

1233

for j=pdf_range

1237

for j=pdf_range

1234

sigma_G_full(j) = norm([param.sigma_RJ*param.sigma_X*norm(h_j_full(:,j)), Struct_Noise.sigma_N, Struct_Noise.sigma_TX]);

1238

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

gaussian_noise_pdf_full(j) = normal_dist(sigma_G_full(j), Struct_Noise.ber_q, delta_y);

1239

gaussian_noise_pdf_full(j) = normal_dist(sigma_G_full(j), Struct_Noise.ber_q, delta_y);

1236

gaussian_noise_pdf_full(j) = conv_fct(gaussian_noise_pdf_full(j), Struct_Noise.ne_noise_pdf);

1240

gaussian_noise_pdf_full(j) = conv_fct(gaussian_noise_pdf_full(j), Struct_Noise.ne_noise_pdf);

1237

p_DD_full(j) = get_pdf_from_sampled_signal(param.A_DD*h_j_full(:,j), param.levels, delta_y);

1241

p_DD_full(j) = get_pdf_from_sampled_signal(param.A_DD*h_j_full(:,j), param.levels, delta_y);

1238

noise_pdf_full(j)=conv_fct(gaussian_noise_pdf_full(j), p_DD_full(j));

1242

noise_pdf_full(j)=conv_fct(gaussian_noise_pdf_full(j), p_DD_full(j));

1239

isi_and_xtalk_pdf_full(j) = conv_fct_MeanNotZero(pdf_full{n}(j), Struct_Noise.cci_pdf);

1243

isi_and_xtalk_pdf_full(j) = conv_fct_MeanNotZero(pdf_full{n}(j), Struct_Noise.cci_pdf);

1240

% change from adam gregory to include crosstalk

1244

% change from adam gregory to include crosstalk

1241

% combined_interference_and_noise_pdf_full = conv_fct(pdf_full(j), noise_pdf_full(j));

1245

% combined_interference_and_noise_pdf_full = conv_fct(pdf_full(j), noise_pdf_full(j));

1242

combined_interference_and_noise_pdf_full{n}(j) = conv_fct_MeanNotZero(isi_and_xtalk_pdf_full(j), noise_pdf_full(j));

1246

combined_interference_and_noise_pdf_full{n}(j) = conv_fct_MeanNotZero(isi_and_xtalk_pdf_full(j), noise_pdf_full(j));

1243

1247

1244

%PDF to CDF

1248

%PDF to CDF

1245

combined_interference_and_noise_cdf_full{n}(j)=pdf_to_cdf(combined_interference_and_noise_pdf_full{n}(j));

1249

combined_interference_and_noise_cdf_full{n}(j)=pdf_to_cdf(combined_interference_and_noise_pdf_full{n}(j));

1246

1250

1247

end

1251

end

1248

end

1252

end

1249

%hold off;

1253

%hold off;

1250

1254

1251

1255

1252

%For the given BER, find the top & bottom voltage level in the CDF

1256

%For the given BER, find the top & bottom voltage level in the CDF

1253

for n=1:param.levels

1257

for n=1:param.levels

1254

A_ni_bottom{n}=zeros(1,samp_UI);

1258

A_ni_bottom{n}=zeros(1,samp_UI);

1255

A_ni_top{n}=zeros(1,samp_UI);

1259

A_ni_top{n}=zeros(1,samp_UI);

1256

for j=pdf_range

1260

for j=pdf_range

1257

[A_ni_top{n}(j),A_ni_bottom{n}(j)]=cdf_to_ber_contour(combined_interference_and_noise_cdf_full{n}(j),param.specBER);

1261

[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

end

1262

end

1259

end

1263

end

1260

%plot(1:samp_UI,cursor_vector-A_ni_top,1:samp_UI,-cursor_vector+A_ni_bottom)

1264

%plot(1:samp_UI,cursor_vector-A_ni_top,1:samp_UI,-cursor_vector+A_ni_bottom)

1261

1265

1262

for n=1:param.levels-1

1266

for n=1:param.levels-1

1263

eye_contour{n}(:,1)=A_ni_top{n+1};

1267

eye_contour{n}(:,1)=A_ni_top{n+1};

1264

eye_contour{n}(:,2)=A_ni_bottom{n};

1268

eye_contour{n}(:,2)=A_ni_bottom{n};

1265

end

1269

end

1266

1270

1267

1271

1268

for n=1:param.levels-1

1272

for n=1:param.levels-1

1269

%eye_contour holds the top eye in the 1st column & bottom eye in the 2nd column

1273

%eye_contour holds the top eye in the 1st column & bottom eye in the 2nd column

1270

%define vref as middle of top eye height and bottom eye height. Now

1274

%define vref as middle of top eye height and bottom eye height. Now

1271

%that all eyes are created, vref is non-zero except for middle eye

1275

%that all eyes are created, vref is non-zero except for middle eye

1272

EH_top=eye_contour{n}(half_UI,1);

1276

EH_top=eye_contour{n}(half_UI,1);

1273

EH_bot=eye_contour{n}(half_UI,2);

1277

EH_bot=eye_contour{n}(half_UI,2);

1274

EH=EH_top-EH_bot;

1278

EH=EH_top-EH_bot;

1275

vref=EH_top/2+EH_bot/2;

1279

vref=EH_top/2+EH_bot/2;

1276

%This function finds left/right eye width by finding the vref crossings of

1280

%This function finds left/right eye width by finding the vref crossings of

1277

%the top and bottom eye contours

1281

%the top and bottom eye contours

1278

[Left_EW(n),Right_EW(n)]=find_eye_width(eye_contour{n},half_UI,samp_UI,vref);

1282

[Left_EW(n),Right_EW(n)]=find_eye_width(eye_contour{n},half_UI,samp_UI,vref);

1279

end

1283

end

1280

1284

1281

%For reporting to .csv, need eye contour to be a matrix instead of cell

1285

%For reporting to .csv, need eye contour to be a matrix instead of cell

1282

eye_contour_tmp=eye_contour;

1286

eye_contour_tmp=eye_contour;

1283

eye_contour=[];

1287

eye_contour=[];

1284

for n=1:param.levels-1

1288

for n=1:param.levels-1

1285

eye_contour(:,(n-1)*2+1:n*2)=eye_contour_tmp{n};

1289

eye_contour(:,(n-1)*2+1:n*2)=eye_contour_tmp{n};

1286

end

1290

end

1287

1291

1288

1292

1289

%Find VEC eye height

1293

%Find VEC eye height

1290

out_VT=[];

1294

out_VT=[];

1291

out_VB=[];

1295

out_VB=[];

1292

if param.T_O ~=0

1296

if param.T_O ~=0

1293

1297

1294

switch lower(OP.Histogram_Window_Weight)

1298

switch lower(OP.Histogram_Window_Weight)

1295

case {'gaussian' 'norm' 'normal' 'guassian'}

1299

case {'gaussian' 'norm' 'normal' 'guassian'}

1296

%build a gaussian window of weights that are multiplied by each pdf in the T_O range

1300

%build a gaussian window of weights that are multiplied by each pdf in the T_O range

1297

%Sigma = T_O/QL. Default QL=2.5. This gives a nice descent to near 0 at the edge of the window

1301

%Sigma = T_O/QL. Default QL=2.5. This gives a nice descent to near 0 at the edge of the window

1298

QL_sigma=T_O/param.QL;

1302

QL_sigma=T_O/param.QL;

1299

weights=exp(-1/2 * ([-T_O:T_O]/QL_sigma).^2);

1303

weights=exp(-1/2 * ([-T_O:T_O]/QL_sigma).^2);

1300

case 'triangle'

1304

case 'triangle'

1301

%triangle window. linear slope from 0 to 1 and back down to 0

1305

%triangle window. linear slope from 0 to 1 and back down to 0

1302

%for the weights

1306

%for the weights

1303

t_slope=1/(T_O);

1307

t_slope=1/(T_O);

1304

weights=[0:t_slope:1 1-t_slope:-t_slope:0];

1308

weights=[0:t_slope:1 1-t_slope:-t_slope:0];

1305

case 'rectangle'

1309

case 'rectangle'

1306

%default = rectangle. all weights = 1

1310

%default = rectangle. all weights = 1

1307

weights(1:2*T_O+1)=1;

1311

weights(1:2*T_O+1)=1;

1308

case 'dual_rayleigh'

1312

case 'dual_rayleigh'

1309

QL_sigma=T_O/param.QL;

1313

QL_sigma=T_O/param.QL;

1310

X=-T_O:T_O;

1314

X=-T_O:T_O;

1311

weights=(X+T_O)/QL_sigma^2.*exp(-1/2 * ((X+T_O)/QL_sigma).^2)...

1315

weights=(X+T_O)/QL_sigma^2.*exp(-1/2 * ((X+T_O)/QL_sigma).^2)...

1312

-(X-T_O)/QL_sigma^2.*exp(-1/2 * ((X-T_O)/QL_sigma).^2);

1316

-(X-T_O)/QL_sigma^2.*exp(-1/2 * ((X-T_O)/QL_sigma).^2);

1313

weights=weights/max(weights);

1317

weights=weights/max(weights);

1314

otherwise

1318

otherwise

1315

error('%s not recognized for Histogram_Window_Weight',OP.Histogram_Window_Weight)

1319

error('%s not recognized for Histogram_Window_Weight',OP.Histogram_Window_Weight)

1316

end

1320

end

1317

1321

1318

for n=1:param.levels

1322

for n=1:param.levels

1319

out_pdf{n}=[];

1323

out_pdf{n}=[];

1320

for j=start_sample:end_sample

1324

for j=start_sample:end_sample

1321

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1325

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1322

target_pdf.y=target_pdf.y*weights(j-start_sample+1);

1326

target_pdf.y=target_pdf.y*weights(j-start_sample+1);

1323

if isempty(out_pdf{n})

1327

if isempty(out_pdf{n})

1324

out_pdf{n}=target_pdf;

1328

out_pdf{n}=target_pdf;

1325

else

1329

else

1326

out_pdf{n} = combine_pdf_same_voltage_axis(out_pdf{n}, target_pdf);

1330

out_pdf{n} = combine_pdf_same_voltage_axis(out_pdf{n}, target_pdf);

1327

end

1331

end

1328

end

1332

end

1329

out_pdf{n}.y=out_pdf{n}.y/sum(out_pdf{n}.y);

1333

out_pdf{n}.y=out_pdf{n}.y/sum(out_pdf{n}.y);

1330

end

1334

end

1331

1335

1332

for n=1:param.levels

1336

for n=1:param.levels

1333

out_cdf{n}=pdf_to_cdf(out_pdf{n});

1337

out_cdf{n}=pdf_to_cdf(out_pdf{n});

1334

end

1338

end

1335

1339

1336

for n=1:param.levels

1340

for n=1:param.levels

1337

[A_ni_top_O(n),A_ni_bottom_O(n)]=cdf_to_ber_contour(out_cdf{n},param.specBER);

1341

[A_ni_top_O(n),A_ni_bottom_O(n)]=cdf_to_ber_contour(out_cdf{n},param.specBER);

1338

end

1342

end

1339

1343

1340

for n=1:param.levels-1

1344

for n=1:param.levels-1

1341

OUT_VT_L(n,1)=A_ni_top_O(n+1);

1345

OUT_VT_L(n,1)=A_ni_top_O(n+1);

1342

OUT_VT_L(n,2)=A_ni_bottom_O(n);

1346

OUT_VT_L(n,2)=A_ni_bottom_O(n);

1343

end

1347

end

1344

1348

1345

%Report the top/bottom eye height of the worst eye

1349

%Report the top/bottom eye height of the worst eye

1346

EH_VT=OUT_VT_L(:,1)-OUT_VT_L(:,2);

1350

EH_VT=OUT_VT_L(:,1)-OUT_VT_L(:,2);

1347

[mineh,min_idx]=min(EH_VT);

1351

[mineh,min_idx]=min(EH_VT);

1348

out_VT=OUT_VT_L(min_idx,1);

1352

out_VT=OUT_VT_L(min_idx,1);

1349

out_VB=OUT_VT_L(min_idx,2);

1353

out_VB=OUT_VT_L(min_idx,2);

1350

1354

1351

% CDF_Mean=mean(A_s_vec(start_sample:end_sample));

1355

% CDF_Mean=mean(A_s_vec(start_sample:end_sample));

1352

% out_VT=2*CDF_Mean-A_ni_top_O;

1356

% out_VT=2*CDF_Mean-A_ni_top_O;

1353

% out_VB=-1*A_ni_bottom_O;

1357

% out_VB=-1*A_ni_bottom_O;

1354

1358

1355

if debug_plot

1359

if debug_plot

1356

figure;

1360

figure;

1357

hold on;

1361

hold on;

1358

for j=start_sample:end_sample

1362

for j=start_sample:end_sample

1359

plot(combined_interference_and_noise_pdf_full(j).x,combined_interference_and_noise_pdf_full(j).y);

1363

plot(combined_interference_and_noise_pdf_full(j).x,combined_interference_and_noise_pdf_full(j).y);

1360

end

1364

end

1361

plot(out_pdf.x,out_pdf.y,'color','k','LineWidth',2);

1365

plot(out_pdf.x,out_pdf.y,'color','k','LineWidth',2);

1362

hold off;

1366

hold off;

1363

end

1367

end

1364

end

1368

end

1365

1369

1366

1370

1367

1371

1368

1372

1369

function [PDF,CDF,NS]=Create_Noise_PDF(A_s,param,fom_result,chdata,OP,sigma_bn,PSD_results)

1373

function [PDF,CDF,NS]=Create_Noise_PDF(A_s,param,fom_result,chdata,OP,sigma_bn,PSD_results)

1370

1374

1371

%This block was originally in main COM function but was moved here for

1375

%This block was originally in main COM function but was moved here for

1372

%cleanup. It returns the combined interference and noise PDF & CDF as well

1376

%cleanup. It returns the combined interference and noise PDF & CDF as well

1373

%as a structure "NS" that contains all the noise parameters that are used

1377

%as a structure "NS" that contains all the noise parameters that are used

1374

%in other places in COM

1378

%in other places in COM

1375

1379

1376

if OP.RX_CALIBRATION

1380

if OP.RX_CALIBRATION

1377

ctle_gain2 = (10.^(param.ctle_gdc_values(fom_result.ctle)/20) + 1i*chdata(2).faxis/param.CTLE_fz(fom_result.ctle)) ./ ...

1381

ctle_gain2 = (10.^(param.ctle_gdc_values(fom_result.ctle)/20) + 1i*chdata(2).faxis/param.CTLE_fz(fom_result.ctle)) ./ ...

1378

((1+1i*chdata(2).faxis/param.CTLE_fp1(fom_result.ctle)).*(1+1i*chdata(2).faxis/param.CTLE_fp2(fom_result.ctle)));

1382

((1+1i*chdata(2).faxis/param.CTLE_fp1(fom_result.ctle)).*(1+1i*chdata(2).faxis/param.CTLE_fp2(fom_result.ctle)));

1379

switch param.CTLE_type

1383

switch param.CTLE_type

1380

case 'CL93'

1384

case 'CL93'

1381

H_low2=1;

1385

H_low2=1;

1382

case 'CL120d' % this clause uses two gain indexes

1386

case 'CL120d' % this clause uses two gain indexes

1383

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));

1387

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

case 'CL120e' % Z1 has been adjusted

1388

case 'CL120e' % Z1 has been adjusted

1385

H_low2=(1 + 1i*chdata(2).faxis/f_HP_P(fom_result.ctle))./(1 + 1i*chdata(2).faxis/f_HP_Z(fom_result.ctle));

1389

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

end

1390

end

1387

H_ctf2=H_low2.*ctle_gain2;

1391

H_ctf2=H_low2.*ctle_gain2;

1388

[ sigma_ne, NS.sigma_hp] = get_sigma_noise( H_ctf2, param, chdata, sigma_bn );

1392

[ sigma_ne, NS.sigma_hp] = get_sigma_noise( H_ctf2, param, chdata, sigma_bn );

1389

else

1393

else

1390

sigma_ne=0;

1394

sigma_ne=0;

1391

end

1395

end

1392

1396

1393

NS.sigma_N = fom_result.sigma_N; % eta zero noise

1397

NS.sigma_N = fom_result.sigma_N; % eta zero noise

1394

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

1398

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

1395

if ~OP.SNR_TXwC0

1399

if ~OP.SNR_TXwC0

1396

% Equation 93A-30 %% h0(ts0)= A_s*R_lm/(L-1)

1400

% Equation 93A-30 %% h0(ts0)= A_s*R_lm/(L-1)

1397

NS.sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx and RLM

1401

NS.sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx and RLM

1398

else

1402

else

1399

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

1403

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

end

1404

end

1401

NS.sigma_G = norm([param.sigma_RJ*param.sigma_X*norm(fom_result.h_J), NS.sigma_N, NS.sigma_TX]);

1405

NS.sigma_G = norm([param.sigma_RJ*param.sigma_X*norm(fom_result.h_J), NS.sigma_N, NS.sigma_TX]);

1402

NS.sigma_rjit= param.sigma_RJ*param.sigma_X*norm(fom_result.h_J);

1406

NS.sigma_rjit= param.sigma_RJ*param.sigma_X*norm(fom_result.h_J);

1403

else

1407

else

1404

NS.sigma_TX =PSD_results.S_tn_rms;

1408

NS.sigma_TX =PSD_results.S_tn_rms;

1405

NS.sigma_G = PSD_results.S_G_rms;

1409

NS.sigma_G = PSD_results.S_G_rms;

1406

NS.sigma_rjit=PSD_results.S_rj_rms ;

1410

NS.sigma_rjit=PSD_results.S_rj_rms ;

1407

NS.sigma_N=PSD_results.S_rn_rms ; % Commit request 4p4_8, healey_3dj_COM_01_240416

1411

NS.sigma_N=PSD_results.S_rn_rms ; % Commit request 4p4_8, healey_3dj_COM_01_240416

1408

end

1412

end

1409

% Equation 93A-41 %%

1413

% Equation 93A-41 %%

1410

1414

1411

1415

1412

% Equation 93A-42 %%

1416

% Equation 93A-42 %%

1413

% number of sigmas needed depends on the required BER.

1417

% number of sigmas needed depends on the required BER.

1414

if param.Noise_Crest_Factor == 0

1418

if param.Noise_Crest_Factor == 0

1415

NS.ber_q = sqrt(2)*erfcinv(2*param.specBER);

1419

NS.ber_q = sqrt(2)*erfcinv(2*param.specBER);

1416

else

1420

else

1417

NS.ber_q=param.Noise_Crest_Factor;

1421

NS.ber_q=param.Noise_Crest_Factor;

1418

end

1422

end

1419

NS.gaussian_noise_pdf = normal_dist(NS.sigma_G, NS.ber_q, param.delta_y);

1423

NS.gaussian_noise_pdf = normal_dist(NS.sigma_G, NS.ber_q, param.delta_y);

1420

% enable overriding the Q factor of the BBN instrument.

1424

% enable overriding the Q factor of the BBN instrument.

1421

if OP.force_BBN_Q_factor

1425

if OP.force_BBN_Q_factor

1422

NS.ne_noise_pdf = normal_dist(sigma_ne, OP.BBN_Q_factor, param.delta_y);

1426

NS.ne_noise_pdf = normal_dist(sigma_ne, OP.BBN_Q_factor, param.delta_y);

1423

else

1427

else

1424

NS.ne_noise_pdf = normal_dist(sigma_ne, NS.ber_q, param.delta_y);

1428

NS.ne_noise_pdf = normal_dist(sigma_ne, NS.ber_q, param.delta_y);

1425

end

1429

end

1426

NS.gaussian_noise_pdf = conv_fct(NS.gaussian_noise_pdf, NS.ne_noise_pdf);

1430

NS.gaussian_noise_pdf = conv_fct(NS.gaussian_noise_pdf, NS.ne_noise_pdf);

1427

1431

1428

% p_DD is computed using the procedure defined in 93A.1.7.1 with h(n)=A_DD*h_J(n)

1432

% p_DD is computed using the procedure defined in 93A.1.7.1 with h(n)=A_DD*h_J(n)

1429

NS.p_DD = get_pdf_from_sampled_signal(param.A_DD*fom_result.h_J, param.levels, param.delta_y);

1433

NS.p_DD = get_pdf_from_sampled_signal(param.A_DD*fom_result.h_J, param.levels, param.delta_y);

1430

1434

1431

% Equation 93A-43 % only used for reporting bathtub curves

1435

% Equation 93A-43 % only used for reporting bathtub curves

1432

NS.noise_pdf=conv_fct(NS.gaussian_noise_pdf, NS.p_DD);

1436

NS.noise_pdf=conv_fct(NS.gaussian_noise_pdf, NS.p_DD);

1433

gaussian_rjitt_pdf = normal_dist(NS.sigma_rjit, NS.ber_q, param.delta_y);

1437

gaussian_rjitt_pdf = normal_dist(NS.sigma_rjit, NS.ber_q, param.delta_y);

1434

NS.jitt_pdf=conv_fct(gaussian_rjitt_pdf, NS.p_DD);

1438

NS.jitt_pdf=conv_fct(gaussian_rjitt_pdf, NS.p_DD);

1435

1439

1436

% Implementation of 93A.1.7.3 combination procedure

1440

% Implementation of 93A.1.7.3 combination procedure

1437

% (effectively Equation 93A-44) %%

1441

% (effectively Equation 93A-44) %%

1438

1442

1439

% Self-Channel Interference is thru residual result

1443

% Self-Channel Interference is thru residual result

1440

NS.sci_pdf = chdata(1).pdfr;

1444

NS.sci_pdf = chdata(1).pdfr;

1441

sci_mxi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1445

sci_mxi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1442

NS.thru_peak_interference_at_BER=abs(NS.sci_pdf.x(sci_mxi));

1446

NS.thru_peak_interference_at_BER=abs(NS.sci_pdf.x(sci_mxi));

1443

sci_msi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1447

sci_msi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1444

NS.sci_sigma=abs(NS.sci_pdf.x(sci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1448

NS.sci_sigma=abs(NS.sci_pdf.x(sci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1445

if OP.RX_CALIBRATION ==0

1449

if OP.RX_CALIBRATION ==0

1446

% Co-Channel Interference PDFs (for information only):

1450

% Co-Channel Interference PDFs (for information only):

1447

% initialize to deltas

1451

% initialize to deltas

1448

MDNEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1452

MDNEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1449

MDFEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1453

MDFEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1450

% serially convolve FEXT/NEXT PDFs

1454

% serially convolve FEXT/NEXT PDFs

1451

for k=2:param.number_of_s4p_files

1455

for k=2:param.number_of_s4p_files

1452

if isequal(chdata(k).type, 'NEXT')

1456

if isequal(chdata(k).type, 'NEXT')

1453

MDNEXT_cci_pdf = conv_fct(MDNEXT_cci_pdf, chdata(k).pdfr);

1457

MDNEXT_cci_pdf = conv_fct(MDNEXT_cci_pdf, chdata(k).pdfr);

1454

else % ... must be FEXT

1458

else % ... must be FEXT

1455

MDFEXT_cci_pdf = conv_fct(MDFEXT_cci_pdf, chdata(k).pdfr);

1459

MDFEXT_cci_pdf = conv_fct(MDFEXT_cci_pdf, chdata(k).pdfr);

1456

end

1460

end

1457

end

1461

end

1458

1462

1459

% find "peaks" of MDNEXT/MDFEXT for reporting

1463

% find "peaks" of MDNEXT/MDFEXT for reporting

1460

mdnxi=find(cumsum(MDNEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1464

mdnxi=find(cumsum(MDNEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1461

NS.MDNEXT_peak_interference=abs(MDNEXT_cci_pdf.x(mdnxi));

1465

NS.MDNEXT_peak_interference=abs(MDNEXT_cci_pdf.x(mdnxi));

1462

mdfxi=find(cumsum(MDFEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1466

mdfxi=find(cumsum(MDFEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1463

NS.MDFEXT_peak_interference=abs(MDFEXT_cci_pdf.x(mdfxi));

1467

NS.MDFEXT_peak_interference=abs(MDFEXT_cci_pdf.x(mdfxi));

1464

1468

1465

% Combined crosstalk effect

1469

% Combined crosstalk effect

1466

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1470

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1467

cci_mxi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1471

cci_mxi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1468

cci_msi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1472

cci_msi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1469

NS.cci_sigma=abs(NS.cci_pdf.x(cci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1473

NS.cci_sigma=abs(NS.cci_pdf.x(cci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1470

NS.crosstalk_peak_interference_at_BER=abs(NS.cci_pdf.x(cci_mxi));

1474

NS.crosstalk_peak_interference_at_BER=abs(NS.cci_pdf.x(cci_mxi));

1471

% combine cci and sci

1475

% combine cci and sci

1472

NS.isi_and_xtalk_pdf = conv_fct(NS.sci_pdf, NS.cci_pdf);

1476

NS.isi_and_xtalk_pdf = conv_fct(NS.sci_pdf, NS.cci_pdf);

1473

else

1477

else

1474

% for calibration there is no cci

1478

% for calibration there is no cci

1475

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1479

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1476

end

1480

end

1477

1481

1478

mxi=find(cumsum(NS.isi_and_xtalk_pdf.y)>=param.specBER, 1, 'first');

1482

mxi=find(cumsum(NS.isi_and_xtalk_pdf.y)>=param.specBER, 1, 'first');

1479

NS.peak_interference_at_BER=abs(NS.isi_and_xtalk_pdf.x(mxi));

1483

NS.peak_interference_at_BER=abs(NS.isi_and_xtalk_pdf.x(mxi));

1480

1484

1481

1485

1482

% Equation 93A-45

1486

% Equation 93A-45

1483

combined_interference_and_noise_pdf = conv_fct(NS.isi_and_xtalk_pdf, NS.noise_pdf);

1487

combined_interference_and_noise_pdf = conv_fct(NS.isi_and_xtalk_pdf, NS.noise_pdf);

+1488

PDF=combined_interference_and_noise_pdf;

1484

1489

1485

%%

1486

% Equation 93A-37

1490

% Equation 93A-37

1487

if param.N_qb ~=0

1488

[chdata,NS,combined_interference_and_noise_pdf] = adjust_Rx_noise_for_quantization(combined_interference_and_noise_pdf,NS, chdata,fom_result,param,OP);

1489

end

1490

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1491

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1491

CDF=combined_interference_and_noise_cdf;

1492

CDF=combined_interference_and_noise_cdf;

1492

PDF=combined_interference_and_noise_pdf;

1493

1494

function [hctf] = FD_CTLE(freq, fb, f_z, f_p1, f_p2, kacdc_dB)

1493

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)) ;

1494

hctf = ( 10.^(kacdc_dB/20) + 1i*freq/f_z ) ./ ( (1+1i*freq/f_p1) .* (1+1i*freq/f_p2)) ;

1496

1495

1497

function [chdata,output_args]=FD_Processing(chdata,output_args,param,OP,SDDp2p,DO_ONCE)

1496

function [chdata,output_args]=FD_Processing(chdata,output_args,param,OP,SDDp2p,DO_ONCE)

1498

%This function calculates various frequency domain metrics

1497

%This function calculates various frequency domain metrics

1499

%Mainly IL_fit, FOM_ILD, ICN, ICN_Fext, and ICN_Next

1498

%Mainly IL_fit, FOM_ILD, ICN, ICN_Fext, and ICN_Next

1500

db = @(x) 20*log10(abs(x));

1499

db = @(x) 20*log10(abs(x));

1501

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1500

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1502

if OP.WC_PORTZ

1501

if OP.WC_PORTZ

1503

A_thru = param.a_thru(param.Tx_rd_sel);

1502

A_thru = param.a_thru(param.Tx_rd_sel);

1504

A_fext = param.a_fext(param.Tx_rd_sel);

1503

A_fext = param.a_fext(param.Tx_rd_sel);

1505

A_next = param.a_next(param.Tx_rd_sel);

1504

A_next = param.a_next(param.Tx_rd_sel);

1506

else

1505

else

1507

A_thru = param.a_thru(package_testcase);

1506

A_thru = param.a_thru(package_testcase);

1508

A_fext = param.a_fext(package_testcase);

1507

A_fext = param.a_fext(package_testcase);

1509

A_next = param.a_next(package_testcase);

1508

A_next = param.a_next(package_testcase);

1510

end

1509

end

1511

for i=1:param.number_of_s4p_files

1510

for i=1:param.number_of_s4p_files

1512

if isequal(chdata(i).type, 'THRU')

1511

if isequal(chdata(i).type, 'THRU')

1513

chdata(i).A=A_thru;

1512

chdata(i).A=A_thru;

1514

chdata(i).Aicn=A_thru;

1513

chdata(i).Aicn=A_thru;

1515

elseif isequal(chdata(i).type, 'FEXT')

1514

elseif isequal(chdata(i).type, 'FEXT')

1516

chdata(i).A=A_fext;

1515

chdata(i).A=A_fext;

1517

chdata(i).Aicn=param.a_icn_fext;

1516

chdata(i).Aicn=param.a_icn_fext;

1518

elseif isequal(chdata(i).type, 'NEXT')

1517

elseif isequal(chdata(i).type, 'NEXT')

1519

chdata(i).A=A_next;

1518

chdata(i).A=A_next;

1520

chdata(i).Aicn=param.a_icn_next;

1519

chdata(i).Aicn=param.a_icn_next;

1521

end

1520

end

1522

end

1521

end

1523

if OP.TDMODE

1522

if OP.TDMODE

1524

for i=1:param.number_of_s4p_files % freq delta for integration

1523

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);

1524

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1526

end

1525

end

1527

end

1526

end

1528

if ~DO_ONCE

1527

if ~DO_ONCE

1529

return;

1528

return;

1530

end

1529

end

1531

%Any new output_args fields set in this function should be initialized here as empty

1530

%Any new output_args fields set in this function should be initialized here as empty

1532

output_args.fitted_IL_dB_at_Fnq = [];

1531

output_args.fitted_IL_dB_at_Fnq = [];

1533

output_args.cable__assembley_loss=[];

1532

output_args.cable__assembley_loss=[];

1534

output_args.loss_with_PCB=[];

1533

output_args.loss_with_PCB=[];

1535

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1534

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1536

output_args.IL_dB_channel_only_at_Fnq=[];

1535

output_args.IL_dB_channel_only_at_Fnq=[];

1537

output_args.VTF_loss_dB_at_Fnq=[];

1536

output_args.VTF_loss_dB_at_Fnq=[];

1538

output_args.IL_db_die_to_die_at_Fnq=[];

1537

output_args.IL_db_die_to_die_at_Fnq=[];

1539

output_args.FOM_TDILN=[];

1538

output_args.FOM_TDILN=[];

1540

output_args.TD_ILN=[];

1539

output_args.TD_ILN=[];

1541

output_args.FOM_RILN=[];

1540

output_args.FOM_RILN=[];

1542

output_args.FOM_ILD=[];

1541

output_args.FOM_ILD=[];

1543

%TD_Mode is just a pass through to set the empty values and return

1542

%TD_Mode is just a pass through to set the empty values and return

1544

if ~OP.GET_FD

1543

if ~OP.GET_FD

1545

return;

1544

return;

1546

end

1545

end

1547

case_number=param.package_testcase_i;

1546

case_number=param.package_testcase_i;

1548

f2=param.f2;

1547

f2=param.f2;

1549

f1=param.f1;

1548

f1=param.f1;

1550

MDFEXT_ICN=0; MDNEXT_ICN=0;

1549

MDFEXT_ICN=0; MDNEXT_ICN=0;

1551

for i=1:param.number_of_s4p_files

1550

for i=1:param.number_of_s4p_files

1552

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1551

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1553

% Equation 93A-20 %%

1552

% 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));

1553

% 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;

1554

f=chdata(i).faxis;

1556

%

1555

%

1557

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

1556

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

1558

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

1557

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

1558

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

1559

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

1560

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;

1561

chdata(i).sdd21=chdata(i).sdd21.*H_r;

1563

if OP.DISPLAY_WINDOW

1562

if OP.DISPLAY_WINDOW

1564

if i==1

1563

if i==1

1565

figure(300+param.package_testcase_i);

1564

figure(300+param.package_testcase_i);

1566

subplot(3,1,1)

1565

subplot(3,1,1)

1567

hold on

1566

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)')')

1567

plot(chdata(i).faxis/1e9, 20*log10(abs(squeeze(chdata(i).sdd21))), 'k-','linewidth',2, 'Disp',sprintf('VTF (no Tx/Rx eq)')')

1569

try

1568

try

1570

legend('NumColumns',2)

1569

legend('NumColumns',2)

1571

legend('location','south')

1570

legend('location','south')

1572

catch

1571

catch

1573

end

1572

end

1574

end

1573

end

1575

end

1574

end

1576

end

1575

end

1577

end

1576

end

1578

for i=1:param.number_of_s4p_files

1577

for i=1:param.number_of_s4p_files

1579

if i == 2

1578

if i == 2

1580

PSXT(1:length(chdata(i).sdd21f))=0;

1579

PSXT(1:length(chdata(i).sdd21f))=0;

1581

MDFEXT(1:length(chdata(i).sdd21f))=0;

1580

MDFEXT(1:length(chdata(i).sdd21f))=0;

1582

MDNEXT(1:length(chdata(i).sdd21f))=0;

1581

MDNEXT(1:length(chdata(i).sdd21f))=0;

1583

end

1582

end

1584

a=find(chdata(i).faxis(:)>=f2,1,'first');% RIM 01-12-21

1583

a=find(chdata(i).faxis(:)>=f2,1,'first');% RIM 01-12-21

1585

if isempty(a)

1584

if isempty(a)

1586

f2=chdata(i).faxis(end);

1585

f2=chdata(i).faxis(end);

1587

index_f2=length(chdata(i).faxis);

1586

index_f2=length(chdata(i).faxis);

1588

else

1587

else

1589

index_f2=a(1);

1588

index_f2=a(1);

1590

end

1589

end

1591

b=find(chdata(i).faxis(:)<=f1,1,'last');% RIM 01-12-21

1590

b=find(chdata(i).faxis(:)<=f1,1,'last');% RIM 01-12-21

1592

if isempty(b)

1591

if isempty(b)

1593

f1=chdata(i).faxis(1);

1592

f1=chdata(i).faxis(1);

1594

index_f1=1;

1593

index_f1=1;

1595

else

1594

else

1596

index_f1=b(1);

1595

index_f1=b(1);

1597

end

1596

end

1598

% R is the frequency dependent parameter for the sinc function use in the

1597

% R is the frequency dependent parameter for the sinc function use in the

1599

% PWF for ICN

1598

% PWF for ICN

1600

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(i).faxis;

1599

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(i).faxis;

1601

if(chdata(i).faxis(1)==0)

1600

if(chdata(i).faxis(1)==0)

1602

temp_angle(1)=1e-20;% we don't want to divide by zero

1601

temp_angle(1)=1e-20;% we don't want to divide by zero

1603

end

1602

end

1604

SINC = sin(temp_angle)./temp_angle;

1603

SINC = sin(temp_angle)./temp_angle;

1605

PWF_data=SINC.^2;

1604

PWF_data=SINC.^2;

1606

PWF_trf=(1+(chdata(i).faxis/chdata(i).ftr).^4).^-1;

1605

PWF_trf=(1+(chdata(i).faxis/chdata(i).ftr).^4).^-1;

1607

%// bw1=2.613126; bw2=3.4142136; bw3=2.613126;

1606

%// bw1=2.613126; bw2=3.4142136; bw3=2.613126;

1608

fr=param.f_r*param.fb;

1607

fr=param.f_r*param.fb;

1609

PWF_rx=(1+(chdata(i).faxis/fr).^8).^-1;

1608

PWF_rx=(1+(chdata(i).faxis/fr).^8).^-1;

1610

PWF_highpass=1;

1609

PWF_highpass=1;

1611

% Equation 93A-57 %

1610

% Equation 93A-57 %

1612

PWF=PWF_data.*PWF_trf.*PWF_rx.*PWF_highpass; % power weight function

1611

PWF=PWF_data.*PWF_trf.*PWF_rx.*PWF_highpass; % power weight function

1613

% freq delta for integration

1612

% freq delta for integration

1614

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1613

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1615

% from ba spec, this is basically ICN

1614

% from ba spec, this is basically ICN

1616

faxis_GHz = chdata(i).faxis/1e9;

1615

faxis_GHz = chdata(i).faxis/1e9;

1617

if isequal(chdata(i).type, 'THRU')

1616

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));

1617

[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

1618

% 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);

1619

[~, 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);

1620

fit_loss = interp1(chdata(i).faxis, -chdata(i).fit_orig, 1/param.ui/2);

1622

chdata(i).fit_ILatNq = fit_loss;

1621

chdata(i).fit_ILatNq = fit_loss;

1623

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1622

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);

1623

IL_interp = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21f)), 1/param.ui/2);

1625

chdata(i).ILatNq = IL_interp;

1624

chdata(i).ILatNq = IL_interp;

1626

if OP.include_pcb

1625

if OP.include_pcb

1627

cable_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_orig)), 1/param.ui/2);

1626

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);

1627

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;

1628

output_args.cable__assembley_loss=cable_loss;

1630

output_args.loss_with_PCB=loss_with_PCB;

1629

output_args.loss_with_PCB=loss_with_PCB;

1631

end

1630

end

1632

Nq_loss=chdata(i).ILatNq;

1631

Nq_loss=chdata(i).ILatNq;

1633

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1632

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1634

% time domain ref RR = complex fit pulse

1633

% time domain ref RR = complex fit pulse

1635

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1634

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);

1635

[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;

1636

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1638

FOM_ILN_complex= TD_ILN.FOM;

1637

FOM_ILN_complex= TD_ILN.FOM;

1639

end

1638

end

1640

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1639

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);

1640

[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;

1641

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1643

FOM_ILN_complex= TD_ILN.FOM;

1642

FOM_ILN_complex= TD_ILN.FOM;

1644

end

1643

end

1645

if OP.COMPUTE_TDILN

1644

if OP.COMPUTE_TDILN

1646

output_args.FOM_TDILN=FOM_TDILN;

1645

output_args.FOM_TDILN=FOM_TDILN;

1647

output_args.TD_ILN=TD_ILN; % struct

1646

output_args.TD_ILN=TD_ILN; % struct

1648

end

1647

end

1649

if OP.COMPUTE_RILN

1648

if OP.COMPUTE_RILN

1650

% Get RIL, RILN, and TD_RILN

1649

% Get RIL, RILN, and TD_RILN

1651

[RIL_struct]= capture_RIL_RILN(chdata);

1650

[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));

1651

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;

1652

output_args.FOM_RILN=FOM_RILN;

1654

%---start. plotting ILN based on ILD and RILN % Hansel 10/18/2021

1653

%---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

1654

plot_tdomain_debug= 0; % must have OP.COMPUTE_TDILN = 1 to use

1656

if plot_tdomain_debug== 1

1655

if plot_tdomain_debug== 1

1657

figure(988); set(gcf,'Tag','COM')

1656

figure(988); set(gcf,'Tag','COM')

1658

ax_1= subplot(3,1,1);

1657

ax_1= subplot(3,1,1);

1659

plot(TD_ILN.REF.t*1e9, TD_ILN.REF.PR*1e3,'disp','ref');

1658

plot(TD_ILN.REF.t*1e9, TD_ILN.REF.PR*1e3,'disp','ref');

1660

hold on;

1659

hold on;

1661

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1660

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1662

hold on;

1661

hold on;

1663

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k','disp','ref - fit (IL noise)');

1662

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);

1663

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1665

grid on;

1664

grid on;

1666

box on;

1665

box on;

1667

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1666

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1668

xlabel('Time [nsec]');

1667

xlabel('Time [nsec]');

1669

ylabel('Pulse Response [mV]');

1668

ylabel('Pulse Response [mV]');

1670

1669

1671

ax_2= subplot(3,1,2);

1670

ax_2= subplot(3,1,2);

1672

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1671

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1673

hold on;

1672

hold on;

1674

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1673

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1675

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1674

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1676

grid on;

1675

grid on;

1677

box on;

1676

box on;

1678

legend('REF', 'TD\_RILN');

1677

legend('REF', 'TD\_RILN');

1679

xlabel('Time [nsec]');

1678

xlabel('Time [nsec]');

1680

ylabel('Pulse Response [mV]');

1679

ylabel('Pulse Response [mV]');

1681

ax_3= subplot(3,1,3);

1680

ax_3= subplot(3,1,3);

1682

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1681

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1683

hold on;

1682

hold on;

1684

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1683

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1685

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1684

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1686

grid on;

1685

grid on;

1687

box on;

1686

box on;

1688

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1687

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1689

xlabel('Time [nsec]');

1688

xlabel('Time [nsec]');

1690

ylabel('Pulse Response [mV]');

1689

ylabel('Pulse Response [mV]');

1691

1690

1692

linkaxes([ax_1, ax_2, ax_3], 'x');

1691

linkaxes([ax_1, ax_2, ax_3], 'x');

1693

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1692

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1694

end

1693

end

1695

%---end. plotting ILN based on ILD and RILN

1694

%---end. plotting ILN based on ILD and RILN

1696

end

1695

end

1697

% Equation 93A-56 %

1696

% Equation 93A-56 %

1698

FOM_ILD=sqrt(chdata(i).delta_f/(param.fb)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1697

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;

1698

output_args.FOM_ILD=FOM_ILD;

1700

if OP.DEBUG

1699

if OP.DEBUG

1701

if OP.DISPLAY_WINDOW

1700

if OP.DISPLAY_WINDOW

1702

figure(300+case_number);

1701

figure(300+case_number);

1703

set(gcf,'Tag','COM')

1702

set(gcf,'Tag','COM')

1704

screen_size=get(0,'ScreenSize');

1703

screen_size=get(0,'ScreenSize');

1705

pos = get(gcf, 'OuterPosition');

1704

pos = get(gcf, 'OuterPosition');

1706

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1705

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

1706

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]);

1707

- (case_number-1)*[0 20 0 0]);

1709

subplot(3,1,1)

1708

subplot(3,1,1)

1710

title('Losses')

1709

title('Losses')

1711

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1710

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1712

hold on

1711

hold on

1713

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1712

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')

1713

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1715

ylim(get(gca, 'ylim'));

1714

ylim(get(gca, 'ylim'));

1716

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1715

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')

1716

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1718

subplot(3,1,3)

1717

subplot(3,1,3)

1719

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1718

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1720

if OP.PLOT_CM

1719

if OP.PLOT_CM

1721

if case_number ==1

1720

if case_number ==1

1722

h350=figure(350);set(gcf,'Tag','COM')

1721

h350=figure(350);set(gcf,'Tag','COM')

1723

screen_size=get(0,'ScreenSize');

1722

screen_size=get(0,'ScreenSize');

1724

pos = get(gcf, 'OuterPosition');

1723

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])

1724

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');

1725

movegui(gcf,'center');

1727

htabgroup350 = uitabgroup(h350);

1726

htabgroup350 = uitabgroup(h350);

1728

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1727

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1729

hax1 = axes('Parent', htab1);

1728

hax1 = axes('Parent', htab1);

1730

set(h350,'CurrentAxes',hax1)

1729

set(h350,'CurrentAxes',hax1)

1731

hold on

1730

hold on

1732

set(gcf,'Tag','COM')

1731

set(gcf,'Tag','COM')

1733

screen_size=get(0,'ScreenSize');

1732

screen_size=get(0,'ScreenSize');

1734

pos = get(gcf, 'OuterPosition');

1733

pos = get(gcf, 'OuterPosition');

1735

title('IL & CM Losses')

1734

title('IL & CM Losses')

1736

base=strrep(chdata(i).base,'_',' ');

1735

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])

1736

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])

1737

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1739

ylabel('dB')

1738

ylabel('dB')

1740

xlabel('GHz')

1739

xlabel('GHz')

1741

legend show

1740

legend show

1742

legend('Location','eastoutside')

1741

legend('Location','eastoutside')

1743

hold on

1742

hold on

1744

grid on

1743

grid on

1745

if param.number_of_s4p_files > 1

1744

if param.number_of_s4p_files > 1

1746

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1745

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1747

hax2 = axes('Parent', htab2);

1746

hax2 = axes('Parent', htab2);

1748

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1747

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1749

hax3 = axes('Parent', htab3);

1748

hax3 = axes('Parent', htab3);

1750

end

1749

end

1751

1750

1752

end

1751

end

1753

end

1752

end

1754

else

1753

else

1755

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1754

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1756

end

1755

end

1757

end

1756

end

1758

else % NEXT or FEXT

1757

else % NEXT or FEXT

1759

if isequal(chdata(i).type, 'FEXT')

1758

if isequal(chdata(i).type, 'FEXT')

1760

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1759

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1761

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.fb*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46 corrected for fb

1760

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;

1761

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1763

elseif isequal(chdata(i).type, 'NEXT')

1762

elseif isequal(chdata(i).type, 'NEXT')

1764

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1763

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1765

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.fb*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47 corrected for fb

1764

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;

1765

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1767

end

1766

end

1768

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1767

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1769

ICN=sqrt(2*chdata(i).delta_f/param.fb*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));% corrected for fb

1768

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;

1769

output_args.ICN_mV=ICN*1000;

1771

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1770

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1772

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1771

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1773

if case_number ==1

1772

if case_number ==1

1774

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1773

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1775

% hax2 = axes('Parent', htab2);

1774

% hax2 = axes('Parent', htab2);

1776

set(h350,'CurrentAxes',hax2)

1775

set(h350,'CurrentAxes',hax2)

1777

hold on

1776

hold on

1778

title('CM Losses')

1777

title('CM Losses')

1779

base=strrep(chdata(i).base,'_',' ');

1778

base=strrep(chdata(i).base,'_',' ');

1780

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1779

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1781

legend('Location','eastoutside')

1780

legend('Location','eastoutside')

1782

hold on

1781

hold on

1783

grid on

1782

grid on

1784

set(h350,'CurrentAxes',hax3)

1783

set(h350,'CurrentAxes',hax3)

1785

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1784

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1786

legend('Location','eastoutside')

1785

legend('Location','eastoutside')

1787

hold on

1786

hold on

1788

grid on

1787

grid on

1789

end

1788

end

1790

end

1789

end

1791

end

1790

end

1792

end % for loop

1791

end % for loop

1793

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1792

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1794

if OP.DEBUG && OP.DISPLAY_WINDOW

1793

if OP.DEBUG && OP.DISPLAY_WINDOW

1795

figure(300+case_number);set(gcf,'Tag','COM');

1794

figure(300+case_number);set(gcf,'Tag','COM');

1796

if param.number_of_s4p_files > 1

1795

if param.number_of_s4p_files > 1

1797

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1796

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1798

subplot(3,1,1)

1797

subplot(3,1,1)

1799

hold on

1798

hold on

1800

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1799

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1801

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1800

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1802

subplot(3,1,2)

1801

subplot(3,1,2)

1803

grid on

1802

grid on

1804

ILtemp=20*log10(abs(chdata(1).sdd21f));

1803

ILtemp=20*log10(abs(chdata(1).sdd21f));

1805

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1804

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1806

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1805

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1807

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1806

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1808

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1807

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1809

hold on

1808

hold on

1810

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1809

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1811

end

1810

end

1812

subplot(3,1,1)

1811

subplot(3,1,1)

1813

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1812

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1814

grid on; legend show

1813

grid on; legend show

1815

subplot(3,1,2)

1814

subplot(3,1,2)

1816

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1815

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1817

ylim([0 80])

1816

ylim([0 80])

1818

xlim([.1 100])

1817

xlim([.1 100])

1819

grid on; %legend show

1818

grid on; %legend show

1820

subplot(3,1,3)

1819

subplot(3,1,3)

1821

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1820

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1822

ylim([-3 3])

1821

ylim([-3 3])

1823

grid on; legend show

1822

grid on; legend show

1824

end

1823

end

1825

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1824

% 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);

1825

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);

1826

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);

1827

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;

1828

output_args.VTF_loss_dB_at_Fnq=total_loss;

1830

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1829

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1831

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1830

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1832

function [ V0 ] = FFE( C , cmx,spui, V )

1831

function [ V0 ] = FFE( C , cmx,spui, V )

1833

% C FFE taps

1832

% C FFE taps

1834

% cmx number of precursors taps

1833

% cmx number of precursors taps

1835

% spui samples per ui

1834

% spui samples per ui

1836

% V input signal

1835

% V input signal

1837

%speed ups implemented:

1836

%speed ups implemented:

1838

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1837

%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

1838

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1840

1839

1841

V0=0;

1840

V0=0;

1842

if iscolumn(V); V=V.';end

1841

if iscolumn(V); V=V.';end

1843

for i=1:length(C)

1842

for i=1:length(C)

1844

if C(i)~=0

1843

if C(i)~=0

1845

ishift=(i-1-cmx)*spui;

1844

ishift=(i-1-cmx)*spui;

1846

V0=circshift(V',[ishift,0])*C(i)+V0;

1845

V0=circshift(V',[ishift,0])*C(i)+V0;

1847

end

1846

end

1848

end

1847

end

1849

%V0=circshift(V0,[(-cmx)*spui,0]);

1848

%V0=circshift(V0,[(-cmx)*spui,0]);

1850

% disp(max(V0));

1849

% disp(max(V0));

1851

1850

1852

1851

1853

% begin yasuo patch 12/11/2018

1852

% begin yasuo patch 12/11/2018

1854

% calculate sigma (standard deviation) value of PDF

1853

% calculate sigma (standard deviation) value of PDF

1855

function [ V0 ] = FFE_Fast( C,V_shift )

1854

function [ V0 ] = FFE_Fast( C,V_shift )

1856

% C FFE taps

1855

% C FFE taps

1857

% V input signal separated into length(C) columns with circshift already performed

1856

% 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

1857

% 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

1858

% 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

1859

% saved by pre-shifting it and remembering it across loops

1861

% Another speed up: only multiply by indices of C that are not 0

1860

% Another speed up: only multiply by indices of C that are not 0

1862

1861

1863

V0=0;

1862

V0=0;

1864

for i=1:length(C)

1863

for i=1:length(C)

1865

if C(i)~=0

1864

if C(i)~=0

1866

V0=V_shift(:,i)*C(i)+V0;

1865

V0=V_shift(:,i)*C(i)+V0;

1867

end

1866

end

1868

end

1867

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)

1868

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1870

1869

1871

hisi=h(isi_start:isi_end);

1870

hisi=h(isi_start:isi_end);

1872

hisi=hisi(param.RxFFE_cpx+1:param.N_bmax);

1871

hisi=hisi(param.RxFFE_cpx+1:param.N_bmax);

1873

bank_size = param.N_bf;

1872

bank_size = param.N_bf;

1874

num_groups = param.N_bg;

1873

num_groups = param.N_bg;

1875

1874

1876

1875

1877

%start with one by one Floating Tap

1876

%start with one by one Floating Tap

1878

num_isi=length(hisi);

1877

num_isi=length(hisi);

1879

max_isi=num_isi-bank_size+1;

1878

max_isi=num_isi-bank_size+1;

1880

valid_tap_locations=1:max_isi;

1879

valid_tap_locations=1:max_isi;

1881

all_idx=[];

1880

all_idx=[];

1882

for j=1:num_groups

1881

for j=1:num_groups

1883

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1882

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1884

for k=1:length(valid_tap_locations)

1883

for k=1:length(valid_tap_locations)

1885

this_location=valid_tap_locations(k);

1884

this_location=valid_tap_locations(k);

1886

new_idx = [all_idx this_location:this_location+bank_size-1];

1885

new_idx = [all_idx this_location:this_location+bank_size-1];

1887

new_idx=sort(new_idx);

1886

new_idx=sort(new_idx);

1888

new_idx = new_idx+param.RxFFE_cpx;

1887

new_idx = new_idx+param.RxFFE_cpx;

1889

%calculate FOM for each one

1888

%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);

1889

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1891

end

1890

end

1892

%choose the location with best FOM

1891

%choose the location with best FOM

1893

%add it to the "all_idx" list and remove it from valid locations

1892

%add it to the "all_idx" list and remove it from valid locations

1894

[~,best_FOM_idx]=max(best_FOM);

1893

[~,best_FOM_idx]=max(best_FOM);

1895

start_tap = valid_tap_locations(best_FOM_idx);

1894

start_tap = valid_tap_locations(best_FOM_idx);

1896

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1895

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1897

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1896

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1898

remove_range(remove_range>length(valid_tap_locations))=[];

1897

remove_range(remove_range>length(valid_tap_locations))=[];

1899

valid_tap_locations(remove_range)=[];

1898

valid_tap_locations(remove_range)=[];

1900

1899

1901

%Also remove illegal taps from valid locations

1900

%Also remove illegal taps from valid locations

1902

%illegal taps are ones that would overlap with the chosen bank

1901

%illegal taps are ones that would overlap with the chosen bank

1903

bad_tap=start_tap-bank_size+1:start_tap-1;

1902

bad_tap=start_tap-bank_size+1:start_tap-1;

1904

bad_tap(bad_tap<1)=[];

1903

bad_tap(bad_tap<1)=[];

1905

for n=1:length(bad_tap)

1904

for n=1:length(bad_tap)

1906

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1905

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1907

if ~isempty(bad_tap_idx)

1906

if ~isempty(bad_tap_idx)

1908

valid_tap_locations(bad_tap_idx)=[];

1907

valid_tap_locations(bad_tap_idx)=[];

1909

end

1908

end

1910

end

1909

end

1911

end

1910

end

1912

1911

1913

%put idx back in the right location (adding RxFFE_cpx)

1912

%put idx back in the right location (adding RxFFE_cpx)

1914

idx = all_idx+param.RxFFE_cpx;

1913

idx = all_idx+param.RxFFE_cpx;

1915

idx = sort(idx);

1914

idx = sort(idx);

1916

function [ V0 ] = Fract_T_FFE( V , skew_step)

1915

function [ V0 ] = Fract_T_FFE( V , skew_step)

1917

% skew_step sub UI skew assuming param.samples_per_ui

1916

% skew_step sub UI skew assuming param.samples_per_ui

1918

% V input signal

1917

% V input signal

1919

% V0 output signal

1918

% V0 output signal

1920

% Richard Mellitz 8/17/2021

1919

% Richard Mellitz 8/17/2021

1921

V0=0;

1920

V0=0;

1922

if iscolumn(V); V=V.';end

1921

if iscolumn(V); V=V.';end

1923

ishift=skew_step;

1922

ishift=skew_step;

1924

V0=circshift(V',[ishift,0])'+V;

1923

V0=circshift(V',[ishift,0])'+V;

1925

V0=V0/2;

1924

V0=V0/2;

1926

function out=Full_Grid_Matrix(in)

1925

function out=Full_Grid_Matrix(in)

1927

1926

1928

%create a full grid matrix of input variables

1927

%create a full grid matrix of input variables

1929

%used to create the full grid of all txffe cases

1928

%used to create the full grid of all txffe cases

1930

%example:

1929

%example:

1931

%Full_Grid_Matrix({ [1 2] [100 200] })

1930

%Full_Grid_Matrix({ [1 2] [100 200] })

1932

%out =

1931

%out =

1933

% 1 100

1932

% 1 100

1934

% 1 200

1933

% 1 200

1935

% 2 100

1934

% 2 100

1936

% 2 200

1935

% 2 200

1937

%

1936

%

1938

%input can also be mixed between numeric and cell of char

1937

%input can also be mixed between numeric and cell of char

1939

%example:

1938

%example:

1940

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1939

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1941

%out =

1940

%out =

1942

% {[1]} {'A'}

1941

% {[1]} {'A'}

1943

% {[1]} {'B'}

1942

% {[1]} {'B'}

1944

% {[2]} {'A'}

1943

% {[2]} {'A'}

1945

% {[2]} {'B'}

1944

% {[2]} {'B'}

1946

1945

1947

if ~iscell(in)

1946

if ~iscell(in)

1948

error('input must be cell array of individual sweep variables');

1947

error('input must be cell array of individual sweep variables');

1949

end

1948

end

1950

1949

1951

num_columns=length(in);

1950

num_columns=length(in);

1952

num_cases=prod(cellfun('length',in));

1951

num_cases=prod(cellfun('length',in));

1953

1952

1954

cell_output=0;

1953

cell_output=0;

1955

cell_indices=cellfun(@(x) iscell(x),in);

1954

cell_indices=cellfun(@(x) iscell(x),in);

1956

if any(cell_indices)

1955

if any(cell_indices)

1957

cell_output=1;

1956

cell_output=1;

1958

end

1957

end

1959

if cell_output

1958

if cell_output

1960

for k=find(~cell_indices)

1959

for k=find(~cell_indices)

1961

in{k}=num2cell(in{k});

1960

in{k}=num2cell(in{k});

1962

end

1961

end

1963

end

1962

end

1964

1963

1965

if cell_output

1964

if cell_output

1966

out=cell(num_cases,num_columns);

1965

out=cell(num_cases,num_columns);

1967

else

1966

else

1968

out=zeros(num_cases,num_columns);

1967

out=zeros(num_cases,num_columns);

1969

end

1968

end

1970

1969

1971

%num_repetitions controls how many times each element of the column

1970

%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

1971

%repeats. The first column is always just a copy of itself since every

1973

%case will vary.

1972

%case will vary.

1974

num_repetitions=1;

1973

num_repetitions=1;

1975

for k=num_columns:-1:1

1974

for k=num_columns:-1:1

1976

this_column=in{k}(:);

1975

this_column=in{k}(:);

1977

%copy the column into a matrix to create the repetitions needed

1976

%copy the column into a matrix to create the repetitions needed

1978

B=repmat(this_column,[1 num_repetitions]);

1977

B=repmat(this_column,[1 num_repetitions]);

1979

%reshape into single column (actual repetitions)

1978

%reshape into single column (actual repetitions)

1980

C=reshape(B',[numel(B) 1]);

1979

C=reshape(B',[numel(B) 1]);

1981

%repeat the single column to build the entire length required

1980

%repeat the single column to build the entire length required

1982

num_repeats=num_cases/length(C);

1981

num_repeats=num_cases/length(C);

1983

D=repmat(C,[num_repeats 1]);

1982

D=repmat(C,[num_repeats 1]);

1984

out(:,k)=D;

1983

out(:,k)=D;

1985

%determine how many repetitions the next column needs

1984

%determine how many repetitions the next column needs

1986

num_repetitions=num_repetitions*length(this_column);

1985

num_repetitions=num_repetitions*length(this_column);

1987

end

1986

end

1988

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1987

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1989

% p=cpdf(type, ...)

1988

% p=cpdf(type, ...)

1990

%

1989

%

1991

% CPDF is a probability mass function for discrete distributions or an

1990

% CPDF is a probability mass function for discrete distributions or an

1992

% approxmation of a PDF for continuous distributions.

1991

% approxmation of a PDF for continuous distributions.

1993

%

1992

%

1994

% cpdf is internally normalized so that the sum of probabilities is 1

1993

% cpdf is internally normalized so that the sum of probabilities is 1

1995

% (regardless of bin size).

1994

% (regardless of bin size).

1996

1995

1997

% Internal fields:

1996

% Internal fields:

1998

% Min: *bin number* of minimum value.

1997

% Min: *bin number* of minimum value.

1999

% BinSize: size of PDF bins. Bin center is the representative value.

1998

% BinSize: size of PDF bins. Bin center is the representative value.

2000

% Vec: vector of probabilities per bin.

1999

% Vec: vector of probabilities per bin.

2001

2000

2002

pdf=EmptyPDF;

2001

pdf=EmptyPDF;

2003

2002

2004

rounded_values_div_binsize=round(values/pdf.BinSize);

2003

rounded_values_div_binsize=round(values/pdf.BinSize);

2005

%values=pdf.BinSize*rounded_values_div_binsize;

2004

%values=pdf.BinSize*rounded_values_div_binsize;

2006

2005

2007

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2006

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2008

% if all(values==0)

2007

% if all(values==0)

2009

% return;

2008

% return;

2010

% end

2009

% end

2011

%

2010

%

2012

% %speed up for all values rounded to the same bin

2011

% %speed up for all values rounded to the same bin

2013

% %The output pdf is the same as the

2012

% %The output pdf is the same as the

2014

% %empty pdf, but the x value is non-zero (but still scalar)

2013

% %empty pdf, but the x value is non-zero (but still scalar)

2015

% if all(values==values(1))

2014

% if all(values==values(1))

2016

% pdf.Min=rounded_values_div_binsize(1);

2015

% pdf.Min=rounded_values_div_binsize(1);

2017

% pdf.x=values(1);

2016

% pdf.x=values(1);

2018

% return;

2017

% return;

2019

% end

2018

% end

2020

%

2019

%

2021

% %The code below requires that values is

2020

% %The code below requires that values is

2022

% %sorted. Generally this should be true, but check to be sure

2021

% %sorted. Generally this should be true, but check to be sure

2023

% if ~issorted(values)

2022

% if ~issorted(values)

2024

% [values,si]=sort(values);

2023

% [values,si]=sort(values);

2025

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2024

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2026

% probs=probs(si);

2025

% probs=probs(si);

2027

% end

2026

% end

2028

2027

2029

2028

2030

%pdf.x=values(1):pdf.BinSize:values(end);

2029

%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);

2030

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);

2031

pdf.Min=rounded_values_div_binsize(1);

2033

2032

2034

pdf.y=zeros(size(pdf.x));

2033

pdf.y=zeros(size(pdf.x));

2035

%The rounded values divided by binsize will reveal the bin number if

2034

%The rounded values divided by binsize will reveal the bin number if

2036

%pdf.Min is subtracted from it

2035

%pdf.Min is subtracted from it

2037

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2036

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2038

%Can avoid one addition by inserting the first probability

2037

%Can avoid one addition by inserting the first probability

2039

%actually helps when calling this 2 million times

2038

%actually helps when calling this 2 million times

2040

pdf.y(bin_placement(1))=probs(1);

2039

pdf.y(bin_placement(1))=probs(1);

2041

for k=2:length(values)

2040

for k=2:length(values)

2042

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2041

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2043

end

2042

end

2044

2043

2045

2044

2046

%Have already ensured that sum(pdf.y)=1

2045

%Have already ensured that sum(pdf.y)=1

2047

%pdf.y=pdf.y/sum(pdf.y);

2046

%pdf.y=pdf.y/sum(pdf.y);

2048

2047

2049

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2048

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2050

% error('PDF must be real and nonnegative');

2049

% error('PDF must be real and nonnegative');

2051

% end

2050

% end

2052

2051

2053

% pMax=pdf.Min+length(pdf.y)-1;

2052

% pMax=pdf.Min+length(pdf.y)-1;

2054

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2053

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2055

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2054

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

2055

% 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

2056

% 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

2057

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2059

2058

2060

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2059

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2061

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2060

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2062

2061

2063

%% step 0

2062

%% step 0

2064

COM_from_matlab=20*log10(A_s/A_ni);

2063

COM_from_matlab=20*log10(A_s/A_ni);

2065

L=param.levels;

2064

L=param.levels;

2066

DER0=param.specBER;

2065

DER0=param.specBER;

2067

%% step 1 from slide 6/5

2066

%% step 1 from slide 6/5

2068

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2067

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2069

main=A_peak;

2068

main=A_peak;

2070

k_DER=qfuncinv(param.specBER);

2069

k_DER=qfuncinv(param.specBER);

2071

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2070

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) ;

2071

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);

2072

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)

2073

% 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

2074

if A_s >= A_ni

2076

%% step 2 slide 10/8

2075

%% step 2 slide 10/8

2077

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2076

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2078

%% step 2 slide 10/8

2077

%% 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));

2078

% 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);

2079

% 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

2080

%% step 3 side 11/9

2082

j=1:200;

2081

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 ) ));

2082

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;

2083

DER_MLSE_CDF=0; jj=1;

2085

DER_delta = inf;

2084

DER_delta = inf;

2086

while DER_delta > .001

2085

while DER_delta > .001

2087

last_DER_MLSE_CDF=DER_MLSE_CDF;

2086

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;

2087

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;

2088

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2090

jj=jj+1;

2089

jj=jj+1;

2091

end

2090

end

2092

%% step 4 slide 12/10

2091

%% step 4 slide 12/10

2093

SNR_DFE_eqivalent=SNR_DFE*(...

2092

SNR_DFE_eqivalent=SNR_DFE*(...

2094

(L-1)*sigma_noise/main * qfuncinv(...

2093

(L-1)*sigma_noise/main * qfuncinv(...

2095

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2094

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2096

) ...

2095

) ...

2097

)^2;

2096

)^2;

2098

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2097

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2099

(L-1)/main * CDF_inv_ev(...

2098

(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 )) ...

2099

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2101

,PDF, CDF ) ...

2100

,PDF, CDF ) ...

2102

)^2;

2101

)^2;

2103

2102

2104

%% step 5 slide 13/11

2103

%% step 5 slide 13/11

2105

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2104

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2106

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2105

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2107

new_com_CDF=COM_from_matlab+delta_com_CDF;

2106

new_com_CDF=COM_from_matlab+delta_com_CDF;

2108

else

2107

else

2109

warning('MLSE not applied because there is more noise than signal')

2108

warning('MLSE not applied because there is more noise than signal')

2110

DER_MLSE=[];

2109

DER_MLSE=[];

2111

DER_MLSE_CDF=[];

2110

DER_MLSE_CDF=[];

2112

SNR_DFE_eqivalent=[];

2111

SNR_DFE_eqivalent=[];

2113

SNR_DFE_eqivalent_CDF=[];

2112

SNR_DFE_eqivalent_CDF=[];

2114

new_com_CDF=COM_from_matlab;

2113

new_com_CDF=COM_from_matlab;

2115

delta_com_CDF=0;

2114

delta_com_CDF=0;

2116

delta_com=0;

2115

delta_com=0;

2117

SNR_DFE=[];

2116

SNR_DFE=[];

2118

end

2117

end

2119

2118

2120

%%

2119

%%

2121

MLSE_results.COM_from_matlab=COM_from_matlab;

2120

MLSE_results.COM_from_matlab=COM_from_matlab;

2122

MLSE_results.SNR_DFE=SNR_DFE;

2121

MLSE_results.SNR_DFE=SNR_DFE;

2123

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2122

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2124

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2123

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2125

MLSE_results.sigma_noise=sigma_noise;

2124

MLSE_results.sigma_noise=sigma_noise;

2126

MLSE_results.SNR_dB=SNR_dB ;

2125

MLSE_results.SNR_dB=SNR_dB ;

2127

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2126

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2128

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2127

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2129

MLSE_results.COM_Gaussian=new_com_CDF;

2128

MLSE_results.COM_Gaussian=new_com_CDF;

2130

MLSE_results.COM_CDF=new_com_CDF;

2129

MLSE_results.COM_CDF=new_com_CDF;

2131

MLSE_results.k_DER=k_DER;

2130

MLSE_results.k_DER=k_DER;

2132

MLSE_results.delta_com_CDF=delta_com_CDF;

2131

MLSE_results.delta_com_CDF=delta_com_CDF;

2133

MLSE_results.delta_com_Gaussian=delta_com;

2132

MLSE_results.delta_com_Gaussian=delta_com;

2134

2133

2135

2134

2136

2135

2137

function [MLSE_results] = MLSE_U1_c_178A(param,b,A_s,A_ni,PDF,CDF,PSD_results)

2136

function [MLSE_results] = MLSE_U1_c_178A(param,b,A_s,A_ni,PDF,CDF,PSD_results)

2138

if 1

2137

if 1

2139

num_ui=param.num_ui_RXFF_noise;

2138

num_ui=param.num_ui_RXFF_noise;

2140

M=param.samples_per_ui;

2139

M=param.samples_per_ui;

2141

L=param.levels;

2140

L=param.levels;

2142

sigma_X2=(L^2-1)/(3*(L-1)^2);

2141

sigma_X2=(L^2-1)/(3*(L-1)^2);

2143

f_b=param.fb;

2142

f_b=param.fb;

2144

DER0=param.specBER; % align terminology

2143

DER0=param.specBER; % align terminology

2145

delta_COM_an=param.pass_threshold; % align terminology

2144

delta_COM_an=param.pass_threshold; % align terminology

2146

end

2145

end

2147

% new function to scale CDF at specified DER; healey_3dj_01_2409 slide 8, 12, and 13

2146

% 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);

2147

% directly compute p_an (PDF) and P_an (CDF);

2149

[p_an, P_an, ~] = scaleCDF( PDF,delta_COM_an,DER0, A_s );

2148

[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);

2149

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;

2150

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;

2151

g_an=(sigma_an_2_pdf-PSD_results.S_G_rms^2)/PSD_results.S_rn_rms^2;

2153

2152

2154

% g_an be squared since votltage was scalted: healey_3dj_01_2409 slide 12 (178A –X) units are power

2153

% 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;

2154

% g_an=g_an^2;

2156

COM_from_matlab=20*log10(A_s/A_ni);

2155

COM_from_matlab=20*log10(A_s/A_ni);

2157

DER_DFE= CDF_ev(A_s,PDF, CDF);% remove 2*(L-1)/L COM Commit Request Numbers 4p7_5

2156

DER_DFE= 2*(L-1)/L*CDF_ev(A_s,PDF, CDF);

2158

if 0 % comparing to healey_3dj_01_2409 slide 8

2157

if 1 % comparing to healey_3dj_01_2409 slide 8

2159

figure(1200);set(gcf,'Tag','COM');

2158

figure(1200);set(gcf,'Tag','COM');

2160

semilogy(PDF.x/A_s,CDF,'disp',sprintf('P(y) case %g',param.package_testcase_i))

2159

semilogy(PDF.x/A_s,CDF,'disp',sprintf('P(y) case %g',param.package_testcase_i))

2161

ylim([1e-7 1e-1])

2160

ylim([1e-7 1e-1])

2162

grid on

2161

grid on

2163

movegui(gcf,[randn randn]*100)

2162

movegui(gcf,[randn randn]*100)

2164

xlabel('-A_ni/A_s')

2163

xlabel('-A_ni/A_s')

2165

ylabel('DER')

2164

ylabel('DER')

2166

hold on

2165

hold on

2167

semilogy(p_an.x/A_s,P_an,'disp',sprintf('P_a_n(y) case %g',param.package_testcase_i'))

2166

semilogy(p_an.x/A_s,P_an,'disp',sprintf('P_a_n(y) case %g',param.package_testcase_i'))

2168

legend show

2167

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 ) ))

2168

% 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

2169

end

2171

% PDF=p_an;

2170

% PDF=p_an;

2172

% CDF=P_an;

2171

% CDF=P_an;

2173

S_an=g_an*PSD_results.S_rn.*PSD_results.H_rxffe_2; % healey_3dj_01_2409 slide 12

2172

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

2173

S_ni=PSD_results.S_isi +PSD_results.S_n +S_an; % 178A-40, healey_3dj_01_2409 slide 15

2175

R_ni=ifft(S_ni)*f_b;

2174

R_ni=ifft(S_ni)*f_b;

2176

p_scaled_by_b=scalePDF(p_an,b(1));

2175

p_scaled_by_b=scalePDF(p_an,b(1));

2177

p_j=conv_fct(p_an,p_scaled_by_b);

2176

p_j=conv_fct(p_an,p_scaled_by_b);

2178

p_scaled_by_1mb=scalePDF(p_an,1-b(1));

2177

p_scaled_by_1mb=scalePDF(p_an,1-b(1));

2179

%% %% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2178

%% %% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2180

p_trunc = p_an;

2179

p_trunc = p_an;

2181

%

2180

%

2182

j=1; DER_MLSE=0; DER_MLSE_j= inf;

2181

j=1; DER_MLSE=0; DER_MLSE_j= inf;

2183

P_j.y=cumsum(p_j.y);

2182

P_j.y=cumsum(p_j.y);

2184

smallest_relative_change=.0001;

2183

smallest_relative_change=.0001;

2185

%% 178A–37

2184

%% 178A–37

2186

rou=R_ni'/R_ni(1);

2185

rou=R_ni'/R_ni(1);

2187

if DER_DFE <= param.DER_CDR

2186

if DER_DFE <= param.DER_CDR

2188

while j <= floor(num_ui/2) && DER_MLSE_j> DER_MLSE*smallest_relative_change

2187

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)

2188

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);

2189

u_j(2:2:end-1)=-u_j(2:2:end-1);

2191

% V_j=toeplitz(R_ni(1:j+1).'/R_ni(1));

2190

% V_j=toeplitz(R_ni(1:j+1).'/R_ni(1));

2192

V_j=toeplitz(rou(1:j+1));

2191

V_j=toeplitz(rou(1:j+1));

2193

P_j=cumsum(p_j.y);

2192

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)

2193

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)

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)

2194

% 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;

2195

DER_MLSE=DER_MLSE+DER_MLSE_j;

2197

p_j=conv_fct(p_j,p_scaled_by_1mb);

2196

p_j=conv_fct(p_j,p_scaled_by_1mb);

2198

%% %% shakiba_3dj_01_2407(to add MLSE sequence truncation penalty)

2197

%% %% shakiba_3dj_01_2407(to add MLSE sequence truncation penalty)

2199

if j == param.trunc

2198

if j == param.trunc

2200

u_trunc = u_j(1:j);

2199

u_trunc = u_j(1:j);

2201

V_trunc = V_j(1:j, 1:j);

2200

V_trunc = V_j(1:j, 1:j);

2202

P_trunc = cumsum(p_trunc.y);

2201

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);

2202

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

2203

elseif j < param.trunc

2205

DER_MLSE_trunc = DER_MLSE;

2204

DER_MLSE_trunc = DER_MLSE;

2206

p_trunc = conv_fct(p_trunc, p_scaled_by_1mb); % Convolves trunc-1 times

2205

p_trunc = conv_fct(p_trunc, p_scaled_by_1mb); % Convolves trunc-1 times

2207

P_trunc = cumsum(p_trunc.y);

2206

P_trunc = cumsum(p_trunc.y);

2208

end

2207

end

2209

j=j+1;

2208

j=j+1;

2210

end

2209

end

2211

%% healey_3dj_01a_2407

2210

%% healey_3dj_01a_2407

2212

if param.Q_budget_adj == 0

2211

if param.Q_budget_adj == 0

2213

Q_budget_adj=0;

2212

Q_budget_adj=0;

2214

else

2213

else

2215

Q_budget_adj=param.Q_budget_adj(1) -param.Q_budget_adj(2)*COM_from_matlab;

2214

Q_budget_adj=param.Q_budget_adj(1) -param.Q_budget_adj(2)*COM_from_matlab;

2216

end

2215

end

2217

%% shakiba_3dj_01_2407

2216

%% 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

2217

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE ,p_an,P_an ) )- 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

2218

delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE_trunc,p_an,P_an ) )- Q_budget_adj ;% shakiba_3dj_01_2405

2220

DER_MLSE_trunc= CDF_ev(A_s*10^(delta_com/20),PDF,CDF);% 4p7 re-evaluates with truncation (delta_com includes truncation)

2221

delta_com_notrunc= 20*log10(1/A_s *-CDF_inv_ev(DER_MLSE,p_an,P_an) ) - Q_budget_adj; % 4p7 calculates COM without truncation

2222

DER_MLSE=CDF_ev(A_s*10^(delta_com_notrunc/20),PDF,CDF);% 4p7 re-evaluated DER without truncation

2223

%% shakiba_3dj_01_2407

2219

%% shakiba_3dj_01_2407

2224

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( 2/3*DER_MLSE,p_an,CDF ) )- Q ;% (178A–36)

2220

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( 2/3*DER_MLSE,p_an,CDF ) )- Q ;% (178A–36)

2225

new_com=COM_from_matlab+delta_com;

2221

new_com=COM_from_matlab+delta_com;

2226

if(delta_com<0)

2222

if(delta_com<0)

2227

delta_com=0;

2223

delta_com=0;

2228

warning('MLSE truncation failed. Try increasing trunc')

2224

warning('MLSE truncation failed. Try increasing trunc')

2229

try

2225

try

2230

hx=msgbox('MLSE truncation failed. Try increasing N_tc','warning','warn');

2226

hx=msgbox('MLSE truncation failed. Try increasing N_tc','warning','warn');

2231

set(hx,'Color',[1 0 1]);

2227

set(hx,'Color',[1 0 1]);

2232

movegui(hx,[randn randn]*100)

2228

movegui(hx,[randn randn]*100)

2233

set(hx,'Tag','COM') %

2229

set(hx,'Tag','COM') %

2234

catch

2230

catch

2235

end

2231

end

2236

end

2232

end

2237

else

2233

else

2238

warning('MLSE not applied because the DER is less than that required for the CDR to lock')

2234

warning('MLSE not applied because the DER is less than that required for the CDR to lock')

2239

DER_MLSE=NaN;

2235

DER_MLSE=NaN;

2240

new_com=COM_from_matlab;

2236

new_com=COM_from_matlab;

2241

delta_com=0;

2237

delta_com=0;

2242

Q=0;

2238

Q=0;

2243

Q_budget_adj=0;

2239

Q_budget_adj=0;

2244

DER_MLSE_trunc=NaN;

2240

DER_MLSE_trunc=NaN;

2245

%% shakiba_3dj_01_2407

2241

%% shakiba_3dj_01_2407

2246

end

2242

end

2247

2243

2248

%%

2244

%%

2249

[PDF1, CDF1, ~] = scaleCDF( PDF,-delta_com,DER0, A_s ); % create new pdf/cdf estimate for display only

2245

[PDF1, CDF1, ~] = scaleCDF( PDF,-delta_com,DER0, A_s ); % create new pdf/cdf estimate for display only

2250

MLSE_results.CDF=CDF1;

2246

MLSE_results.CDF=CDF1;

2251

MLSE_results.PDF=PDF1;

2247

MLSE_results.PDF=PDF1;

2252

MLSE_results.DER_MLSE_trunc = DER_MLSE_trunc;% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2248

MLSE_results.DER_MLSE_trunc = DER_MLSE_trunc;% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2253

MLSE_results.Q_budget_adj=Q_budget_adj; % healey_3dj_01a_2407

2249

MLSE_results.Q_budget_adj=Q_budget_adj; % healey_3dj_01a_2407

2254

MLSE_results.COM_from_matlab=COM_from_matlab;

2250

MLSE_results.COM_from_matlab=COM_from_matlab;

2255

MLSE_results.DER_MLSE=DER_MLSE;

2251

MLSE_results.DER_MLSE=DER_MLSE;

2256

MLSE_results.DER_DFE=DER_DFE;

2252

MLSE_results.DER_DFE=DER_DFE;

2257

MLSE_results.COM=new_com;

2253

MLSE_results.COM=new_com;

2258

MLSE_results.delta_com=delta_com;

2254

MLSE_results.delta_com=delta_com;

2259

MLSE_results.g_an=g_an;

2255

MLSE_results.g_an=g_an;

2260

2256

2261

2257

2262

2258

2263

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2259

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2264

if 1

2260

if 1

2265

num_ui=param.num_ui_RXFF_noise;

2261

num_ui=param.num_ui_RXFF_noise;

2266

M=param.samples_per_ui;

2262

M=param.samples_per_ui;

2267

L=param.levels;

2263

L=param.levels;

2268

sigma_X2=(L^2-1)/(3*(L-1)^2);

2264

sigma_X2=(L^2-1)/(3*(L-1)^2);

2269

fb=param.fb;

2265

fb=param.fb;

2270

R_LM=param.R_LM;

2266

R_LM=param.R_LM;

2271

end

2267

end

2272

% h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2268

% h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2273

% h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2269

% h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2274

% h=reshape(h,1,[]); % make row vectors

2270

% h=reshape(h,1,[]); % make row vectors

2275

% h=[ h(1:floor(length(h)/M)*M) ];

2271

% h=[ h(1:floor(length(h)/M)*M) ];

2276

% h= [h zeros(1,num_ui*M-length(h)) ];

2272

% h= [h zeros(1,num_ui*M-length(h)) ];

2277

% h=h(1:M:end);% resample

2273

% h=h(1:M:end);% resample

2278

% N=length(h);

2274

% N=length(h);

2279

% dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2275

% dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2280

% dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2276

% dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2281

2277

2282

samp_idx = (mod(cursor_i-1,M )+1):M:length(sbr);

2278

samp_idx = (mod(cursor_i-1,M )+1):M:length(sbr);

2283

dh= find(samp_idx == cursor_i)-1;

2279

dh= find(samp_idx == cursor_i)-1;

2284

dw=param.RxFFE_cmx;

2280

dw=param.RxFFE_cmx;

2285

h = reshape(sbr(samp_idx),1,[]); % make row vector

2281

h = reshape(sbr(samp_idx),1,[]); % make row vector

2286

h(end+1:num_ui)=0;

2282

h(end+1:num_ui)=0;

2287

h = h(1:num_ui); % h needs to have num_ui points

2283

h = h(1:num_ui); % h needs to have num_ui points

2288

N=length(h); % used in subsequent expressions

2284

N=length(h); % used in subsequent expressions

2289

2285

2290

if param.N_bg == 0

2286

if param.N_bg == 0

2291

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2287

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2292

bmax=param.bmax;

2288

bmax=param.bmax;

2293

bmin=param.bmin ;

2289

bmin=param.bmin ;

2294

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 ];

2290

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 ];

2295

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 ];

2291

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 ];

2296

idx=[];

2292

idx=[];

2297

else

2293

else

2298

Nfloating_taps=param.N_bf*param.N_bg;

2294

Nfloating_taps=param.N_bf*param.N_bg;

2299

Nmax=param.N_bmax;

2295

Nmax=param.N_bmax;

2300

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2296

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2301

Ng=param.N_bg;

2297

Ng=param.N_bg;

2302

Nf=param.N_bf;

2298

Nf=param.N_bf;

2303

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2299

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2304

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2300

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2305

% hisi=h(dh+2:((dh-dw)+Nw));

2301

% hisi=h(dh+2:((dh-dw)+Nw));

2306

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2302

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2307

% idx=sort(idx);

2303

% idx=sort(idx);

2308

bmax=param.bmax;

2304

bmax=param.bmax;

2309

bmin=param.bmin ;

2305

bmin=param.bmin ;

2310

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 ];

2306

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 ];

2311

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 ];

2307

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 ];

2312

end

2308

end

2313

Nb=param.ndfe; % DFE taps

2309

Nb=param.ndfe; % DFE taps

2314

d=dw+dh; % used for index in algorithms

2310

d=dw+dh; % used for index in algorithms

2315

indx(1:N)=(1:N)-dh-1;

2311

indx(1:N)=(1:N)-dh-1;

2316

S_n=PSD_results.S_n; % total agregate noise PSD

2312

S_n=PSD_results.S_n; % total agregate noise PSD

2317

Rn=ifft(S_n)*fb;

2313

Rn=ifft(S_n)*fb;

2318

%% HH and R

2314

%% HH and R

2319

2315

2320

%Test routine finding rxffe floating taps using best FOM for each bank

2316

%Test routine finding rxffe floating taps using best FOM for each bank

2321

isi_start = dh+2;

2317

isi_start = dh+2;

2322

isi_end = (dh-dw)+Nw;

2318

isi_end = (dh-dw)+Nw;

2323

2319

2324

%check for num_ui too small

2320

%check for num_ui too small

2325

if isi_end > length(h)

2321

if isi_end > length(h)

2326

error('num_ui_RXFF_noise (%d) is too small',num_ui);

2322

error('num_ui_RXFF_noise (%d) is too small',num_ui);

2327

end

2323

end

2328

2324

2329

hc1=[ h zeros(1,Nw-1) ];

2325

hc1=[ h zeros(1,Nw-1) ];

2330

hr1=[ h(1) zeros(1,Nw-1)];

2326

hr1=[ h(1) zeros(1,Nw-1)];

2331

H=toeplitz(hc1,hr1);

2327

H=toeplitz(hc1,hr1);

2332

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2328

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2333

if param.N_bg ~= 0

2329

if param.N_bg ~= 0

2334

switch lower(OP.RXFFE_FLOAT_CTL)

2330

switch lower(OP.RXFFE_FLOAT_CTL)

2335

case 'isi'

2331

case 'isi'

2336

hisi=h(dh+2:((dh-dw)+Nw));

2332

hisi=h(dh+2:((dh-dw)+Nw));

2337

[idx]=findbankloc( hisi ,param.RxFFE_cpx+1,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2333

[idx]=findbankloc( hisi ,param.RxFFE_cpx+1,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2338

idx=sort(idx);

2334

idx=sort(idx);

2339

otherwise

2335

otherwise

2340

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2336

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2341

idx=sort(idx);

2337

idx=sort(idx);

2342

end

2338

end

2343

end

2339

end

2344

[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

2340

[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

2345

MMSE_results.sigma_e=sigma_e; %

2341

MMSE_results.sigma_e=sigma_e; %

2346

MMSE_results.FOM=FOM;

2342

MMSE_results.FOM=FOM;

2347

Craw=w/w(dw+1); % returned Rx FFE taps

2343

Craw=w/w(dw+1); % returned Rx FFE taps

2348

% re-align Cmod to floating tap locations

2344

% re-align Cmod to floating tap locations

2349

if param.N_bg ~= 0

2345

if param.N_bg ~= 0

2350

C=Craw;

2346

C=Craw;

2351

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2347

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2352

C(idx+param.RxFFE_cmx+1 )=Craw(Nfix+(1:Nfloating_taps));

2348

C(idx+param.RxFFE_cmx+1 )=Craw(Nfix+(1:Nfloating_taps));

2353

else

2349

else

2354

C=Craw;

2350

C=Craw;

2355

end

2351

end

2356

MMSE_results.floating_tap_locations=idx + param.RxFFE_cmx+1;

2352

MMSE_results.floating_tap_locations=idx + param.RxFFE_cmx+1;

2357

MMSE_results.C=C;

2353

MMSE_results.C=C;

2358

MMSE_results.blim=blim; % added blim passed out for MLSD for 178A-39

2354

MMSE_results.blim=blim; % added blim passed out for MLSD for 178A-39

2359

MMSE_results.Nw=Nw;

2355

MMSE_results.Nw=Nw;

2360

2356

2361

2357

2362

2358

2363

2359

2364

2360

2365

function [sigma_e,FOM,w,idx,Nw,blim] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2361

function [sigma_e,FOM,w,idx,Nw,blim] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2366

% added blim passed out for MLSD

2362

% added blim passed out for MLSD

2367

if isempty(idx)

2363

if isempty(idx)

2368

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2364

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2369

bmax=param.bmax;

2365

bmax=param.bmax;

2370

bmin=param.bmin ;

2366

bmin=param.bmin ;

2371

else

2367

else

2372

Nfloating_taps=param.N_bf*param.N_bg;

2368

Nfloating_taps=param.N_bf*param.N_bg;

2373

%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

2369

%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

2374

Nfloating_taps = length(idx);

2370

Nfloating_taps = length(idx);

2375

Nmax=param.N_bmax;

2371

Nmax=param.N_bmax;

2376

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2372

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2377

Ng=param.N_bg;

2373

Ng=param.N_bg;

2378

Nf=param.N_bf;

2374

Nf=param.N_bf;

2379

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2375

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2380

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2376

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2381

end

2377

end

2382

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2378

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2383

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2379

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2384

% hc1=[ h zeros(1,Nw-1) ];

2380

% hc1=[ h zeros(1,Nw-1) ];

2385

% hr1=[ h(1) zeros(1,Nw-1)];

2381

% hr1=[ h(1) zeros(1,Nw-1)];

2386

% H=toeplitz(hc1,hr1);

2382

% H=toeplitz(hc1,hr1);

2387

2383

2388

if param.N_bg ~= 0

2384

if param.N_bg ~= 0

2389

H=H( :,[1:Nfix idx+param.RxFFE_cmx+1 ]);

2385

H=H( :,[1:Nfix idx+param.RxFFE_cmx+1 ]);

2390

end

2386

end

2391

%% HH and R

2387

%% HH and R

2392

HH= H'*H;

2388

HH= H'*H;

2393

if param.N_bg ~= 0

2389

if param.N_bg ~= 0

2394

Rnn=Rnn( [1:Nfix idx+param.RxFFE_cmx+1],[1:Nfix idx+param.RxFFE_cmx+1]);

2390

Rnn=Rnn( [1:Nfix idx+param.RxFFE_cmx+1],[1:Nfix idx+param.RxFFE_cmx+1]);

2395

end

2391

end

2396

R=HH+Rnn/sigma_X2;

2392

R=HH+Rnn/sigma_X2;

2397

%% hb and h0

2393

%% hb and h0

2398

Hb= H(d+2:d+Nb+1,:);

2394

Hb= H(d+2:d+Nb+1,:);

2399

h0=H(d+1,:);

2395

h0=H(d+1,:);

2400

% display(floor(h0));

2396

% display(floor(h0));

2401

2397

2402

%% Ib and zb (slide 10)

2398

%% Ib and zb (slide 10)

2403

ib=eye(Nb);

2399

ib=eye(Nb);

2404

zb=zeros(1,Nb);

2400

zb=zeros(1,Nb);

2405

wbl= [ R -Hb' -h0';...

2401

wbl= [ R -Hb' -h0';...

2406

-Hb ib zb'; ...

2402

-Hb ib zb'; ...

2407

h0 zb 0]\[h0'; zb' ;1];

2403

h0 zb 0]\[h0'; zb' ;1];

2408

2404

2409

%% re-adjust Nw to number of used taps

2405

%% re-adjust Nw to number of used taps

2410

if param.N_bg ~= 0

2406

if param.N_bg ~= 0

2411

Nw=Nwft;

2407

Nw=Nwft;

2412

end

2408

end

2413

%% check equalized pulse

2409

%% check equalized pulse

2414

w=wbl(1:Nw);

2410

w=wbl(1:Nw);

2415

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2411

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2416

2412

2417

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2413

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2418

blim = min(bmax(:), max(bmin(:), b));

2414

blim = min(bmax(:), max(bmin(:), b));

2419

if (Nb > 0) && ~isequal(b, blim)

2415

if (Nb > 0) && ~isequal(b, blim)

2420

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2416

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2421

w = wl(1:Nw);

2417

w = wl(1:Nw);

2422

end

2418

end

2423

2419

2424

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2420

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2425

%so need to chop off the extra indices on wmax and wmin

2421

%so need to chop off the extra indices on wmax and wmin

2426

if length(w)<length(wmax)

2422

if length(w)<length(wmax)

2427

wmax=wmax(1:length(w));

2423

wmax=wmax(1:length(w));

2428

wmin=wmin(1:length(w));

2424

wmin=wmin(1:length(w));

2429

end

2425

end

2430

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2426

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2431

if ~isequal(w, wlim)

2427

if ~isequal(w, wlim)

2432

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2428

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2433

if Nb > 0

2429

if Nb > 0

2434

b = Hb*wlim; % Update the feedback coefficients.

2430

b = Hb*wlim; % Update the feedback coefficients.

2435

blim = min(bmax(:), max(bmin(:), b));

2431

blim = min(bmax(:), max(bmin(:), b));

2436

end

2432

end

2437

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2433

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2438

% wl = wl(1:Nw);

2434

% wl = wl(1:Nw);

2439

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2435

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2440

end

2436

end

2441

% w=w(1:Nw) ;

2437

% w=w(1:Nw) ;

2442

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2438

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2443

w=wlim;

2439

w=wlim;

2444

b=blim;

2440

b=blim;

2445

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

2441

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

2446

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2442

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2447

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2443

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2448

2444

2449

%not all output_args are filled here but most are

2445

%not all output_args are filled here but most are

2450

2446

2451

switch lower(OP.TDECQ)

2447

switch lower(OP.TDECQ)

2452

case { false 'none' } % should be the default

2448

case { false 'none' } % should be the default

2453

output_args.VMA=[];

2449

output_args.VMA=[];

2454

case 'vma'

2450

case 'vma'

2455

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2451

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2456

output_args.VMA=est_vma.VMA;

2452

output_args.VMA=est_vma.VMA;

2457

otherwise

2453

otherwise

2458

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2454

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2459

end

2455

end

2460

2456

2461

fileset_str=str2csv({chdata.base});

2457

fileset_str=str2csv({chdata.base});

2462

output_args.file_names=sprintf('"%s"', fileset_str);

2458

output_args.file_names=sprintf('"%s"', fileset_str);

2463

% [ahealey] Echo the termination parameters in the output arguments..

2459

% [ahealey] Echo the termination parameters in the output arguments..

2464

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2460

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2465

output_args.(odt_param{:}) = param.(odt_param{:});

2461

output_args.(odt_param{:}) = param.(odt_param{:});

2466

end

2462

end

2467

% [ahealey] End of modifications.

2463

% [ahealey] End of modifications.

2468

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2464

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2469

output_args.(pkg_params{:})= param.(pkg_params{:});

2465

output_args.(pkg_params{:})= param.(pkg_params{:});

2470

end

2466

end

2471

output_args.baud_rate_GHz=param.fb/1e9;

2467

output_args.baud_rate_GHz=param.fb/1e9;

2472

output_args.f_Nyquist_GHz = param.fb/2e9;

2468

output_args.f_Nyquist_GHz = param.fb/2e9;

2473

output_args.BER=param.specBER;

2469

output_args.BER=param.specBER;

2474

output_args.FOM = fom_result.FOM;

2470

output_args.FOM = fom_result.FOM;

2475

output_args.sigma_N=Noise_Struct.sigma_N;

2471

output_args.sigma_N=Noise_Struct.sigma_N;

2476

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2472

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2477

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2473

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2478

output_args.tail_RSS=fom_result.tail_RSS;

2474

output_args.tail_RSS=fom_result.tail_RSS;

2479

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2475

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2480

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2476

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2481

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2477

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2482

try

2478

try

2483

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2479

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2484

catch

2480

catch

2485

output_args.uneq_FIR_peak_time=[];

2481

output_args.uneq_FIR_peak_time=[];

2486

end

2482

end

2487

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2483

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2488

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2484

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2489

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2485

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2490

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2486

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2491

2487

2492

if OP.RX_CALIBRATION== 1

2488

if OP.RX_CALIBRATION== 1

2493

output_args.sigma_bn=sigma_bn;

2489

output_args.sigma_bn=sigma_bn;

2494

else

2490

else

2495

output_args.sigma_bn=[];

2491

output_args.sigma_bn=[];

2496

end

2492

end

2497

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2493

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2498

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2494

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2499

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2495

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2500

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2496

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2501

2497

2502

if OP.RX_CALIBRATION == 0

2498

if OP.RX_CALIBRATION == 0

2503

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2499

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2504

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2500

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2505

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2501

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2506

else

2502

else

2507

output_args.peak_MDXTK_interference_at_BER_mV=[];

2503

output_args.peak_MDXTK_interference_at_BER_mV=[];

2508

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2504

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2509

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2505

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2510

end

2506

end

2511

%output_args.ICN_mV=ICN*1000;

2507

%output_args.ICN_mV=ICN*1000;

2512

% output_args.ICN_test_mV=ICN_test*1000;

2508

% output_args.ICN_test_mV=ICN_test*1000;

2513

xtk=param.num_next+param.num_fext;

2509

xtk=param.num_next+param.num_fext;

2514

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2510

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2515

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2511

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2516

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2512

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2517

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2513

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2518

else

2514

else

2519

output_args.MDNEXT_ICN_92_46_mV=0;

2515

output_args.MDNEXT_ICN_92_46_mV=0;

2520

output_args.MDFEXT_ICN_92_47_mV=0;

2516

output_args.MDFEXT_ICN_92_47_mV=0;

2521

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2517

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2522

end

2518

end

2523

%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

2519

%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

2524

if 1

2520

if 1

2525

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)));

2521

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)));

2526

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2522

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2527

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2523

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2528

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2524

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2529

end

2525

end

2530

2526

2531

2527

2532

switch param.CTLE_type

2528

switch param.CTLE_type

2533

case 'CL93'

2529

case 'CL93'

2534

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2530

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2535

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2531

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2536

output_args.g_DC_HP=[];

2532

output_args.g_DC_HP=[];

2537

output_args.HP_poles_zero=[];

2533

output_args.HP_poles_zero=[];

2538

case 'CL120d'

2534

case 'CL120d'

2539

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2535

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2540

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2536

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2541

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2537

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2542

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2538

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2543

case 'CL120e'

2539

case 'CL120e'

2544

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)];

2540

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)];

2545

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2541

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2546

output_args.g_DC_HP=[];

2542

output_args.g_DC_HP=[];

2547

output_args.HP_poles_zero=[];

2543

output_args.HP_poles_zero=[];

2548

end

2544

end

2549

output_args.TXLE_taps=fom_result.txffe;

2545

output_args.TXLE_taps=fom_result.txffe;

2550

if length(output_args.TXLE_taps) >= 3

2546

if length(output_args.TXLE_taps) >= 3

2551

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2547

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2552

else

2548

else

2553

output_args.Pre2Pmax=[];

2549

output_args.Pre2Pmax=[];

2554

end

2550

end

2555

output_args.DFE_taps=fom_result.DFE_taps;

2551

output_args.DFE_taps=fom_result.DFE_taps;

2556

if param.Floating_DFE || param.Floating_RXFFE

2552

if param.Floating_DFE || param.Floating_RXFFE

2557

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2553

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2558

else

2554

else

2559

output_args.floating_tap_locations=[];

2555

output_args.floating_tap_locations=[];

2560

end

2556

end

2561

2557

2562

if OP.RxFFE

2558

if OP.RxFFE

2563

output_args.RxFFE=fom_result.RxFFE;

2559

output_args.RxFFE=fom_result.RxFFE;

2564

output_args.RxFFEgain=param.current_ffegain;

2560

output_args.RxFFEgain=param.current_ffegain;

2565

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2561

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2566

output_args.RxFFE=[];

2562

output_args.RxFFE=[];

2567

output_args.RxFFEgain=[];

2563

output_args.RxFFEgain=[];

2568

end

2564

end

2569

2565

2570

output_args.itick=fom_result.itick;

2566

output_args.itick=fom_result.itick;

2571

2567

2572

% Calculation of error propagation and burst probability

2568

% Calculation of error propagation and burst probability

2573

if OP.nburst>0

2569

if OP.nburst>0

2574

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2570

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2575

output_args.error_propagation_probability = p_error_propagation;

2571

output_args.error_propagation_probability = p_error_propagation;

2576

output_args.burst_probabilities = p_burst;

2572

output_args.burst_probabilities = p_burst;

2577

else

2573

else

2578

output_args.error_propagation_probability = [];

2574

output_args.error_propagation_probability = [];

2579

output_args.burst_probabilities = [];

2575

output_args.burst_probabilities = [];

2580

end

2576

end

2581

2577

2582

2578

2583

%begin yasuo patch 12/11/2018

2579

%begin yasuo patch 12/11/2018

2584

% collect sigma values to report

2580

% collect sigma values to report

2585

% pdf2sgm() is a function to calculate sigma value from PDF

2581

% pdf2sgm() is a function to calculate sigma value from PDF

2586

% It is added at the end of this file code.

2582

% It is added at the end of this file code.

2587

% I am not sure if an equivalent function already exists.

2583

% I am not sure if an equivalent function already exists.

2588

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2584

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2589

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2585

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2590

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2586

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2591

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2587

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2592

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2588

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2593

output_args.sgm_G = Noise_Struct.sigma_G;

2589

output_args.sgm_G = Noise_Struct.sigma_G;

2594

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2590

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2595

output_args.sgm_N = Noise_Struct.sigma_N;

2591

output_args.sgm_N = Noise_Struct.sigma_N;

2596

output_args.sgm_TX = Noise_Struct.sigma_TX;

2592

output_args.sgm_TX = Noise_Struct.sigma_TX;

2597

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2593

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2598

if OP.RX_CALIBRATION == 0

2594

if OP.RX_CALIBRATION == 0

2599

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2595

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2600

else

2596

else

2601

output_args.sgm_xt=[];

2597

output_args.sgm_xt=[];

2602

end

2598

end

2603

% end yasuo patch

2599

% end yasuo patch

2604

2600

2605

% r259 putting COM, VEO and loss last in report

2601

% r259 putting COM, VEO and loss last in report

2606

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2602

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2607

if param.N_qb ~= 0

2608

output_args.sgm_Q =Noise_Struct.sigma_Q;

2609

output_args.sigma_before_clip = Noise_Struct.sigma_before_clip;

2610

output_args.peak_clip = Noise_Struct.peak_clip;

2611

output_args.P2ptopsigma_clip = Noise_Struct.p2ptosigma_clip;

2612

end

2613

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2603

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2614

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2604

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2615

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2605

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2616

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2606

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2617

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2607

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2618

output_args.VEO_window_mUI= param.T_O;

2608

output_args.VEO_window_mUI= param.T_O;

2619

else

2609

else

2620

output_args.EW_UI_est=[];

2610

output_args.EW_UI_est=[];

2621

output_args.eye_contour=[];

2611

output_args.eye_contour=[];

2622

output_args.VEO_window_mUI= [];

2612

output_args.VEO_window_mUI= [];

2623

end

2613

end

2624

2614

2625

if sum(param.AC_CM_RMS) ~= 0

2615

if sum(param.AC_CM_RMS) ~= 0

2626

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2616

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2627

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2617

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2628

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2618

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2629

else

2619

else

2630

output_args.sigma_ACCM_at_tp0_mV=[];

2620

output_args.sigma_ACCM_at_tp0_mV=[];

2631

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2621

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2632

end

2622

end

2633

if OP.MLSE

2623

if OP.MLSE

2634

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2624

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2635

output_args.delta_COM = COM_SNR_Struct.delta_COM;

2625

output_args.delta_COM = COM_SNR_Struct.delta_COM;

2636

output_args.DER_DFE= COM_SNR_Struct.DER_DFE;

2626

output_args.DER_DFE= COM_SNR_Struct.DER_DFE;

2637

output_args.DER_MLSE= COM_SNR_Struct.DER_MLSE;

2627

output_args.DER_MLSE= COM_SNR_Struct.DER_MLSE;

2638

if strcmpi(upper(OP.PHY),'C2M')

2628

if strcmpi(upper(OP.PHY),'C2M')

2639

output_args.VEC_dB_orig= COM_SNR_Struct.VEC_dB_orig;

2629

output_args.VEC_dB_orig= COM_SNR_Struct.VEC_dB_orig;

2640

output_args.delta_VEC = COM_SNR_Struct.delta_VEC;

2630

output_args.delta_VEC = COM_SNR_Struct.delta_VEC;

2641

output_args.VEC_dB_orig = COM_SNR_Struct.VEC_dB_orig;

2631

output_args.VEC_dB_orig = COM_SNR_Struct.VEC_dB_orig;

2642

output_args.VEC_dB= COM_SNR_Struct.VEC_dB;

2632

output_args.VEC_dB= COM_SNR_Struct.VEC_dB;

2643

end

2633

end

2644

end

2634

end

2645

%

2635

%

2646

output_args.COM_dB=COM_SNR_Struct.COM;

2636

output_args.COM_dB=COM_SNR_Struct.COM;

2647

% end yasuo patch

2637

% end yasuo patch

2648

% begin yasuo patch 3/18/2019

2638

% begin yasuo patch 3/18/2019

2649

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2639

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2650

% end yasuo patch

2640

% end yasuo patch

2651

function [ seq syms syms_nrz ] = PRBS13Q( )

2641

function [ seq syms syms_nrz ] = PRBS13Q( )

2652

%UNTITLED Summary of this function goes here

2642

%UNTITLED Summary of this function goes here

2653

% Detailed explanation goes here

2643

% Detailed explanation goes here

2654

2644

2655

2645

2656

taps = ([13 12 2 1]);

2646

taps = ([13 12 2 1]);

2657

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2647

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2658

[seq_nrz c] =LFSR(seed,taps);

2648

[seq_nrz c] =LFSR(seed,taps);

2659

seq_nrz=2*(seq_nrz-0.5);

2649

seq_nrz=2*(seq_nrz-0.5);

2660

seq=pam(seq_nrz);

2650

seq=pam(seq_nrz);

2661

% syms=round(2*(seq+1));

2651

% syms=round(2*(seq+1));

2662

syms((round(2*(seq+1))/2==2))=3;

2652

syms((round(2*(seq+1))/2==2))=3;

2663

syms((round(2*(seq+1))/2==1.5))=2;

2653

syms((round(2*(seq+1))/2==1.5))=2;

2664

syms((round(2*(seq+1))/2==.5))=1;

2654

syms((round(2*(seq+1))/2==.5))=1;

2665

syms((round(2*(seq+1))/2==0))=0;

2655

syms((round(2*(seq+1))/2==0))=0;

2666

2656

2667

% syms_nrz=((seq_nrz+1)/2);

2657

% syms_nrz=((seq_nrz+1)/2);

2668

2658

2669

syms_nrz=seq_nrz;

2659

syms_nrz=seq_nrz;

2670

2660

2671

2661

2672

function[seq c]=LFSR(s,t)

2662

function[seq c]=LFSR(s,t)

2673

%s=initial state of LFSR, you can choose any lenght of LFSR

2663

%s=initial state of LFSR, you can choose any lenght of LFSR

2674

%Instruction:==========

2664

%Instruction:==========

2675

%Save LFSR.m in your current directory and type following

2665

%Save LFSR.m in your current directory and type following

2676

%on Command window for simulating 5 bit LFSR with tap [5 2]

2666

%on Command window for simulating 5 bit LFSR with tap [5 2]

2677

%---------------------

2667

%---------------------

2678

%>>s=[1 1 0 0 1]

2668

%>>s=[1 1 0 0 1]

2679

%>>t=[5 2]

2669

%>>t=[5 2]

2680

%>>[seq c] =LFSR(s,t)

2670

%>>[seq c] =LFSR(s,t)

2681

%---------------------------

2671

%---------------------------

2682

%seq = generated sequence

2672

%seq = generated sequence

2683

%c will be matrix containing the states of LFSR raw wise

2673

%c will be matrix containing the states of LFSR raw wise

2684

%

2674

%

2685

%-----------------------------------------------------------

2675

%-----------------------------------------------------------

2686

%If any doubt, confusion or feedback please contact me

2676

%If any doubt, confusion or feedback please contact me

2687

% NIKESH BAJAJ

2677

% NIKESH BAJAJ

2688

% bajaj.nikkey@gmail.com (+91-9915522564)

2678

% bajaj.nikkey@gmail.com (+91-9915522564)

2689

% Asst. Professor at Lovely Profesional University

2679

% Asst. Professor at Lovely Profesional University

2690

% Masters from Aligarh Muslim University,INDIA

2680

% Masters from Aligarh Muslim University,INDIA

2691

%--------------------------------------------------

2681

%--------------------------------------------------

2692

n=length(s);

2682

n=length(s);

2693

c(1,:)=s;

2683

c(1,:)=s;

2694

m=length(t);

2684

m=length(t);

2695

for k=1:2^n-2;

2685

for k=1:2^n-2;

2696

b(1)=xor(s(t(1)), s(t(2)));

2686

b(1)=xor(s(t(1)), s(t(2)));

2697

if m>2;

2687

if m>2;

2698

for i=1:m-2;

2688

for i=1:m-2;

2699

b(i+1)=xor(s(t(i+2)), b(i));

2689

b(i+1)=xor(s(t(i+2)), b(i));

2700

end

2690

end

2701

end

2691

end

2702

j=1:n-1;

2692

j=1:n-1;

2703

s(n+1-j)=s(n-j);

2693

s(n+1-j)=s(n-j);

2704

s(1)=b(m-1);

2694

s(1)=b(m-1);

2705

c(k+1,:)=s;

2695

c(k+1,:)=s;

2706

end

2696

end

2707

seq=c(:,n)';

2697

seq=c(:,n)';

2708

2698

2709

function [ dataout ] = pam( data )

2699

function [ dataout ] = pam( data )

2710

% mapping data usng Grey Coding

2700

% mapping data usng Grey Coding

2711

for i=1:2:floor(length(data)/2)*2

2701

for i=1:2:floor(length(data)/2)*2

2712

if data(i:i+1)==[ -1 -1 ]

2702

if data(i:i+1)==[ -1 -1 ]

2713

dataout(ceil(i/2)) = -1;

2703

dataout(ceil(i/2)) = -1;

2714

elseif data(i:i+1)==[ -1 1 ]

2704

elseif data(i:i+1)==[ -1 1 ]

2715

dataout(ceil(i/2)) = -1/3;

2705

dataout(ceil(i/2)) = -1/3;

2716

elseif data(i:i+1)==[ 1 1 ]

2706

elseif data(i:i+1)==[ 1 1 ]

2717

dataout(ceil(i/2)) = 1/3;

2707

dataout(ceil(i/2)) = 1/3;

2718

elseif data(i:i+1)==[ 1 -1 ]

2708

elseif data(i:i+1)==[ 1 -1 ]

2719

dataout(ceil(i/2)) = 1;

2709

dataout(ceil(i/2)) = 1;

2720

end

2710

end

2721

end

2711

end

2722

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2712

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2723

db = @(x) 20*log10(abs(x));

2713

db = @(x) 20*log10(abs(x));

2724

disp('computing TD_RILN...')

2714

disp('computing TD_RILN...')

2725

sdd21=squeeze(sdd21);

2715

sdd21=squeeze(sdd21);

2726

if iscolumn(sdd21)

2716

if iscolumn(sdd21)

2727

sdd21=sdd21.';

2717

sdd21=sdd21.';

2728

end

2718

end

2729

RIL=squeeze(RIL);

2719

RIL=squeeze(RIL);

2730

if iscolumn(RIL)

2720

if iscolumn(RIL)

2731

RIL=RIL.';

2721

RIL=RIL.';

2732

end

2722

end

2733

print_for_codereview=1;

2723

print_for_codereview=1;

2734

if exist('OP','var')

2724

if exist('OP','var')

2735

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2725

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2736

2726

2737

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2727

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2738

H_bw=Butterworth_Filter(param,faxis_f2,1);

2728

H_bw=Butterworth_Filter(param,faxis_f2,1);

2739

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2729

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2740

H_tw=Tukey_Window(faxis_f2,param);

2730

H_tw=Tukey_Window(faxis_f2,param);

2741

H_tw=ones(1,length(faxis_f2) );

2731

H_tw=ones(1,length(faxis_f2) );

2742

[RILN_TD_struct.REF.FIR, ...

2732

[RILN_TD_struct.REF.FIR, ...

2743

RILN_TD_struct.REF.t, ...

2733

RILN_TD_struct.REF.t, ...

2744

RILN_TD_struct.REF.causality_correction_dB, ...

2734

RILN_TD_struct.REF.causality_correction_dB, ...

2745

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2735

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2746

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2736

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2747

[RILN_TD_struct.FIT.FIR, ...

2737

[RILN_TD_struct.FIT.FIR, ...

2748

RILN_TD_struct.FIT.t, ...

2738

RILN_TD_struct.FIT.t, ...

2749

RILN_TD_struct.FIT.causality_correction_dB, ...

2739

RILN_TD_struct.FIT.causality_correction_dB, ...

2750

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2740

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2751

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2741

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2752

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2742

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2753

NrangeUI=1000;

2743

NrangeUI=1000;

2754

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2744

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2755

range=ipeak:range_end;

2745

range=ipeak:range_end;

2756

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2746

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2757

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2747

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2758

RILN_TD_struct.FOM=-inf;

2748

RILN_TD_struct.FOM=-inf;

2759

RILN_TD_struct.FOM_PDF=-inf;

2749

RILN_TD_struct.FOM_PDF=-inf;

2760

rms_fom=-inf;

2750

rms_fom=-inf;

2761

for im=1:param.samples_per_ui

2751

for im=1:param.samples_per_ui

2762

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2752

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2763

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2753

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2764

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2754

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2765

cdf=pdf; cdf.y=cumsum(pdf.y);

2755

cdf=pdf; cdf.y=cumsum(pdf.y);

2766

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2756

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2767

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2757

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2768

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2758

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2769

if print_for_codereview % remove once all checked out

2759

if print_for_codereview % remove once all checked out

2770

h=figure(191);set(gcf,'Tag','COM');

2760

h=figure(191);set(gcf,'Tag','COM');

2771

semilogy(-cdf.x,cdf.y);

2761

semilogy(-cdf.x,cdf.y);

2772

% xlim ([0,-cdf.x(1)])

2762

% xlim ([0,-cdf.x(1)])

2773

ylim([param.specBER 1]);title ('CDF of RILN')

2763

ylim([param.specBER 1]);title ('CDF of RILN')

2774

hold on

2764

hold on

2775

end

2765

end

2776

if rms>rms_fom

2766

if rms>rms_fom

2777

rms_fom=rms;

2767

rms_fom=rms;

2778

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2768

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2779

RILN_TD_struct.PDF=pdf;

2769

RILN_TD_struct.PDF=pdf;

2780

end

2770

end

2781

end

2771

end

2782

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2772

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2783

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2773

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2784

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2774

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2785

if print_for_codereview % remove once all checked out

2775

if print_for_codereview % remove once all checked out

2786

figure(9003);set(gcf,'Tag','COM');

2776

figure(9003);set(gcf,'Tag','COM');

2787

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2777

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2788

hold on

2778

hold on

2789

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2779

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2790

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2780

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2791

hold off

2781

hold off

2792

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)

2782

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)

2793

figure(9004);set(gcf,'Tag','COM');

2783

figure(9004);set(gcf,'Tag','COM');

2794

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2784

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2795

hold on

2785

hold on

2796

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2786

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2797

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2787

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2798

grid on

2788

grid on

2799

legend('show')

2789

legend('show')

2800

end

2790

end

2801

end

2791

end

2802

function is_illegal=RXFFE_Illegal(C,param,last_index)

2792

function is_illegal=RXFFE_Illegal(C,param,last_index)

2803

2793

2804

%check if RXFFE taps are illegal

2794

%check if RXFFE taps are illegal

2805

%C = RXFFE taps

2795

%C = RXFFE taps

2806

%param = COM param struct

2796

%param = COM param struct

2807

%last_index is used when computing illegality prior to Backoff. It will be set so taps

2797

%last_index is used when computing illegality prior to Backoff. It will be set so taps

2808

% in the Backoff region are not considered in the legality check.

2798

% in the Backoff region are not considered in the legality check.

2809

2799

2810

%If last index is omitted, set it to length(C)

2800

%If last index is omitted, set it to length(C)

2811

if nargin<3

2801

if nargin<3

2812

last_index=length(C);

2802

last_index=length(C);

2813

end

2803

end

2814

2804

2815

is_illegal=0;

2805

is_illegal=0;

2816

2806

2817

%Check cursor tap

2807

%Check cursor tap

2818

Ccur_i=param.RxFFE_cmx+1;

2808

Ccur_i=param.RxFFE_cmx+1;

2819

if C(Ccur_i) < param.ffe_main_cursor_min

2809

if C(Ccur_i) < param.ffe_main_cursor_min

2820

is_illegal=1;

2810

is_illegal=1;

2821

return;

2811

return;

2822

end

2812

end

2823

2813

2824

%Check postcursors

2814

%Check postcursors

2825

if param.ffe_post_tap_len ~=0

2815

if param.ffe_post_tap_len ~=0

2826

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

2816

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

2827

is_illegal=1;

2817

is_illegal=1;

2828

return;

2818

return;

2829

end

2819

end

2830

if (param.ffe_post_tap_len > 1)

2820

if (param.ffe_post_tap_len > 1)

2831

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

2821

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

2832

is_illegal=1;

2822

is_illegal=1;

2833

return;

2823

return;

2834

end

2824

end

2835

end

2825

end

2836

end

2826

end

2837

2827

2838

%Check precursors

2828

%Check precursors

2839

if param.ffe_pre_tap_len ~=0

2829

if param.ffe_pre_tap_len ~=0

2840

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

2830

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

2841

is_illegal=1;

2831

is_illegal=1;

2842

return;

2832

return;

2843

end

2833

end

2844

if (param.ffe_pre_tap_len > 1)

2834

if (param.ffe_pre_tap_len > 1)

2845

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

2835

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

2846

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

2836

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

2847

is_illegal=1;

2837

is_illegal=1;

2848

return;

2838

return;

2849

end % 11.22.2018 Yasou Hadaka

2839

end % 11.22.2018 Yasou Hadaka

2850

end

2840

end

2851

end

2841

end

2852

function S =R_series2(zref,f,R)

2842

function S =R_series2(zref,f,R)

2853

r=ones(1,length(f))*R;

2843

r=ones(1,length(f))*R;

2854

S.Parameters(1,1,:) = r./(r + 2*zref);

2844

S.Parameters(1,1,:) = r./(r + 2*zref);

2855

S.Parameters(2,2,:) = r./(r + 2*zref);

2845

S.Parameters(2,2,:) = r./(r + 2*zref);

2856

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

2846

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

2857

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

2847

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

2858

% Sm=sparameters(S.Parameters,f,zref);

2848

% Sm=sparameters(S.Parameters,f,zref);

2859

2849

2860

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

2850

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

2861

2851

2862

if use_RC

2852

if use_RC

2863

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

2853

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

2864

else

2854

else

2865

H_tw=ones(1,length(f));

2855

H_tw=ones(1,length(f));

2866

end

2856

end

2867

function SLD=SL(S,f,R)

2857

function SLD=SL(S,f,R)

2868

% source load impact return loss add to S21

2858

% source load impact return loss add to S21

2869

% S and SLD are the same structure

2859

% S and SLD are the same structure

2870

% S.Parameters

2860

% S.Parameters

2871

% S.Impedance

2861

% S.Impedance

2872

% S.NumPorts

2862

% S.NumPorts

2873

% S.Frequencies

2863

% S.Frequencies

2874

SLD=S; % assign the fields

2864

SLD=S; % assign the fields

2875

zref=100;

2865

zref=100;

2876

if R==0

2866

if R==0

2877

warndlg('Termination should not be set to zero');

2867

warndlg('Termination should not be set to zero');

2878

SLD=S;

2868

SLD=S;

2879

return

2869

return

2880

end

2870

end

2881

2871

2882

if R > zref

2872

if R > zref

2883

spr =R_series2(zref,f,(R-zref)); % make series sparameter

2873

spr =R_series2(zref,f,(R-zref)); % make series sparameter

2884

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

2874

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

2885

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2875

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2886

combines4p( ...

2876

combines4p( ...

2887

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2877

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2888

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2878

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2889

);

2879

);

2890

elseif R < zref

2880

elseif R < zref

2891

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

2881

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

2892

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

2882

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

2893

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2883

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2894

combines4p( ...

2884

combines4p( ...

2895

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2885

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2896

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2886

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2897

);

2887

);

2898

else

2888

else

2899

SLD=S;

2889

SLD=S;

2900

end

2890

end

2901

2891

2902

%%

2892

%%

2903

2893

2904

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

2894

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

2905

p1=param.CTLE_fp1(1);

2895

p1=param.CTLE_fp1(1);

2906

z1=param.CTLE_fz(1);

2896

z1=param.CTLE_fz(1);

2907

p2=param.CTLE_fp2(1);

2897

p2=param.CTLE_fp2(1);

2908

zlf=param.f_HP(1);

2898

zlf=param.f_HP(1);

2909

plf=param.f_HP(1);

2899

plf=param.f_HP(1);

2910

f_b=param.fb;

2900

f_b=param.fb;

2911

f_r=param.f_r;

2901

f_r=param.f_r;

2912

eta_0=param.eta_0;

2902

eta_0=param.eta_0;

2913

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));

2903

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));

2914

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

2904

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

2915

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

2905

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

2916

if 0

2906

if 0

2917

figure

2907

figure

2918

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

2908

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

2919

% see if it looks correct

2909

% see if it looks correct

2920

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

2910

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

2921

ylabel('dB');

2911

ylabel('dB');

2922

xlabel('GHz');

2912

xlabel('GHz');

2923

title( 'H_ctf with H_r')

2913

title( 'H_ctf with H_r')

2924

grid on

2914

grid on

2925

ylim([-30 0])

2915

ylim([-30 0])

2926

end

2916

end

2927

2917

2928

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

2918

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

2929

2919

2930

%Fill TDR data

2920

%Fill TDR data

2931

if package_testcase_i == 1

2921

if package_testcase_i == 1

2932

if OP.TDR

2922

if OP.TDR

2933

output_args.Z11est=chdata(1).TDR11.avgZport;

2923

output_args.Z11est=chdata(1).TDR11.avgZport;

2934

if ~param.FLAG.S2P

2924

if ~param.FLAG.S2P

2935

output_args.Z22est=chdata(1).TDR22.avgZport;

2925

output_args.Z22est=chdata(1).TDR22.avgZport;

2936

else

2926

else

2937

output_args.Z22est=[];

2927

output_args.Z22est=[];

2938

end

2928

end

2939

if OP.AUTO_TFX

2929

if OP.AUTO_TFX

2940

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

2930

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

2941

else

2931

else

2942

output_args.tfx_estimate=[];

2932

output_args.tfx_estimate=[];

2943

end

2933

end

2944

else

2934

else

2945

output_args.Z11est=[];

2935

output_args.Z11est=[];

2946

output_args.Z22est=[];

2936

output_args.Z22est=[];

2947

output_args.tfx_estimate=[];

2937

output_args.tfx_estimate=[];

2948

end

2938

end

2949

end

2939

end

2950

2940

2951

% Process ERL

2941

% Process ERL

2952

if package_testcase_i == 1

2942

if package_testcase_i == 1

2953

if OP.ERL

2943

if OP.ERL

2954

output_args.ERL11=chdata(1).TDR11.ERL;

2944

output_args.ERL11=chdata(1).TDR11.ERL;

2955

if ~param.FLAG.S2P

2945

if ~param.FLAG.S2P

2956

output_args.ERL22=chdata(1).TDR22.ERL;

2946

output_args.ERL22=chdata(1).TDR22.ERL;

2957

else

2947

else

2958

output_args.ERL22=[];

2948

output_args.ERL22=[];

2959

end

2949

end

2960

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

2950

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

2961

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

2951

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

2962

else

2952

else

2963

output_args.ERL11=[];

2953

output_args.ERL11=[];

2964

output_args.ERL22=[];

2954

output_args.ERL22=[];

2965

end

2955

end

2966

end

2956

end

2967

if OP.ERL

2957

if OP.ERL

2968

if OP.TDR_W_TXPKG

2958

if OP.TDR_W_TXPKG

2969

min_ERL=output_args.ERL22;

2959

min_ERL=output_args.ERL22;

2970

ERL= [ nan output_args.ERL22 ];

2960

ERL= [ nan output_args.ERL22 ];

2971

else

2961

else

2972

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

2962

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

2973

min_ERL=output_args.ERL11;

2963

min_ERL=output_args.ERL11;

2974

ERL= [ output_args.ERL11 nan ];

2964

ERL= [ output_args.ERL11 nan ];

2975

else

2965

else

2976

min_ERL=min(output_args.ERL11,output_args.ERL22);

2966

min_ERL=min(output_args.ERL11,output_args.ERL22);

2977

ERL= [ output_args.ERL11 output_args.ERL22 ];

2967

ERL= [ output_args.ERL11 output_args.ERL22 ];

2978

end

2968

end

2979

end

2969

end

2980

output_args.ERL=min_ERL;

2970

output_args.ERL=min_ERL;

2981

else

2971

else

2982

min_ERL=[];

2972

min_ERL=[];

2983

ERL= [];

2973

ERL= [];

2984

output_args.ERL=[];

2974

output_args.ERL=[];

2985

end

2975

end

2986

if OP.ERL_ONLY

2976

if OP.ERL_ONLY

2987

if OP.BREAD_CRUMBS

2977

if OP.BREAD_CRUMBS

2988

output_args.OP=OP;

2978

output_args.OP=OP;

2989

output_args.param=param;

2979

output_args.param=param;

2990

output_args.chdata=chdata;

2980

output_args.chdata=chdata;

2991

%This seems to be the intent of setting fom_result.ran=0. Add it

2981

%This seems to be the intent of setting fom_result.ran=0. Add it

2992

%to output_args so there is a fom_result field.

2982

%to output_args so there is a fom_result field.

2993

fom_result.ran=0;

2983

fom_result.ran=0;

2994

output_args.fom_result=fom_result;

2984

output_args.fom_result=fom_result;

2995

end

2985

end

2996

output_args.Z_t=param.Z_t;

2986

output_args.Z_t=param.Z_t;

2997

fileset_str=str2csv({chdata(1).base});

2987

fileset_str=str2csv({chdata(1).base});

2998

output_args.file_names=sprintf('"%s"', fileset_str);

2988

output_args.file_names=sprintf('"%s"', fileset_str);

2999

if OP.DISPLAY_WINDOW

2989

if OP.DISPLAY_WINDOW

3000

savefigs(param, OP);

2990

savefigs(param, OP);

3001

end

2991

end

3002

end

2992

end

3003

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

2993

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3004

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

2994

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3005

p1_ctle = -2*pi*f_p1;

2995

p1_ctle = -2*pi*f_p1;

3006

p2_ctle = -2*pi*f_p2;

2996

p2_ctle = -2*pi*f_p2;

3007

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

2997

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3008

k_ctle = -p2_ctle;

2998

k_ctle = -p2_ctle;

3009

bilinear_fs = 2*fb*oversampling;

2999

bilinear_fs = 2*fb*oversampling;

3010

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3000

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3011

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3001

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3012

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3002

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3013

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3003

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3014

% allow for different pole zeros RIM 9-29-2015

3004

% allow for different pole zeros RIM 9-29-2015

3015

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3005

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3016

B_filt =k_ctle*kd*poly([zd, -1]);

3006

B_filt =k_ctle*kd*poly([zd, -1]);

3017

A_filt=poly([p1d, p2d]);

3007

A_filt=poly([p1d, p2d]);

3018

impulse_response=filter(B_filt,A_filt,ir_in);

3008

impulse_response=filter(B_filt,A_filt,ir_in);

3019

3009

3020

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3010

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3021

Over_sample=2;

3011

Over_sample=2;

3022

num_files=length(chdata);

3012

num_files=length(chdata);

3023

for i=1:num_files

3013

for i=1:num_files

3024

V=chdata(i).uneq_pulse_response;

3014

V=chdata(i).uneq_pulse_response;

3025

T=chdata(i).t;

3015

T=chdata(i).t;

3026

dt=T(2)-T(1);

3016

dt=T(2)-T(1);

3027

f=0:1/max(T):1/dt;

3017

f=0:1/max(T):1/dt;

3028

chdata(i).faxis=f;

3018

chdata(i).faxis=f;

3029

f75=find(f >= param.fb*.75,1,'first');

3019

f75=find(f >= param.fb*.75,1,'first');

3030

fnq=find(f >= param.fb*.5,1,'first');

3020

fnq=find(f >= param.fb*.5,1,'first');

3031

chdata(i).fmaxi = length(f);

3021

chdata(i).fmaxi = length(f);

3032

chdata(i).faxis = f;

3022

chdata(i).faxis = f;

3033

UI=param.ui; % unit interval

3023

UI=param.ui; % unit interval

3034

M=param.samples_per_ui; % sample per UI

3024

M=param.samples_per_ui; % sample per UI

3035

N_v=param.N_v; % number of UI for Vf determination

3025

N_v=param.N_v; % number of UI for Vf determination

3036

3026

3037

% filters

3027

% filters

3038

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3028

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3039

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3029

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3040

H_ftr=H_bw.*H_bt;

3030

H_ftr=H_bw.*H_bt;

3041

H_ftr=H_ftr(:);

3031

H_ftr=H_ftr(:);

3042

% fd of PR

3032

% fd of PR

3043

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3033

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3044

prr = prr(:);

3034

prr = prr(:);

3045

if f(1)==0, prr(1)=1; end %remove NaN

3035

if f(1)==0, prr(1)=1; end %remove NaN

3046

fd=fft(V);

3036

fd=fft(V);

3047

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3037

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3048

3038

3049

%% get Vf

3039

%% get Vf

3050

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3040

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3051

step_response=filter(V,1, shifting_vector);

3041

step_response=filter(V,1, shifting_vector);

3052

Vf=step_response(end);

3042

Vf=step_response(end);

3053

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3043

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3054

%%

3044

%%

3055

% 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

3045

% 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

3056

% figure

3046

% figure

3057

% plot(f(1:f75),ILest)

3047

% plot(f(1:f75),ILest)

3058

3048

3059

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

3049

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

3060

% set same variables as get_s4p_files

3050

% set same variables as get_s4p_files

3061

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3051

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3062

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3052

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3063

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3053

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3064

zero_vector=zeros(length(IL_conv),1);

3054

zero_vector=zeros(length(IL_conv),1);

3065

for j=1:length(IL_fields)

3055

for j=1:length(IL_fields)

3066

chdata(i).(IL_fields{j})=IL_conv;

3056

chdata(i).(IL_fields{j})=IL_conv;

3067

end

3057

end

3068

for j=1:length(Zero_fields)

3058

for j=1:length(Zero_fields)

3069

chdata(i).(Zero_fields{j})=zero_vector;

3059

chdata(i).(Zero_fields{j})=zero_vector;

3070

end

3060

end

3071

3061

3072

if i==1

3062

if i==1

3073

SDDch(:,1,2)=chdata.sdd12_raw;

3063

SDDch(:,1,2)=chdata.sdd12_raw;

3074

SDDch(:,2,1)=chdata.sdd21_raw;

3064

SDDch(:,2,1)=chdata.sdd21_raw;

3075

SDDch(:,1,1)=chdata.sdd11_raw;

3065

SDDch(:,1,1)=chdata.sdd11_raw;

3076

SDDch(:,2,2)=chdata.sdd22_raw;

3066

SDDch(:,2,2)=chdata.sdd22_raw;

3077

SDDp2p= zeros(length(IL_conv),1);

3067

SDDp2p= zeros(length(IL_conv),1);

3078

end

3068

end

3079

chdata(i).TX_RL=[];

3069

chdata(i).TX_RL=[];

3080

chdata(i).TDR11=[];

3070

chdata(i).TDR11=[];

3081

chdata(i).PDTR11=[];

3071

chdata(i).PDTR11=[];

3082

chdata(i).TDR22=[];

3072

chdata(i).TDR22=[];

3083

chdata(i).PDTR22=[];

3073

chdata(i).PDTR22=[];

3084

end

3074

end

3085

3075

3086

3076

3087

function H_tw=Tukey_Window(f,param,fr,fb)

3077

function H_tw=Tukey_Window(f,param,fr,fb)

3088

% RIM 05/26/2022 added optional fr and fb

3078

% RIM 05/26/2022 added optional fr and fb

3089

% fr is the start of the raised cosine window

3079

% fr is the start of the raised cosine window

3090

% fb is the end of the raised cosine window

3080

% fb is the end of the raised cosine window

3091

if ~exist('fr','var') && ~exist('fb','var')

3081

if ~exist('fr','var') && ~exist('fb','var')

3092

fb=param.fb;

3082

fb=param.fb;

3093

fr=param.f_r*param.fb;

3083

fr=param.f_r*param.fb;

3094

end

3084

end

3095

fperiod=2*(fb-fr);

3085

fperiod=2*(fb-fr);

3096

H_tw = [ ones(1,length(f(f<fr))) ...

3086

H_tw = [ ones(1,length(f(f<fr))) ...

3097

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3087

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3098

zeros(1,length(f(f>fb)) )];

3088

zeros(1,length(f(f>fb)) )];

3099

H_tw=H_tw(1:length(f));

3089

H_tw=H_tw(1:length(f));

3100

if 0

3090

if 0

3101

plot(f/1e9,H_tw)

3091

plot(f/1e9,H_tw)

3102

end

3092

end

3103

3093

3104

3094

3105

3095

3106

%% moved output control to functions

3096

%% moved output control to functions

3107

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3097

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3108

% Author: Richard Mellitz

3098

% Author: Richard Mellitz

3109

% Date: 7/29/2022

3099

% Date: 7/29/2022

3110

% generate FD tx ffe system function

3100

% generate FD tx ffe system function

3111

% varagins...

3101

% varagins...

3112

% param - stucture

3102

% param - stucture

3113

% param.fb baud rate

3103

% param.fb baud rate

3114

% param.Tx_FFE Tx FFE coef

3104

% param.Tx_FFE Tx FFE coef

3115

% f - freq array

3105

% f - freq array

3116

% Use_Tx_FFE = flag to use or not

3106

% Use_Tx_FFE = flag to use or not

3117

% H_TxFFE is system function for Tx_FFE

3107

% H_TxFFE is system function for Tx_FFE

3118

db = @(x) 20*log10(abs(x));

3108

db = @(x) 20*log10(abs(x));

3119

[param,varargin]=varargin_extractor(varargin{:});

3109

[param,varargin]=varargin_extractor(varargin{:});

3120

[f,varargin]=varargin_extractor(varargin{:});

3110

[f,varargin]=varargin_extractor(varargin{:});

3121

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3111

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3122

if isempty(Use_Tx_FFE)

3112

if isempty(Use_Tx_FFE)

3123

Use_Tx_FFE=0;

3113

Use_Tx_FFE=0;

3124

end

3114

end

3125

if isempty(param)

3115

if isempty(param)

3126

param.fb=106.25e9;

3116

param.fb=106.25e9;

3127

Tx_FFE=[1 ];

3117

Tx_FFE=[1 ];

3128

else

3118

else

3129

if ~isfield(param, 'Pkg_TXFFE_preset')

3119

if ~isfield(param, 'Pkg_TXFFE_preset')

3130

Tx_FFE=[ 1 ];

3120

Tx_FFE=[ 1 ];

3131

else

3121

else

3132

Tx_FFE=param.Pkg_TXFFE_preset;

3122

Tx_FFE=param.Pkg_TXFFE_preset;

3133

end

3123

end

3134

end

3124

end

3135

if isempty(f)

3125

if isempty(f)

3136

f=0:10e6:param.fb;

3126

f=0:10e6:param.fb;

3137

end

3127

end

3138

3128

3139

3129

3140

if Use_Tx_FFE ~=0

3130

if Use_Tx_FFE ~=0

3141

[mcur,icur] = max(Tx_FFE);

3131

[mcur,icur] = max(Tx_FFE);

3142

H_TxFFE=zeros(1,length(f));

3132

H_TxFFE=zeros(1,length(f));

3143

for ii=1:length(Tx_FFE)

3133

for ii=1:length(Tx_FFE)

3144

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3134

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3145

end

3135

end

3146

else

3136

else

3147

H_TxFFE=ones(1,length(f));

3137

H_TxFFE=ones(1,length(f));

3148

end

3138

end

3149

% figure (1102320)

3139

% figure (1102320)

3150

% plot(f/1e9,db(H_TxFFE))

3140

% plot(f/1e9,db(H_TxFFE))

3151

% hold on

3141

% hold on

3152

function Write_CSV(output_args,csv_file)

3142

function Write_CSV(output_args,csv_file)

3153

3143

3154

items = fieldnames(output_args);

3144

items = fieldnames(output_args);

3155

item_value_strings = cell(size(items));

3145

item_value_strings = cell(size(items));

3156

for field_id=1:length(items)

3146

for field_id=1:length(items)

3157

field_name=items{field_id};

3147

field_name=items{field_id};

3158

field_value=output_args.(field_name);

3148

field_value=output_args.(field_name);

3159

if isstruct(output_args.(field_name))

3149

if isstruct(output_args.(field_name))

3160

field_value='struct';

3150

field_value='struct';

3161

end

3151

end

3162

if ischar(field_value)

3152

if ischar(field_value)

3163

item_value_strings{field_id}=field_value;

3153

item_value_strings{field_id}=field_value;

3164

elseif isempty(field_value)

3154

elseif isempty(field_value)

3165

item_value_strings{field_id}='';

3155

item_value_strings{field_id}='';

3166

elseif numel(field_value)==1

3156

elseif numel(field_value)==1

3167

item_value_strings{field_id}=num2str(field_value);

3157

item_value_strings{field_id}=num2str(field_value);

3168

else

3158

else

3169

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3159

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3170

end

3160

end

3171

end

3161

end

3172

3162

3173

header_string = str2csv(items);

3163

header_string = str2csv(items);

3174

data_string = str2csv(item_value_strings);

3164

data_string = str2csv(item_value_strings);

3175

fid = fopen(csv_file,'w');

3165

fid = fopen(csv_file,'w');

3176

fprintf(fid,'%s\n', header_string);

3166

fprintf(fid,'%s\n', header_string);

3177

fprintf(fid,'%s\n', data_string);

3167

fprintf(fid,'%s\n', data_string);

3178

fclose(fid);

3168

fclose(fid);

3179

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3169

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3180

%% Used in Clause 92 for adding board trace between TP0 and TP2

3170

%% Used in Clause 92 for adding board trace between TP0 and TP2

3181

3171

3182

switch chdata.type

3172

switch chdata.type

3183

case 'THRU'

3173

case 'THRU'

3184

z_bp_tx = param.z_bp_tx;

3174

z_bp_tx = param.z_bp_tx;

3185

z_bp_rx = param.z_bp_rx;

3175

z_bp_rx = param.z_bp_rx;

3186

case 'NEXT'

3176

case 'NEXT'

3187

z_bp_tx = param.z_bp_rx;

3177

z_bp_tx = param.z_bp_rx;

3188

z_bp_rx = param.z_bp_next;

3178

z_bp_rx = param.z_bp_next;

3189

case 'FEXT'

3179

case 'FEXT'

3190

z_bp_tx = param.z_bp_fext;

3180

z_bp_tx = param.z_bp_fext;

3191

z_bp_rx = param.z_bp_rx;

3181

z_bp_rx = param.z_bp_rx;

3192

end

3182

end

3193

% Same cap on each tx and rx three is a data stratue for bifrucation but

3183

% Same cap on each tx and rx three is a data stratue for bifrucation but

3194

% logic no implemented here RIM 06/28/2019

3184

% logic no implemented here RIM 06/28/2019

3195

zref=param.Z0;

3185

zref=param.Z0;

3196

c1=param.C_0;

3186

c1=param.C_0;

3197

c2=param.C_1;

3187

c2=param.C_1;

3198

f=chdata.faxis;

3188

f=chdata.faxis;

3199

f(f<eps)=eps;

3189

f(f<eps)=eps;

3200

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3190

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3201

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3191

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3202

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3192

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3203

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3193

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3204

[ 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);

3194

[ 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);

3205

% add Tx caps

3195

% add Tx caps

3206

[s11tx, s12tx, s21tx, s22tx ]= ...

3196

[s11tx, s12tx, s21tx, s22tx ]= ...

3207

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3197

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3208

[s11tx, s12tx, s21tx, s22tx ]= ...

3198

[s11tx, s12tx, s21tx, s22tx ]= ...

3209

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3199

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3210

3200

3211

3201

3212

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3202

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3213

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3203

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3214

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3204

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3215

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3205

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3216

[ 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);

3206

[ 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);

3217

% add Rx caps

3207

% add Rx caps

3218

[s11rx, s12rx, s21rx, s22rx ]= ...

3208

[s11rx, s12rx, s21rx, s22rx ]= ...

3219

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3209

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3220

[s11rx, s12rx, s21rx, s22rx ]= ...

3210

[s11rx, s12rx, s21rx, s22rx ]= ...

3221

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3211

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3222

3212

3223

3213

3224

switch OP.include_pcb

3214

switch OP.include_pcb

3225

case 1

3215

case 1

3226

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3216

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3227

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3217

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3228

case 2

3218

case 2

3229

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3219

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3230

end

3220

end

3231

3221

3232

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3222

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3233

% Used in Clause 92 for adding board trace between TP0 and TP2

3223

% Used in Clause 92 for adding board trace between TP0 and TP2

3234

switch chdata.type

3224

switch chdata.type

3235

case 'THRU'

3225

case 'THRU'

3236

z_bp_tx = param.z_bp_tx;

3226

z_bp_tx = param.z_bp_tx;

3237

case 'NEXT'

3227

case 'NEXT'

3238

z_bp_tx = param.z_bp_next;

3228

z_bp_tx = param.z_bp_next;

3239

case 'FEXT'

3229

case 'FEXT'

3240

z_bp_tx = param.z_bp_fext;

3230

z_bp_tx = param.z_bp_fext;

3241

end

3231

end

3242

3232

3243

[ 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);

3233

[ 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);

3244

[ 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);

3234

[ 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);

3245

3235

3246

switch OP.include_pcb

3236

switch OP.include_pcb

3247

case 1

3237

case 1

3248

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3238

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3249

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3239

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3250

case 2

3240

case 2

3251

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3241

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3252

end

3242

end

3253

3243

3254

function [chdata,NS,combined_interference_and_noise_pdf] = adjust_Rx_noise_for_quantization(combined_interference_and_noise_pdf,NS, chdata,fom_result,param,OP)

3255

% expected input

3256

% chdata(1).eq_pulse_response --- includes packages, Hf, and Hr, Ht, and Hffe(from tx)

3257

% align the first sample point to to ts in chdata(1).eq_pulse_response

3258

% align to termiolgy used in MMSE and optimize_FOM

3259

3260

%

3261

sig_after_ctle_pdf = get_pdf_from_sampled_signal(chdata(1).pulse_sampled_w_tx_ffe_ctle, param.levels, param.delta_y);

3262

sig_after_ctle_pdf = conv_fct(sig_after_ctle_pdf, combined_interference_and_noise_pdf);

3263

sig_after_ctle_cdf = cumsum(sig_after_ctle_pdf.y);

3264

adc_clip = -CDF_inv_ev(param.P_qc, sig_after_ctle_pdf, sig_after_ctle_cdf);

3265

ctle_signal_sigma = sqrt(sum((sig_after_ctle_pdf.x.^2).*sig_after_ctle_pdf.y));

3266

adc_lsb = 2*adc_clip/(2^param.N_qb-1);

3267

NS.sigma_Q = adc_lsb/sqrt(12);

3268

NS.sigma_before_clip = ctle_signal_sigma;

3269

NS.peak_clip = adc_clip;

3270

NS.p2ptosigma_clip = 2*adc_clip/ctle_signal_sigma;

3271

quantization_noise_in_pdf = combined_interference_and_noise_pdf; % This is to copy the fields of the structure

3272

[~,adc_ind_right] = min(abs(quantization_noise_in_pdf.x-adc_lsb/2));

3273

[~,adc_ind_left] = min(abs(quantization_noise_in_pdf.x+adc_lsb/2));

3274

% adc_ind_right= find ( min(abs(quantization_noise_pdf.x-adc_lsb/2)) == abs(quantization_noise_pdf.x-adc_lsb/2) );

3275

% adc_ind_left= find ( min(abs(quantization_noise_pdf.x+adc_lsb/2)) == abs(quantization_noise_pdf.x+adc_lsb/2) );

3276

quantization_noise_in_pdf.y = zeros(size(quantization_noise_in_pdf.x));

3277

quantization_noise_in_pdf.y(adc_ind_left:adc_ind_right) = 1/(adc_ind_right-adc_ind_left+1);

3278

% initialize quantization noise PDF afeter RxFFE to a Dirac delta PDF

3279

quantization_noise_pdf = combined_interference_and_noise_pdf;

3280

[~,ind_center]= min(abs(quantization_noise_pdf.x));

3281

quantization_noise_pdf.y = zeros(size(quantization_noise_pdf.x));

3282

quantization_noise_pdf.y(ind_center) = 1;

3283

% Calculate quantization noise PDF after RxFFE

3284

h_rxffe = fom_result.RxFFE(find(fom_result.RxFFE ~= 0));

3285

for irxffe = 1:length(h_rxffe)

3286

if irxffe ~= param.ffe_pre_tap_len

3287

quantization_noise_in_pdf_scale = scalePDF(quantization_noise_in_pdf, abs(h_rxffe(irxffe)));

3288

quantization_noise_pdf = conv_fct(quantization_noise_pdf, quantization_noise_in_pdf_scale);

3289

end

3290

end

3291

combined_interference_and_noise_pdf = conv_fct(combined_interference_and_noise_pdf, quantization_noise_pdf);

3292

NS.quantization_noise_pdf = quantization_noise_pdf ;

3293

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3244

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3294

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3245

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3295

% applying a bank of DFE at desired location

3246

% applying a bank of DFE at desired location

3296

% hisi: waveform with cursor values;

3247

% hisi: waveform with cursor values;

3297

% idx: starting index of the bank;

3248

% idx: starting index of the bank;

3298

% tap_bk: number of taps in bank;

3249

% tap_bk: number of taps in bank;

3299

% bmaxg: maxmum coefficient in bank;

3250

% bmaxg: maxmum coefficient in bank;

3300

3251

3301

if nargin<6

3252

if nargin<6

3302

dfe_delta=0;

3253

dfe_delta=0;

3303

end

3254

end

3304

3255

3305

rng=idx:idx+tap_bk-1;

3256

rng=idx:idx+tap_bk-1;

3306

flt_curval=hisi(rng);

3257

flt_curval=hisi(rng);

3307

3258

3308

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3259

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3309

3260

3310

if dfe_delta~=0

3261

if dfe_delta~=0

3311

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3262

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3312

dfe_delta.*sign(flt_curval)*curval;

3263

dfe_delta.*sign(flt_curval)*curval;

3313

else

3264

else

3314

flt_curval_q=hisi(rng);

3265

flt_curval_q=hisi(rng);

3315

end

3266

end

3316

3267

3317

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3268

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3318

hisi(rng)= hisi(rng) - curval*tap_coef;

3269

hisi(rng)= hisi(rng) - curval*tap_coef;

3319

hisi_ref(rng)=0;

3270

hisi_ref(rng)=0;

3320

3271

3321

%AJG021820

3272

%AJG021820

3322

function [ a] = bessel( n )

3273

function [ a] = bessel( n )

3323

% bessel polynomial

3274

% bessel polynomial

3324

for ii= 0:n

3275

for ii= 0:n

3325

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3276

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3326

end

3277

end

3327

3278

3328

3279

3329

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3280

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3330

% History:

3281

% History:

3331

% 1. 14th October, 2021 (Intial release)

3282

% 1. 14th October, 2021 (Intial release)

3332

3283

3333

% Definition:

3284

% Definition:

3334

% This function captures the channel delay through the time domain using causality enforcement.

3285

% This function captures the channel delay through the time domain using causality enforcement.

3335

% Following are the steps being followed.

3286

% Following are the steps being followed.

3336

% Step 1. Cascade negative frequencies

3287

% Step 1. Cascade negative frequencies

3337

% Step 2. Extract magnitude

3288

% Step 2. Extract magnitude

3338

% Step 3. IFFT of the magnitude

3289

% Step 3. IFFT of the magnitude

3339

% Step 4. Multiply by the sign(t)

3290

% Step 4. Multiply by the sign(t)

3340

% Step 5. Calculate the phase of the 1j*causal_phase

3291

% Step 5. Calculate the phase of the 1j*causal_phase

3341

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3292

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3342

% Step 7. f-domain to t-domain pulse response

3293

% Step 7. f-domain to t-domain pulse response

3343

% Step 8. Calculate the delay

3294

% Step 8. Calculate the delay

3344

3295

3345

% Author:

3296

% Author:

3346

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3297

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3347

3298

3348

% Reference:

3299

% Reference:

3349

% 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.

3300

% 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.

3350

3301

3351

% Input:

3302

% Input:

3352

% freq %frequency in hertz (odd number points)

3303

% freq %frequency in hertz (odd number points)

3353

% sdd21 %insertion loss in complex (odd number points)

3304

% sdd21 %insertion loss in complex (odd number points)

3354

% param %COM native structure passed

3305

% param %COM native structure passed

3355

% OP %COM native structure passed

3306

% OP %COM native structure passed

3356

3307

3357

% Output:

3308

% Output:

3358

% delay_sec %channel delay in seconds

3309

% delay_sec %channel delay in seconds

3359

% delay_idx %channel delay index

3310

% delay_idx %channel delay index

3360

3311

3361

if iscolumn(sdd21)

3312

if iscolumn(sdd21)

3362

sdd21= sdd21.';

3313

sdd21= sdd21.';

3363

end

3314

end

3364

if iscolumn(freq)

3315

if iscolumn(freq)

3365

freq= freq.';

3316

freq= freq.';

3366

end

3317

end

3367

3318

3368

%---start. Step 1. Cascade negative frequencies

3319

%---start. Step 1. Cascade negative frequencies

3369

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3320

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3370

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3321

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3371

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3322

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3372

%---end. Step 1. Cascade negative frequencies

3323

%---end. Step 1. Cascade negative frequencies

3373

3324

3374

%---start. Step 2. Extract magnitude

3325

%---start. Step 2. Extract magnitude

3375

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3326

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3376

%---end. Step 2. Extract magnitude

3327

%---end. Step 2. Extract magnitude

3377

3328

3378

%---start. Step 3. IFFT of the magnitude

3329

%---start. Step 3. IFFT of the magnitude

3379

sdd21_mag_time = ifft(sdd21_mag_conj);

3330

sdd21_mag_time = ifft(sdd21_mag_conj);

3380

%---end. Step 3. IFFT of the magnitude

3331

%---end. Step 3. IFFT of the magnitude

3381

3332

3382

%---start. Step 4. Multiply by the sign(t)

3333

%---start. Step 4. Multiply by the sign(t)

3383

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3334

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3384

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3335

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3385

%---end. Step 4. Multiply by the sign(t)

3336

%---end. Step 4. Multiply by the sign(t)

3386

3337

3387

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3338

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3388

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3339

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3389

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3340

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3390

3341

3391

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3342

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3392

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3343

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3393

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3344

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3394

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3345

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3395

3346

3396

%---start. Step 7. f-domain to t-domain pulse response

3347

%---start. Step 7. f-domain to t-domain pulse response

3397

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3348

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3398

%--------- Extrapolation has been already done by the COM tool

3349

%--------- Extrapolation has been already done by the COM tool

3399

freq_array= freq;

3350

freq_array= freq;

3400

time_step= param.sample_dt;

3351

time_step= param.sample_dt;

3401

fmax=1/time_step/2;

3352

fmax=1/time_step/2;

3402

freq_step=(freq_array(3)-freq_array(2))/1;

3353

freq_step=(freq_array(3)-freq_array(2))/1;

3403

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3354

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3404

3355

3405

ILin=sdd21;

3356

ILin=sdd21;

3406

IL=interp_Sparam(ILin,freq_array,fout, ...

3357

IL=interp_Sparam(ILin,freq_array,fout, ...

3407

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3358

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3408

IL_nan = find(isnan(IL));

3359

IL_nan = find(isnan(IL));

3409

for in=IL_nan

3360

for in=IL_nan

3410

IL(in)=IL(in-1);

3361

IL(in)=IL(in-1);

3411

end

3362

end

3412

IL = IL(:);

3363

IL = IL(:);

3413

% add padding for time steps

3364

% add padding for time steps

3414

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3365

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3415

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3366

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3416

clear IL IL_nan IL_symmetric

3367

clear IL IL_nan IL_symmetric

3417

3368

3418

ILin=sdd21_causality_enforced;

3369

ILin=sdd21_causality_enforced;

3419

IL=interp_Sparam(ILin,freq_array,fout, ...

3370

IL=interp_Sparam(ILin,freq_array,fout, ...

3420

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3371

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3421

IL_nan = find(isnan(IL));

3372

IL_nan = find(isnan(IL));

3422

for in=IL_nan

3373

for in=IL_nan

3423

IL(in)=IL(in-1);

3374

IL(in)=IL(in-1);

3424

end

3375

end

3425

IL = IL(:);

3376

IL = IL(:);

3426

% add padding for time steps

3377

% add padding for time steps

3427

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3378

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3428

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3379

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3429

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3380

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3430

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3381

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3431

clear IL IL_nan IL_symmetric

3382

clear IL IL_nan IL_symmetric

3432

3383

3433

clear time_step fmax freq_step freq_array

3384

clear time_step fmax freq_step freq_array

3434

3385

3435

freq_step=(fout(3)-fout(2))/1;

3386

freq_step=(fout(3)-fout(2))/1;

3436

L= length(sdd21_PR);

3387

L= length(sdd21_PR);

3437

t_base = (0:L-1)/(freq_step*L);

3388

t_base = (0:L-1)/(freq_step*L);

3438

clear fout freq_step L

3389

clear fout freq_step L

3439

%---end. Step 7. f-domain to t-domain pulse response

3390

%---end. Step 7. f-domain to t-domain pulse response

3440

3391

3441

%---start. Step 8. Calculate the delay

3392

%---start. Step 8. Calculate the delay

3442

%------start. Remove the last 5% of the waveform for noise due to IFFT

3393

%------start. Remove the last 5% of the waveform for noise due to IFFT

3443

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3394

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3444

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3395

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3445

%------end. Remove the last 5% of the waveform for noise due to IFFT

3396

%------end. Remove the last 5% of the waveform for noise due to IFFT

3446

3397

3447

%---start. calculate the difference in index between the peaks

3398

%---start. calculate the difference in index between the peaks

3448

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3399

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3449

[~, peak_y_idx] = max(sdd21_PR_reduced);

3400

[~, peak_y_idx] = max(sdd21_PR_reduced);

3450

peak_idx_difference = peak_x_idx - peak_y_idx;

3401

peak_idx_difference = peak_x_idx - peak_y_idx;

3451

%---end. calculate the difference in index between the peaks

3402

%---end. calculate the difference in index between the peaks

3452

3403

3453

if peak_idx_difference~=0

3404

if peak_idx_difference~=0

3454

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

3405

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

3455

error_value = length(sdd21_causality_enforced_PR_reduced);

3406

error_value = length(sdd21_causality_enforced_PR_reduced);

3456

error_idx = 0;

3407

error_idx = 0;

3457

% i= 1;

3408

% i= 1;

3458

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3409

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3459

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3410

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3460

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3411

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3461

if (error_value > current_error)

3412

if (error_value > current_error)

3462

error_idx = shift_value;

3413

error_idx = shift_value;

3463

error_value = current_error;

3414

error_value = current_error;

3464

end

3415

end

3465

% error_idx_H(i)= error_idx;

3416

% error_idx_H(i)= error_idx;

3466

% i= i+ 1;

3417

% i= i+ 1;

3467

end

3418

end

3468

%plot(error_idx_H);

3419

%plot(error_idx_H);

3469

3420

3470

if error_idx==0

3421

if error_idx==0

3471

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3422

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3472

end

3423

end

3473

3424

3474

delay_idx = error_idx;

3425

delay_idx = error_idx;

3475

else

3426

else

3476

delay_idx= 1;

3427

delay_idx= 1;

3477

end

3428

end

3478

3429

3479

delay_sec= t_base(abs(delay_idx));

3430

delay_sec= t_base(abs(delay_idx));

3480

3431

3481

3432

3482

function [return_struct]= capture_RIL_RILN(chdata)

3433

function [return_struct]= capture_RIL_RILN(chdata)

3483

% History:

3434

% History:

3484

% 1. 12th April, 2019 (Intial release)

3435

% 1. 12th April, 2019 (Intial release)

3485

%

3436

%

3486

% 2. 11th October, 2021

3437

% 2. 11th October, 2021

3487

% - Details:

3438

% - Details:

3488

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3439

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3489

% 2] Revised the selection criteria for the solution of the quadratic

3440

% 2] Revised the selection criteria for the solution of the quadratic

3490

% equation in finding the reflection coefficient (rho).

3441

% equation in finding the reflection coefficient (rho).

3491

% - Impact:

3442

% - Impact:

3492

% => Zero impact in |RIL|, while impact on angle(RIL).

3443

% => Zero impact in |RIL|, while impact on angle(RIL).

3493

% - Previous:

3444

% - Previous:

3494

% %---start. For passive networks the reflection coefficient should be less than one

3445

% %---start. For passive networks the reflection coefficient should be less than one

3495

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3446

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3496

% rho_port2= solution_1;

3447

% rho_port2= solution_1;

3497

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3448

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3498

% rho_port2= solution_2;

3449

% rho_port2= solution_2;

3499

% else

3450

% else

3500

% rho_port2= solution_1;

3451

% rho_port2= solution_1;

3501

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3452

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3502

% end

3453

% end

3503

% %---end. For passive networks the reflection coefficient should be less than one

3454

% %---end. For passive networks the reflection coefficient should be less than one

3504

%

3455

%

3505

% 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) ) );

3456

% 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) ) );

3506

% - Change:

3457

% - Change:

3507

% %---start. Given the real part of the impedance is to be positive

3458

% %---start. Given the real part of the impedance is to be positive

3508

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3459

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3509

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3460

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3510

%

3461

%

3511

% rho_port2= zeros(length(solution_1), 1);

3462

% rho_port2= zeros(length(solution_1), 1);

3512

% for solution_idx= 1:length(solution_1)

3463

% for solution_idx= 1:length(solution_1)

3513

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3464

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3514

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3465

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3515

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3466

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3516

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3467

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3517

% else

3468

% else

3518

% error('An odd case has occured. Please contact the tool developer.');

3469

% error('An odd case has occured. Please contact the tool developer.');

3519

% end

3470

% end

3520

% end

3471

% end

3521

% %---end. Given the real part of the impedance is to be positive

3472

% %---end. Given the real part of the impedance is to be positive

3522

% 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) ) );

3473

% 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) ) );

3523

3474

3524

% Definition:

3475

% Definition:

3525

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3476

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3526

3477

3527

% Author:

3478

% Author:

3528

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3479

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3529

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3480

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3530

3481

3531

% 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.

3482

% 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.

3532

3483

3533

% Reference:

3484

% Reference:

3534

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3485

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3535

% 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.

3486

% 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.

3536

3487

3537

% Input:

3488

% Input:

3538

% 1] SCH: S-matrix structure

3489

% 1] SCH: S-matrix structure

3539

% SCH.Frequencies= faxis;

3490

% SCH.Frequencies= faxis;

3540

% SCH.Parameters(1,1,:)= sdd11;

3491

% SCH.Parameters(1,1,:)= sdd11;

3541

% SCH.Parameters(2,2,:)= sdd22;

3492

% SCH.Parameters(2,2,:)= sdd22;

3542

% SCH.Parameters(1,2,:)= sdd12;

3493

% SCH.Parameters(1,2,:)= sdd12;

3543

% SCH.Parameters(2,1,:)= sdd21;

3494

% SCH.Parameters(2,1,:)= sdd21;

3544

% SCH.NumPorts= 2;

3495

% SCH.NumPorts= 2;

3545

% SCH.Impedance= 100;

3496

% SCH.Impedance= 100;

3546

3497

3547

% Output: Struct returned has the following,

3498

% Output: Struct returned has the following,

3548

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3499

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3549

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3500

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3550

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3501

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3551

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3502

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3552

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3503

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3553

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3504

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3554

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3505

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3555

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3506

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3556

% return_struct.freq %Frequency axis

3507

% return_struct.freq %Frequency axis

3557

3508

3558

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3509

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3559

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3510

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3560

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3511

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3561

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3512

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3562

SCH.Frequencies=chdata(1).faxis;

3513

SCH.Frequencies=chdata(1).faxis;

3563

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3514

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3564

SCH.NumPorts= 2;

3515

SCH.NumPorts= 2;

3565

3516

3566

%---start. allowed is only a 2-port network having a transmitter and receiver

3517

%---start. allowed is only a 2-port network having a transmitter and receiver

3567

if size(SCH.Parameters, 1)~=2

3518

if size(SCH.Parameters, 1)~=2

3568

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3519

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3569

error('Allowed is only a 2-port network having a transmitter and receiver.');

3520

error('Allowed is only a 2-port network having a transmitter and receiver.');

3570

end

3521

end

3571

%---end. allowed is only a 2-port network having a transmitter and receiver

3522

%---end. allowed is only a 2-port network having a transmitter and receiver

3572

3523

3573

%---start. do not include the DC point given sinusoidals at DC are not

3524

%---start. do not include the DC point given sinusoidals at DC are not

3574

%defined

3525

%defined

3575

if SCH.Frequencies(1)==0

3526

if SCH.Frequencies(1)==0

3576

idx_start= 2;

3527

idx_start= 2;

3577

else

3528

else

3578

idx_start= 1;

3529

idx_start= 1;

3579

end

3530

end

3580

%---end. do not include the DC point given sinusoidals at DC are not

3531

%---end. do not include the DC point given sinusoidals at DC are not

3581

%defined

3532

%defined

3582

3533

3583

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3534

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3584

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3535

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3585

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3536

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3586

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3537

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3587

3538

3588

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3539

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3589

b= 1+ Sdd22.*conj(Sdd22)+...

3540

b= 1+ Sdd22.*conj(Sdd22)+...

3590

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3541

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3591

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3542

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3592

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3543

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3593

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3544

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3594

Sdd11.*conj(Sdd11);

3545

Sdd11.*conj(Sdd11);

3595

c= -conj(Sdd22)-...

3546

c= -conj(Sdd22)-...

3596

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3547

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3597

Sdd11.*conj(Sdd11).*conj(Sdd22);

3548

Sdd11.*conj(Sdd11).*conj(Sdd22);

3598

3549

3599

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3550

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3600

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3551

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3601

3552

3602

clear a b c

3553

clear a b c

3603

3554

3604

%---start. Given the real part of the impedance is to be positive

3555

%---start. Given the real part of the impedance is to be positive

3605

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3556

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3606

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3557

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3607

3558

3608

rho_port2= zeros(length(solution_1), 1);

3559

rho_port2= zeros(length(solution_1), 1);

3609

for solution_idx= 1:length(solution_1)

3560

for solution_idx= 1:length(solution_1)

3610

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3561

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3611

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3562

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3612

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3563

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3613

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3564

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3614

else

3565

else

3615

error('An odd case has occured. Please contact the tool developer.');

3566

error('An odd case has occured. Please contact the tool developer.');

3616

end

3567

end

3617

end

3568

end

3618

%---end. Given the real part of the impedance is to be positive

3569

%---end. Given the real part of the impedance is to be positive

3619

3570

3620

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3571

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3621

3572

3622

%---start. calculate the equivalent port impedance

3573

%---start. calculate the equivalent port impedance

3623

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3574

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3624

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3575

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3625

%---end. calculate the equivalent port impedance

3576

%---end. calculate the equivalent port impedance

3626

3577

3627

3578

3628

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3579

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3629

% %to zero reflections.

3580

% %to zero reflections.

3630

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) ) );

3581

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) ) );

3631

%---end. The reflectionless insertion loss is the insertion loss corresponding

3582

%---end. The reflectionless insertion loss is the insertion loss corresponding

3632

%to zero reflections.

3583

%to zero reflections.

3633

3584

3634

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3585

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3635

RILN= RIL- Sdd21;

3586

RILN= RIL- Sdd21;

3636

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3587

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3637

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3588

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3638

3589

3639

%---start. preparing returns struct

3590

%---start. preparing returns struct

3640

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3591

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3641

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3592

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3642

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3593

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3643

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3594

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3644

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3595

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3645

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3596

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3646

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3597

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3647

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3598

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3648

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3599

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3649

%---end. preparing returns struct

3600

%---end. preparing returns struct

3650

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3601

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3651

3602

3652

3603

3653

%For the given BER, find the top & bottom voltage level in the CDF

3604

%For the given BER, find the top & bottom voltage level in the CDF

3654

3605

3655

%for the top, just find the first index at the spec BER

3606

%for the top, just find the first index at the spec BER

3656

nidx=find(cdf.y>specBER, 1, 'first');

3607

nidx=find(cdf.y>specBER, 1, 'first');

3657

noise_bottom = cdf.x(nidx);

3608

noise_bottom = cdf.x(nidx);

3658

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3609

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3659

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3610

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3660

%the true index without flipping

3611

%the true index without flipping

3661

nidx=length(cdf.y)-nidx+1;

3612

nidx=length(cdf.y)-nidx+1;

3662

noise_top = cdf.x(nidx);

3613

noise_top = cdf.x(nidx);

3663

function p=comb_fct(p1, p2)

3614

function p=comb_fct(p1, p2)

3664

if p1.BinSize ~= p2.BinSize

3615

if p1.BinSize ~= p2.BinSize

3665

error('bin size must be equal')

3616

error('bin size must be equal')

3666

end

3617

end

3667

3618

3668

p=p1;

3619

p=p1;

3669

p.BinSize=p1.BinSize;

3620

p.BinSize=p1.BinSize;

3670

%p.Min=p1.Min+p2.Min;

3621

%p.Min=p1.Min+p2.Min;

3671

p.Min=min(p1.Min,p2.Min);

3622

p.Min=min(p1.Min,p2.Min);

3672

difsz=abs(p1.Min-p2.Min);

3623

difsz=abs(p1.Min-p2.Min);

3673

lp1=length(p1.y);

3624

lp1=length(p1.y);

3674

lp2=length(p2.y);

3625

lp2=length(p2.y);

3675

if p1.Min == p.Min

3626

if p1.Min == p.Min

3676

p2.y(difsz+1:lp2+difsz)=p2.y;

3627

p2.y(difsz+1:lp2+difsz)=p2.y;

3677

p2.y(1:difsz)=0;

3628

p2.y(1:difsz)=0;

3678

p2.y(lp2+difsz+1:lp1)=0;

3629

p2.y(lp2+difsz+1:lp1)=0;

3679

elseif p2.Min == p.Min

3630

elseif p2.Min == p.Min

3680

p1.y(difsz+1:lp1+difsz)=p1.y;

3631

p1.y(difsz+1:lp1+difsz)=p1.y;

3681

p1.y(1:difsz)=0;

3632

p1.y(1:difsz)=0;

3682

p1.y(lp1+difsz+1:lp2)=0;

3633

p1.y(lp1+difsz+1:lp2)=0;

3683

end

3634

end

3684

% p.y=conv(p1.y, p2.y);

3635

% p.y=conv(p1.y, p2.y);

3685

p.y=(p1.y+p2.y);

3636

p.y=(p1.y+p2.y);

3686

% p.y=p.y/sum(p.y);

3637

% p.y=p.y/sum(p.y);

3687

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3638

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3688

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3639

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3689

3640

3690

3641

3691

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

3642

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

3692

3643

3693

if pdf1.BinSize ~= pdf2.BinSize

3644

if pdf1.BinSize ~= pdf2.BinSize

3694

error('bin size must be equal')

3645

error('bin size must be equal')

3695

end

3646

end

3696

3647

3697

x1=pdf1.x;

3648

x1=pdf1.x;

3698

y1=pdf1.y;

3649

y1=pdf1.y;

3699

x2=pdf2.x;

3650

x2=pdf2.x;

3700

y2=pdf2.y;

3651

y2=pdf2.y;

3701

%find the pdf with a larger min, force it to have the same min, and insert

3652

%find the pdf with a larger min, force it to have the same min, and insert

3702

%probability = 0

3653

%probability = 0

3703

min1=pdf1.x(1);

3654

min1=pdf1.x(1);

3704

min2=pdf2.x(1);

3655

min2=pdf2.x(1);

3705

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

3656

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

3706

if min1<min2

3657

if min1<min2

3707

x2=[pdf1.x(1:shift_amount) pdf2.x];

3658

x2=[pdf1.x(1:shift_amount) pdf2.x];

3708

y2=[zeros(1,shift_amount) pdf2.y];

3659

y2=[zeros(1,shift_amount) pdf2.y];

3709

else

3660

else

3710

x1=[pdf2.x(1:shift_amount) pdf1.x];

3661

x1=[pdf2.x(1:shift_amount) pdf1.x];

3711

y1=[zeros(1,shift_amount) pdf1.y];

3662

y1=[zeros(1,shift_amount) pdf1.y];

3712

end

3663

end

3713

%find the pdf with smaller max, force it to have the same max, and insert

3664

%find the pdf with smaller max, force it to have the same max, and insert

3714

%probability=0

3665

%probability=0

3715

L1=length(x1);

3666

L1=length(x1);

3716

L2=length(x2);

3667

L2=length(x2);

3717

Ldiff=abs(L1-L2);

3668

Ldiff=abs(L1-L2);

3718

if L1>L2

3669

if L1>L2

3719

out_x=x1;

3670

out_x=x1;

3720

y2=[y2 zeros(1,Ldiff)];

3671

y2=[y2 zeros(1,Ldiff)];

3721

else

3672

else

3722

out_x=x2;

3673

out_x=x2;

3723

y1=[y1 zeros(1,Ldiff)];

3674

y1=[y1 zeros(1,Ldiff)];

3724

end

3675

end

3725

%now the 2 pdfs have the same voltage axis, add probabilities together

3676

%now the 2 pdfs have the same voltage axis, add probabilities together

3726

%renormalization is not handled here, so the output pdf will not have sum=1

3677

%renormalization is not handled here, so the output pdf will not have sum=1

3727

%It is the responsibility of the calling function to handle renormalization

3678

%It is the responsibility of the calling function to handle renormalization

3728

%if needed

3679

%if needed

3729

out_y=y1+y2;

3680

out_y=y1+y2;

3730

out_pdf.x=out_x;

3681

out_pdf.x=out_x;

3731

out_pdf.y=out_y;

3682

out_pdf.y=out_y;

3732

out_pdf.BinSize=pdf1.BinSize;

3683

out_pdf.BinSize=pdf1.BinSize;

3733

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

3684

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

3734

3685

3735

%original method:

3686

%original method:

3736

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

3687

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

3737

% for i=1:length(s11in1)

3688

% for i=1:length(s11in1)

3738

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

3689

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

3739

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

3690

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

3740

% end

3691

% end

3741

% t1=stot(s1);

3692

% t1=stot(s1);

3742

% t2=stot(s2);

3693

% t2=stot(s2);

3743

% for i=1:length(s11in1)

3694

% for i=1:length(s11in1)

3744

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

3695

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

3745

% end

3696

% end

3746

% s3=ttos(t3);

3697

% s3=ttos(t3);

3747

% s11out=s3(1,1,:);

3698

% s11out=s3(1,1,:);

3748

% s11out=transpose(s11out(:));

3699

% s11out=transpose(s11out(:));

3749

% s12out=s3(1,2,:);

3700

% s12out=s3(1,2,:);

3750

% s12out=transpose(s12out(:));

3701

% s12out=transpose(s12out(:));

3751

% s21out=s3(2,1,:);

3702

% s21out=s3(2,1,:);

3752

% s21out=transpose(s21out(:));

3703

% s21out=transpose(s21out(:));

3753

% s22out=s3(2,2,:);

3704

% s22out=s3(2,2,:);

3754

% s22out=transpose(s22out(:));

3705

% s22out=transpose(s22out(:));

3755

3706

3756

3707

3757

%vectorized method:

3708

%vectorized method:

3758

s1(1,1,:)=s11in1;

3709

s1(1,1,:)=s11in1;

3759

s1(1,2,:)=s12in1;

3710

s1(1,2,:)=s12in1;

3760

s1(2,1,:)=s21in1;

3711

s1(2,1,:)=s21in1;

3761

s1(2,2,:)=s22in1;

3712

s1(2,2,:)=s22in1;

3762

s2(1,1,:)=s11in2;

3713

s2(1,1,:)=s11in2;

3763

s2(1,2,:)=s12in2;

3714

s2(1,2,:)=s12in2;

3764

s2(2,1,:)=s21in2;

3715

s2(2,1,:)=s21in2;

3765

s2(2,2,:)=s22in2;

3716

s2(2,2,:)=s22in2;

3766

3717

3767

3718

3768

N = (1-s1(2,2,:).*s2(1,1,:)) ;

3719

N = (1-s1(2,2,:).*s2(1,1,:)) ;

3769

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

3720

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

3770

s12out = s1(1,2,:).*s2(1,2,:)./N ;

3721

s12out = s1(1,2,:).*s2(1,2,:)./N ;

3771

s21out = s2(2,1,:).*s1(2,1,:)./N;

3722

s21out = s2(2,1,:).*s1(2,1,:)./N;

3772

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

3723

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

3773

3724

3774

s11out=transpose(squeeze(s11out));

3725

s11out=transpose(squeeze(s11out));

3775

s12out=transpose(squeeze(s12out));

3726

s12out=transpose(squeeze(s12out));

3776

s21out=transpose(squeeze(s21out));

3727

s21out=transpose(squeeze(s21out));

3777

s22out=transpose(squeeze(s22out));

3728

s22out=transpose(squeeze(s22out));

3778

function p=conv_fct(p1, p2)

3729

function p=conv_fct(p1, p2)

3779

if p1.BinSize ~= p2.BinSize

3730

if p1.BinSize ~= p2.BinSize

3780

error('bin size must be equal')

3731

error('bin size must be equal')

3781

end

3732

end

3782

3733

3783

p=p1;

3734

p=p1;

3784

%p.BinSize=p1.BinSize;

3735

%p.BinSize=p1.BinSize;

3785

%p.Min=p1.Min+p2.Min;

3736

%p.Min=p1.Min+p2.Min;

3786

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3737

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3787

p.y=conv2(p1.y, p2.y);

3738

p.y=conv2(p1.y, p2.y);

3788

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3739

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3789

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3740

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3790

pMax=p.Min+length(p.y)-1;

3741

pMax=p.Min+length(p.y)-1;

3791

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3742

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3792

3743

3793

3744

3794

3745

3795

3746

3796

function p=conv_fct_MeanNotZero(p1, p2)

3747

function p=conv_fct_MeanNotZero(p1, p2)

3797

3748

3798

if p1.BinSize ~= p2.BinSize

3749

if p1.BinSize ~= p2.BinSize

3799

error('bin size must be equal')

3750

error('bin size must be equal')

3800

end

3751

end

3801

3752

3802

p=p1;

3753

p=p1;

3803

%p.BinSize=p1.BinSize;

3754

%p.BinSize=p1.BinSize;

3804

%p.Min=p1.Min+p2.Min;

3755

%p.Min=p1.Min+p2.Min;

3805

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3756

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3806

p.y=conv2(p1.y, p2.y);

3757

p.y=conv2(p1.y, p2.y);

3807

3758

3808

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

3759

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

3809

%But it is faster to pre-multiply BinSize instead of multiplying the entire

3760

%But it is faster to pre-multiply BinSize instead of multiplying the entire

3810

%vector by BinSize

3761

%vector by BinSize

3811

pMax=p.Min+length(p.y)-1;

3762

pMax=p.Min+length(p.y)-1;

3812

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3763

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3813

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

3764

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

3814

3765

3815

%IN:

3766

%IN:

3816

%sbr = pulse response

3767

%sbr = pulse response

3817

%param = COM "param" struct

3768

%param = COM "param" struct

3818

%OP = COM "OP" struct

3769

%OP = COM "OP" struct

3819

%peak_search_range= a limited range to search for the peak (for speed up)

3770

%peak_search_range= a limited range to search for the peak (for speed up)

3820

% it is usually +/- 20 UI

3771

% it is usually +/- 20 UI

3821

%

3772

%

3822

%OUT:

3773

%OUT:

3823

%cursor_i = sampling location

3774

%cursor_i = sampling location

3824

%no_zero_crossing = flag that reveals if sampling is not possible.

3775

%no_zero_crossing = flag that reveals if sampling is not possible.

3825

% When this function is called in optimize_fom, it signals to quit the current case

3776

% When this function is called in optimize_fom, it signals to quit the current case

3826

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

3777

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

3827

% time consuming, so saving the peak in one spot is advantageous

3778

% time consuming, so saving the peak in one spot is advantageous

3828

%zxi = zero crossing index (returned because RXFFE uses it)

3779

%zxi = zero crossing index (returned because RXFFE uses it)

3829

3780

3830

no_zero_crossing=0;

3781

no_zero_crossing=0;

3831

%need to set cursor_i to empty in case no_zero_crossing flag is set

3782

%need to set cursor_i to empty in case no_zero_crossing flag is set

3832

cursor_i=[];

3783

cursor_i=[];

3833

3784

3834

%get peak of pulse and peak index

3785

%get peak of pulse and peak index

3835

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

3786

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

3836

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

3787

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

3837

3788

3838

3789

3839

% initial guess at cursor location (t_s) - based on approximate zero crossing

3790

% initial guess at cursor location (t_s) - based on approximate zero crossing

3840

%limit search space for speed up

3791

%limit search space for speed up

3841

search_start=sbr_peak_i-4*param.samples_per_ui;

3792

search_start=sbr_peak_i-4*param.samples_per_ui;

3842

if search_start<1

3793

if search_start<1

3843

search_start=1;

3794

search_start=1;

3844

end

3795

end

3845

%Find zero crossings

3796

%Find zero crossings

3846

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

3797

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

3847

3798

3848

%Note: the original implementation of zxi:

3799

%Note: the original implementation of zxi:

3849

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

3800

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

3850

% zxi = zxi(zxi<sbr_peak_i);

3801

% zxi = zxi(zxi<sbr_peak_i);

3851

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

3802

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

3852

% The changes to limit search space and remember max(sbr) give 10x speed up

3803

% The changes to limit search space and remember max(sbr) give 10x speed up

3853

% A test case of 25k runs, reduced from 1.2s to 0.1s

3804

% A test case of 25k runs, reduced from 1.2s to 0.1s

3854

3805

3855

3806

3856

if isempty(zxi)

3807

if isempty(zxi)

3857

%if no zero crossing, the calling program must respond (since sample point will be empty)

3808

%if no zero crossing, the calling program must respond (since sample point will be empty)

3858

no_zero_crossing=1;

3809

no_zero_crossing=1;

3859

return;

3810

return;

3860

elseif length(zxi)>1

3811

elseif length(zxi)>1

3861

%only need the last zero crossing

3812

%only need the last zero crossing

3862

zxi=zxi(end);

3813

zxi=zxi(end);

3863

end

3814

end

3864

if param.ndfe==0

3815

if param.ndfe==0

3865

max_dfe1=0;

3816

max_dfe1=0;

3866

else

3817

else

3867

max_dfe1=param.bmax(1);

3818

max_dfe1=param.bmax(1);

3868

end

3819

end

3869

% adjust cursor_i to Solve equation 93A-25 %%

3820

% adjust cursor_i to Solve equation 93A-25 %%

3870

% Muller-Mueller criterion with DFE

3821

% Muller-Mueller criterion with DFE

3871

mm_range = zxi+(0:2*param.samples_per_ui);

3822

mm_range = zxi+(0:2*param.samples_per_ui);

3872

switch OP.CDR

3823

switch OP.CDR

3873

case 'Mod-MM'

3824

case 'Mod-MM'

3874

mm_metric = ...

3825

mm_metric = ...

3875

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

3826

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

3876

otherwise % MM

3827

otherwise % MM

3877

%MM is generally: first precursor = 0

3828

%MM is generally: first precursor = 0

3878

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

3829

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

3879

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

3830

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

3880

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

3831

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

3881

%first precursor = first postcursor - max_dfe

3832

%first precursor = first postcursor - max_dfe

3882

mm_metric = ...

3833

mm_metric = ...

3883

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

3834

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

3884

end

3835

end

3885

[~, mm_cursor_offset] = min(mm_metric);

3836

[~, mm_cursor_offset] = min(mm_metric);

3886

3837

3887

%cursor_i = the sample location

3838

%cursor_i = the sample location

3888

cursor_i = zxi+mm_cursor_offset-1;

3839

cursor_i = zxi+mm_cursor_offset-1;

3889

function pdf=d_cpdf( binsize, values, probs)

3840

function pdf=d_cpdf( binsize, values, probs)

3890

% p=cpdf(type, ...)

3841

% p=cpdf(type, ...)

3891

%

3842

%

3892

% CPDF is a probability mass function for discrete distributions or an

3843

% CPDF is a probability mass function for discrete distributions or an

3893

% approxmation of a PDF for continuous distributions.

3844

% approxmation of a PDF for continuous distributions.

3894

%

3845

%

3895

% cpdf is internally normalized so that the sum of probabilities is 1

3846

% cpdf is internally normalized so that the sum of probabilities is 1

3896

% (regardless of bin size).

3847

% (regardless of bin size).

3897

3848

3898

% Internal fields:

3849

% Internal fields:

3899

% Min: *bin number* of minimum value.

3850

% Min: *bin number* of minimum value.

3900

% BinSize: size of PDF bins. Bin center is the representative value.

3851

% BinSize: size of PDF bins. Bin center is the representative value.

3901

% Vec: vector of probabilities per bin.

3852

% Vec: vector of probabilities per bin.

3902

3853

3903

%speed up for initializing empty pdf

3854

%speed up for initializing empty pdf

3904

if all(values==0)

3855

if all(values==0)

3905

pdf.BinSize=binsize;

3856

pdf.BinSize=binsize;

3906

pdf.Min=0;

3857

pdf.Min=0;

3907

pdf.y=1;

3858

pdf.y=1;

3908

pdf.x=0;

3859

pdf.x=0;

3909

return;

3860

return;

3910

end

3861

end

3911

3862

3912

if ~issorted(values)

3863

if ~issorted(values)

3913

[values,si]=sort(values);

3864

[values,si]=sort(values);

3914

probs=probs(si);

3865

probs=probs(si);

3915

end

3866

end

3916

values=binsize*round(values/binsize);

3867

values=binsize*round(values/binsize);

3917

t=(values(1):binsize:values(end));

3868

t=(values(1):binsize:values(end));

3918

pdf.Min=values(1)/binsize;

3869

pdf.Min=values(1)/binsize;

3919

pdf.y=zeros(size(t));

3870

pdf.y=zeros(size(t));

3920

for k=1:length(values)

3871

for k=1:length(values)

3921

if k==1

3872

if k==1

3922

bin=1;

3873

bin=1;

3923

elseif k==length(values)

3874

elseif k==length(values)

3924

bin=length(t);

3875

bin=length(t);

3925

else

3876

else

3926

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

3877

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

3927

end

3878

end

3928

pdf.y(bin) = pdf.y(bin)+probs(k);

3879

pdf.y(bin) = pdf.y(bin)+probs(k);

3929

end

3880

end

3930

3881

3931

pdf.BinSize=binsize;

3882

pdf.BinSize=binsize;

3932

pdf.y=pdf.y/sum(pdf.y);

3883

pdf.y=pdf.y/sum(pdf.y);

3933

if any(~isreal(pdf.y)) || any(pdf.y<0)

3884

if any(~isreal(pdf.y)) || any(pdf.y<0)

3934

error('PDF must be real and nonnegative');

3885

error('PDF must be real and nonnegative');

3935

end

3886

end

3936

support=find(pdf.y);

3887

support=find(pdf.y);

3937

pdf.y=pdf.y(support(1):support(end));

3888

pdf.y=pdf.y(support(1):support(end));

3938

pdf.Min=pdf.Min+(support(1)-1);

3889

pdf.Min=pdf.Min+(support(1)-1);

3939

pdf.x=(pdf.Min:-pdf.Min)*binsize;

3890

pdf.x=(pdf.Min:-pdf.Min)*binsize;

3940

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

3891

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

3941

3892

3942

if isrow(input)

3893

if isrow(input)

3943

max_threshold=max_threshold(:).';

3894

max_threshold=max_threshold(:).';

3944

min_threshold=min_threshold(:).';

3895

min_threshold=min_threshold(:).';

3945

else

3896

else

3946

max_threshold=max_threshold(:);

3897

max_threshold=max_threshold(:);

3947

min_threshold=min_threshold(:);

3898

min_threshold=min_threshold(:);

3948

end

3899

end

3949

3900

3950

clip_output=input;

3901

clip_output=input;

3951

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

3902

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

3952

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

3903

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

3953

3904

3954

3905

3955

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

3906

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

3956

[ncases, mele]=size(param.z_p_tx_cases);

3907

[ncases, mele]=size(param.z_p_tx_cases);

3957

if mele ==2

3908

if mele ==2

3958

param.flex=2;

3909

param.flex=2;

3959

elseif mele==4

3910

elseif mele==4

3960

param.flex=4;

3911

param.flex=4;

3961

elseif mele==1

3912

elseif mele==1

3962

param.flex=1;

3913

param.flex=1;

3963

else

3914

else

3964

error(springf('config file syntax error'))

3915

error(springf('config file syntax error'))

3965

end

3916

end

3966

3917

3967

3918

3968

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

3919

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

3969

% display bathtub curves in one axis per test case.

3920

% display bathtub curves in one axis per test case.

3970

% h=findall(0, 'Name', 'COM results');

3921

% h=findall(0, 'Name', 'COM results');

3971

if ~exist('h','var')

3922

if ~exist('h','var')

3972

msgtext = cell(1, length(OP.pkg_len_select));

3923

msgtext = cell(1, length(OP.pkg_len_select));

3973

msgcolor = 'g';

3924

msgcolor = 'g';

3974

else

3925

else

3975

msgtext=get(findobj(h, 'type', 'text'), 'string');

3926

msgtext=get(findobj(h, 'type', 'text'), 'string');

3976

msgcolor = get(h, 'color');

3927

msgcolor = get(h, 'color');

3977

close(h); % will be recreated

3928

close(h); % will be recreated

3978

end

3929

end

3979

msgctr=size(msgtext,1)+1;

3930

msgctr=size(msgtext,1)+1;

3980

if ~OP.ERL_ONLY

3931

if ~OP.ERL_ONLY

3981

switch OP.PHY

3932

switch OP.PHY

3982

case 'C2M'

3933

case 'C2M'

3983

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

3934

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

3984

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

3935

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

3985

msg, VEO_mV);

3936

msg, VEO_mV);

3986

else

3937

else

3987

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

3938

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

3988

msg, VEO_mV);

3939

msg, VEO_mV);

3989

msgcolor = 'r';

3940

msgcolor = 'r';

3990

end

3941

end

3991

3942

3992

if VEC_dB <= param.VEC_pass_threshold

3943

if VEC_dB <= param.VEC_pass_threshold

3993

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

3944

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

3994

(msg), VEC_dB);

3945

(msg), VEC_dB);

3995

else

3946

else

3996

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

3947

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

3997

(msg), VEC_dB);

3948

(msg), VEC_dB);

3998

msgcolor = 'r';

3949

msgcolor = 'r';

3999

end

3950

end

4000

case 'C2C'

3951

case 'C2C'

4001

if COM >= param.pass_threshold

3952

if COM >= param.pass_threshold

4002

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

3953

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4003

% msg, COM);

3954

% msg, COM);

4004

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

3955

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4005

msg, COM);

3956

msg, COM);

4006

else

3957

else

4007

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

3958

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4008

% msg, COM);

3959

% msg, COM);

4009

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

3960

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4010

msg, COM);

3961

msg, COM);

4011

msgcolor = 'r';

3962

msgcolor = 'r';

4012

end

3963

end

4013

% begin yasuo patch 3/18/2019

3964

% begin yasuo patch 3/18/2019

4014

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

3965

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4015

% end yasuo patch

3966

% end yasuo patch

4016

case 'C2Mcom'

3967

case 'C2Mcom'

4017

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

3968

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4018

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

3969

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4019

msg, VEO_mV);

3970

msg, VEO_mV);

4020

else

3971

else

4021

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

3972

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4022

msg, VEO_mV);

3973

msg, VEO_mV);

4023

msgcolor = 'r';

3974

msgcolor = 'r';

4024

end

3975

end

4025

3976

4026

if VEC_dB <= param.VEC_pass_threshold

3977

if VEC_dB <= param.VEC_pass_threshold

4027

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

3978

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4028

(msg), VEC_dB);

3979

(msg), VEC_dB);

4029

else

3980

else

4030

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

3981

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4031

(msg), VEC_dB);

3982

(msg), VEC_dB);

4032

msgcolor = 'r';

3983

msgcolor = 'r';

4033

end

3984

end

4034

if COM >= param.pass_threshold

3985

if COM >= param.pass_threshold

4035

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

3986

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4036

% msg, COM);

3987

% msg, COM);

4037

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

3988

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4038

msg, COM);

3989

msg, COM);

4039

else

3990

else

4040

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

3991

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4041

% msg, COM);

3992

% msg, COM);

4042

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

3993

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4043

msg, COM);

3994

msg, COM);

4044

msgcolor = 'r';

3995

msgcolor = 'r';

4045

end

3996

end

4046

% begin yasuo patch 3/18/2019

3997

% begin yasuo patch 3/18/2019

4047

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

3998

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4048

% end yasuo patch

3999

% end yasuo patch

4049

end

4000

end

4050

end

4001

end

4051

if OP.ERL

4002

if OP.ERL

4052

if ~isempty(ERL)

4003

if ~isempty(ERL)

4053

if min_ERL >= param.ERL_pass_threshold

4004

if min_ERL >= param.ERL_pass_threshold

4054

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4005

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4055

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4006

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4056

else

4007

else

4057

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4008

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4058

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4009

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4059

msgcolor = 'r';

4010

msgcolor = 'r';

4060

end

4011

end

4061

end

4012

end

4062

end

4013

end

4063

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4014

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4064

set(h, 'color', msgcolor, 'tag', 'COM');

4015

set(h, 'color', msgcolor, 'tag', 'COM');

4065

movegui(h, 'center');

4016

movegui(h, 'center');

4066

else % no windows

4017

else % no windows

4067

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4018

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4068

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4019

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4069

if ~OP.ERL_ONLY

4020

if ~OP.ERL_ONLY

4070

switch OP.PHY

4021

switch OP.PHY

4071

case 'C2C'

4022

case 'C2C'

4072

if COM >= param.pass_threshold

4023

if COM >= param.pass_threshold

4073

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4024

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4074

else

4025

else

4075

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4026

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4076

end

4027

end

4077

% begin yasuo patch 3/18/2019

4028

% begin yasuo patch 3/18/2019

4078

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4029

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4079

% end yasuo patch

4030

% end yasuo patch

4080

case 'C2Mcom'

4031

case 'C2Mcom'

4081

if VEC_dB <= param.VEC_pass_threshold

4032

if VEC_dB <= param.VEC_pass_threshold

4082

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4033

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4083

else

4034

else

4084

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4035

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4085

end

4036

end

4086

4037

4087

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4038

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4088

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4039

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4089

else

4040

else

4090

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4041

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4091

end

4042

end

4092

if COM >= param.pass_threshold

4043

if COM >= param.pass_threshold

4093

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4044

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4094

else

4045

else

4095

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4046

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4096

end

4047

end

4097

% begin yasuo patch 3/18/2019

4048

% begin yasuo patch 3/18/2019

4098

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4049

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4099

% end yasuo patch

4050

% end yasuo patch

4100

case 'C2M'

4051

case 'C2M'

4101

if VEC_dB <= param.VEC_pass_threshold

4052

if VEC_dB <= param.VEC_pass_threshold

4102

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4053

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4103

else

4054

else

4104

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4055

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4105

end

4056

end

4106

4057

4107

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4058

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4108

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4059

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4109

else

4060

else

4110

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4061

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4111

end

4062

end

4112

end

4063

end

4113

end

4064

end

4114

if OP.ERL

4065

if OP.ERL

4115

if ~isempty(ERL)

4066

if ~isempty(ERL)

4116

if min_ERL >= param.ERL_pass_threshold

4067

if min_ERL >= param.ERL_pass_threshold

4117

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4068

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4118

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4069

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4119

else

4070

else

4120

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4071

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4121

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4072

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4122

end

4073

end

4123

end

4074

end

4124

end

4075

end

4125

end

4076

end

4126

4077

4127

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4078

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4128

4079

4129

%Left eye Width (Top Eye)

4080

%Left eye Width (Top Eye)

4130

left_top=eye_contour(half_UI:-1:1,1);

4081

left_top=eye_contour(half_UI:-1:1,1);

4131

%vref_crossing is the first point less than vref (usually first point < 0)

4082

%vref_crossing is the first point less than vref (usually first point < 0)

4132

vref_crossing=find(left_top<vref,1,'first');

4083

vref_crossing=find(left_top<vref,1,'first');

4133

if isempty(vref_crossing)

4084

if isempty(vref_crossing)

4134

%this case handles completely open eye

4085

%this case handles completely open eye

4135

L1=half_UI;

4086

L1=half_UI;

4136

elseif vref_crossing==1

4087

elseif vref_crossing==1

4137

%this case handles completely closed eye

4088

%this case handles completely closed eye

4138

L1=0;

4089

L1=0;

4139

else

4090

else

4140

%this case handles the normal eye

4091

%this case handles the normal eye

4141

%INT is a linear interpolation between the 2 points on either side of

4092

%INT is a linear interpolation between the 2 points on either side of

4142

%vref to determine where the vref crossing occurred. In systems with

4093

%vref to determine where the vref crossing occurred. In systems with

4143

%a small number of samples_per_UI, interpolation improves accuracy over

4094

%a small number of samples_per_UI, interpolation improves accuracy over

4144

%just using the integer sample point

4095

%just using the integer sample point

4145

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4096

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4146

L1=half_UI-INT;

4097

L1=half_UI-INT;

4147

end

4098

end

4148

%Left eye Width (Bottom Eye)

4099

%Left eye Width (Bottom Eye)

4149

left_bot=eye_contour(half_UI:-1:1,2);

4100

left_bot=eye_contour(half_UI:-1:1,2);

4150

vref_crossing=find(left_bot>vref,1,'first');

4101

vref_crossing=find(left_bot>vref,1,'first');

4151

if isempty(vref_crossing)

4102

if isempty(vref_crossing)

4152

L0=half_UI;

4103

L0=half_UI;

4153

elseif vref_crossing==1

4104

elseif vref_crossing==1

4154

L0=0;

4105

L0=0;

4155

else

4106

else

4156

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4107

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4157

L0=half_UI-INT;

4108

L0=half_UI-INT;

4158

end

4109

end

4159

%Right eye Width (Top Eye)

4110

%Right eye Width (Top Eye)

4160

right_top=eye_contour(half_UI:end,1);

4111

right_top=eye_contour(half_UI:end,1);

4161

vref_crossing=find(right_top<vref,1,'first');

4112

vref_crossing=find(right_top<vref,1,'first');

4162

if isempty(vref_crossing)

4113

if isempty(vref_crossing)

4163

R1=samples_per_UI-half_UI;

4114

R1=samples_per_UI-half_UI;

4164

elseif vref_crossing==1

4115

elseif vref_crossing==1

4165

R1=0;

4116

R1=0;

4166

else

4117

else

4167

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4118

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4168

R1=INT-half_UI;

4119

R1=INT-half_UI;

4169

end

4120

end

4170

%Right eye Width (Bottom Eye)

4121

%Right eye Width (Bottom Eye)

4171

right_bot=eye_contour(half_UI:end,2);

4122

right_bot=eye_contour(half_UI:end,2);

4172

vref_crossing=find(right_bot>vref,1,'first');

4123

vref_crossing=find(right_bot>vref,1,'first');

4173

if isempty(vref_crossing)

4124

if isempty(vref_crossing)

4174

R0=samples_per_UI-half_UI;

4125

R0=samples_per_UI-half_UI;

4175

elseif vref_crossing==1

4126

elseif vref_crossing==1

4176

R0=0;

4127

R0=0;

4177

else

4128

else

4178

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4129

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4179

R0=INT-half_UI;

4130

R0=INT-half_UI;

4180

end

4131

end

4181

4132

4182

%L1 = top left eye width

4133

%L1 = top left eye width

4183

%L0 = bottom left eye width

4134

%L0 = bottom left eye width

4184

%Left eye width is the minimum

4135

%Left eye width is the minimum

4185

%R1 = top right eye width

4136

%R1 = top right eye width

4186

%R0 = bottom right eye width

4137

%R0 = bottom right eye width

4187

%Right eye width is the minimum

4138

%Right eye width is the minimum

4188

Left_EW=min([L1 L0]);

4139

Left_EW=min([L1 L0]);

4189

Right_EW=min([R1 R0]);

4140

Right_EW=min([R1 R0]);

4190

4141

4191

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4142

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4192

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4143

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4193

% find the location of the DFE bank

4144

% find the location of the DFE bank

4194

% hisi: waveform with cursor values;

4145

% hisi: waveform with cursor values;

4195

% idx_st: starting index;

4146

% idx_st: starting index;

4196

% idx_en: ending index ;

4147

% idx_en: ending index ;

4197

% tap_bk: number of taps per bank;

4148

% tap_bk: number of taps per bank;

4198

% bmaxg: maximum coefficient;

4149

% bmaxg: maximum coefficient;

4199

4150

4200

hisi=hisi(:);

4151

hisi=hisi(:);

4201

len=idx_en-idx_st+1;

4152

len=idx_en-idx_st+1;

4202

h0=abs(hisi(idx_st:idx_en));

4153

h0=abs(hisi(idx_st:idx_en));

4203

h1=max(0,h0-bmaxg*curval);

4154

h1=max(0,h0-bmaxg*curval);

4204

4155

4205

%if cursor value is negative, force h1 to all zeros

4156

%if cursor value is negative, force h1 to all zeros

4206

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4157

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4207

%this makes the weakest isi the most desirable to choose so everything breaks

4158

%this makes the weakest isi the most desirable to choose so everything breaks

4208

if curval<0

4159

if curval<0

4209

h1=zeros(size(h0));

4160

h1=zeros(size(h0));

4210

end

4161

end

4211

4162

4212

h0n=zeros(len-tap_bk+1,1);

4163

h0n=zeros(len-tap_bk+1,1);

4213

h1n=h0n;

4164

h1n=h0n;

4214

4165

4215

for ii=1:tap_bk

4166

for ii=1:tap_bk

4216

h0tmp=h0(ii:ii+len-tap_bk);

4167

h0tmp=h0(ii:ii+len-tap_bk);

4217

h0n=h0n+h0tmp.^2;

4168

h0n=h0n+h0tmp.^2;

4218

h1tmp=h1(ii:ii+len-tap_bk);

4169

h1tmp=h1(ii:ii+len-tap_bk);

4219

h1n=h1n+h1tmp.^2;

4170

h1n=h1n+h1tmp.^2;

4220

end

4171

end

4221

4172

4222

ndiff=h0n-h1n;

4173

ndiff=h0n-h1n;

4223

4174

4224

min_energy = -Inf;

4175

min_energy = -Inf;

4225

4176

4226

idx=zeros(1,tap_bk*N_bg);

4177

idx=zeros(1,tap_bk*N_bg);

4227

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4178

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4228

set_next_bank=0;

4179

set_next_bank=0;

4229

%Loop through each group

4180

%Loop through each group

4230

for k=1:N_bg

4181

for k=1:N_bg

4231

%Sort to choose the strongest

4182

%Sort to choose the strongest

4232

[~,val_sort]=sort(ndiff,'descend');

4183

[~,val_sort]=sort(ndiff,'descend');

4233

if k==1

4184

if k==1

4234

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4185

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4235

if isequal(sort(val_sort(ordered_set)),ordered_set)

4186

if isequal(sort(val_sort(ordered_set)),ordered_set)

4236

idx=1:N_bg*tap_bk;

4187

idx=1:N_bg*tap_bk;

4237

break;

4188

break;

4238

end

4189

end

4239

end

4190

end

4240

if set_next_bank>0

4191

if set_next_bank>0

4241

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4192

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4242

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4193

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4243

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4194

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4244

set_next_bank=0;

4195

set_next_bank=0;

4245

ndiff(new_bank)=min_energy;

4196

ndiff(new_bank)=min_energy;

4246

bad_start=new_bank(1)-tap_bk+1;

4197

bad_start=new_bank(1)-tap_bk+1;

4247

bad_end=new_bank(1)-1;

4198

bad_end=new_bank(1)-1;

4248

if bad_end<=0

4199

if bad_end<=0

4249

badV=[];

4200

badV=[];

4250

elseif bad_start>0

4201

elseif bad_start>0

4251

badV=bad_start:bad_end;

4202

badV=bad_start:bad_end;

4252

else

4203

else

4253

badV=1:bad_end;

4204

badV=1:bad_end;

4254

end

4205

end

4255

if ~isempty(badV)

4206

if ~isempty(badV)

4256

ndiff(badV)=min_energy;

4207

ndiff(badV)=min_energy;

4257

end

4208

end

4258

continue;

4209

continue;

4259

end

4210

end

4260

%potential bank = the strongest tap group

4211

%potential bank = the strongest tap group

4261

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4212

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4262

if k==N_bg

4213

if k==N_bg

4263

%Last group: just choose the strongest

4214

%Last group: just choose the strongest

4264

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4215

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4265

break;

4216

break;

4266

end

4217

end

4267

4218

4268

do_it_again=1;

4219

do_it_again=1;

4269

first_time=1;

4220

first_time=1;

4270

num_loops=0;

4221

num_loops=0;

4271

while do_it_again

4222

while do_it_again

4272

do_it_again=0;

4223

do_it_again=0;

4273

if num_loops>length(ndiff)

4224

if num_loops>length(ndiff)

4274

break;

4225

break;

4275

end

4226

end

4276

%note badV: taps smaller and less than 1 group away

4227

%note badV: taps smaller and less than 1 group away

4277

bad_start=new_bank(1)-tap_bk+1;

4228

bad_start=new_bank(1)-tap_bk+1;

4278

bad_end=new_bank(1)-1;

4229

bad_end=new_bank(1)-1;

4279

if bad_end<=0

4230

if bad_end<=0

4280

badV=[];

4231

badV=[];

4281

elseif bad_start>0

4232

elseif bad_start>0

4282

badV=bad_start:bad_end;

4233

badV=bad_start:bad_end;

4283

else

4234

else

4284

badV=1:bad_end;

4235

badV=1:bad_end;

4285

end

4236

end

4286

for j=length(badV):-1:1

4237

for j=length(badV):-1:1

4287

if any(badV(j)-idx==0)

4238

if any(badV(j)-idx==0)

4288

badV(j)=[];

4239

badV(j)=[];

4289

end

4240

end

4290

end

4241

end

4291

%note goodV: the tap exactly 1 tap_bk smaller

4242

%note goodV: the tap exactly 1 tap_bk smaller

4292

goodV=new_bank(1)-tap_bk;

4243

goodV=new_bank(1)-tap_bk;

4293

if ~isempty(badV)

4244

if ~isempty(badV)

4294

if ~first_time

4245

if ~first_time

4295

[~,val_sort]=sort(ndiff,'descend');

4246

[~,val_sort]=sort(ndiff,'descend');

4296

end

4247

end

4297

first_time=0;

4248

first_time=0;

4298

checkV=[badV new_bank];

4249

checkV=[badV new_bank];

4299

4250

4300

badV_pos=zeros(1,length(badV));

4251

badV_pos=zeros(1,length(badV));

4301

for j=1:length(badV)

4252

for j=1:length(badV)

4302

badV_pos(j)=find(badV(j)==val_sort);

4253

badV_pos(j)=find(badV(j)==val_sort);

4303

end

4254

end

4304

4255

4305

%loop through the sorted list to find the first tap outside the group and not a member of badV

4256

%loop through the sorted list to find the first tap outside the group and not a member of badV

4306

found_goodV=0;

4257

found_goodV=0;

4307

for ii=1:length(val_sort)

4258

for ii=1:length(val_sort)

4308

if val_sort(ii)==goodV

4259

if val_sort(ii)==goodV

4309

found_goodV=1;

4260

found_goodV=1;

4310

break;

4261

break;

4311

end

4262

end

4312

if all(val_sort(ii)-checkV~=0)

4263

if all(val_sort(ii)-checkV~=0)

4313

break;

4264

break;

4314

end

4265

end

4315

end

4266

end

4316

4267

4317

if ~found_goodV && min(badV_pos)<ii

4268

if ~found_goodV && min(badV_pos)<ii

4318

%if goodV wasn't found and bad taps occur before non group members are found

4269

%if goodV wasn't found and bad taps occur before non group members are found

4319

%throw out the strongest tap and take the next strongest

4270

%throw out the strongest tap and take the next strongest

4320

do_it_again=1;

4271

do_it_again=1;

4321

ndiff(new_bank(1))=min_energy;

4272

ndiff(new_bank(1))=min_energy;

4322

%speed up: new max_val is always val_sort(2)

4273

%speed up: new max_val is always val_sort(2)

4323

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4274

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4324

end

4275

end

4325

if found_goodV

4276

if found_goodV

4326

%if goodV was found, set the next bank to goodV

4277

%if goodV was found, set the next bank to goodV

4327

set_next_bank=goodV;

4278

set_next_bank=goodV;

4328

end

4279

end

4329

end

4280

end

4330

num_loops=num_loops+1;

4281

num_loops=num_loops+1;

4331

end

4282

end

4332

%at the end, the floating taps are set to idx

4283

%at the end, the floating taps are set to idx

4333

%and ndiff has illegal values set to zero

4284

%and ndiff has illegal values set to zero

4334

ndiff(new_bank)=min_energy;

4285

ndiff(new_bank)=min_energy;

4335

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4286

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4336

if ~isempty(badV)

4287

if ~isempty(badV)

4337

ndiff(badV)=min_energy;

4288

ndiff(badV)=min_energy;

4338

end

4289

end

4339

end

4290

end

4340

4291

4341

4292

4342

idx=idx+idx_st-1;

4293

idx=idx+idx_st-1;

4343

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4294

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4344

4295

4345

% hisi = postcursor isi

4296

% hisi = postcursor isi

4346

% N_b = number of fixed dfe taps (before floating taps begin)

4297

% N_b = number of fixed dfe taps (before floating taps begin)

4347

% N_bf = number of floating taps per group

4298

% N_bf = number of floating taps per group

4348

% N_bg = nubmber of groups

4299

% N_bg = nubmber of groups

4349

% N_bmax = max tap number that can be used for floating tap

4300

% N_bmax = max tap number that can be used for floating tap

4350

% bmaxg = max tap strength for floating taps

4301

% bmaxg = max tap strength for floating taps

4351

% curval = value of the cursor

4302

% curval = value of the cursor

4352

4303

4353

4304

4354

if nargin<8, dfe_delta=0;end

4305

if nargin<8, dfe_delta=0;end

4355

4306

4356

4307

4357

tap_coef=zeros(1,length(hisi));

4308

tap_coef=zeros(1,length(hisi));

4358

b=zeros(1,length(hisi));

4309

b=zeros(1,length(hisi));

4359

4310

4360

4311

4361

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4312

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4362

4313

4363

%Apply DFE to all taps

4314

%Apply DFE to all taps

4364

flt_curval=hisi(tap_loc);

4315

flt_curval=hisi(tap_loc);

4365

if dfe_delta~=0

4316

if dfe_delta~=0

4366

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4317

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4367

dfe_delta.*sign(flt_curval)*curval;

4318

dfe_delta.*sign(flt_curval)*curval;

4368

else

4319

else

4369

flt_curval_q=hisi(tap_loc);

4320

flt_curval_q=hisi(tap_loc);

4370

end

4321

end

4371

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4322

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4372

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4323

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4373

tap_coef(tap_loc)=applied_coef;

4324

tap_coef(tap_loc)=applied_coef;

4374

4325

4375

4326

4376

4327

4377

tap_loc=sort(tap_loc,'ascend');

4328

tap_loc=sort(tap_loc,'ascend');

4378

b(tap_loc)=bmaxg;

4329

b(tap_loc)=bmaxg;

4379

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4330

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4380

% Richard Mellitz: 04/23/2019

4331

% Richard Mellitz: 04/23/2019

4381

% hisi is the isi 1 ui/sample

4332

% hisi is the isi 1 ui/sample

4382

% N_b number of fixed dfe taps

4333

% N_b number of fixed dfe taps

4383

% N_bf number of floating taps per group

4334

% N_bf number of floating taps per group

4384

% N_bg number of floating tap groups. 1 2 or 3 right now

4335

% N_bg number of floating tap groups. 1 2 or 3 right now

4385

% N_bmax number of ui for the max reach of the floating taps

4336

% N_bmax number of ui for the max reach of the floating taps

4386

% bmaxg limit for the floating taps

4337

% bmaxg limit for the floating taps

4387

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4338

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4388

%

4339

%

4389

%

4340

%

4390

% function to remove isi or add noise above bmaxg

4341

% function to remove isi or add noise above bmaxg

4391

if ~exist('COOP','var'), COOP=0;end

4342

if ~exist('COOP','var'), COOP=0;end

4392

if iscolumn(hisi); hisi=hisi.';end

4343

if iscolumn(hisi); hisi=hisi.';end

4393

hsis_in=hisi;

4344

hsis_in=hisi;

4394

% find all the reduction group taken N_bf at a time

4345

% find all the reduction group taken N_bf at a time

4395

% we are looking for the group when when remove yield the miminim isi, h, power

4346

% we are looking for the group when when remove yield the miminim isi, h, power

4396

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4347

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4397

% add on switch and loop for each potential group

4348

% add on switch and loop for each potential group

4398

switch N_bg

4349

switch N_bg

4399

case 0

4350

case 0

4400

bmax=0;

4351

bmax=0;

4401

return

4352

return

4402

case 1

4353

case 1

4403

end1=N_bmax-N_bf;

4354

end1=N_bmax-N_bf;

4404

end2=N_b+1;

4355

end2=N_b+1;

4405

end3=N_b+1;

4356

end3=N_b+1;

4406

case 2

4357

case 2

4407

end1=N_bmax-N_bf;

4358

end1=N_bmax-N_bf;

4408

end2=N_bmax-N_bf;

4359

end2=N_bmax-N_bf;

4409

end3=N_b+1;

4360

end3=N_b+1;

4410

case 3

4361

case 3

4411

end1=N_bmax-N_bf;

4362

end1=N_bmax-N_bf;

4412

end2=N_bmax-N_bf;

4363

end2=N_bmax-N_bf;

4413

end3=N_bmax-N_bf;

4364

end3=N_bmax-N_bf;

4414

end

4365

end

4415

if COOP

4366

if COOP

4416

for ig1= N_b+1:end1 % now remove the 2nd group

4367

for ig1= N_b+1:end1 % now remove the 2nd group

4417

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4368

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4418

% loop for 2rd group

4369

% loop for 2rd group

4419

for ig2= N_b+1: end2

4370

for ig2= N_b+1: end2

4420

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4371

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4421

if N_bg < 2; hcap2 =hcap; end

4372

if N_bg < 2; hcap2 =hcap; end

4422

for ig3= N_b+1: end3

4373

for ig3= N_b+1: end3

4423

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4374

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4424

if N_bg < 3 ; hcap3=hcap2 ; end

4375

if N_bg < 3 ; hcap3=hcap2 ; end

4425

sigma=norm( hcap3 );

4376

sigma=norm( hcap3 );

4426

if sigma < best_sigma

4377

if sigma < best_sigma

4427

best_sigma=sigma;

4378

best_sigma=sigma;

4428

best_ig1=ig1;

4379

best_ig1=ig1;

4429

best_ig2=ig2;

4380

best_ig2=ig2;

4430

best_ig3=ig3;

4381

best_ig3=ig3;

4431

best_hcap=hcap3;

4382

best_hcap=hcap3;

4432

end

4383

end

4433

end

4384

end

4434

end

4385

end

4435

end

4386

end

4436

else % sequentail

4387

else % sequentail

4437

for ig1= N_b+1:end1 % now remove the 1st group

4388

for ig1= N_b+1:end1 % now remove the 1st group

4438

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4389

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4439

sigma=norm( hcap );

4390

sigma=norm( hcap );

4440

if sigma < best_sigma

4391

if sigma < best_sigma

4441

best_sigma=sigma;

4392

best_sigma=sigma;

4442

best_ig1=ig1;

4393

best_ig1=ig1;

4443

best_hcap=hcap;

4394

best_hcap=hcap;

4444

end

4395

end

4445

end

4396

end

4446

% loop for 2rd group

4397

% loop for 2rd group

4447

hisi=best_hcap;

4398

hisi=best_hcap;

4448

for ig2= N_b+1: end2

4399

for ig2= N_b+1: end2

4449

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4400

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4450

sigma=norm( hcap );

4401

sigma=norm( hcap );

4451

if sigma < best_sigma

4402

if sigma < best_sigma

4452

best_sigma=sigma;

4403

best_sigma=sigma;

4453

best_ig2=ig2;

4404

best_ig2=ig2;

4454

best_hcap=hcap;

4405

best_hcap=hcap;

4455

end

4406

end

4456

end

4407

end

4457

hisi=best_hcap;

4408

hisi=best_hcap;

4458

% loop for 3rd group

4409

% loop for 3rd group

4459

for ig3= N_b+1: end3

4410

for ig3= N_b+1: end3

4460

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4411

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4461

sigma=norm( hcap );

4412

sigma=norm( hcap );

4462

if sigma < best_sigma

4413

if sigma < best_sigma

4463

best_sigma=sigma;

4414

best_sigma=sigma;

4464

best_ig3=ig3;

4415

best_ig3=ig3;

4465

best_hcap=hcap;

4416

best_hcap=hcap;

4466

end

4417

end

4467

end

4418

end

4468

4419

4469

end

4420

end

4470

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4421

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4471

switch N_bg

4422

switch N_bg

4472

case 1

4423

case 1

4473

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4424

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4474

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4425

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4475

case 2

4426

case 2

4476

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4427

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4477

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4428

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4478

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4429

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4479

case 3

4430

case 3

4480

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4431

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4481

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4432

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4482

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4433

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4483

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4434

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4484

end

4435

end

4485

floating_tap_locations=sort(floating_tap_locations);

4436

floating_tap_locations=sort(floating_tap_locations);

4486

if 0 % for code debug

4437

if 0 % for code debug

4487

close force all

4438

close force all

4488

stem(best_hcap,'disp','hcap')

4439

stem(best_hcap,'disp','hcap')

4489

hold on

4440

hold on

4490

stem(bmax,'-k','disp','bmax')

4441

stem(bmax,'-k','disp','bmax')

4491

stem(hisi,'disp','hisi')

4442

stem(hisi,'disp','hisi')

4492

hold off

4443

hold off

4493

end

4444

end

4494

4445

4495

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4446

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4496

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4447

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4497

% Vfilter is vector forced filtered sbr

4448

% Vfilter is vector forced filtered sbr

4498

% Cmod is the ffe tap co-efficient vector

4449

% Cmod is the ffe tap co-efficient vector

4499

% if C is passed, just process V with C else compute C

4450

% if C is passed, just process V with C else compute C

4500

% cmx=param.rx_cmx; number of pre cursor taps

4451

% cmx=param.rx_cmx; number of pre cursor taps

4501

% cpx=param.rx_cps; number of post cursor taps

4452

% cpx=param.rx_cps; number of post cursor taps

4502

% V=sbr; pass pulse response

4453

% V=sbr; pass pulse response

4503

% ix the sample point in the passed pulse response

4454

% ix the sample point in the passed pulse response

4504

% the sample point is recomputed by optimize_fom

4455

% the sample point is recomputed by optimize_fom

4505

% idx - return floating tap location (RIM 9-19-2023)

4456

% idx - return floating tap location (RIM 9-19-2023)

4506

% OP not used for now

4457

% OP not used for now

4507

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4458

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4508

% this allows significant speed up in optimize_fom since FFE is time consuming

4459

% this allows significant speed up in optimize_fom since FFE is time consuming

4509

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4460

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4510

% Vfiltered to be calculated

4461

% Vfiltered to be calculated

4511

% test with load('SBR_FIR_resp.mydata','-mat')

4462

% test with load('SBR_FIR_resp.mydata','-mat')

4512

idx=[];

4463

idx=[];

4513

if nargin<4

4464

if nargin<4

4514

ix=find(V==max(V),1,'first');

4465

ix=find(V==max(V),1,'first');

4515

end

4466

end

4516

if nargin<5

4467

if nargin<5

4517

C=[];

4468

C=[];

4518

end

4469

end

4519

if nargin<6

4470

if nargin<6

4520

return_V=1;

4471

return_V=1;

4521

end

4472

end

4522

cmx=param.RxFFE_cmx;

4473

cmx=param.RxFFE_cmx;

4523

cpx=param.RxFFE_cpx;

4474

cpx=param.RxFFE_cpx;

4524

% do this early on so we can reuse the old code

4475

% do this early on so we can reuse the old code

4525

if param.N_bg ~=0 % must be floating taps

4476

if param.N_bg ~=0 % must be floating taps

4526

cpx=param.N_bmax; % N_f in spreadsheet

4477

cpx=param.N_bmax; % N_f in spreadsheet

4527

end

4478

end

4528

num_taps=cmx+cpx+1;

4479

num_taps=cmx+cpx+1;

4529

cstep=param.RxFFE_stepz;

4480

cstep=param.RxFFE_stepz;

4530

ndfe=param.ndfe;

4481

ndfe=param.ndfe;

4531

spui=param.samples_per_ui;

4482

spui=param.samples_per_ui;

4532

param.current_ffegain=0;

4483

param.current_ffegain=0;

4533

if return_V && ~isempty(C)

4484

if return_V && ~isempty(C)

4534

% RIM 2-3-23 when we just want to EQ not find EQ

4485

% RIM 2-3-23 when we just want to EQ not find EQ

4535

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4486

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4536

Cmod=C;

4487

Cmod=C;

4537

return

4488

return

4538

end

4489

end

4539

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4490

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4540

if ix < length(V)

4491

if ix < length(V)

4541

if isrow(V)

4492

if isrow(V)

4542

if mod(ix,spui) == 0

4493

if mod(ix,spui) == 0

4543

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4494

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4544

else

4495

else

4545

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4496

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4546

end

4497

end

4547

4498

4548

else

4499

else

4549

if mod(ix,spui) == 0

4500

if mod(ix,spui) == 0

4550

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4501

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4551

else

4502

else

4552

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4503

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4553

end

4504

end

4554

end

4505

end

4555

else

4506

else

4556

if isrow(V)

4507

if isrow(V)

4557

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4508

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4558

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4509

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4559

else

4510

else

4560

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4511

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4561

end

4512

end

4562

else

4513

else

4563

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4514

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4564

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4515

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4565

else

4516

else

4566

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4517

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4567

end

4518

end

4568

end

4519

end

4569

end

4520

end

4570

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4521

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4571

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4522

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4572

4523

4573

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4524

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4574

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4525

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4575

% Upen Kareti suggested fix for indexing 11/04/18

4526

% Upen Kareti suggested fix for indexing 11/04/18

4576

if ix < length(V)

4527

if ix < length(V)

4577

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4528

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4578

else

4529

else

4579

ivs=find(vsampled == max(vsampled),1,'first');

4530

ivs=find(vsampled == max(vsampled),1,'first');

4580

end

4531

end

4581

4532

4582

4533

4583

%% create VV matrix of shifted UI spaced sample of the pulse response

4534

%% create VV matrix of shifted UI spaced sample of the pulse response

4584

% only consider the VV matrix that correstonds to the FFE taps

4535

% only consider the VV matrix that correstonds to the FFE taps

4585

VV=zeros(num_taps,num_taps);

4536

VV=zeros(num_taps,num_taps);

4586

for i=1:num_taps

4537

for i=1:num_taps

4587

start_idx=ivs+i-1;

4538

start_idx=ivs+i-1;

4588

end_idx=start_idx-num_taps+1;

4539

end_idx=start_idx-num_taps+1;

4589

VV(:,i)=vsampled(start_idx:-1:end_idx);

4540

VV(:,i)=vsampled(start_idx:-1:end_idx);

4590

end

4541

end

4591

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4542

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4592

%% Apply RXFFE

4543

%% Apply RXFFE

4593

if isempty(C)

4544

if isempty(C)

4594

switch upper(OP.FFE_OPT_METHOD)

4545

switch upper(OP.FFE_OPT_METHOD)

4595

case 'WIENER-HOPF'

4546

case 'WIENER-HOPF'

4596

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4547

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4597

Cmod=C(1:num_taps);

4548

Cmod=C(1:num_taps);

4598

otherwise

4549

otherwise

4599

% cmx+1 is the cursor or sample point

4550

% cmx+1 is the cursor or sample point

4600

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4551

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4601

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4552

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4602

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4553

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4603

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4554

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4604

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4555

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4605

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4556

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4606

end

4557

end

4607

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4558

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4608

if diff(size(VV))==0

4559

if diff(size(VV))==0

4609

%For square matrix, can solve C using simple inv(VV')*FV'

4560

%For square matrix, can solve C using simple inv(VV')*FV'

4610

C=VV'\FV';

4561

C=VV'\FV';

4611

else

4562

else

4612

%otherwise use the general solution with psuedo inverse

4563

%otherwise use the general solution with psuedo inverse

4613

%note: this is the same as doing pinv(VV') but pinv is far slower

4564

%note: this is the same as doing pinv(VV') but pinv is far slower

4614

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4565

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4615

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4566

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4616

end

4567

end

4617

4568

4618

Cmod=C(1:num_taps);

4569

Cmod=C(1:num_taps);

4619

end

4570

end

4620

4571

4621

4572

4622

% added for 4.2 find floating taps with either ISI or taps

4573

% added for 4.2 find floating taps with either ISI or taps

4623

switch lower(OP.RXFFE_FLOAT_CTL)

4574

switch lower(OP.RXFFE_FLOAT_CTL)

4624

case 'taps'

4575

case 'taps'

4625

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4576

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4626

otherwise

4577

otherwise

4627

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4578

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4628

end

4579

end

4629

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4580

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4630

case 'unity cursor'

4581

case 'unity cursor'

4631

Cmod=Cmod/Cmod(cmx+1);

4582

Cmod=Cmod/Cmod(cmx+1);

4632

otherwise

4583

otherwise

4633

Cmod=C;

4584

Cmod=C;

4634

end

4585

end

4635

if cstep ~= 0

4586

if cstep ~= 0

4636

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4587

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4637

end

4588

end

4638

4589

4639

if ~isempty(idx)

4590

if ~isempty(idx)

4640

idx=sort(idx);

4591

idx=sort(idx);

4641

C1=Cmod;

4592

C1=Cmod;

4642

% C1(param.N_tail_start:end)=0;

4593

% C1(param.N_tail_start:end)=0;

4643

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4594

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4644

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4595

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4645

Cmod=C1;

4596

Cmod=C1;

4646

else

4597

else

4647

% Cmod=C;

4598

% Cmod=C;

4648

end

4599

end

4649

4600

4650

% now when ussing RxFFE floating taps need to tag stems correctly and

4601

% now when ussing RxFFE floating taps need to tag stems correctly and

4651

% make sure DFEfloating tap code does not get exectuted

4602

% make sure DFEfloating tap code does not get exectuted

4652

4603

4653

%

4604

%

4654

else

4605

else

4655

Cmod=C;%just us the FFE taps, C, passed for filtering

4606

Cmod=C;%just us the FFE taps, C, passed for filtering

4656

end

4607

end

4657

%%

4608

%%

4658

%% filter the pulse response with the solved FFE

4609

%% filter the pulse response with the solved FFE

4659

% (now option to avoid this and just return Cmod for speed up)

4610

% (now option to avoid this and just return Cmod for speed up)

4660

if return_V

4611

if return_V

4661

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4612

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4662

else

4613

else

4663

Vfiltered=[];

4614

Vfiltered=[];

4664

end

4615

end

4665

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4616

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4666

% used for FD IL fitting

4617

% used for FD IL fitting

4667

% sdd21 us a complex insertion loss

4618

% sdd21 us a complex insertion loss

4668

db = @(x) 20*log10(abs(x));

4619

db = @(x) 20*log10(abs(x));

4669

sdd21=squeeze(sdd21);

4620

sdd21=squeeze(sdd21);

4670

if iscolumn(sdd21)

4621

if iscolumn(sdd21)

4671

sdd21=sdd21.';

4622

sdd21=sdd21.';

4672

end

4623

end

4673

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)) ];

4624

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)) ];

4674

warning('off','MATLAB:nearlySingularMatrix');

4625

warning('off','MATLAB:nearlySingularMatrix');

4675

LGw=transpose(abs(sdd21).*db(sdd21));

4626

LGw=transpose(abs(sdd21).*db(sdd21));

4676

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4627

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4677

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4628

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4678

ILN = db(sdd21)-efit;

4629

ILN = db(sdd21)-efit;

4679

4630

4680

4631

4681

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4632

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4682

% Complex IL fitting

4633

% Complex IL fitting

4683

% sdd21 us a complex insertion loss

4634

% sdd21 us a complex insertion loss

4684

% efit and ILN are in db

4635

% efit and ILN are in db

4685

% faxix_f2 needs to be at least to fb

4636

% faxix_f2 needs to be at least to fb

4686

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

4637

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

4687

% still need to settle on voltage scaling.

4638

% still need to settle on voltage scaling.

4688

% maybe db(peak/Rss

4639

% maybe db(peak/Rss

4689

4640

4690

OP.interp_sparam_mag= 'trend_to_DC';

4641

OP.interp_sparam_mag= 'trend_to_DC';

4691

OP.interp_sparam_phase= 'interp_to_DC';

4642

OP.interp_sparam_phase= 'interp_to_DC';

4692

% OP.interp_sparam_mag= 'linear_trend_to_DC';

4643

% OP.interp_sparam_mag= 'linear_trend_to_DC';

4693

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

4644

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

4694

4645

4695

print_for_codereview=0;

4646

print_for_codereview=0;

4696

if ~exist('A_T','var')

4647

if ~exist('A_T','var')

4697

A_T=1;

4648

A_T=1;

4698

end

4649

end

4699

4650

4700

db = @(x) 20*log10(abs(x));

4651

db = @(x) 20*log10(abs(x));

4701

sdd21=squeeze(sdd21);

4652

sdd21=squeeze(sdd21);

4702

if iscolumn(sdd21)

4653

if iscolumn(sdd21)

4703

sdd21=sdd21.';

4654

sdd21=sdd21.';

4704

end

4655

end

4705

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) ];

4656

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) ];

4706

warning('off','MATLAB:nearlySingularMatrix');

4657

warning('off','MATLAB:nearlySingularMatrix');

4707

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

4658

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

4708

LGw=transpose(sdd21.*unwraplog);

4659

LGw=transpose(sdd21.*unwraplog);

4709

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4660

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4710

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4661

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4711

FIT=transpose(exp(transpose(efit_C)));

4662

FIT=transpose(exp(transpose(efit_C)));

4712

efit=db(abs(FIT));

4663

efit=db(abs(FIT));

4713

ILN = db(sdd21)-efit;

4664

ILN = db(sdd21)-efit;

4714

% time domain

4665

% time domain

4715

fprintf('computing TD_ILN (dB) ...')

4666

fprintf('computing TD_ILN (dB) ...')

4716

if exist('OP','var')

4667

if exist('OP','var')

4717

% OP.fraction_of_F_range_start_extrap_from=.95;

4668

% OP.fraction_of_F_range_start_extrap_from=.95;

4718

OP.impulse_response_truncation_threshold =1e-7;

4669

OP.impulse_response_truncation_threshold =1e-7;

4719

4670

4720

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

4671

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

4721

H_bw=Butterworth_Filter(param,faxis_f2,1);

4672

H_bw=Butterworth_Filter(param,faxis_f2,1);

4722

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

4673

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

4723

H_tw=Tukey_Window(faxis_f2,param);

4674

H_tw=Tukey_Window(faxis_f2,param);

4724

H_tw=ones(1,length(faxis_f2) );

4675

H_tw=ones(1,length(faxis_f2) );

4725

4676

4726

[TD_ILN.REF.FIR, ...

4677

[TD_ILN.REF.FIR, ...

4727

TD_ILN.REF.t, ...

4678

TD_ILN.REF.t, ...

4728

TD_ILN.REF.causality_correction_dB, ...

4679

TD_ILN.REF.causality_correction_dB, ...

4729

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4680

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4730

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

4681

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

4731

4682

4732

[TD_ILN.FIT.FIR, ...

4683

[TD_ILN.FIT.FIR, ...

4733

TD_ILN.FIT.t, ...

4684

TD_ILN.FIT.t, ...

4734

TD_ILN.FIT.causality_correction_dB, ...

4685

TD_ILN.FIT.causality_correction_dB, ...

4735

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4686

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4736

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

4687

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

4737

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

4688

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

4738

% NrangeUI=1000;

4689

% NrangeUI=1000;

4739

% 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);

4690

% 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);

4740

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

4691

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

4741

range=ipeak:range_end;

4692

range=ipeak:range_end;

4742

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

4693

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

4743

TD_ILN.t=TD_ILN.FIT.t(range);

4694

TD_ILN.t=TD_ILN.FIT.t(range);

4744

TD_ILN.FOM=-inf;

4695

TD_ILN.FOM=-inf;

4745

TD_ILN.FOM_PDF=-inf;

4696

TD_ILN.FOM_PDF=-inf;

4746

rms_fom=-inf;

4697

rms_fom=-inf;

4747

for im=1:param.samples_per_ui

4698

for im=1:param.samples_per_ui

4748

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

4699

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

4749

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

4700

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

4750

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

4701

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

4751

cdf=pdf; cdf.y=cumsum(pdf.y);

4702

cdf=pdf; cdf.y=cumsum(pdf.y);

4752

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

4703

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

4753

% signal_and_isi_pdf = conv_fct(cursors, pdf);

4704

% signal_and_isi_pdf = conv_fct(cursors, pdf);

4754

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

4705

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

4755

if print_for_codereview % remove once all checked out

4706

if print_for_codereview % remove once all checked out

4756

h=figure(190);set(gcf,'Tag','COM');

4707

h=figure(190);set(gcf,'Tag','COM');

4757

semilogy(-cdf.x,cdf.y);

4708

semilogy(-cdf.x,cdf.y);

4758

% xlim ([0,-cdf.x(1)])

4709

% xlim ([0,-cdf.x(1)])

4759

ylim([param.specBER 1]);title ('CDF of ILN')

4710

ylim([param.specBER 1]);title ('CDF of ILN')

4760

hold on

4711

hold on

4761

end

4712

end

4762

if rms>rms_fom

4713

if rms>rms_fom

4763

rms_fom=rms;

4714

rms_fom=rms;

4764

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

4715

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

4765

TD_ILN.PDF=pdf;

4716

TD_ILN.PDF=pdf;

4766

end

4717

end

4767

end

4718

end

4768

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

4719

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

4769

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

4720

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

4770

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

4721

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

4771

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

4722

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

4772

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

4723

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

4773

if print_for_codereview % remove once all checked out

4724

if print_for_codereview % remove once all checked out

4774

figure(9000);set(gcf,'Tag','COM');

4725

figure(9000);set(gcf,'Tag','COM');

4775

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

4726

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

4776

hold on

4727

hold on

4777

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

4728

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

4778

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

4729

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

4779

hold off

4730

hold off

4780

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)

4731

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)

4781

figure(9002);set(gcf,'Tag','COM');

4732

figure(9002);set(gcf,'Tag','COM');

4782

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

4733

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

4783

hold on

4734

hold on

4784

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

4735

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

4785

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

4736

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

4786

grid on

4737

grid on

4787

legend('show')

4738

legend('show')

4788

end

4739

end

4789

end

4740

end

4790

% display('got to end of get_ILN_cmp_td')

4741

% display('got to end of get_ILN_cmp_td')

4791

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

4742

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

4792

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

4743

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

4793

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

4744

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

4794

if 1 % force indent for doc

4745

if 1 % force indent for doc

4795

num_ui=param.num_ui_RXFF_noise;

4746

num_ui=param.num_ui_RXFF_noise;

4796

M=param.samples_per_ui;

4747

M=param.samples_per_ui;

4797

L=param.levels;

4748

L=param.levels;

4798

f_b=param.fb;

4749

f_b=param.fb;

4799

SNR_TX=param.SNR_TX;

4750

SNR_TX=param.SNR_TX;

4800

dw=param.RxFFE_cmx;

4751

dw=param.RxFFE_cmx;

4801

bmax=param.bmax;

4752

bmax=param.bmax;

4802

bmin=param.bmin ;

4753

bmin=param.bmin ;

4803

Nb=param.ndfe;

4754

Nb=param.ndfe;

4804

sigma_X2=(L^2-1)/(3*(L-1)^2);

4755

sigma_X2=(L^2-1)/(3*(L-1)^2);

4805

eta_0=param.eta_0; %V^2/GHz

4756

eta_0=param.eta_0; %V^2/GHz

4806

T_b=1/f_b;

4757

T_b=1/f_b;

4807

delta_f = f_b/num_ui; % Units are Hz.

4758

delta_f = f_b/num_ui; % Units are Hz.

4808

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

4759

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

4809

result.fvec=fvec;

4760

result.fvec=fvec;

4810

end

4761

end

4811

if OP.COMPUTE_COM

4762

if OP.COMPUTE_COM

4812

%% H_rxffe eq 178A-28 d1.0

4763

%% H_rxffe eq 178A-28 d1.0

4813

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

4764

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

4814

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

4765

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

4815

H_rxffe=0;

4766

H_rxffe=0;

4816

for nn=1:length(result.w)

4767

for nn=1:length(result.w)

4817

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

4768

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

4818

end

4769

end

4819

H_rxffe_2_of_f=abs(H_rxffe).^2;

4770

H_rxffe_2_of_f=abs(H_rxffe).^2;

4820

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

4771

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

4821

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))];

4772

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))];

4822

else

4773

else

4823

H_rxffe_2=1;

4774

H_rxffe_2=1;

4824

end

4775

end

4825

result.H_rxffe_2=H_rxffe_2;% pass as output for compuation in healey_3dj_01_2409 slide 12

4776

result.H_rxffe_2=H_rxffe_2;% pass as output for compuation in healey_3dj_01_2409 slide 12

4826

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

4777

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

4827

% --->this is the point in the code may fork where we add extra rx noise

4778

% --->this is the point in the code may fork where we add extra rx noise

4828

%% compute S_rn ( eq 178A-15 d0.2 )

4779

%% compute S_rn ( eq 178A-15 d0.2 )

4829

if ~OP.COMPUTE_COM

4780

if ~OP.COMPUTE_COM

4830

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

4781

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

4831

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

4782

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

4832

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

4783

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

4833

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

4784

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

4834

S_rn = sum(reshape(rxn_psd, num_ui, M).');

4785

S_rn = sum(reshape(rxn_psd, num_ui, M).');

4835

S_rn=S_rn(1:num_ui/2+1);

4786

S_rn=S_rn(1:num_ui/2+1);

4836

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

4787

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

4837

result.S_rn=S_rn;

4788

result.S_rn=S_rn;

4838

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4789

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4839

else

4790

else

4840

result.S_rn=result.S_rn.*H_rxffe_2;

4791

result.S_rn=result.S_rn.*H_rxffe_2;

4841

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4792

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4842

end

4793

end

4843

4794

4844

else % find noise for item that set have tx ffe for each loop

4795

else % find noise for item that set have tx ffe for each loop

4845

%% S_xn from eq 178A-16

4796

%% S_xn from eq 178A-16

4846

%% Crosstalk power spectral density

4797

%% Crosstalk power spectral density

4847

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

4798

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

4848

result.S_xn=0;

4799

result.S_xn=0;

4849

if length(chdata)~=1

4800

if length(chdata)~=1

4850

for xchan=2:length(chdata)

4801

for xchan=2:length(chdata)

4851

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

4802

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

4852

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

4803

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

4853

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

4804

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

4854

% enable less UI for computation speed improvement

4805

% enable less UI for computation speed improvement

4855

%%

4806

%%

4856

if num_ui*M > length(pulse_ctle)

4807

if num_ui*M > length(pulse_ctle)

4857

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

4808

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

4858

else

4809

else

4859

hk(xchan).k=hk(xchan).k(1:num_ui*M);

4810

hk(xchan).k=hk(xchan).k(1:num_ui*M);

4860

end

4811

end

4861

for i1=1:M

4812

for i1=1:M

4862

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

4813

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

4863

end

4814

end

4864

iphase(xchan)=find(hxn==max(hxn));

4815

iphase(xchan)=find(hxn==max(hxn));

4865

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

4816

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

4866

result.hk(xchan).hrn= hk(xchan).hrn;

4817

result.hk(xchan).hrn= hk(xchan).hrn;

4867

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

4818

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

4868

result.S_xn=hk(xchan).S_xn+result.S_xn;

4819

result.S_xn=hk(xchan).S_xn+result.S_xn;

4869

end

4820

end

4870

result.S_xn=result.S_xn;

4821

result.S_xn=result.S_xn;

4871

result.hk=hk;

4822

result.hk=hk;

4872

result.iphase=iphase;

4823

result.iphase=iphase;

4873

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4824

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4874

else % if no crosstalk, perserve structure and return 0 for S_xn

4825

else % if no crosstalk, perserve structure and return 0 for S_xn

4875

result.S_xn=0;

4826

result.S_xn=0;

4876

result.hk=[];

4827

result.hk=[];

4877

result.iphase=1;

4828

result.iphase=1;

4878

result.S_xn_rms = 0;

4829

result.S_xn_rms = 0;

4879

end

4830

end

4880

else % adjust for H_rxffe when computing COM

4831

else % adjust for H_rxffe when computing COM

4881

result.S_xn=result.S_xn.*H_rxffe_2;

4832

result.S_xn=result.S_xn.*H_rxffe_2;

4882

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4833

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4883

end

4834

end

4884

%% S_tn from eq 178A-17

4835

%% S_tn from eq 178A-17

4885

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

4836

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

4886

%% Transmitter noise power spectral density

4837

%% Transmitter noise power spectral density

+4838

if ~OP.COMPUTE_COM

4887

if ~OP.TDMODE

4839

if ~OP.TDMODE

4888

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

4840

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

4889

else % only use when the input was a pulse response not s-parameters

4841

else % only use when the input was a pulse response not s-parameters

4890

if isfield(chdata(1),'ctle_pulse_response')

4842

if isfield(chdata(1),'ctle_pulse_response')

4891

htn=chdata(1).ctle_pulse_response;

4843

htn=chdata(1).ctle_pulse_response;

4892

else

4844

else

4893

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

4845

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

4894

end

4846

end

4895

end

4847

end

4896

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

4848

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

4897

htn=reshape(htn,1,[]); % make row vectors

4849

htn=reshape(htn,1,[]); % make row vectors

4898

htn=[ htn(1:floor(length(htn)/M)*M) ];

4850

htn=[ htn(1:floor(length(htn)/M)*M) ];

4899

htn= [htn zeros(1,num_ui*M-length(htn)) ];

4851

htn= [htn zeros(1,num_ui*M-length(htn)) ];

4900

htn=htn(1:M:end);% resample

4852

htn=htn(1:M:end);% resample

4901

if num_ui>length(htn)

4853

if num_ui>length(htn)

4902

hext=[htn zeros(1,num_ui-length(htn))];

4854

hext=[htn zeros(1,num_ui-length(htn))];

4903

else

4855

else

4904

hext=htn(1:num_ui);

4856

hext=htn(1:num_ui);

4905

end

4857

end

4906

if ~OP.COMPUTE_COM

4907

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

4858

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

4908

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4859

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4909

else

4860

else

4910

result.S_tn=result.S_tn.*H_rxffe_2;

4861

result.S_tn=result.S_tn.*H_rxffe_2;

4911

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4862

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4912

end

4863

end

4913

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

4864

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

4914

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

4865

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

4915

%% Power spectral density of noise due to jitter

4866

%% Power spectral density of noise due to jitter

4916

%% Eq. 93A-28 %%

4867

%% Eq. 93A-28 %%

4917

if ~OP.COMPUTE_COM

4868

if ~OP.COMPUTE_COM

4918

sampling_offset = mod(cursor_i, M);

4869

sampling_offset = mod(cursor_i, M);

4919

%ensure we can take early sample

4870

%ensure we can take early sample

4920

if sampling_offset<=1

4871

if sampling_offset<=1

4921

sampling_offset=sampling_offset+M;

4872

sampling_offset=sampling_offset+M;

4922

end

4873

end

4923

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

4874

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

4924

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

4875

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

4925

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

4876

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

4926

else

4877

else

4927

cursors_early_sample = h(sampling_offset-1:M:end);

4878

cursors_early_sample = h(sampling_offset-1:M:end);

4928

cursors_late_sample = h(sampling_offset+1:M:end);

4879

cursors_late_sample = h(sampling_offset+1:M:end);

4929

end

4880

end

4930

% ensure lengths are equal

4881

% ensure lengths are equal

4931

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

4882

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

4932

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

4883

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

4933

h_J=reshape(h_J,1,[]); % make row vectors

4884

h_J=reshape(h_J,1,[]); % make row vectors

4934

if num_ui>length(h_J)

4885

if num_ui>length(h_J)

4935

h_J=[h_J zeros(1,num_ui-length(h_J))];

4886

h_J=[h_J zeros(1,num_ui-length(h_J))];

4936

else

4887

else

4937

h_J=h_J(1:num_ui);

4888

h_J=h_J(1:num_ui);

4938

end

4889

end

4939

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4890

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4940

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4891

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4941

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4892

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4942

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4893

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4943

else

4894

else

4944

result.S_jn=result.S_jn.*H_rxffe_2;

4895

result.S_jn=result.S_jn.*H_rxffe_2;

4945

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4896

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4946

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

4897

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

4947

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4898

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4948

end

4899

end

4949

% result.S_qn

4900

% result.S_jnesult.S_rn

4950

if(param.N_qb ~=0)

4951

hext_txffe=filter(txffe,1,hext);

4952

sig_aftert_ctle_pdf = get_pdf_from_sampled_signal(hext_txffe,param.levels,OP.BinSize);

4953

noise_after_ctle_pdf = sig_aftert_ctle_pdf;

4954

sigma_noise = sqrt(result.S_rn_rms^2+result.S_xn_rms^2++result.S_tn_rms^2++result.S_rj_rms^2);

4955

noise_after_ctle_pdf.y = 1/(sqrt(2*pi)*sigma_noise)*exp(-noise_after_ctle_pdf.x.^2/(2*sigma_noise^2))*OP.BinSize;

4956

sig_noise_after_ctle_pdf= conv_fct(sig_aftert_ctle_pdf,noise_after_ctle_pdf);

4957

sig_noise_after_ctle_cdf = cumsum(sig_noise_after_ctle_pdf.y);

4958

ctle_signal_sigma = sqrt(sum((sig_noise_after_ctle_pdf.x.^2).*sig_noise_after_ctle_pdf.y));

4959

adc_clip=-CDF_inv_ev(param.P_qc, sig_noise_after_ctle_pdf,sig_noise_after_ctle_cdf);

4960

adc_lsb=2*adc_clip/(2^param.N_qb-1);

4961

sigma_Q=adc_lsb/sqrt(12);

4962

S_qn=sigma_Q^2/f_b*ones(size(hext));

4963

result.adc_clip=adc_clip;

4964

result.ctle_signal_sigma=ctle_signal_sigma;

4965

result.S_qn=S_qn;

4966

result.s_qn_rms=sqrt(sum(result.S_qn)*delta_f);

4967

if OP.INCLUDE_CTLE == 1

4968

eq_ir = TD_CTLE(chdata(1).uneq_imp_response, param.fb, param.CTLE_fz(1), param.CTLE_fp1(1), param.CTLE_fp2(1), G_DC, param.samples_per_ui);

4969

eq_ir = TD_CTLE(eq_ir, param.fb, param.f_HP(1), param.f_HP(1), 100e100 , G_DC2, param.samples_per_ui);

4970

else

4971

eq_ir = chdata(1).uneq_imp_response;

4972

end

4973

ctle_pulse = filter(ones(1, param.samples_per_ui), 1, eq_ir);

4974

ind_max = find(ctle_pulse == max(ctle_pulse));

4975

adc_clip = sum(abs([ctle_pulse(ind_max-param.samples_per_ui:-param.samples_per_ui:1); ctle_pulse(ind_max:param.samples_per_ui:end)]));

4976

adc_lsb = 2*adc_clip/(2^param.N_qb-1);

4977

sigma_Q = adc_lsb/sqrt(12);

4978

S_qn = sigma_Q^2/(length(result.S_rn)*delta_f)*ones(size(result.S_rn));

4979

result.S_qn = S_qn;

4980

result.qn_rms = sqrt(sum(result.S_qn)* delta_f);

4981

else

4982

result.S_qn=0;

4983

result.S_qn_rms = 0;

4984

% result.S_n

4985

end

4986

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn+ result.S_qn;

4901

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn;

4987

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

4902

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

4988

4903

4989

%%

4904

%%

4990

%% Hisi to be included in MLSE rho eq 178a-28

4905

%% Hisi to be included in MLSE rho eq 178a-28

4991

if OP.COMPUTE_COM

4906

if OP.COMPUTE_COM

4992

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

4907

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

4993

% sampling_offset = mod(cursor_i-1, M)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

4908

% sampling_offset = mod(cursor_i-1, M)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

4994

% hisi=h(sampling_offset:M:end);

4909

% hisi=h(sampling_offset:M:end);

4995

% hisi=hisi(:).';

4910

% hisi=hisi(:).';

4996

% if num_ui>length(hisi)

4911

% if num_ui>length(hisi)

4997

% hisi=[hisi zeros(1,num_ui-length(hisi))];

4912

% hisi=[hisi zeros(1,num_ui-length(hisi))];

4998

% else

4913

% else

4999

% hisi=hisi(1:num_ui);% sometime cable channels need a bigger num_ui. prehap compare to the tripple transit time and compute num_ui

4914

% hisi=hisi(1:num_ui);% sometime cable channels need a bigger num_ui. prehap compare to the tripple transit time and compute num_ui

5000

% end

4915

% end

5001

% cursor_n=find(hisi==max(hisi),1','first');

4916

% cursor_n=find(hisi==max(hisi),1','first');

5002

samp_idx = (mod(cursor_i-1,M)+1):M:length(h);% Commit request 4p5_2, healey_3dj_COM_01_240521.pdf

4917

samp_idx = (mod(cursor_i-1,M)+1):M:length(h);% Commit request 4p5_2, healey_3dj_COM_01_240521.pdf

5003

cursor_n=find(samp_idx == cursor_i);

4918

cursor_n=find(samp_idx == cursor_i);

5004

hisi=h(samp_idx);

4919

hisi=h(samp_idx);

5005

hisi(end+1:num_ui)=0;

4920

hisi(end+1:num_ui)=0;

5006

hisi=reshape(hisi(1:num_ui),1,[]);

4921

hisi=reshape(hisi(1:num_ui),1,[]);

5007

%% Eq 178a-29

4922

%% Eq 178a-29

5008

for ii=1:length(hisi)

4923

for ii=1:length(hisi)

5009

if ii==cursor_n % cursor

4924

if ii==cursor_n % cursor

5010

cursor=hisi(ii);

4925

cursor=hisi(ii);

5011

hisi(ii)= 0;

4926

hisi(ii)= 0;

5012

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

4927

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

5013

ib_indx=ii-cursor_n;

4928

ib_indx=ii-cursor_n;

5014

if hisi(ii) >= bmax(ib_indx)*cursor

4929

if hisi(ii) >= bmax(ib_indx)*cursor

5015

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

4930

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

5016

elseif hisi(ii) <= bmin(ib_indx)*cursor

4931

elseif hisi(ii) <= bmin(ib_indx)*cursor

5017

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

4932

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

5018

else

4933

else

5019

hisi(ii)=0;

4934

hisi(ii)=0;

5020

end

4935

end

5021

end

4936

end

5022

end

4937

end

5023

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

4938

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

5024

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

4939

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

5025

%%

4940

%%

5026

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

4941

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

5027

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

4942

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

5028

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

4943

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

5029

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

4944

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

5030

end

4945

end

5031

end

4946

end

5032

function result=get_PulseR(ir,param,cb_step,ZT)

4947

function result=get_PulseR(ir,param,cb_step,ZT)

5033

%ir = impulse response

4948

%ir = impulse response

5034

%t_base=time array with equal time steps

4949

%t_base=time array with equal time steps

5035

%samp_UI = number of samples per UI for ir

4950

%samp_UI = number of samples per UI for ir

5036

4951

5037

% t for debug

4952

% t for debug

5038

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

4953

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5039

4954

5040

if cb_step

4955

if cb_step

5041

Ag=1;

4956

Ag=1;

5042

dt=1/param.fb/param.samples_per_ui;

4957

dt=1/param.fb/param.samples_per_ui;

5043

edge_time=param.TR_TDR*1e-9;

4958

edge_time=param.TR_TDR*1e-9;

5044

fedge=1/edge_time;

4959

fedge=1/edge_time;

5045

tedge=0:dt:edge_time*2;

4960

tedge=0:dt:edge_time*2;

5046

%

4961

%

5047

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

4962

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5048

drive_pulse=[edge ones(1,param.samples_per_ui)];

4963

drive_pulse=[edge ones(1,param.samples_per_ui)];

5049

%pulse=filter(UI_ones,1,ir);

4964

%pulse=filter(UI_ones,1,ir);

5050

% t for debug

4965

% t for debug

5051

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

4966

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5052

4967

5053

pulse=filter(drive_pulse,1,ir);

4968

pulse=filter(drive_pulse,1,ir);

5054

else

4969

else

5055

pulse=filter( ones(1,param.samples_per_ui),1,ir);

4970

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5056

end

4971

end

5057

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

4972

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5058

result.PDR=PDR_response;

4973

result.PDR=PDR_response;

5059

result.pulse=pulse;

4974

result.pulse=pulse;

5060

4975

5061

4976

5062

4977

5063

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

4978

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5064

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

4979

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

5065

if ~iscolumn(H), H=H.';end

4980

if ~iscolumn(H), H=H.';end

5066

if ~iscolumn(H_r), H_r=H_r.';end

4981

if ~iscolumn(H_r), H_r=H_r.';end

5067

H=H(:).*H_r;

4982

H=H(:).*H_r;

5068

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

4983

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5069

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

4984

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5070

4985

5071

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

4986

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5072

% Complex reflection and re-reflection noise using the concept of zero'ing

4987

% Complex reflection and re-reflection noise using the concept of zero'ing

5073

% out of reflections

4988

% out of reflections

5074

% sdd21 us a complex insertion loss

4989

% sdd21 us a complex insertion loss

5075

% RIL_struct is the output of capture_RIL_RILN()

4990

% RIL_struct is the output of capture_RIL_RILN()

5076

% faxix_f2 needs to be at least to fb

4991

% faxix_f2 needs to be at least to fb

5077

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

4992

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5078

% still need to settle on voltage scaling.

4993

% still need to settle on voltage scaling.

5079

% maybe db(peak/Rss

4994

% maybe db(peak/Rss

5080

db = @(x) 20*log10(abs(x));

4995

db = @(x) 20*log10(abs(x));

5081

fprintf('computing TD_RILN (dB) ...');

4996

fprintf('computing TD_RILN (dB) ...');

5082

4997

5083

OP.interp_sparam_mag= 'trend_to_DC';

4998

OP.interp_sparam_mag= 'trend_to_DC';

5084

OP.interp_sparam_phase= 'interp_to_DC';

4999

OP.interp_sparam_phase= 'interp_to_DC';

5085

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5000

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5086

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5001

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5087

5002

5088

sdd21=squeeze(sdd21);

5003

sdd21=squeeze(sdd21);

5089

if iscolumn(sdd21)

5004

if iscolumn(sdd21)

5090

sdd21=sdd21.';

5005

sdd21=sdd21.';

5091

end

5006

end

5092

RIL=squeeze(RIL_struct.RIL);

5007

RIL=squeeze(RIL_struct.RIL);

5093

if iscolumn(RIL)

5008

if iscolumn(RIL)

5094

RIL=RIL.';

5009

RIL=RIL.';

5095

end

5010

end

5096

rho_port1=squeeze(RIL_struct.rho_port1);

5011

rho_port1=squeeze(RIL_struct.rho_port1);

5097

if iscolumn(rho_port1)

5012

if iscolumn(rho_port1)

5098

rho_port1=rho_port1.';

5013

rho_port1=rho_port1.';

5099

end

5014

end

5100

rho_port2=squeeze(RIL_struct.rho_port2);

5015

rho_port2=squeeze(RIL_struct.rho_port2);

5101

if iscolumn(rho_port2)

5016

if iscolumn(rho_port2)

5102

rho_port2=rho_port2.';

5017

rho_port2=rho_port2.';

5103

end

5018

end

5104

RIL_f=squeeze(RIL_struct.freq);

5019

RIL_f=squeeze(RIL_struct.freq);

5105

if iscolumn(RIL_f)

5020

if iscolumn(RIL_f)

5106

RIL_f=RIL_f.';

5021

RIL_f=RIL_f.';

5107

end

5022

end

5108

5023

5109

%---start. Calculate the reflection and re-reflection noise

5024

%---start. Calculate the reflection and re-reflection noise

5110

number_of_echos= 1e3;

5025

number_of_echos= 1e3;

5111

fmin= 1e9;%<-------------

5026

fmin= 1e9;%<-------------

5112

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5027

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5113

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5028

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5114

for m= 1:number_of_echos

5029

for m= 1:number_of_echos

5115

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);

5030

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);

5116

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);

5031

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);

5117

end

5032

end

5118

5033

5119

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5034

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5120

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5035

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5121

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5036

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5122

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5037

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5123

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5038

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5124

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5039

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5125

5040

5126

% clear RIL RIL_f rho_port1 rho_port2

5041

% clear RIL RIL_f rho_port1 rho_port2

5127

% clear fmin m

5042

% clear fmin m

5128

%---end. Calculate the reflection and re-reflection noise

5043

%---end. Calculate the reflection and re-reflection noise

5129

5044

5130

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) ];

5045

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) ];

5131

warning('off','MATLAB:nearlySingularMatrix');

5046

warning('off','MATLAB:nearlySingularMatrix');

5132

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5047

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5133

LGw=transpose(sdd21.*unwraplog);

5048

LGw=transpose(sdd21.*unwraplog);

5134

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5049

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5135

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5050

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5136

FIT=transpose(exp(transpose(efit_C)));

5051

FIT=transpose(exp(transpose(efit_C)));

5137

efit=db(abs(FIT));

5052

efit=db(abs(FIT));

5138

ILN = db(sdd21)-efit;

5053

ILN = db(sdd21)-efit;

5139

5054

5140

5055

5141

OP.impulse_response_truncation_threshold =1e-7;

5056

OP.impulse_response_truncation_threshold =1e-7;

5142

5057

5143

print_for_codereview=0;

5058

print_for_codereview=0;

5144

if exist('OP','var')

5059

if exist('OP','var')

5145

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5060

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5146

H_bw=Butterworth_Filter(param,faxis_f2,1);

5061

H_bw=Butterworth_Filter(param,faxis_f2,1);

5147

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5062

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5148

H_tw=Tukey_Window(faxis_f2,param);

5063

H_tw=Tukey_Window(faxis_f2,param);

5149

H_tw=ones(1,length(faxis_f2) );

5064

H_tw=ones(1,length(faxis_f2) );

5150

[RILN_TD_struct.REF.FIR, ...

5065

[RILN_TD_struct.REF.FIR, ...

5151

RILN_TD_struct.REF.t, ...

5066

RILN_TD_struct.REF.t, ...

5152

RILN_TD_struct.REF.causality_correction_dB, ...

5067

RILN_TD_struct.REF.causality_correction_dB, ...

5153

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5068

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5154

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5069

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5155

5070

5156

5071

5157

[RILN_TD_struct.FIT.FIR, ...

5072

[RILN_TD_struct.FIT.FIR, ...

5158

RILN_TD_struct.FIT.t, ...

5073

RILN_TD_struct.FIT.t, ...

5159

RILN_TD_struct.FIT.causality_correction_dB, ...

5074

RILN_TD_struct.FIT.causality_correction_dB, ...

5160

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5075

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5161

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5076

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5162

5077

5163

5078

5164

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5079

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5165

H_bw=Butterworth_Filter(param,RIL_f,1);

5080

H_bw=Butterworth_Filter(param,RIL_f,1);

5166

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5081

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5167

H_tw=Tukey_Window(RIL_f,param);

5082

H_tw=Tukey_Window(RIL_f,param);

5168

H_tw=ones(1,length(RIL_f) );

5083

H_tw=ones(1,length(RIL_f) );

5169

[RILN_TD_struct.RIL.FIR, ...

5084

[RILN_TD_struct.RIL.FIR, ...

5170

RILN_TD_struct.RIL.t, ...

5085

RILN_TD_struct.RIL.t, ...

5171

RILN_TD_struct.RIL.causality_correction_dB, ...

5086

RILN_TD_struct.RIL.causality_correction_dB, ...

5172

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5087

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5173

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5088

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5174

5089

5175

5090

5176

%---start. Calculate the channel delay

5091

%---start. Calculate the channel delay

5177

try

5092

try

5178

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5093

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5179

catch

5094

catch

5180

end

5095

end

5181

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5096

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5182

clear delay_sec delay_idx

5097

clear delay_sec delay_idx

5183

%---end. Calculate the channel delay

5098

%---end. Calculate the channel delay

5184

5099

5185

5100

5186

5101

5187

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5102

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5188

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5103

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5189

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5104

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5190

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5105

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5191

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5106

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5192

[RILN_TD_struct.REF_noise.FIR, ...

5107

[RILN_TD_struct.REF_noise.FIR, ...

5193

RILN_TD_struct.REF_noise.t, ...

5108

RILN_TD_struct.REF_noise.t, ...

5194

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5109

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5195

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) ;

5110

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) ;

5196

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5111

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5197

5112

5198

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5113

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5199

% NrangeUI=1000;

5114

% NrangeUI=1000;

5200

% 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);

5115

% 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);

5201

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5116

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5202

range=ipeak:range_end;

5117

range=ipeak:range_end;

5203

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5118

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5204

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5119

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5205

RILN_TD_struct.FOM=-inf;

5120

RILN_TD_struct.FOM=-inf;

5206

RILN_TD_struct.FOM_PDF=-inf;

5121

RILN_TD_struct.FOM_PDF=-inf;

5207

rms_fom=-inf;

5122

rms_fom=-inf;

5208

for im=1:param.samples_per_ui

5123

for im=1:param.samples_per_ui

5209

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5124

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5210

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5125

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5211

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5126

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5212

cdf=pdf; cdf.y=cumsum(pdf.y);

5127

cdf=pdf; cdf.y=cumsum(pdf.y);

5213

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5128

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5214

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5129

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5215

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5130

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5216

if print_for_codereview % remove once all checked out

5131

if print_for_codereview % remove once all checked out

5217

h=figure(190);set(gcf,'Tag','COM');

5132

h=figure(190);set(gcf,'Tag','COM');

5218

semilogy(-cdf.x,cdf.y);

5133

semilogy(-cdf.x,cdf.y);

5219

% xlim ([0,-cdf.x(1)])

5134

% xlim ([0,-cdf.x(1)])

5220

ylim([param.specBER 1]);title ('CDF of ILN')

5135

ylim([param.specBER 1]);title ('CDF of ILN')

5221

hold on

5136

hold on

5222

end

5137

end

5223

if rms>rms_fom

5138

if rms>rms_fom

5224

rms_fom=rms;

5139

rms_fom=rms;

5225

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5140

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5226

RILN_TD_struct.PDF=pdf;

5141

RILN_TD_struct.PDF=pdf;

5227

end

5142

end

5228

end

5143

end

5229

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5144

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5230

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5145

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5231

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5146

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5232

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5147

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5233

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5148

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5234

if print_for_codereview % remove once all checked out

5149

if print_for_codereview % remove once all checked out

5235

figure(9000);set(gcf,'Tag','COM');

5150

figure(9000);set(gcf,'Tag','COM');

5236

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5151

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5237

hold on

5152

hold on

5238

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5153

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5239

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5154

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5240

yyaxis right

5155

yyaxis right

5241

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5156

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5242

hold off

5157

hold off

5243

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)

5158

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)

5244

figure(9002);set(gcf,'Tag','COM');

5159

figure(9002);set(gcf,'Tag','COM');

5245

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5160

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5246

hold on

5161

hold on

5247

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5162

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5248

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5163

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5249

grid on

5164

grid on

5250

legend('show')

5165

legend('show')

5251

end

5166

end

5252

end

5167

end

5253

function result=get_StepR(ir,param,cb_step,ZT)

5168

function result=get_StepR(ir,param,cb_step,ZT)

5254

%ir = impulse response

5169

%ir = impulse response

5255

%t_base=time array with equal time steps

5170

%t_base=time array with equal time steps

5256

%samp_UI = number of samples per UI for ir

5171

%samp_UI = number of samples per UI for ir

5257

% result.SBR

5172

% result.SBR

5258

% t for debug

5173

% t for debug

5259

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5174

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5260

5175

5261

if cb_step

5176

if cb_step

5262

Ag=1;

5177

Ag=1;

5263

dt=1/param.fb/param.samples_per_ui;

5178

dt=1/param.fb/param.samples_per_ui;

5264

edge_time=param.TR_TDR*1e-9;

5179

edge_time=param.TR_TDR*1e-9;

5265

fedge=1/edge_time;

5180

fedge=1/edge_time;

5266

tedge=0:dt:edge_time*2;

5181

tedge=0:dt:edge_time*2;

5267

%

5182

%

5268

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5183

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5269

drive_pulse=[edge ones(1,param.samples_per_ui)];

5184

drive_pulse=[edge ones(1,param.samples_per_ui)];

5270

%pulse=filter(UI_ones,1,ir);

5185

%pulse=filter(UI_ones,1,ir);

5271

5186

5272

pulse=filter(drive_pulse,1,ir);

5187

pulse=filter(drive_pulse,1,ir);

5273

else

5188

else

5274

pulse=cumsum(ir);

5189

pulse=cumsum(ir);

5275

end

5190

end

5276

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5191

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5277

result.ZSR=TDR_response;

5192

result.ZSR=TDR_response;

5278

result.pulse=pulse;

5193

result.pulse=pulse;

5279

5194

5280

5195

5281

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5196

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5282

% sdd is differential s-parameters structure (2 port assumed)

5197

% sdd is differential s-parameters structure (2 port assumed)

5283

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5198

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5284

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5199

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5285

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5200

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5286

% TDR_results.t starting at t=0

5201

% TDR_results.t starting at t=0

5287

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5202

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5288

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5203

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5289

% TDR_results.f frequency for filter and s parameters

5204

% TDR_results.f frequency for filter and s parameters

5290

% TDR_results.ptdr_RL reflection waveform from the pulse

5205

% TDR_results.ptdr_RL reflection waveform from the pulse

5291

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5206

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5292

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5207

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5293

% TDR_results.ERL reported effective return loss

5208

% TDR_results.ERL reported effective return loss

5294

%

5209

%

5295

db = @(x) 20*log10(abs(x));

5210

db = @(x) 20*log10(abs(x));

5296

rms =@(x) norm(x)/sqrt(length(x));

5211

rms =@(x) norm(x)/sqrt(length(x));

5297

if isfield(OP,'TDR_duration')

5212

if isfield(OP,'TDR_duration')

5298

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5213

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5299

else

5214

else

5300

TDR_duration=5;

5215

TDR_duration=5;

5301

end

5216

end

5302

if ~isfield(OP,'DISPLAY_WINDOW')

5217

if ~isfield(OP,'DISPLAY_WINDOW')

5303

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5218

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5304

end

5219

end

5305

f=sdd.Frequencies;

5220

f=sdd.Frequencies;

5306

TDR_results.f=f;

5221

TDR_results.f=f;

5307

% OP.Zt_adj=2;

5222

% OP.Zt_adj=2;

5308

if param.FLAG.S2P == 0

5223

if param.FLAG.S2P == 0

5309

5224

5310

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5225

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5311

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);

5226

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);

5312

5227

5313

if param.RL_sel==1, other_port=2;end

5228

if param.RL_sel==1, other_port=2;end

5314

if param.RL_sel==2, other_port=1;end

5229

if param.RL_sel==2, other_port=1;end

5315

for i = 1:length(sdd.Frequencies)

5230

for i = 1:length(sdd.Frequencies)

5316

if size(sdd.Parameters,2) ==1 % for s2p files

5231

if size(sdd.Parameters,2) ==1 % for s2p files

5317

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) );

5232

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) );

5318

else

5233

else

5319

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) );

5234

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) );

5320

end

5235

end

5321

end

5236

end

5322

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5237

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5323

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5238

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5324

% Z_t=ZT;

5239

% Z_t=ZT;

5325

% zref=sdd.Impedance/2;

5240

% zref=sdd.Impedance/2;

5326

% if Z_t > zref

5241

% if Z_t > zref

5327

% radjust= (zref-Z_t);

5242

% radjust= (zref-Z_t);

5328

% S11adjust= radjust./(radjust + 2*zref);

5243

% S11adjust= radjust./(radjust + 2*zref);

5329

% RL=RL +S11adjust;

5244

% RL=RL +S11adjust;

5330

% elseif Z_t < zref

5245

% elseif Z_t < zref

5331

% rpad=-Z_t*zref/(Z_t-zref);

5246

% rpad=-Z_t*zref/(Z_t-zref);

5332

% S11adjust=zref/(rpad*(zref/rpad + 2));

5247

% S11adjust=zref/(rpad*(zref/rpad + 2));

5333

% RL=RL + S11adjust;

5248

% RL=RL + S11adjust;

5334

% else

5249

% else

5335

% RL=RL;

5250

% RL=RL;

5336

% end

5251

% end

5337

else

5252

else

5338

for i = 1:length(sdd.Frequencies)

5253

for i = 1:length(sdd.Frequencies)

5339

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5254

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5340

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5255

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5341

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5256

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5342

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5257

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5343

end

5258

end

5344

end

5259

end

5345

5260

5346

% end

5261

% end

5347

RL=squeeze(RL);

5262

RL=squeeze(RL);

5348

f9=f/1e9;

5263

f9=f/1e9;

5349

tr=param.TR_TDR;

5264

tr=param.TR_TDR;

5350

TDR_results.delay=500e-12 ;

5265

TDR_results.delay=500e-12 ;

5351

% determine max time from thue

5266

% determine max time from thue

5352

% if sdd.NumPorts==1

5267

% if sdd.NumPorts==1

5353

% try

5268

% try

5354

% maxtime=OP.N*param.ui;

5269

% maxtime=OP.N*param.ui;

5355

% catch

5270

% catch

5356

% maxtime=2e-9;

5271

% maxtime=2e-9;

5357

% end

5272

% end

5358

% pix=1;

5273

% pix=1;

5359

% else

5274

% else

5360

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5275

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5361

% pix=find(fir4del==max(fir4del),1);

5276

% pix=find(fir4del==max(fir4del),1);

5362

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5277

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5363

% if maxtime > tu(end); maxtime=tu(end);end

5278

% if maxtime > tu(end); maxtime=tu(end);end

5364

% endS

5279

% endS

5365

5280

5366

try

5281

try

5367

maxtime=OP.N*param.ui;

5282

maxtime=OP.N*param.ui;

5368

catch

5283

catch

5369

maxtime=2e-9;

5284

maxtime=2e-9;

5370

end

5285

end

5371

if OP.N==0

5286

if OP.N==0

5372

if sdd.NumPorts==1

5287

if sdd.NumPorts==1

5373

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5288

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5374

else

5289

else

5375

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5290

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5376

pix=find(fir4del==max(fir4del),1);

5291

pix=find(fir4del==max(fir4del),1);

5377

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5292

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5378

if maxtime > tu(end); maxtime=tu(end);end

5293

if maxtime > tu(end); maxtime=tu(end);end

5379

end

5294

end

5380

end

5295

end

5381

5296

5382

5297

5383

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5298

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5384

% (makes gausian edge somewhat causal)

5299

% (makes gausian edge somewhat causal)

5385

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);

5300

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);

5386

if ~isfield(OP,'cb_Guassian')

5301

if ~isfield(OP,'cb_Guassian')

5387

Use_gaussian=1;

5302

Use_gaussian=1;

5388

else

5303

else

5389

Use_gaussian=OP.cb_Guassian;

5304

Use_gaussian=OP.cb_Guassian;

5390

end

5305

end

5391

if Use_gaussian

5306

if Use_gaussian

5392

if iscolumn(H_t), H_t=H_t.'; end

5307

if iscolumn(H_t), H_t=H_t.'; end

5393

RLf=RL(:).'.*H_t;

5308

RLf=RL(:).'.*H_t;

5394

else % add extra 3x tr delay for causality

5309

else % add extra 3x tr delay for causality

5395

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5310

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5396

end

5311

end

5397

5312

5398

%Bessesl-Thomson turned off here (3rd input=0)

5313

%Bessesl-Thomson turned off here (3rd input=0)

5399

OP.TDR_Bessel_Thomson=0;

5314

OP.TDR_Bessel_Thomson=0;

5400

H_bt=Bessel_Thomson_Filter(param,f,OP.TDR_Bessel_Thomson);

5315

H_bt=Bessel_Thomson_Filter(param,f,OP.TDR_Bessel_Thomson);

5401

5316

5402

if isfield(OP,'TDR_Butterworth')

5317

if isfield(OP,'TDR_Butterworth')

5403

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5318

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5404

else

5319

else

5405

H_bw=ones(1,length(f));

5320

H_bw=ones(1,length(f));

5406

end

5321

end

5407

5322

5408

5323

5409

if param.Tukey_Window ~= 0

5324

if param.Tukey_Window ~= 0

5410

H_tw= Tukey_Window(f,param);

5325

H_tw= Tukey_Window(f,param);

5411

else

5326

else

5412

H_tw=ones(1,length(f));

5327

H_tw=ones(1,length(f));

5413

end

5328

end

5414

5329

5415

5330

5416

if iscolumn(H_tw), H_tw=H_tw.';end

5331

if iscolumn(H_tw), H_tw=H_tw.';end

5417

if iscolumn(H_bt), H_bt=H_bt.';end

5332

if iscolumn(H_bt), H_bt=H_bt.';end

5418

if iscolumn(H_bw), H_bw=H_bw.';end

5333

if iscolumn(H_bw), H_bw=H_bw.';end

5419

if iscolumn(RLf), RLf=RLf.';end

5334

if iscolumn(RLf), RLf=RLf.';end

5420

5335

5421

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5336

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5422

RLf=RLf.*TDR_results.Rx_filter;

5337

RLf=RLf.*TDR_results.Rx_filter;

5423

TDR_results.tx_filter=H_t;

5338

TDR_results.tx_filter=H_t;

5424

5339

5425

5340

5426

[IR, t, causality_correction_dB, truncation_dB] = ...

5341

[IR, t, causality_correction_dB, truncation_dB] = ...

5427

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5342

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5428

5343

5429

5344

5430

%

5345

%

5431

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5346

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5432

tfx=param.tfx(np); % use fixture delay for port (np)

5347

tfx=param.tfx(np); % use fixture delay for port (np)

5433

5348

5434

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5349

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5435

5350

5436

t = t-TDR_results.delay;

5351

t = t-TDR_results.delay;

5437

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5352

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5438

if isempty(tend), tend=length(t); end

5353

if isempty(tend), tend=length(t); end

5439

IR=IR(1:tend);

5354

IR=IR(1:tend);

5440

t=t(1:tend);

5355

t=t(1:tend);

5441

if isempty(tend), tend=length(t); end

5356

if isempty(tend), tend=length(t); end

5442

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5357

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5443

if isempty(tstart), tstart=1;end

5358

if isempty(tstart), tstart=1;end

5444

if isempty(tend) || tstart >= tend

5359

if isempty(tend) || tstart >= tend

5445

if isempty(tend) || tstart >= tend

5360

if isempty(tend) || tstart >= tend

5446

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5361

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5447

end

5362

end

5448

tend=length(t);

5363

tend=length(t);

5449

tstart=1;

5364

tstart=1;

5450

end

5365

end

5451

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5366

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5452

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5367

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5453

TDR_results.tdr= ch.ZSR;

5368

TDR_results.tdr= ch.ZSR;

5454

TDR_results.t = t(tstart:tend);

5369

TDR_results.t = t(tstart:tend);

5455

5370

5456

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5371

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5457

if OP.TDR || OP.PTDR % determin average impededance with

5372

if OP.TDR || OP.PTDR % determin average impededance with

5458

try

5373

try

5459

tfstart=find(t>=3*tr*1e-9,1);

5374

tfstart=find(t>=3*tr*1e-9,1);

5460

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5375

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5461

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5376

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5462

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5377

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5463

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5378

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5464

catch

5379

catch

5465

TDR_results.avgZport=0;

5380

TDR_results.avgZport=0;

5466

fit=zeros(1,1);

5381

fit=zeros(1,1);

5467

p=[0 0 0 0 ];

5382

p=[0 0 0 0 ];

5468

end

5383

end

5469

TDR_results.RL=RL;

5384

TDR_results.RL=RL;

5470

end

5385

end

5471

if OP.PTDR

5386

if OP.PTDR

5472

% param.N_bx=param.ndfe;

5387

% param.N_bx=param.ndfe;

5473

RL_equiv=-inf;

5388

RL_equiv=-inf;

5474

L=param.levels;

5389

L=param.levels;

5475

BinSize=OP.BinSize;

5390

BinSize=OP.BinSize;

5476

% param.specBER=1e-5;

5391

% param.specBER=1e-5;

5477

if OP.DISPLAY_WINDOW

5392

if OP.DISPLAY_WINDOW

5478

hwaitbar=waitbar(0);

5393

hwaitbar=waitbar(0);

5479

else

5394

else

5480

fprintf('Worst ERL searching');

5395

fprintf('Worst ERL searching');

5481

end

5396

end

5482

% adjust PTDR for NDFE

5397

% adjust PTDR for NDFE

5483

% ---------------------- 2.7 code

5398

% ---------------------- 2.7 code

5484

% ntx=find(TDR_results.t >= tfx,1,'first');

5399

% ntx=find(TDR_results.t >= tfx,1,'first');

5485

% % gatestartt=TDR_results.t(ntx);

5400

% % gatestartt=TDR_results.t(ntx);

5486

% % gatestartV=PTDR.pulse(ntx);

5401

% % gatestartV=PTDR.pulse(ntx);

5487

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5402

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5488

% tk=param.ui*1*(param.N_bx+1)+tfx;

5403

% tk=param.ui*1*(param.N_bx+1)+tfx;

5489

% -------------------

5404

% -------------------

5490

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5405

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5491

% time filter.

5406

% time filter.

5492

% ntx=find(TDR_results.t >= tfx,1,'first');

5407

% ntx=find(TDR_results.t >= tfx,1,'first');

5493

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5408

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5494

% gatestartt=TDR_results.t(ntx);

5409

% gatestartt=TDR_results.t(ntx);

5495

% gatestartV=PTDR.pulse(ntx);

5410

% gatestartV=PTDR.pulse(ntx);

5496

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5411

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5497

% tk=param.ui*1*(param.N_bx+1)+tfx;

5412

% tk=param.ui*1*(param.N_bx+1)+tfx;

5498

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5413

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5499

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5414

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5500

% [ahealey] End of modifications.

5415

% [ahealey] End of modifications.

5501

if isempty(ndfex), ndfex=length(TDR_results.t); end

5416

if isempty(ndfex), ndfex=length(TDR_results.t); end

5502

PTDR.pulse_orig=PTDR.pulse;

5417

PTDR.pulse_orig=PTDR.pulse;

5503

5418

5504

switch param.Grr

5419

switch param.Grr

5505

case 0 % pre .3cd release

5420

case 0 % pre .3cd release

5506

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5421

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5507

case 1 % .3cd release

5422

case 1 % .3cd release

5508

fctrx(1:length(PTDR.pulse_orig))=1;

5423

fctrx(1:length(PTDR.pulse_orig))=1;

5509

case 2 % .3ck working

5424

case 2 % .3ck working

5510

fctrx(1:length(PTDR.pulse_orig))=1;

5425

fctrx(1:length(PTDR.pulse_orig))=1;

5511

end

5426

end

5512

Gloss(1:length(TDR_results.t))=1;

5427

Gloss(1:length(TDR_results.t))=1;

5513

Grr(1:length(TDR_results.t))=1;

5428

Grr(1:length(TDR_results.t))=1;

5514

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5429

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5515

5430

5516

for ii=ntx:ndfex

5431

for ii=ntx:ndfex

5517

% adjust for near end loss

5432

% adjust for near end loss

5518

if param.N_bx>0 && param.beta_x~=0;

5433

if param.N_bx>0 && param.beta_x~=0;

5519

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5434

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5520

else

5435

else

5521

Gloss(ii)=1;

5436

Gloss(ii)=1;

5522

end

5437

end

5523

% ---------------------- 2.7 code

5438

% ---------------------- 2.7 code

5524

% x=(TDR_results.t(ii)-tfx)/param.ui;

5439

% x=(TDR_results.t(ii)-tfx)/param.ui;

5525

% ----------------------

5440

% ----------------------

5526

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5441

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5527

% rise time filter.

5442

% rise time filter.

5528

% x=(TDR_results.t(ii)-tfx)/param.ui;

5443

% x=(TDR_results.t(ii)-tfx)/param.ui;

5529

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5444

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5530

% determine how much of the return loss to use base on expected

5445

% determine how much of the return loss to use base on expected

5531

% missing reflections

5446

% missing reflections

5532

switch param.Grr

5447

switch param.Grr

5533

case 0 % pre .3cd release

5448

case 0 % pre .3cd release

5534

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5449

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5535

case 1 % .3cd release

5450

case 1 % .3cd release

5536

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5451

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5537

case 2 % .3ck working

5452

case 2 % .3ck working

5538

Grr(ii)= param.rho_x ;

5453

Grr(ii)= param.rho_x ;

5539

end

5454

end

5540

fctrx(ii)=Gloss(ii).*Grr(ii);

5455

fctrx(ii)=Gloss(ii).*Grr(ii);

5541

end

5456

end

5542

5457

5543

if isrow(fctrx), fctrx=fctrx(:);end

5458

if isrow(fctrx), fctrx=fctrx(:);end

5544

PTDR.pulse=PTDR.pulse.*fctrx;

5459

PTDR.pulse=PTDR.pulse.*fctrx;

5545

if 0

5460

if 0

5546

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5461

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5547

s1=subplot(2,1,1);

5462

s1=subplot(2,1,1);PTDR.pulse

5548

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5463

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5549

hold on

5464

hold on

5550

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5465

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5551

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5466

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5552

grid on

5467

grid on

5553

ylim([ 0 1.2])

5468

ylim([ 0 1.2])

5554

s2=subplot(2,1,2);

5469

s2=subplot(2,1,2);

5555

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5470

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5556

grid on

5471

grid on

5557

linkaxes([s1,s2],'x')

5472

linkaxes([s1,s2],'x')

5558

xlabel 'UI'

5473

xlabel 'UI'

5559

xlim ([ 1 200])

5474

xlim ([ 1 200])

5560

end

5475

end

5561

5476

5562

FAST_NOISE_CONV=0;

5477

FAST_NOISE_CONV=0;

5563

ERLRMS=rms(PTDR.pulse);

5478

ERLRMS=rms(PTDR.pulse);

5564

for ki=1:param.samples_per_ui

5479

for ki=1:param.samples_per_ui

5565

progress = ki/param.samples_per_ui;

5480

progress = ki/param.samples_per_ui;

5566

if OP.DISPLAY_WINDOW

5481

if OP.DISPLAY_WINDOW

5567

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5482

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5568

else

5483

else

5569

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5484

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5570

end

5485

end

5571

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5486

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5572

if OP.RL_norm_test

5487

if OP.RL_norm_test

5573

rl_fom=(norm(tps));

5488

rl_fom=(norm(tps));

5574

else

5489

else

5575

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5490

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5576

cdf_test=cumsum(testpdf.y);

5491

cdf_test=cumsum(testpdf.y);

5577

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5492

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5578

rl_fom=rl_test;

5493

rl_fom=rl_test;

5579

end

5494

end

5580

if rl_fom > RL_equiv

5495

if rl_fom > RL_equiv

5581

RL_equiv=rl_fom;

5496

RL_equiv=rl_fom;

5582

best_ki=ki;

5497

best_ki=ki;

5583

end

5498

end

5584

if ~OP.RL_norm_test

5499

if ~OP.RL_norm_test

5585

best_erl=rl_test;

5500

best_erl=rl_test;

5586

best_pdf=testpdf;

5501

best_pdf=testpdf;

5587

best_cdf=cdf_test;

5502

best_cdf=cdf_test;

5588

end

5503

end

5589

5504

5590

end

5505

end

5591

if OP.RL_norm_test

5506

if OP.RL_norm_test

5592

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5507

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5593

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5508

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5594

cdf_test=cumsum(testpdf.y);

5509

cdf_test=cumsum(testpdf.y);

5595

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5510

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5596

end

5511

end

5597

5512

5598

fprintf('\n');

5513

fprintf('\n');

5599

try

5514

try

5600

close(hwaitbar)

5515

close(hwaitbar)

5601

catch

5516

catch

5602

end

5517

end

5603

if ~exist('best_ki','var'),best_ki=1;end

5518

if ~exist('best_ki','var'),best_ki=1;end

5604

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5519

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5605

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5520

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5606

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5521

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5607

TDR_results.ERL=-db(best_erl);

5522

TDR_results.ERL=-db(best_erl);

5608

TDR_results.ERLRMS=-db(ERLRMS);

5523

TDR_results.ERLRMS=-db(ERLRMS);

5609

5524

5610

end

5525

end

5611

5526

5612

5527

5613

% end get TDR

5528

% end get TDR

5614

%%

5529

%%

5615

5530

5616

5531

5617

5532

5618

5533

5619

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5534

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5620

% filename parsing and acquisition

5535

% filename parsing and acquisition

5621

%------------------------------------------------------------------

5536

%------------------------------------------------------------------

5622

%----------put files names into chdata structure ---------

5537

%----------put files names into chdata structure ---------

5623

% The thru file has the index of 1

5538

% The thru file has the index of 1

5624

% crosstalk file are indexed from 2

5539

% crosstalk file are indexed from 2

5625

% nxi is incremented each time a file is read in so that nxi will end

5540

% nxi is incremented each time a file is read in so that nxi will end

5626

filepath=[]; % path name for file

5541

filepath=[]; % path name for file

5627

nxi=0; % file index

5542

nxi=0; % file index

5628

% get the THRU file

5543

% get the THRU file

5629

if size(file_list,2) ~= 0

5544

if size(file_list,2) ~= 0

5630

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5545

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5631

[filepath, basename, fileext]=fileparts(file_list{1});

5546

[filepath, basename, fileext]=fileparts(file_list{1});

5632

5547

5633

else

5548

else

5634

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5549

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5635

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5550

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5636

movegui(h,'northeast')

5551

movegui(h,'northeast')

5637

end

5552

end

5638

dir=fullfile(filepath, '*.csv');

5553

dir=fullfile(filepath, '*.csv');

5639

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5554

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5640

if filepath == 0

5555

if filepath == 0

5641

error('No Thru file')

5556

error('No Thru file')

5642

end

5557

end

5643

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5558

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5644

end

5559

end

5645

nxi=nxi+1;

5560

nxi=nxi+1;

5646

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5561

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5647

chdata(nxi).ext = fileext;

5562

chdata(nxi).ext = fileext;

5648

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5563

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5649

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5564

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5650

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5565

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5651

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5566

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5652

chdata(nxi).type='THRU';

5567

chdata(nxi).type='THRU';

5653

chdata(nxi).ftr=param.fb*param.f_v;

5568

chdata(nxi).ftr=param.fb*param.f_v;

5654

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5569

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5655

5570

5656

% now get FEXT file names into chdata structure

5571

% now get FEXT file names into chdata structure

5657

kxi=nxi;

5572

kxi=nxi;

5658

for nxi=kxi+1:num_fext+kxi

5573

for nxi=kxi+1:num_fext+kxi

5659

lastfilepath=filepath;

5574

lastfilepath=filepath;

5660

if size(file_list,2) ~= 0

5575

if size(file_list,2) ~= 0

5661

[filepath, basename, fileext]=fileparts(file_list{nxi});

5576

[filepath, basename, fileext]=fileparts(file_list{nxi});

5662

else

5577

else

5663

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5578

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5664

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5579

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5665

movegui(h,'northeast')

5580

movegui(h,'northeast')

5666

end

5581

end

5667

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5582

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5668

dir=fullfile(filepath, '*.csv');

5583

dir=fullfile(filepath, '*.csv');

5669

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5584

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5670

if filepath==0

5585

if filepath==0

5671

error('Not enough NEXT files')

5586

error('Not enough NEXT files')

5672

end

5587

end

5673

else

5588

else

5674

dir=fullfile(filepath, '*.csv');

5589

dir=fullfile(filepath, '*.csv');

5675

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5590

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5676

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5591

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5677

else

5592

else

5678

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5593

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5679

end

5594

end

5680

if filepath==0

5595

if filepath==0

5681

error('Not enough NEXT files')

5596

error('Not enough NEXT files')

5682

end

5597

end

5683

end

5598

end

5684

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5599

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5685

end

5600

end

5686

if isempty( filepath), filepath=lastfilepath; end

5601

if isempty( filepath), filepath=lastfilepath; end

5687

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5602

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5688

chdata(nxi).ext = fileext;

5603

chdata(nxi).ext = fileext;

5689

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5604

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5690

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5605

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5691

% chdata(nxi).A=param.a_fext;

5606

% chdata(nxi).A=param.a_fext;

5692

chdata(nxi).ftr=param.fb*param.f_f;

5607

chdata(nxi).ftr=param.fb*param.f_f;

5693

chdata(nxi).type='FEXT';

5608

chdata(nxi).type='FEXT';

5694

end

5609

end

5695

% now get NEXT file names into chdata structure

5610

% now get NEXT file names into chdata structure

5696

kxi=num_fext+kxi;

5611

kxi=num_fext+kxi;

5697

for nxi=kxi+1:num_next+kxi

5612

for nxi=kxi+1:num_next+kxi

5698

lastfilepath=filepath;

5613

lastfilepath=filepath;

5699

if size(file_list,2) ~= 0

5614

if size(file_list,2) ~= 0

5700

[filepath, basename, fileext]=fileparts(file_list{nxi});

5615

[filepath, basename, fileext]=fileparts(file_list{nxi});

5701

else

5616

else

5702

dir=fullfile(filepath, '*.csv');

5617

dir=fullfile(filepath, '*.csv');

5703

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5618

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5704

if filepath==0

5619

if filepath==0

5705

error('Not enough NEXT files')

5620

error('Not enough NEXT files')

5706

end

5621

end

5707

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5622

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5708

end

5623

end

5709

if isempty( filepath), filepath=lastfilepath; end

5624

if isempty( filepath), filepath=lastfilepath; end

5710

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5625

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5711

chdata(nxi).ext = fileext;

5626

chdata(nxi).ext = fileext;

5712

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5627

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5713

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5628

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5714

% chdata(nxi).A=param.A_next;

5629

% chdata(nxi).A=param.A_next;

5715

chdata(nxi).ftr=param.fb*param.f_n;

5630

chdata(nxi).ftr=param.fb*param.f_n;

5716

chdata(nxi).type='NEXT';

5631

chdata(nxi).type='NEXT';

5717

end

5632

end

5718

function half_UI=get_center_of_UI(samples_per_UI)

5633

function half_UI=get_center_of_UI(samples_per_UI)

5719

5634

5720

%half_UI reveals which value to use for the center of the UI. For eye

5635

%half_UI reveals which value to use for the center of the UI. For eye

5721

%width calculations, it is necessary to place the cursor in the center of the

5636

%width calculations, it is necessary to place the cursor in the center of the

5722

%UI window to ensure a 0 crossing on both left/right inside the window.

5637

%UI window to ensure a 0 crossing on both left/right inside the window.

5723

%This function was written in order to support even and odd samples_per_UI

5638

%This function was written in order to support even and odd samples_per_UI

5724

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

5639

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

5725

5640

5726

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

5641

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

5727

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

5642

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

5728

%the center of the UI is sample closest to 0.5

5643

%the center of the UI is sample closest to 0.5

5729

[temp_diff,half_UI]=min(abs(UI_window-0.5));

5644

[temp_diff,half_UI]=min(abs(UI_window-0.5));

5730

function results= get_cm_noise(M,PR,L,BER,OP)

5645

function results= get_cm_noise(M,PR,L,BER,OP)

5731

5646

5732

if ~exist('OP')

5647

if ~exist('OP')

5733

OP.DC_norm_test=0;

5648

OP.DC_norm_test=0;

5734

OP.DISPLAY_WINDOW=1;

5649

OP.DISPLAY_WINDOW=1;

5735

end

5650

end

5736

param.BinSize=1e-5;

5651

param.BinSize=1e-5;

5737

PR_test=-inf;

5652

PR_test=-inf;

5738

PR_fom_best=-inf;

5653

PR_fom_best=-inf;

5739

% hwaitbar=waitbar(0);

5654

% hwaitbar=waitbar(0);

5740

for ki=1:M

5655

for ki=1:M

5741

progress = ki/M;

5656

progress = ki/M;

5742

% if OP.DISPLAY_WINDOW

5657

% if OP.DISPLAY_WINDOW

5743

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

5658

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

5744

% else

5659

% else

5745

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5660

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5746

% end

5661

% end

5747

tps=PR(ki:M:end);

5662

tps=PR(ki:M:end);

5748

if OP.DC_norm_test

5663

if OP.DC_norm_test

5749

PR_fom=(norm(tps));

5664

PR_fom=(norm(tps));

5750

else

5665

else

5751

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

5666

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

5752

cdf_test=cumsum(testpdf.y);

5667

cdf_test=cumsum(testpdf.y);

5753

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

5668

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

5754

PR_fom=PRn_test;

5669

PR_fom=PRn_test;

5755

end

5670

end

5756

if PR_fom > PR_fom_best

5671

if PR_fom > PR_fom_best

5757

PR_fom_best=PR_fom;

5672

PR_fom_best=PR_fom;

5758

best_ki=ki;

5673

best_ki=ki;

5759

end

5674

end

5760

if ~OP.DC_norm_test

5675

if ~OP.DC_norm_test

5761

results.DCn=PR_fom_best;

5676

results.DCn=PR_fom_best;

5762

results.DCn_pdf=testpdf;

5677

results.DCn_pdf=testpdf;

5763

results.DCn_cdf=cdf_test;

5678

results.DCn_cdf=cdf_test;

5764

else

5679

else

5765

results.DCn=PR_fom_best;

5680

results.DCn=PR_fom_best;

5766

end

5681

end

5767

results.DCn_p2p=max(PR)-min(PR);

5682

results.DCn_p2p=max(PR)-min(PR);

5768

end

5683

end

5769

5684

5770

5685

5771

5686

5772

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

5687

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

5773

SBR=chdata.eq_pulse_response(:)'; % row vector

5688

SBR=chdata.eq_pulse_response(:)'; % row vector

5774

type=chdata.type;

5689

type=chdata.type;

5775

samp_UI=param.samples_per_ui;

5690

samp_UI=param.samples_per_ui;

5776

residual_response = SBR;

5691

residual_response = SBR;

5777

5692

5778

if isequal(type, 'THRU')

5693

if isequal(type, 'THRU')

5779

% for thru pulse response:

5694

% for thru pulse response:

5780

% remove the cursor and the DFE postcursors (up to their limit), since

5695

% remove the cursor and the DFE postcursors (up to their limit), since

5781

% we only care about the residuals.

5696

% we only care about the residuals.

5782

5697

5783

if ~param.Floating_DFE

5698

if ~param.Floating_DFE

5784

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

5699

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

5785

else

5700

else

5786

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

5701

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

5787

end

5702

end

5788

if param.dfe_delta ~= 0

5703

if param.dfe_delta ~= 0

5789

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);

5704

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);

5790

else

5705

else

5791

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5706

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5792

end

5707

end

5793

5708

5794

%AJG021820

5709

%AJG021820

5795

if ~param.Floating_DFE

5710

if ~param.Floating_DFE

5796

bmax_vec=residual_response(t_s)*[1,param.bmax];

5711

bmax_vec=residual_response(t_s)*[1,param.bmax];

5797

bmin_vec=residual_response(t_s)*[1,param.bmin];

5712

bmin_vec=residual_response(t_s)*[1,param.bmin];

5798

else

5713

else

5799

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

5714

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

5800

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

5715

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

5801

end

5716

end

5802

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5717

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5803

5718

5804

5719

5805

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

5720

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

5806

dfetaps=effective_cancelled_cursors/SBR(t_s);

5721

dfetaps=effective_cancelled_cursors/SBR(t_s);

5807

5722

5808

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5723

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5809

% really needed for COM, but helps debugging. May be factored out in future revisions.

5724

% really needed for COM, but helps debugging. May be factored out in future revisions.

5810

start_cancel = t_s-param.samples_per_ui/2;

5725

start_cancel = t_s-param.samples_per_ui/2;

5811

if ~param.Floating_DFE

5726

if ~param.Floating_DFE

5812

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

5727

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

5813

else

5728

else

5814

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

5729

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

5815

end

5730

end

5816

residual_response(start_cancel:end_cancel) = ...

5731

residual_response(start_cancel:end_cancel) = ...

5817

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5732

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5818

%else

5733

%else

5819

% for crosstalk pulse responses, nothing is cancelled, and all phases

5734

% for crosstalk pulse responses, nothing is cancelled, and all phases

5820

% are equally important.

5735

% are equally important.

5821

end

5736

end

5822

5737

5823

nui=round(length(residual_response)/param.samples_per_ui);

5738

nui=round(length(residual_response)/param.samples_per_ui);

5824

5739

5825

vs=zeros(nui-2, param.samples_per_ui);

5740

vs=zeros(nui-2, param.samples_per_ui);

5826

for i=1:param.samples_per_ui

5741

for i=1:param.samples_per_ui

5827

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

5742

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

5828

end

5743

end

5829

5744

5830

if OP.DISPLAY_WINDOW,

5745

if OP.DISPLAY_WINDOW,

5831

hwaitbar=waitbar(0);

5746

hwaitbar=waitbar(0);

5832

end

5747

end

5833

5748

5834

% determine which pdf to use

5749

% determine which pdf to use

5835

if isequal(type, 'THRU')

5750

if isequal(type, 'THRU')

5836

% one phase is interesting for thru

5751

% one phase is interesting for thru

5837

phases = mod(t_s,param.samples_per_ui);

5752

phases = mod(t_s,param.samples_per_ui);

5838

if phases==0, phases = param.samples_per_ui; end

5753

if phases==0, phases = param.samples_per_ui; end

5839

else

5754

else

5840

phases=1:samp_UI;

5755

phases=1:samp_UI;

5841

end

5756

end

5842

5757

5843

mxV = zeros(size(phases));

5758

mxV = zeros(size(phases));

5844

% we already found the phase in the PSD process for MMSE

5759

% we already found the phase in the PSD process for MMSE

5845

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

5760

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

5846

if isequal(type, 'THRU')

5761

if isequal(type, 'THRU')

5847

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

5762

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

5848

else

5763

else

5849

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

5764

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

5850

end

5765

end

5851

else

5766

else

5852

for k=phases

5767

for k=phases

5853

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

5768

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

5854

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

5769

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

5855

progress = k/length(phases);

5770

progress = k/length(phases);

5856

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

5771

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

5857

end

5772

end

5858

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

5773

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

5859

pdf=pdf_samples(pxi);

5774

pdf=pdf_samples(pxi);

5860

end

5775

end

5861

5776

5862

5777

5863

5778

5864

if OP.DISPLAY_WINDOW

5779

if OP.DISPLAY_WINDOW

5865

close(hwaitbar);

5780

close(hwaitbar);

5866

end

5781

end

5867

5782

5868

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

5783

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

5869

% Create PDF from interference vector using successive delta-set convolutions.

5784

% Create PDF from interference vector using successive delta-set convolutions.

5870

% input_vector = list of values of samples

5785

% input_vector = list of values of samples

5871

% return

5786

% return

5872

% pdf.x

5787

% pdf.x

5873

% pdf.y

5788

% pdf.y

5874

% pdf.vec

5789

% pdf.vec

5875

% pdf.bin

5790

% pdf.bin

5876

if ~exist('FAST_NOISE_CONV','var')

5791

if ~exist('FAST_NOISE_CONV','var')

5877

FAST_NOISE_CONV=0;

5792

FAST_NOISE_CONV=0;

5878

end

5793

end

5879

if max(input_vector) > BinSize

5794

if max(input_vector) > BinSize

5880

input_vector=input_vector(abs(input_vector)>BinSize);

5795

input_vector=input_vector(abs(input_vector)>BinSize);

5881

end

5796

end

5882

% for i = 1:length(input_vector)

5797

% for i = 1:length(input_vector)

5883

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

5798

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

5884

%end

5799

%end

5885

5800

5886

input_vector(abs(input_vector)<BinSize) = 0;

5801

input_vector(abs(input_vector)<BinSize) = 0;

5887

b=sign(input_vector);

5802

b=sign(input_vector);

5888

[input_vector,index]=sort(abs(input_vector),'descend');

5803

[input_vector,index]=sort(abs(input_vector),'descend');

5889

input_vector=input_vector.*b(index);

5804

input_vector=input_vector.*b(index);

5890

if FAST_NOISE_CONV

5805

if FAST_NOISE_CONV

5891

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

5806

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

5892

res_pdf= normal_dist(sig_res,5,BinSize);

5807

res_pdf= normal_dist(sig_res,5,BinSize);

5893

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

5808

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

5894

end

5809

end

5895

%% Equation 93A-39 %%

5810

%% Equation 93A-39 %%

5896

values = 2*(0:L-1)/(L-1)-1;

5811

values = 2*(0:L-1)/(L-1)-1;

5897

prob = ones(1,L)/L;

5812

prob = ones(1,L)/L;

5898

5813

5899

%% Initialize pdf to delta at 0

5814

%% Initialize pdf to delta at 0

5900

pdf=d_cpdf(BinSize, 0, 1);

5815

pdf=d_cpdf(BinSize, 0, 1);

5901

empty_pdf=pdf;

5816

empty_pdf=pdf;

5902

for k = 1:length(input_vector)

5817

for k = 1:length(input_vector)

5903

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

5818

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

5904

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

5819

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

5905

pdf=conv_fct(pdf, pdfn);

5820

pdf=conv_fct(pdf, pdfn);

5906

end

5821

end

5907

if FAST_NOISE_CONV

5822

if FAST_NOISE_CONV

5908

% pdf=conv_fct(pdf,res_pdf);

5823

% pdf=conv_fct(pdf,res_pdf);

5909

pdf=conv_fct_TEST(pdf,res_pdf);

5824

pdf=conv_fct_TEST(pdf,res_pdf);

5910

end

5825

end

5911

5826

5912

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

5827

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

5913

t_s_orig=t_s;

5828

t_s_orig=t_s;

5914

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

5829

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

5915

type=chdata.type;

5830

type=chdata.type;

5916

5831

5917

pulse_orig=chdata.eq_pulse_response(:)';

5832

pulse_orig=chdata.eq_pulse_response(:)';

5918

%build arbitrary time axis with step size = 1/samples per ui

5833

%build arbitrary time axis with step size = 1/samples per ui

5919

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

5834

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

5920

%force t_s at time =0 (makes the other things below easy)

5835

%force t_s at time =0 (makes the other things below easy)

5921

original_sample_time=old_time(t_s_orig);

5836

original_sample_time=old_time(t_s_orig);

5922

old_time=old_time-original_sample_time;

5837

old_time=old_time-original_sample_time;

5923

%build new time axis that forces time=0 to be in the axis

5838

%build new time axis that forces time=0 to be in the axis

5924

%unless the new/old samples per UI are integer ratios, time 0 will not be

5839

%unless the new/old samples per UI are integer ratios, time 0 will not be

5925

%there by default

5840

%there by default

5926

samp_UI=param.samples_for_C2M;

5841

samp_UI=param.samples_for_C2M;

5927

new_timea=[0:-1/samp_UI:min(old_time)];

5842

new_timea=[0:-1/samp_UI:min(old_time)];

5928

new_timeb=[0:1/samp_UI:max(old_time)];

5843

new_timeb=[0:1/samp_UI:max(old_time)];

5929

new_time=[fliplr(new_timea) new_timeb(2:end)];

5844

new_time=[fliplr(new_timea) new_timeb(2:end)];

5930

SBR=interp1(old_time,pulse_orig,new_time);

5845

SBR=interp1(old_time,pulse_orig,new_time);

5931

%new sample time is simply the point where new_time = 0

5846

%new sample time is simply the point where new_time = 0

5932

[tmp,t_s]=min(abs(new_time));

5847

[tmp,t_s]=min(abs(new_time));

5933

5848

5934

residual_response = SBR;

5849

residual_response = SBR;

5935

5850

5936

half_UI=get_center_of_UI(samp_UI);

5851

half_UI=get_center_of_UI(samp_UI);

5937

5852

5938

if isequal(type, 'THRU')

5853

if isequal(type, 'THRU')

5939

% for thru pulse response:

5854

% for thru pulse response:

5940

% remove the cursor and the DFE postcursors (up to their limit), since

5855

% remove the cursor and the DFE postcursors (up to their limit), since

5941

% we only care about the residuals.

5856

% we only care about the residuals.

5942

5857

5943

%AJG021820

5858

%AJG021820

5944

if ~param.Floating_DFE

5859

if ~param.Floating_DFE

5945

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

5860

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

5946

else

5861

else

5947

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

5862

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

5948

end

5863

end

5949

if param.dfe_delta ~= 0

5864

if param.dfe_delta ~= 0

5950

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);

5865

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);

5951

else

5866

else

5952

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5867

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5953

end

5868

end

5954

5869

5955

if ~param.Floating_DFE

5870

if ~param.Floating_DFE

5956

bmax_vec=residual_response(t_s)*[param.bmax];

5871

bmax_vec=residual_response(t_s)*[param.bmax];

5957

bmin_vec=residual_response(t_s)*[param.bmin];

5872

bmin_vec=residual_response(t_s)*[param.bmin];

5958

else

5873

else

5959

bmax_vec=residual_response(t_s)*[param.use_bmax];

5874

bmax_vec=residual_response(t_s)*[param.use_bmax];

5960

bmin_vec=residual_response(t_s)*[param.use_bmin];

5875

bmin_vec=residual_response(t_s)*[param.use_bmin];

5961

end

5876

end

5962

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5877

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5963

5878

5964

5879

5965

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

5880

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

5966

dfetaps=effective_cancelled_cursors/SBR(t_s);

5881

dfetaps=effective_cancelled_cursors/SBR(t_s);

5967

5882

5968

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5883

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5969

% really needed for COM, but helps debugging. May be factored out in future revisions.

5884

% really needed for COM, but helps debugging. May be factored out in future revisions.

5970

5885

5971

%avoid dividing samp_UI by 2 in case it is not even

5886

%avoid dividing samp_UI by 2 in case it is not even

5972

start_cancel=t_s-half_UI+1+samp_UI;

5887

start_cancel=t_s-half_UI+1+samp_UI;

5973

%AJG021820

5888

%AJG021820

5974

if ~param.Floating_DFE

5889

if ~param.Floating_DFE

5975

end_cancel=start_cancel+param.ndfe*samp_UI-1;

5890

end_cancel=start_cancel+param.ndfe*samp_UI-1;

5976

else

5891

else

5977

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

5892

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

5978

end

5893

end

5979

residual_response(start_cancel:end_cancel) = ...

5894

residual_response(start_cancel:end_cancel) = ...

5980

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5895

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5981

%else

5896

%else

5982

% for crosstalk pulse responses, nothing is cancelled, and all phases

5897

% for crosstalk pulse responses, nothing is cancelled, and all phases

5983

% are equally important.

5898

% are equally important.

5984

5899

5985

%remove entire cursor UI

5900

%remove entire cursor UI

5986

uiv_start=start_cancel-samp_UI;

5901

uiv_start=start_cancel-samp_UI;

5987

uiv_end=uiv_start+samp_UI-1;

5902

uiv_end=uiv_start+samp_UI-1;

5988

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

5903

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

5989

residual_response(uiv_start:uiv_end)=0;

5904

residual_response(uiv_start:uiv_end)=0;

5990

end

5905

end

5991

5906

5992

nui=round(length(residual_response)/samp_UI);

5907

nui=round(length(residual_response)/samp_UI);

5993

5908

5994

5909

5995

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5910

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5996

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

5911

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

5997

%response without DFE included. (Can't include DFE for jitter calc)

5912

%response without DFE included. (Can't include DFE for jitter calc)

5998

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5913

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5999

5914

6000

% if OP.DISPLAY_WINDOW,

5915

% if OP.DISPLAY_WINDOW,

6001

% hwaitbar=waitbar(0);

5916

% hwaitbar=waitbar(0);

6002

% end

5917

% end

6003

5918

6004

% determine which pdf to use

5919

% determine which pdf to use

6005

if isequal(type, 'THRU')

5920

if isequal(type, 'THRU')

6006

% one phase is interesting for thru

5921

% one phase is interesting for thru

6007

phases = mod(t_s,samp_UI);

5922

phases = mod(t_s,samp_UI);

6008

if phases==0, phases = samp_UI; end

5923

if phases==0, phases = samp_UI; end

6009

else

5924

else

6010

phases=1:samp_UI;

5925

phases=1:samp_UI;

6011

end

5926

end

6012

5927

6013

mxV = zeros(size(phases));

5928

mxV = zeros(size(phases));

6014

5929

6015

%phases reveals the raw position in the UI window of the cursor.

5930

%phases reveals the raw position in the UI window of the cursor.

6016

%shift_amount is the amount to shift so that it aligns with half_UI

5931

%shift_amount is the amount to shift so that it aligns with half_UI

6017

shift_amount=half_UI-phases;

5932

shift_amount=half_UI-phases;

6018

%vs_shift puts the cursor at the center

5933

%vs_shift puts the cursor at the center

6019

vs_shift=circshift(vs,[0 shift_amount]);

5934

vs_shift=circshift(vs,[0 shift_amount]);

6020

L=size(vs_raw,1);

5935

L=size(vs_raw,1);

6021

%allow partial UI computation through pdf_range

5936

%allow partial UI computation through pdf_range

6022

%if pdf_range is empty, do full UI

5937

%if pdf_range is empty, do full UI

6023

if isempty(pdf_range)

5938

if isempty(pdf_range)

6024

pdf_range=1:samp_UI;

5939

pdf_range=1:samp_UI;

6025

else

5940

else

6026

pdf_range=min(pdf_range):max(pdf_range);

5941

pdf_range=min(pdf_range):max(pdf_range);

6027

end

5942

end

6028

h_j_full=zeros(L,samp_UI);

5943

h_j_full=zeros(L,samp_UI);

6029

for k=pdf_range

5944

for k=pdf_range

6030

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

5945

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6031

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

5946

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6032

%progress = k/length(phases);

5947

%progress = k/length(phases);

6033

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

5948

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6034

5949

6035

%build the circshift of h_j_full into the loop to support a reduced

5950

%build the circshift of h_j_full into the loop to support a reduced

6036

%range of sampling points. circshift at the end only works if doing the

5951

%range of sampling points. circshift at the end only works if doing the

6037

%full range of sampling points. And shifting before the loop will

5952

%full range of sampling points. And shifting before the loop will

6038

%yield the wrong answer at the edges of the UI

5953

%yield the wrong answer at the edges of the UI

6039

hk=k-shift_amount;

5954

hk=k-shift_amount;

6040

if hk<1

5955

if hk<1

6041

hk=hk+samp_UI;

5956

hk=hk+samp_UI;

6042

elseif hk>samp_UI

5957

elseif hk>samp_UI

6043

hk=hk-samp_UI;

5958

hk=hk-samp_UI;

6044

end

5959

end

6045

if hk==1

5960

if hk==1

6046

%when hk=1, the early UI is the last column

5961

%when hk=1, the early UI is the last column

6047

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

5962

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6048

elseif hk==samp_UI

5963

elseif hk==samp_UI

6049

%when hk=samp_UI, the late UI is the first column

5964

%when hk=samp_UI, the late UI is the first column

6050

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

5965

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6051

else

5966

else

6052

%for all other cases, do the normal late=+1, early = -1

5967

%for all other cases, do the normal late=+1, early = -1

6053

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

5968

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6054

end

5969

end

6055

end

5970

end

6056

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

5971

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6057

% filename parsing and acquisition

5972

% filename parsing and acquisition

6058

%------------------------------------------------------------------

5973

%------------------------------------------------------------------

6059

%----------put files names into chdata structure ---------

5974

%----------put files names into chdata structure ---------

6060

% The thru file has the index of 1

5975

% The thru file has the index of 1

6061

% crosstalk file are indexed from 2

5976

% crosstalk file are indexed from 2

6062

% nxi is incremented each time a file is read in so that nxi will end

5977

% nxi is incremented each time a file is read in so that nxi will end

6063

filepath=[]; % path name for file

5978

filepath=[]; % path name for file

6064

nxi=0; % file index

5979

nxi=0; % file index

6065

% get the THRU file

5980

% get the THRU file

6066

if size(file_list,2) ~= 0

5981

if size(file_list,2) ~= 0

6067

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5982

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6068

[filepath, basename, fileext]=fileparts(file_list{1});

5983

[filepath, basename, fileext]=fileparts(file_list{1});

6069

5984

6070

else

5985

else

6071

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5986

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6072

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5987

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6073

movegui(h,'northeast')

5988

movegui(h,'northeast')

6074

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

5989

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6075

end

5990

end

6076

if OP.ERL == 2

5991

if OP.ERL == 2

6077

dir=fullfile(filepath, '*.s2p');

5992

dir=fullfile(filepath, '*.s2p');

6078

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

5993

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6079

if filepath == 0

5994

if filepath == 0

6080

error('No RL measurement file')

5995

error('No RL measurement file')

6081

end

5996

end

6082

else

5997

else

6083

dir=fullfile(filepath, '*.s4p');

5998

dir=fullfile(filepath, '*.s4p');

6084

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

5999

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6085

if filepath == 0

6000

if filepath == 0

6086

error('No Thru file')

6001

error('No Thru file')

6087

end

6002

end

6088

end

6003

end

6089

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6004

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6090

end

6005

end

6091

nxi=nxi+1;

6006

nxi=nxi+1;

6092

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6007

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6093

chdata(nxi).ext = fileext;

6008

chdata(nxi).ext = fileext;

6094

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6009

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6095

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6010

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6096

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6011

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6097

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6012

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6098

chdata(nxi).type='THRU';

6013

chdata(nxi).type='THRU';

6099

chdata(nxi).ftr=param.fb*param.f_v;

6014

chdata(nxi).ftr=param.fb*param.f_v;

6100

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6015

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6101

6016

6102

% now get FEXT file names into chdata structure

6017

% now get FEXT file names into chdata structure

6103

kxi=nxi;

6018

kxi=nxi;

6104

for nxi=kxi+1:num_fext+kxi

6019

for nxi=kxi+1:num_fext+kxi

6105

lastfilepath=filepath;

6020

lastfilepath=filepath;

6106

if size(file_list,2) ~= 0

6021

if size(file_list,2) ~= 0

6107

[filepath, basename, fileext]=fileparts(file_list{nxi});

6022

[filepath, basename, fileext]=fileparts(file_list{nxi});

6108

else

6023

else

6109

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6024

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6110

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6025

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6111

movegui(h,'northeast')

6026

movegui(h,'northeast')

6112

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6027

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6113

end

6028

end

6114

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6029

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6115

dir=fullfile(filepath, '*.s4p');

6030

dir=fullfile(filepath, '*.s4p');

6116

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6031

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6117

if filepath==0

6032

if filepath==0

6118

error('Not enough NEXT files')

6033

error('Not enough NEXT files')

6119

end

6034

end

6120

else

6035

else

6121

dir=fullfile(filepath, '*.s4p');

6036

dir=fullfile(filepath, '*.s4p');

6122

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6037

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6123

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6038

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6124

else

6039

else

6125

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6040

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6126

end

6041

end

6127

if filepath==0

6042

if filepath==0

6128

error('Not enough NEXT files')

6043

error('Not enough NEXT files')

6129

end

6044

end

6130

end

6045

end

6131

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6046

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6132

end

6047

end

6133

if isempty( filepath), filepath=lastfilepath; end

6048

if isempty( filepath), filepath=lastfilepath; end

6134

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6049

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6135

chdata(nxi).ext = fileext;

6050

chdata(nxi).ext = fileext;

6136

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6051

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6137

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6052

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6138

% chdata(nxi).A=param.a_fext;

6053

% chdata(nxi).A=param.a_fext;

6139

chdata(nxi).ftr=param.fb*param.f_v;

6054

chdata(nxi).ftr=param.fb*param.f_f;

6140

chdata(nxi).type='FEXT';

6055

chdata(nxi).type='FEXT';

6141

end

6056

end

6142

% now get NEXT file names into chdata structure

6057

% now get NEXT file names into chdata structure

6143

kxi=num_fext+kxi;

6058

kxi=num_fext+kxi;

6144

for nxi=kxi+1:num_next+kxi

6059

for nxi=kxi+1:num_next+kxi

6145

lastfilepath=filepath;

6060

lastfilepath=filepath;

6146

if size(file_list,2) ~= 0

6061

if size(file_list,2) ~= 0

6147

[filepath, basename, fileext]=fileparts(file_list{nxi});

6062

[filepath, basename, fileext]=fileparts(file_list{nxi});

6148

else

6063

else

6149

dir=fullfile(filepath, '*.s4p');

6064

dir=fullfile(filepath, '*.s4p');

6150

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6065

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6151

if filepath==0

6066

if filepath==0

6152

error('Not enough NEXT files')

6067

error('Not enough NEXT files')

6153

end

6068

end

6154

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6069

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6155

end

6070

end

6156

if isempty( filepath), filepath=lastfilepath; end

6071

if isempty( filepath), filepath=lastfilepath; end

6157

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6072

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6158

chdata(nxi).ext = fileext;

6073

chdata(nxi).ext = fileext;

6159

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6074

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6160

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6075

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6161

% chdata(nxi).A=param.A_next;

6076

% chdata(nxi).A=param.A_next;

6162

chdata(nxi).ftr=param.fb*param.f_v;

6077

chdata(nxi).ftr=param.fb*param.f_n;

6163

chdata(nxi).type='NEXT';

6078

chdata(nxi).type='NEXT';

6164

end

6079

end

6165

6080

6166

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6081

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6167

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6082

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6168

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6083

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6169

% H_r - receiver filter, Butterworth

6084

% H_r - receiver filter, Butterworth

6170

% H_ctf - total gain of CTLE and low freq filtering

6085

% H_ctf - total gain of CTLE and low freq filtering

6171

% H_dc - the common mode channel gain

6086

% H_dc - the common mode channel gain

6172

% param.eta_0 -input referred Rx noise

6087

% param.eta_0 -input referred Rx noise

6173

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6088

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6174

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6089

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6175

%% Equation 93A-35 - independent of FFE setting %%

6090

%% Equation 93A-35 - independent of FFE setting %%

6176

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

6091

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

6177

if sum(param.AC_CM_RMS) ~= 0

6092

if sum(param.AC_CM_RMS) ~= 0

6178

sigma_ACCM=0;

6093

sigma_ACCM=0;

6179

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6094

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6180

for i=1:length(chdata)

6095

for i=1:length(chdata)

6181

H_dc=abs(squeeze(chdata(i).sdc21));

6096

H_dc=abs(squeeze(chdata(i).sdc21));

6182

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) );

6097

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) );

6183

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6098

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6184

end

6099

end

6185

sigma_N=norm([sigma_N1,sigma_ACCM]);

6100

sigma_N=norm([sigma_N1,sigma_ACCM]);

6186

else

6101

else

6187

sigma_N=sigma_N1;

6102

sigma_N=sigma_N1;

6188

end

6103

end

6189

%%

6104

%%

6190

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6105

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6191

% for Rx calibratrion only

6106

% for Rx calibratrion only

6192

% the FEXT channel for calibration basically a DC connection unlike normal

6107

% the FEXT channel for calibration basically a DC connection unlike normal

6193

% FEXT channels which are nearly open at DC channels

6108

% FEXT channels which are nearly open at DC channels

6194

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6109

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6195

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6110

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6196

if size(chdata,2) >= 2

6111

if size(chdata,2) >= 2

6197

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6112

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6198

else

6113

else

6199

Hnoise_channel=1;

6114

Hnoise_channel=1;

6200

end

6115

end

6201

f=chdata(2).faxis;

6116

f=chdata(2).faxis;

6202

f_hp=param.f_hp;

6117

f_hp=param.f_hp;

6203

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6118

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6204

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6119

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6205

else

6120

else

6206

H_hp=ones(1,length(f));

6121

H_hp=ones(1,length(f));

6207

end

6122

end

6208

%% Equation 93A-47 or 162-12

6123

%% Equation 93A-47 or 162-12

6209

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6124

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6210

6125

6211

%% Equation 93A-48 or 162-14%%

6126

%% Equation 93A-48 or 162-14%%

6212

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6127

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6213

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6128

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6214

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6129

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6215

% Modified not to double count crosstalk: John Ewen 13/12/2018

6130

% Modified not to double count crosstalk: John Ewen 13/12/2018

6216

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6131

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6217

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6132

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6218

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6133

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6219

f=chdata(1).faxis;

6134

f=chdata(1).faxis;

6220

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6135

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6221

if(f(1)==0)

6136

if(f(1)==0)

6222

temp_angle(1)=1e-20;% we don't want to divide by zero

6137

temp_angle(1)=1e-20;% we don't want to divide by zero

6223

end

6138

end

6224

PWF_tx=ones(1,length(f));

6139

PWF_tx=ones(1,length(f));

6225

if max(upsampled_txffe) > 0

6140

if max(upsampled_txffe) > 0

6226

PWF_tx=zeros(1,length(f));

6141

PWF_tx=zeros(1,length(f));

6227

[mcur,icur] = max(upsampled_txffe);

6142

[mcur,icur] = max(upsampled_txffe);

6228

if exist('phase_memory','var') && ~isempty(phase_memory)

6143

if exist('phase_memory','var') && ~isempty(phase_memory)

6229

pre_calc=1;

6144

pre_calc=1;

6230

else

6145

else

6231

pre_calc=0;

6146

pre_calc=0;

6232

end

6147

end

6233

for ii=1:length(upsampled_txffe)

6148

for ii=1:length(upsampled_txffe)

6234

if upsampled_txffe(ii)==0

6149

if upsampled_txffe(ii)==0

6235

%speed up: skip cases when txffe=0

6150

%speed up: skip cases when txffe=0

6236

continue;

6151

continue;

6237

end

6152

end

6238

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6153

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6239

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6154

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6240

% that is needed

6155

% that is needed

6241

if ii==icur

6156

if ii==icur

6242

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6157

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6243

PWF_tx = PWF_tx + upsampled_txffe(ii);

6158

PWF_tx = PWF_tx + upsampled_txffe(ii);

6244

else

6159

else

6245

if pre_calc

6160

if pre_calc

6246

%speed up: avoid vector exp calculation by externally pre-calculating it

6161

%speed up: avoid vector exp calculation by externally pre-calculating it

6247

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6162

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6248

else

6163

else

6249

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6164

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6250

end

6165

end

6251

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6166

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6252

PWF_tx = PWF_tx + transpose(term_ii(:));

6167

PWF_tx = PWF_tx + transpose(term_ii(:));

6253

end

6168

end

6254

% /Adee

6169

% /Adee

6255

end

6170

end

6256

end

6171

end

6257

PWF_rx=ones(1,length(f));

6172

PWF_rx=ones(1,length(f));

6258

if exist('C','var')

6173

if exist('C','var')

6259

PWF_rx=zeros(1,length(f));

6174

PWF_rx=zeros(1,length(f));

6260

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6175

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6261

if C(ii+param.RxFFE_cmx+1)==0

6176

if C(ii+param.RxFFE_cmx+1)==0

6262

%speed up: skip cases when rxffe=0

6177

%speed up: skip cases when rxffe=0

6263

continue;

6178

continue;

6264

end

6179

end

6265

if ii+1==0

6180

if ii+1==0

6266

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6181

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6267

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6182

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6268

else

6183

else

6269

if pre_calc

6184

if pre_calc

6270

%speed up: avoid vector exp calculation by externally pre-calculating it

6185

%speed up: avoid vector exp calculation by externally pre-calculating it

6271

%The latter columns of phase_memory hold RXFFE shift vectors

6186

%The latter columns of phase_memory hold RXFFE shift vectors

6272

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6187

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6273

term_ii=transpose(term_ii);

6188

term_ii=transpose(term_ii);

6274

else

6189

else

6275

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6190

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6276

end

6191

end

6277

PWF_rx=PWF_rx+term_ii;

6192

PWF_rx=PWF_rx+term_ii;

6278

end

6193

end

6279

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6194

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6280

end

6195

end

6281

end

6196

end

6282

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6197

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6283

for ii=2:size(chdata,2)

6198

for ii=2:size(chdata,2)

6284

SINC = sin(temp_angle)./temp_angle;

6199

SINC = sin(temp_angle)./temp_angle;

6285

PWF_data=SINC.^2;

6200

PWF_data=SINC.^2;

6286

PWF=PWF_data.*PWF_rx; % power weight function

6201

PWF=PWF_data.*PWF_rx; % power weight function

6287

PWFnext=abs(PWF);

6202

PWFnext=abs(PWF);

6288

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6203

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6289

PWFfext=abs(PWF);

6204

PWFfext=abs(PWF);

6290

if isequal(chdata(ii).type, 'FEXT')

6205

if isequal(chdata(ii).type, 'FEXT')

6291

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6206

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6292

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

6207

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

6293

elseif isequal(chdata(ii).type, 'NEXT')

6208

elseif isequal(chdata(ii).type, 'NEXT')

6294

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6209

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6295

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

6210

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

6296

end

6211

end

6297

end

6212

end

6298

if nargout == 1 && isequal(type,'NEXT')

6213

if nargout == 1 && isequal(type,'NEXT')

6299

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6214

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6300

elseif nargout == 1 && isequal(type,'FEXT')

6215

elseif nargout == 1 && isequal(type,'FEXT')

6301

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6216

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6302

elseif nargout == 3

6217

elseif nargout == 3

6303

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6218

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6304

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6219

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6305

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6220

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6306

end

6221

end

6307

6222

6308

function out=hrem(h,index,N_bf,bmaxg)

6223

function out=hrem(h,index,N_bf,bmaxg)

6309

6224

6310

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) ];

6225

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) ];

6311

% faster than single line function

6226

% faster than single line function

6312

% hrem =@(h,index,N_bf,bmaxg) ...

6227

% hrem =@(h,index,N_bf,bmaxg) ...

6313

% [ h(1:index-1) ...

6228

% [ h(1:index-1) ...

6314

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6229

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6315

% h(index+N_bf:end) ]...

6230

% h(index+N_bf:end) ]...

6316

% ;

6231

% ;

6317

6232

6318

%% floating DFE taps

6233

%% floating DFE taps

6319

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6234

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6320

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6235

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6321

% Sout = interp_Sparam(Sin,fin,fout)

6236

% Sout = interp_Sparam(Sin,fin,fout)

6322

%

6237

%

6323

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6238

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6324

% fout.

6239

% fout.

6325

6240

6326

if ( fin(end)<fout(end) )

6241

if ( fin(end)<fout(end) )

6327

% warning('Channel high frequencies extrapolation might be inaccurate!');

6242

% warning('Channel high frequencies extrapolation might be inaccurate!');

6328

end

6243

end

6329

6244

6330

H_mag = abs(Sin);

6245

H_mag = abs(Sin);

6331

H_mag(H_mag<eps)=eps; % handle ill cases...

6246

H_mag(H_mag<eps)=eps; % handle ill cases...

6332

H_ph = unwrap(angle(Sin));

6247

H_ph = unwrap(angle(Sin));

6333

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6248

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6334

% user ignore that.

6249

% user ignore that.

6335

if mean(diff(H_ph))>0

6250

if mean(diff(H_ph))>0

6336

if OP.DEBUG

6251

if OP.DEBUG

6337

warning('Anti-causal response found. Finer frequency step is required for this channel');

6252

warning('Anti-causal response found. Finer frequency step is required for this channel');

6338

else

6253

else

6339

error('Anti-causal response found. Finer frequency step is required for this channel');

6254

error('Anti-causal response found. Finer frequency step is required for this channel');

6340

end

6255

end

6341

end

6256

end

6342

6257

6343

%opt_interp_Sparam_mag='linear_trend_to_DC';

6258

%opt_interp_Sparam_mag='linear_trend_to_DC';

6344

switch opt_interp_Sparam_mag

6259

switch opt_interp_Sparam_mag

6345

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6260

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6346

if -iscolumn(H_mag), H_mag=H_mag.';end

6261

if -iscolumn(H_mag), H_mag=H_mag.';end

6347

if -iscolumn(fin), fin=fin.';end

6262

if -iscolumn(fin), fin=fin.';end

6348

fin_x=fin;

6263

fin_x=fin;

6349

H_mag_x=H_mag(:);

6264

H_mag_x=H_mag(:);

6350

if fin(1)>0

6265

if fin(1)>0

6351

p=polyfit(fin(1:10), H_mag(1:10), 1);

6266

p=polyfit(fin(1:10), H_mag(1:10), 1);

6352

dc_trend_val=polyval(p, 0);

6267

dc_trend_val=polyval(p, 0);

6353

fin_x=[0, fin_x];

6268

fin_x=[0, fin_x];

6354

H_mag_x = [dc_trend_val; H_mag_x];

6269

H_mag_x = [dc_trend_val; H_mag_x];

6355

end

6270

end

6356

if fin(end)<fout(end)

6271

if fin(end)<fout(end)

6357

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6272

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6358

mid_freq_ind=round(length(fin)/2);

6273

mid_freq_ind=round(length(fin)/2);

6359

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6274

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6360

warning(warn_state);

6275

warning(warn_state);

6361

hf_trend_val=polyval(p, fout(end));

6276

hf_trend_val=polyval(p, fout(end));

6362

if hf_trend_val>H_mag(end)

6277

if hf_trend_val>H_mag(end)

6363

hf_trend_val=H_mag(end);

6278

hf_trend_val=H_mag(end);

6364

hf_logtrend_val = H_mag(end);

6279

hf_logtrend_val = H_mag(end);

6365

elseif hf_trend_val<eps

6280

elseif hf_trend_val<eps

6366

hf_trend_val=eps;

6281

hf_trend_val=eps;

6367

hf_logtrend_val = realmin;

6282

hf_logtrend_val = realmin;

6368

end

6283

end

6369

fin_x=[fin_x, fout(end)];

6284

fin_x=[fin_x, fout(end)];

6370

H_mag_x = [H_mag_x; hf_trend_val];

6285

H_mag_x = [H_mag_x; hf_trend_val];

6371

end

6286

end

6372

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6287

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6373

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6288

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6374

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6289

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6375

indx = find(fout > fin(end),1,'first');

6290

indx = find(fout > fin(end),1,'first');

6376

H_mag_i(indx:end) = H_logmag_i(indx:end);

6291

H_mag_i(indx:end) = H_logmag_i(indx:end);

6377

end

6292

end

6378

case 'trend_to_DC'

6293

case 'trend_to_DC'

6379

% extrapolate to trend value at DC.

6294

% extrapolate to trend value at DC.

6380

if -iscolumn(H_mag), H_mag=H_mag.';end

6295

if -iscolumn(H_mag), H_mag=H_mag.';end

6381

if -iscolumn(fin), fin=fin.';end

6296

if -iscolumn(fin), fin=fin.';end

6382

fin_x=fin;

6297

fin_x=fin;

6383

H_mag_x=H_mag;

6298

H_mag_x=H_mag;

6384

if fin(1)>0

6299

if fin(1)>0

6385

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6300

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6386

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6301

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6387

dc_trend_val=10^polyval(p, 0);

6302

dc_trend_val=10^polyval(p, 0);

6388

fin_x=[0, fin_x];

6303

fin_x=[0, fin_x];

6389

H_mag_x = [dc_trend_val H_mag_x];

6304

H_mag_x = [dc_trend_val H_mag_x];

6390

end

6305

end

6391

if fin(end)<fout(end)

6306

if fin(end)<fout(end)

6392

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6307

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6393

mid_freq_ind=round(length(fin)/2);

6308

mid_freq_ind=round(length(fin)/2);

6394

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6309

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6395

warning(warn_state);

6310

warning(warn_state);

6396

hf_trend_val=10^polyval(p, fout(end));

6311

hf_trend_val=10^polyval(p, fout(end));

6397

if hf_trend_val>H_mag(end)

6312

if hf_trend_val>H_mag(end)

6398

hf_trend_val=H_mag(end);

6313

hf_trend_val=H_mag(end);

6399

end

6314

end

6400

fin_x=[fin_x, fout(end)];

6315

fin_x=[fin_x, fout(end)];

6401

H_mag_x = [H_mag_x hf_trend_val];

6316

H_mag_x = [H_mag_x hf_trend_val];

6402

end

6317

end

6403

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6318

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6404

case 'extrap_to_DC_or_zero'

6319

case 'extrap_to_DC_or_zero'

6405

% same as extrap_to_DC but detect AC-coupled channels and

6320

% same as extrap_to_DC but detect AC-coupled channels and

6406

% extrapolate them to 0.

6321

% extrapolate them to 0.

6407

if fin(1)>0 && 20*log10(H_mag(1))<-20

6322

if fin(1)>0 && 20*log10(H_mag(1))<-20

6408

% assume AC coupling, with 0 at DC

6323

% assume AC coupling, with 0 at DC

6409

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6324

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6410

else

6325

else

6411

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6326

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6412

end

6327

end

6413

H_mag_i(fout>fin(end)) = H_mag(end);

6328

H_mag_i(fout>fin(end)) = H_mag(end);

6414

case 'extrap_to_DC'

6329

case 'extrap_to_DC'

6415

% first extrapolate down to DC, then use highest available frequency

6330

% first extrapolate down to DC, then use highest available frequency

6416

% for higher frequencies

6331

% for higher frequencies

6417

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6332

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6418

H_mag_i(fout>fin(end)) = H_mag(end);

6333

H_mag_i(fout>fin(end)) = H_mag(end);

6419

case 'old'

6334

case 'old'

6420

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6335

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6421

otherwise

6336

otherwise

6422

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6337

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6423

end

6338

end

6424

6339

6425

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6340

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6426

6341

6427

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6342

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6428

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6343

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6429

switch opt_interp_Sparam_phase

6344

switch opt_interp_Sparam_phase

6430

case 'old'

6345

case 'old'

6431

H_ph_i = H_ph_i-H_ph_i(1);

6346

H_ph_i = H_ph_i-H_ph_i(1);

6432

case 'zero_DC'

6347

case 'zero_DC'

6433

H_ph_i(1) = 0;

6348

H_ph_i(1) = 0;

6434

case 'interp_to_DC'

6349

case 'interp_to_DC'

6435

if fin(1) ~= 0

6350

if fin(1) ~= 0

6436

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6351

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6437

end

6352

end

6438

case 'extrap_cubic_to_dc_linear_to_inf'

6353

case 'extrap_cubic_to_dc_linear_to_inf'

6439

if fin(1) ~= 0

6354

if fin(1) ~= 0

6440

% estimate low frequency group delay

6355

% estimate low frequency group delay

6441

group_delay = -diff(H_ph(:))./diff(fin(:));

6356

group_delay = -diff(H_ph(:))./diff(fin(:));

6442

low_freq_gd = group_delay(1:50);

6357

low_freq_gd = group_delay(1:50);

6443

% calculate trend, throwing away outliers

6358

% calculate trend, throwing away outliers

6444

m = median(low_freq_gd); sigma = std(low_freq_gd);

6359

m = median(low_freq_gd); sigma = std(low_freq_gd);

6445

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6360

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6446

% correct outliers in first 10 phase samples

6361

% correct outliers in first 10 phase samples

6447

for k=10:-1:1

6362

for k=10:-1:1

6448

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6363

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6449

end

6364

end

6450

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6365

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6451

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6366

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6452

% modification - trend to inf

6367

% modification - trend to inf

6453

if (1)

6368

if (1)

6454

high_freq_gd = group_delay(end-50:end);

6369

high_freq_gd = group_delay(end-50:end);

6455

% calculate trend, throwing away outliers

6370

% calculate trend, throwing away outliers

6456

m = median(high_freq_gd); sigma = std(high_freq_gd);

6371

m = median(high_freq_gd); sigma = std(high_freq_gd);

6457

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6372

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6458

hf_extrap_range = find(fout>fin(end));

6373

hf_extrap_range = find(fout>fin(end));

6459

last_data_sample = hf_extrap_range(1)-1;

6374

last_data_sample = hf_extrap_range(1)-1;

6460

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6375

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6461

% for k=hf_range

6376

% for k=hf_range

6462

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6377

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6463

% end

6378

% end

6464

end

6379

end

6465

6380

6466

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6381

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6467

H_ph_i=H_ph_cubic;

6382

H_ph_i=H_ph_cubic;

6468

H_ph_i(indx:end) = H_ph_linear(indx:end);

6383

H_ph_i(indx:end) = H_ph_linear(indx:end);

6469

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6384

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6470

end

6385

end

6471

case 'interp_and_shift_to_DC'

6386

case 'interp_and_shift_to_DC'

6472

if fin(1) ~= 0

6387

if fin(1) ~= 0

6473

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6388

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6474

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6389

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6475

end

6390

end

6476

case 'trend_and_shift_to_DC'

6391

case 'trend_and_shift_to_DC'

6477

% estimate low frequency group delay

6392

% estimate low frequency group delay

6478

group_delay = -diff(H_ph(:))./diff(fin(:));

6393

group_delay = -diff(H_ph(:))./diff(fin(:));

6479

low_freq_gd = group_delay(1:50);

6394

low_freq_gd = group_delay(1:50);

6480

% calculate trend, throwing away outliers

6395

% calculate trend, throwing away outliers

6481

m = median(low_freq_gd); sigma = std(low_freq_gd);

6396

m = median(low_freq_gd); sigma = std(low_freq_gd);

6482

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6397

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6483

fin_x=fin;

6398

fin_x=fin;

6484

H_ph_x=H_ph(:);

6399

H_ph_x=H_ph(:);

6485

if fin(1) ~= 0

6400

if fin(1) ~= 0

6486

% correct outliers in first 10 phase samples

6401

% correct outliers in first 10 phase samples

6487

for k=10:-1:1

6402

for k=10:-1:1

6488

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6403

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6489

end

6404

end

6490

6405

6491

% shift all phase data so that DC extrapolation to 0 follows trend

6406

% shift all phase data so that DC extrapolation to 0 follows trend

6492

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6407

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6493

fin_x=[0, fin_x];

6408

fin_x=[0, fin_x];

6494

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6409

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6495

end

6410

end

6496

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6411

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6497

% the last two samples, so noise can create an inverted slope and

6412

% the last two samples, so noise can create an inverted slope and

6498

% non-causal response).

6413

% non-causal response).

6499

if fout(end)>fin(end)

6414

if fout(end)>fin(end)

6500

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6415

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6501

% p=polyfit(fin_x', H_ph_x, 1);

6416

% p=polyfit(fin_x', H_ph_x, 1);

6502

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6417

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6503

% hf_phase_trend=polyval(p,max(fout));

6418

% hf_phase_trend=polyval(p,max(fout));

6504

fin_x=[fin_x, fout(end)];

6419

fin_x=[fin_x, fout(end)];

6505

H_ph_x=[H_ph_x; hf_phase_trend];

6420

H_ph_x=[H_ph_x; hf_phase_trend];

6506

end

6421

end

6507

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6422

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6508

6423

6509

otherwise

6424

otherwise

6510

error('COM:Extrap:InvalidOption', ...

6425

error('COM:Extrap:InvalidOption', ...

6511

'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"');

6426

'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"');

6512

end

6427

end

6513

H_i = H_mag_i.*exp(1j*H_ph_i);

6428

H_i = H_mag_i.*exp(1j*H_ph_i);

6514

Sout=H_i;

6429

Sout=H_i;

6515

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6430

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6516

6431

6517

%This function makes the TX or RX package. The type input must be

6432

%This function makes the TX or RX package. The type input must be

6518

%'TX' or 'RX'

6433

%'TX' or 'RX'

6519

%If the mode argument is omitted, mode='dd' is assumed. Currently

6434

%If the mode argument is omitted, mode='dd' is assumed. Currently

6520

%mode='dc' is only used when making the TX package for AC CM noise

6435

%mode='dc' is only used when making the TX package for AC CM noise

6521

%inclusion. The Rx package for 'dc' mode is still generated using

6436

%inclusion. The Rx package for 'dc' mode is still generated using

6522

%the same parameters as 'dd' mode

6437

%the same parameters as 'dd' mode

6523

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6438

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6524

%

6439

%

6525

%One instance of package block looks like this (if no elements are set to 0):

6440

%One instance of package block looks like this (if no elements are set to 0):

6526

%-------------Lcomp----------Tline---------------

6441

%-------------Lcomp----------Tline---------------

6527

% | | |

6442

% | | |

6528

% Cpad Cbump Cball

6443

% Cpad Cbump Cball

6529

% | | |

6444

% | | |

6530

%------------------------------------------------

6445

%------------------------------------------------

6531

6446

6532

if nargin<6

6447

if nargin<6

6533

%optional input "include_die"=0 allows die parameters to be forced to 0

6448

%optional input "include_die"=0 allows die parameters to be forced to 0

6534

%this includes Cpad, Lcomp, and Cbump

6449

%this includes Cpad, Lcomp, and Cbump

6535

include_die=1;

6450

include_die=1;

6536

end

6451

end

6537

if nargin<5

6452

if nargin<5

6538

mode='dd';

6453

mode='dd';

6539

end

6454

end

6540

6455

6541

6456

6542

if ~isempty(param.PKG_NAME)

6457

if ~isempty(param.PKG_NAME)

6543

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6458

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6544

%so they are swapped in depending on if Tx or Rx is set for type

6459

%so they are swapped in depending on if Tx or Rx is set for type

6545

%Note that param is not returned from this function, so the swap does not persist

6460

%Note that param is not returned from this function, so the swap does not persist

6546

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6461

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6547

if strcmpi(type,'tx')

6462

if strcmpi(type,'tx')

6548

pkg_name = param.PKG_NAME{1};

6463

pkg_name = param.PKG_NAME{1};

6549

elseif strcmpi(type,'rx')

6464

elseif strcmpi(type,'rx')

6550

pkg_name = param.PKG_NAME{2};

6465

pkg_name = param.PKG_NAME{2};

6551

else

6466

else

6552

error('Pkg type must be Tx or Rx');

6467

error('Pkg type must be Tx or Rx');

6553

end

6468

end

6554

pkg_parameter_struct = param.PKG.(pkg_name);

6469

pkg_parameter_struct = param.PKG.(pkg_name);

6555

6470

6556

6471

6557

for j=1:length(swap_fields)

6472

for j=1:length(swap_fields)

6558

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6473

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6559

end

6474

end

6560

6475

6561

end

6476

end

6562

6477

6563

C_diepad = param.C_diepad;

6478

C_diepad = param.C_diepad;

6564

C_pkg_board = param.C_pkg_board;

6479

C_pkg_board = param.C_pkg_board;

6565

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6480

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6566

L_comp = param.L_comp;

6481

L_comp = param.L_comp;

6567

C_bump = param.C_bump;

6482

C_bump = param.C_bump;

6568

if ~include_die

6483

if ~include_die

6569

%best to multiply by 0. that way vectors maintain original size

6484

%best to multiply by 0. that way vectors maintain original size

6570

C_diepad=C_diepad*0;

6485

C_diepad=C_diepad*0;

6571

L_comp=L_comp*0;

6486

L_comp=L_comp*0;

6572

C_bump=C_bump*0;

6487

C_bump=C_bump*0;

6573

end

6488

end

6574

% [ahealey] End of modifications.

6489

% [ahealey] End of modifications.

6575

% generate TX package according to channel type.

6490

% generate TX package according to channel type.

6576

[ncases, mele]=size(param.z_p_next_cases);

6491

[ncases, mele]=size(param.z_p_next_cases);

6577

6492

6578

%Syntax update for C_diepad and L_comp

6493

%Syntax update for C_diepad and L_comp

6579

%Allow a chain of values to be entered as a matrix:

6494

%Allow a chain of values to be entered as a matrix:

6580

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6495

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6581

if isvector(C_diepad)

6496

if isvector(C_diepad)

6582

Cd_Tx=C_diepad(1);

6497

Cd_Tx=C_diepad(1);

6583

Cd_Rx=C_diepad(2);

6498

Cd_Rx=C_diepad(2);

6584

L_comp_Tx=L_comp(1);

6499

L_comp_Tx=L_comp(1);

6585

L_comp_Rx=L_comp(2);

6500

L_comp_Rx=L_comp(2);

6586

num_blocks=mele;

6501

num_blocks=mele;

6587

else

6502

else

6588

Cd_Tx=C_diepad(1,:);

6503

Cd_Tx=C_diepad(1,:);

6589

Cd_Rx=C_diepad(2,:);

6504

Cd_Rx=C_diepad(2,:);

6590

L_comp_Tx=L_comp(1,:);

6505

L_comp_Tx=L_comp(1,:);

6591

L_comp_Rx=L_comp(2,:);

6506

L_comp_Rx=L_comp(2,:);

6592

num_blocks=mele+length(Cd_Tx)-1;

6507

num_blocks=mele+length(Cd_Tx)-1;

6593

end

6508

end

6594

extra_LC=length(Cd_Tx)-1;

6509

extra_LC=length(Cd_Tx)-1;

6595

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6510

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6596

insert_zeros=zeros([1 extra_LC]);

6511

insert_zeros=zeros([1 extra_LC]);

6597

6512

6598

%Updated technique of building Tx/Rx packages

6513

%Updated technique of building Tx/Rx packages

6599

%each index corresponds to the package segment

6514

%each index corresponds to the package segment

6600

switch type

6515

switch type

6601

case 'TX'

6516

case 'TX'

6602

switch mele

6517

switch mele

6603

case 1

6518

case 1

6604

Cpad=Cd_Tx;

6519

Cpad=Cd_Tx;

6605

Lcomp=L_comp_Tx;

6520

Lcomp=L_comp_Tx;

6606

Cbump=C_bump(1);

6521

Cbump=C_bump(1);

6607

Cball=C_pkg_board(1);

6522

Cball=C_pkg_board(1);

6608

Zpkg=param.pkg_Z_c(1);

6523

Zpkg=param.pkg_Z_c(1);

6609

case 4

6524

case 4

6610

Cpad=[Cd_Tx 0 0 0];

6525

Cpad=[Cd_Tx 0 0 0];

6611

Lcomp=[L_comp_Tx 0 0 0];

6526

Lcomp=[L_comp_Tx 0 0 0];

6612

Cbump=[C_bump(1) 0 0 0];

6527

Cbump=[C_bump(1) 0 0 0];

6613

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6528

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6614

Zpkg=param.pkg_Z_c(1,:);

6529

Zpkg=param.pkg_Z_c(1,:);

6615

otherwise

6530

otherwise

6616

error('package syntax error')

6531

error('package syntax error')

6617

end

6532

end

6618

switch upper(channel_type)

6533

switch upper(channel_type)

6619

case 'THRU'

6534

case 'THRU'

6620

Len=param.Pkg_len_TX;

6535

Len=param.Pkg_len_TX;

6621

case 'NEXT'

6536

case 'NEXT'

6622

Len=param.Pkg_len_NEXT;

6537

Len=param.Pkg_len_NEXT;

6623

case 'FEXT'

6538

case 'FEXT'

6624

Len=param.Pkg_len_FEXT;

6539

Len=param.Pkg_len_FEXT;

6625

end

6540

end

6626

case 'RX'

6541

case 'RX'

6627

switch mele

6542

switch mele

6628

case 1

6543

case 1

6629

Cpad=Cd_Rx;

6544

Cpad=Cd_Rx;

6630

Lcomp=L_comp_Rx;

6545

Lcomp=L_comp_Rx;

6631

Cbump=C_bump(2);

6546

Cbump=C_bump(2);

6632

Cball=C_pkg_board(2);

6547

Cball=C_pkg_board(2);

6633

Zpkg=param.pkg_Z_c(2);

6548

Zpkg=param.pkg_Z_c(2);

6634

case 4

6549

case 4

6635

Cpad=[Cd_Rx 0 0 0];

6550

Cpad=[Cd_Rx 0 0 0];

6636

Lcomp=[L_comp_Rx 0 0 0];

6551

Lcomp=[L_comp_Rx 0 0 0];

6637

Cbump=[C_bump(2) 0 0 0];

6552

Cbump=[C_bump(2) 0 0 0];

6638

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6553

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6639

Zpkg=param.pkg_Z_c(2,:);

6554

Zpkg=param.pkg_Z_c(2,:);

6640

otherwise

6555

otherwise

6641

error('package syntax error')

6556

error('package syntax error')

6642

end

6557

end

6643

switch upper(channel_type)

6558

switch upper(channel_type)

6644

case 'THRU'

6559

case 'THRU'

6645

Len=param.Pkg_len_RX;

6560

Len=param.Pkg_len_RX;

6646

case 'NEXT'

6561

case 'NEXT'

6647

Len=param.Pkg_len_RX;

6562

Len=param.Pkg_len_RX;

6648

case 'FEXT'

6563

case 'FEXT'

6649

Len=param.Pkg_len_RX;

6564

Len=param.Pkg_len_RX;

6650

end

6565

end

6651

end

6566

end

6652

6567

6653

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6568

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6654

Cball=[insert_zeros Cball];

6569

Cball=[insert_zeros Cball];

6655

Cbump=[insert_zeros Cbump];

6570

Cbump=[insert_zeros Cbump];

6656

Len=[insert_zeros Len];

6571

Len=[insert_zeros Len];

6657

Zpkg=[insert_zeros Zpkg];

6572

Zpkg=[insert_zeros Zpkg];

6658

6573

6659

% debug_string='';

6574

% debug_string='';

6660

% for j=1:length(Zpkg)

6575

% for j=1:length(Zpkg)

6661

% if Cpad(j)~=0

6576

% if Cpad(j)~=0

6662

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6577

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6663

% end

6578

% end

6664

% if Lcomp(j)~=0

6579

% if Lcomp(j)~=0

6665

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6580

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6666

% end

6581

% end

6667

% if Cbump(j)~=0

6582

% if Cbump(j)~=0

6668

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6583

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6669

% end

6584

% end

6670

% if Len(j)~=0

6585

% if Len(j)~=0

6671

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6586

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6672

% end

6587

% end

6673

% if Cball(j)~=0

6588

% if Cball(j)~=0

6674

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6589

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6675

% end

6590

% end

6676

% end

6591

% end

6677

% if length(debug_string)>2

6592

% if length(debug_string)>2

6678

% debug_string=debug_string(3:end);

6593

% debug_string=debug_string(3:end);

6679

% end

6594

% end

6680

6595

6681

% tx package

6596

% tx package

6682

pkg_param=param;

6597

pkg_param=param;

6683

if strcmpi(mode,'dc')

6598

if strcmpi(mode,'dc')

6684

% change tx package to CC mode

6599

% change tx package to CC mode

6685

pkg_param.Z0=pkg_param.Z0/2;

6600

pkg_param.Z0=pkg_param.Z0/2;

6686

Cpad=Cpad*2;

6601

Cpad=Cpad*2;

6687

Cball=Cball*2;

6602

Cball=Cball*2;

6688

Zpkg=Zpkg*2;

6603

Zpkg=Zpkg*2;

6689

Lcomp=Lcomp/2;

6604

Lcomp=Lcomp/2;

6690

Cbump=Cbump*2;

6605

Cbump=Cbump*2;

6691

end

6606

end

6692

switch num_blocks

6607

switch num_blocks

6693

case 1

6608

case 1

6694

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6609

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6695

otherwise

6610

otherwise

6696

for j=1:num_blocks

6611

for j=1:num_blocks

6697

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6612

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6698

if j==1

6613

if j==1

6699

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6614

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6700

else

6615

else

6701

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6616

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6702

end

6617

end

6703

end

6618

end

6704

end

6619

end

6705

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6620

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6706

f(f<eps)=eps;

6621

f(f<eps)=eps;

6707

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6622

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6708

%% Equation 93A-8

6623

%% Equation 93A-8

6709

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6624

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6710

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6625

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6711

6626

6712

% [ahealey] Add compensating L and shunt C (bump) when requested.

6627

% [ahealey] Add compensating L and shunt C (bump) when requested.

6713

s12pad = s21pad;

6628

s12pad = s21pad;

6714

s22pad = s11pad;

6629

s22pad = s11pad;

6715

if nargin > 6

6630

if nargin > 6

6716

lcomp = varargin{1};

6631

lcomp = varargin{1};

6717

if lcomp>0

6632

if lcomp>0

6718

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6633

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6719

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6634

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6720

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6635

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6721

s11pad, s12pad, s21pad, s22pad, ...

6636

s11pad, s12pad, s21pad, s22pad, ...

6722

s11comp, s21comp, s21comp, s11comp);

6637

s11comp, s21comp, s21comp, s11comp);

6723

end

6638

end

6724

end

6639

end

6725

if nargin > 7

6640

if nargin > 7

6726

cbump = varargin{2};

6641

cbump = varargin{2};

6727

if cbump>0

6642

if cbump>0

6728

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

6643

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

6729

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

6644

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

6730

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6645

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6731

s11pad, s12pad, s21pad, s22pad, ...

6646

s11pad, s12pad, s21pad, s22pad, ...

6732

s11bump, s21bump, s21bump, s11bump);

6647

s11bump, s21bump, s21bump, s11bump);

6733

end

6648

end

6734

end

6649

end

6735

% [ahealey] End of modifications.

6650

% [ahealey] End of modifications.

6736

6651

6737

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

6652

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

6738

% [ahealey] Symmetry cannot be assumed with more complex termination models.

6653

% [ahealey] Symmetry cannot be assumed with more complex termination models.

6739

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

6654

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

6740

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

6655

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

6741

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

6656

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

6742

s11pad, s12pad, s21pad, s22pad, ...

6657

s11pad, s12pad, s21pad, s22pad, ...

6743

S11, S21, S21, S11);

6658

S11, S21, S21, S11);

6744

% [ahealey] End of modifications.

6659

% [ahealey] End of modifications.

6745

6660

6746

%% Equation 93A-8

6661

%% Equation 93A-8

6747

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

6662

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

6748

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

6663

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

6749

[ s11out, s12out, s21out, s22out ]= ...

6664

[ s11out, s12out, s21out, s22out ]= ...

6750

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

6665

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

6751

6666

6752

function missingParameter (parameterName)

6667

function missingParameter (parameterName)

6753

error( 'error:badParameterInformation', ...

6668

error( 'error:badParameterInformation', ...

6754

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

6669

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

6755

6670

6756

function pdf = normal_dist(sigma,nsigma,binsize)

6671

function pdf = normal_dist(sigma,nsigma,binsize)

6757

pdf.BinSize=binsize;

6672

pdf.BinSize=binsize;

6758

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

6673

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

6759

pdf.x=(pdf.Min:-pdf.Min)*binsize;

6674

pdf.x=(pdf.Min:-pdf.Min)*binsize;

6760

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

6675

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

6761

pdf.y=pdf.y/sum(pdf.y);

6676

pdf.y=pdf.y/sum(pdf.y);

6762

6677

6763

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

6678

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

6764

%% input

6679

%% input

6765

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

6680

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

6766

% baud_rate - baud rate in seconds

6681

% baud_rate - baud rate in seconds

6767

% param.samples_per_ui = samples per UI of IR

6682

% param.samples_per_ui = samples per UI of IR

6768

% param.max_ctle - maximum ac to dc gain in dB

6683

% param.max_ctle - maximum ac to dc gain in dB

6769

% param.tx_ffe(1) - maximum pre cursor (positive value)

6684

% param.tx_ffe(1) - maximum pre cursor (positive value)

6770

% param.tx_ffe(2) - maximum post cursor (positive value)

6685

% param.tx_ffe(2) - maximum post cursor (positive value)

6771

% param.tx_ffe_step - sweep step size for tx pre and post taps

6686

% param.tx_ffe_step - sweep step size for tx pre and post taps

6772

% param.ndfe - number of reference dfe taps

6687

% param.ndfe - number of reference dfe taps

6773

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

6688

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

6774

% output

6689

% output

6775

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

6690

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

6776

% result.eq.ctle - index of CTLE parameters in table

6691

% result.eq.ctle - index of CTLE parameters in table

6777

% result.IR - impulse response

6692

% result.IR - impulse response

6778

% result.avail_signal - maximum signal after equalization

6693

% result.avail_signal - maximum signal after equalization

6779

% result.avail_sig_index - index in result.IR of max signal

6694

% result.avail_sig_index - index in result.IR of max signal

6780

% result.best_FOM - best raw ISI

6695

% result.best_FOM - best raw ISI

6781

6696

6782

min_number_of_UI_in_response=40;

6697

min_number_of_UI_in_response=40;

6783

baud_rate=1/param.ui;

6698

baud_rate=1/param.ui;

6784

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

6699

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

6785

f=chdata(1).faxis;

6700

f=chdata(1).faxis;

6786

6701

6787

%Read user input of ts_sample_adj_range

6702

%Read user input of ts_sample_adj_range

6788

%if one value was entered, go from 0 to that value

6703

%if one value was entered, go from 0 to that value

6789

%if 2 values were entered, go from the 1st value to the 2nd value

6704

%if 2 values were entered, go from the 1st value to the 2nd value

6790

if length(param.ts_sample_adj_range)==1

6705

if length(param.ts_sample_adj_range)==1

6791

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

6706

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

6792

param.ts_sample_adj_range(1)=0;

6707

param.ts_sample_adj_range(1)=0;

6793

end

6708

end

6794

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

6709

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

6795

6710

6796

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

6711

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

6797

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

6712

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

6798

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

6713

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

6799

% need to include H_RCos in noise and when computing the system ir for thru

6714

% need to include H_RCos in noise and when computing the system ir for thru

6800

% and crosstalk

6715

% and crosstalk

6801

H_r=H_bw.*H_bt.*H_RCos;

6716

H_r=H_bw.*H_bt.*H_RCos;

6802

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

6717

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

6803

% Get f vector from 0 to Fs/2-delta_f.

6718

% Get f vector from 0 to Fs/2-delta_f.

6804

N_fft_by2 = 512;

6719

N_fft_by2 = 512;

6805

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

6720

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

6806

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

6721

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

6807

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

6722

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

6808

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

6723

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

6809

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

6724

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

6810

%%

6725

%%

6811

6726

6812

% system noise H_sy PSD

6727

% system noise H_sy PSD

6813

if OP.USE_ETA0_PSD

6728

if OP.USE_ETA0_PSD

6814

fspike=1e9;

6729

fspike=1e9;

6815

% requires communication tool box if used

6730

% requires communication tool box if used

6816

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

6731

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

6817

else

6732

else

6818

H_sy=ones(1,length(chdata(1).faxis));

6733

H_sy=ones(1,length(chdata(1).faxis));

6819

end

6734

end

6820

6735

6821

%Build txffe values dynamically

6736

%Build txffe values dynamically

6822

%any param field that is "tx_ffe_cm<X>_values" is a precursor

6737

%any param field that is "tx_ffe_cm<X>_values" is a precursor

6823

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

6738

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

6824

%where <X> is any integer

6739

%where <X> is any integer

6825

param_fields=fieldnames(param);

6740

param_fields=fieldnames(param);

6826

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

6741

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

6827

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

6742

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

6828

num_taps=num_pre+num_post;

6743

num_taps=num_pre+num_post;

6829

cur=num_pre+1;

6744

cur=num_pre+1;

6830

%txffe_cell combines all the txffe values into a single cell array

6745

%txffe_cell combines all the txffe values into a single cell array

6831

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

6746

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

6832

txffe_cell=cell(1,num_taps);

6747

txffe_cell=cell(1,num_taps);

6833

for k=num_pre:-1:1

6748

for k=num_pre:-1:1

6834

idx=num_pre-k+1;

6749

idx=num_pre-k+1;

6835

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

6750

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

6836

txffe_cell{idx}=param.(this_tx_field);

6751

txffe_cell{idx}=param.(this_tx_field);

6837

end

6752

end

6838

for k=1:num_post

6753

for k=1:num_post

6839

idx=k+num_pre;

6754

idx=k+num_pre;

6840

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

6755

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

6841

txffe_cell{idx}=param.(this_tx_field);

6756

txffe_cell{idx}=param.(this_tx_field);

6842

end

6757

end

6843

%total number of txffe runs is the product of the lengths of each tap

6758

%total number of txffe runs is the product of the lengths of each tap

6844

txffe_lengths=cellfun('length',txffe_cell);

6759

txffe_lengths=cellfun('length',txffe_cell);

6845

if isempty(txffe_cell)

6760

if isempty(txffe_cell)

6846

num_txffe_runs=1;

6761

num_txffe_runs=1;

6847

else

6762

else

6848

num_txffe_runs=prod(txffe_lengths);

6763

num_txffe_runs=prod(txffe_lengths);

6849

end

6764

end

6850

%txffe_sweep_indices are used in the LOCAL_SEARCH block

6765

%txffe_sweep_indices are used in the LOCAL_SEARCH block

6851

%any tap with length=1 can be ignored

6766

%any tap with length=1 can be ignored

6852

%Also is statistically likely that taps with greater number of values

6767

%Also is statistically likely that taps with greater number of values

6853

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

6768

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

6854

txffe_sweep_indices=find(txffe_lengths>1);

6769

txffe_sweep_indices=find(txffe_lengths>1);

6855

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

6770

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

6856

txffe_sweep_indices=txffe_sweep_indices(length_sort);

6771

txffe_sweep_indices=txffe_sweep_indices(length_sort);

6857

num_txffe_sweep_indices=length(txffe_sweep_indices);

6772

num_txffe_sweep_indices=length(txffe_sweep_indices);

6858

6773

6859

gdc_values = param.ctle_gdc_values;

6774

gdc_values = param.ctle_gdc_values;

6860

Gffe_values = param.cursor_gain;

6775

Gffe_values = param.cursor_gain;

6861

switch param.CTLE_type

6776

switch param.CTLE_type

6862

case 'CL93'

6777

case 'CL93'

6863

case 'CL120d'

6778

case 'CL120d'

6864

g_DC_HP_values =param.g_DC_HP_values;

6779

g_DC_HP_values =param.g_DC_HP_values;

6865

case 'CL120e'

6780

case 'CL120e'

6866

f_HP_Z=param.f_HP_Z;

6781

f_HP_Z=param.f_HP_Z;

6867

f_HP_P=param.f_HP_P;

6782

f_HP_P=param.f_HP_P;

6868

6783

6869

end

6784

end

6870

best_ctle = [];

6785

best_ctle = [];

6871

best_FOM = -inf;

6786

best_FOM = -inf;

6872

best_txffe = [];

6787

best_txffe = [];

6873

delta_sbr = [];

6788

delta_sbr = [];

6874

PSD_results=[];

6789

PSD_results=[];

6875

MMSE_results=[];

6790

MMSE_results=[];

6876

best_bmax=param.bmax;

6791

best_bmax=param.bmax;

6877

%AJG021820

6792

%AJG021820

6878

best_bmin=param.bmin;

6793

best_bmin=param.bmin;

6879

h_J=[];

6794

h_J=[];

6880

pxi=0;

6795

pxi=0;

6881

if OP.DISPLAY_WINDOW

6796

if OP.DISPLAY_WINDOW

6882

hwaitbar=waitbar(0);

6797

hwaitbar=waitbar(0);

6883

else

6798

else

6884

fprintf('FOM search ');

6799

fprintf('FOM search ');

6885

end

6800

end

6886

FOM=0;

6801

FOM=0;

6887

if ~OP.RxFFE

6802

if ~OP.RxFFE

6888

Gffe_values=0;

6803

Gffe_values=0;

6889

end

6804

end

6890

param.ndfe_passed=param.ndfe;

6805

param.ndfe_passed=param.ndfe;

6891

old_loops=0;

6806

old_loops=0;

6892

new_loops=0;

6807

new_loops=0;

6893

6808

6894

%GDC Qual construction

6809

%GDC Qual construction

6895

gqual= param.gqual;

6810

gqual= param.gqual;

6896

g2qual=param.g2qual;

6811

g2qual=param.g2qual;

6897

if ~strcmp(param.CTLE_type,'CL120d')

6812

if ~strcmp(param.CTLE_type,'CL120d')

6898

qual=ones(1,length(gdc_values));

6813

qual=ones(1,length(gdc_values));

6899

else

6814

else

6900

if isempty(gqual) && isempty(g2qual)

6815

if isempty(gqual) && isempty(g2qual)

6901

qual=ones(length(g_DC_HP_values),length(gdc_values));

6816

qual=ones(length(g_DC_HP_values),length(gdc_values));

6902

else

6817

else

6903

qual=zeros(length(g_DC_HP_values),length(gdc_values));

6818

qual=zeros(length(g_DC_HP_values),length(gdc_values));

6904

6819

6905

%prepare gqual and g2qual

6820

%prepare gqual and g2qual

6906

[g2qual,si]=sort(g2qual,'descend');

6821

[g2qual,si]=sort(g2qual,'descend');

6907

gqual=gqual(si,:);

6822

gqual=gqual(si,:);

6908

tmp=g2qual;

6823

tmp=g2qual;

6909

g2qual=zeros(length(tmp),2);

6824

g2qual=zeros(length(tmp),2);

6910

for kk=1:length(tmp)

6825

for kk=1:length(tmp)

6911

if kk==1

6826

if kk==1

6912

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

6827

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

6913

else

6828

else

6914

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

6829

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

6915

end

6830

end

6916

gqual(kk,:)=sort(gqual(kk,:),'descend');

6831

gqual(kk,:)=sort(gqual(kk,:),'descend');

6917

end

6832

end

6918

6833

6919

%Qual Construction

6834

%Qual Construction

6920

for jj=1:length(g_DC_HP_values)

6835

for jj=1:length(g_DC_HP_values)

6921

for ii=1:length(gdc_values)

6836

for ii=1:length(gdc_values)

6922

for kk=1:size(gqual,1)

6837

for kk=1:size(gqual,1)

6923

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

6838

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

6924

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

6839

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

6925

qual(jj,ii)=1;

6840

qual(jj,ii)=1;

6926

break;

6841

break;

6927

end

6842

end

6928

end

6843

end

6929

end

6844

end

6930

end

6845

end

6931

end

6846

end

6932

end

6847

end

6933

end

6848

end

6934

6849

6935

progress_interval=0.025;

6850

progress_interval=0.025;

6936

if do_C2M

6851

if do_C2M

6937

loop_count=[1 2];

6852

loop_count=[1 2];

6938

T_O=floor((param.T_O/1000)*param.samples_per_ui);

6853

T_O=floor((param.T_O/1000)*param.samples_per_ui);

6939

T_O=max(0,T_O);

6854

T_O=max(0,T_O);

6940

else

6855

else

6941

loop_count=1;

6856

loop_count=1;

6942

T_O=0;

6857

T_O=0;

6943

end

6858

end

6944

switch param.CTLE_type

6859

switch param.CTLE_type

6945

case 'CL93'

6860

case 'CL93'

6946

lf_indx=1;

6861

lf_indx=1;

6947

case 'CL120d'

6862

case 'CL120d'

6948

lf_indx=length(g_DC_HP_values);

6863

lf_indx=length(g_DC_HP_values);

6949

case 'CL120e'

6864

case 'CL120e'

6950

lf_indx=1;

6865

lf_indx=1;

6951

end

6866

end

6952

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

6867

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

6953

if OP.Optimize_loop_speed_up == 1

6868

if OP.Optimize_loop_speed_up == 1

6954

OP.BinSize = 1e-4;

6869

OP.BinSize = 1e-4;

6955

OP.impulse_response_truncation_threshold = 1e-3;

6870

OP.impulse_response_truncation_threshold = 1e-3;

6956

end

6871

end

6957

6872

6958

%Used to speed up FFE by only performing circshift when necessary

6873

%Used to speed up FFE by only performing circshift when necessary

6959

pulse_struc(1).pulse_ctle_circshift=[];

6874

pulse_struc(1).pulse_ctle_circshift=[];

6960

ctle_response_updated=1;

6875

ctle_response_updated=1;

6961

6876

6962

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

6877

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

6963

calc_exp_phase=0;

6878

calc_exp_phase=0;

6964

6879

6965

%calculate cur index and pre/post indices outside of the loop

6880

%calculate cur index and pre/post indices outside of the loop

6966

cur_start=cur;

6881

cur_start=cur;

6967

precursor_indices=[];

6882

precursor_indices=[];

6968

postcursor_indices=[];

6883

postcursor_indices=[];

6969

auto_count_trigger=0;

6884

auto_count_trigger=0;

6970

for kv=1:num_taps

6885

for kv=1:num_taps

6971

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

6886

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

6972

%precursor values fill the beginning of the vector. Any empty precursor means

6887

%precursor values fill the beginning of the vector. Any empty precursor means

6973

%cursor position must be subtracted by 1

6888

%cursor position must be subtracted by 1

6974

if kv<cur_start

6889

if kv<cur_start

6975

cur=cur-1;

6890

cur=cur-1;

6976

end

6891

end

6977

else

6892

else

6978

%non empty value: add to precursor or postcursor indices depending on position

6893

%non empty value: add to precursor or postcursor indices depending on position

6979

%in the vector

6894

%in the vector

6980

if kv<cur_start

6895

if kv<cur_start

6981

auto_count_trigger=1;

6896

auto_count_trigger=1;

6982

precursor_indices=[precursor_indices kv];

6897

precursor_indices=[precursor_indices kv];

6983

else

6898

else

6984

auto_count_trigger=0;

6899

auto_count_trigger=0;

6985

postcursor_indices=[postcursor_indices kv];

6900

postcursor_indices=[postcursor_indices kv];

6986

end

6901

end

6987

end

6902

end

6988

end

6903

end

6989

if ~isempty(postcursor_indices)

6904

if ~isempty(postcursor_indices)

6990

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

6905

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

6991

end

6906

end

6992

6907

6993

%Calculate the full grid matrix of all txffe combinations

6908

%Calculate the full grid matrix of all txffe combinations

6994

if isempty(txffe_cell)

6909

if isempty(txffe_cell)

6995

TXFFE_grid=0;

6910

TXFFE_grid=0;

6996

FULL_tx_index_vector=1;

6911

FULL_tx_index_vector=1;

6997

else

6912

else

6998

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

6913

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

6999

%Also calculate the full grid matrix for the index used in each txffe combination

6914

%Also calculate the full grid matrix for the index used in each txffe combination

7000

%(the index is used in the LOCAL SEARCH block)

6915

%(the index is used in the LOCAL SEARCH block)

7001

for k=1:num_taps

6916

for k=1:num_taps

7002

txffe_index_cell{k}=1:txffe_lengths(k);

6917

txffe_index_cell{k}=1:txffe_lengths(k);

7003

end

6918

end

7004

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

6919

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

7005

end

6920

end

7006

6921

7007

%pre-calculate cursor to save time

6922

%pre-calculate cursor to save time

7008

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

6923

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

7009

6924

7010

%pre-calculate full txffe for each iteration to save time

6925

%pre-calculate full txffe for each iteration to save time

7011

precursor_matrix=TXFFE_grid(:,precursor_indices);

6926

precursor_matrix=TXFFE_grid(:,precursor_indices);

7012

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

6927

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7013

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

6928

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7014

6929

7015

if OP.TDMODE

6930

if OP.TDMODE

7016

uneq_field='uneq_pulse_response';

6931

uneq_field='uneq_pulse_response';

7017

ctle_field='ctle_pulse_response';

6932

ctle_field='ctle_pulse_response';

7018

else

6933

else

7019

uneq_field='uneq_imp_response';

6934

uneq_field='uneq_imp_response';

7020

ctle_field='ctle_imp_response';

6935

ctle_field='ctle_imp_response';

7021

end

6936

end

7022

6937

7023

%Speed up search for max(sbr)

6938

%Speed up search for max(sbr)

7024

if OP.TDMODE

6939

if OP.TDMODE

7025

[~,init_max]=max(chdata(1).uneq_pulse_response);

6940

[~,init_max]=max(chdata(1).uneq_pulse_response);

7026

else

6941

else

7027

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

6942

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7028

end

6943

end

7029

UI_max_window=20;

6944

UI_max_window=20;

7030

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

6945

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7031

if start_max_idx<1

6946

if start_max_idx<1

7032

start_max_idx=1;

6947

start_max_idx=1;

7033

end

6948

end

7034

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

6949

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7035

if end_max_idx>length(chdata(1).(uneq_field))

6950

if end_max_idx>length(chdata(1).(uneq_field))

7036

end_max_idx=length(chdata(1).(uneq_field));

6951

end_max_idx=length(chdata(1).(uneq_field));

7037

end

6952

end

7038

6953

7039

itick_skips=0;

6954

itick_skips=0;

7040

itick_cases=0;

6955

itick_cases=0;

7041

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

6956

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7042

for i=loop_count

6957

for i=loop_count

7043

6958

7044

for Gffe_index=1:length(Gffe_values)

6959

for Gffe_index=1:length(Gffe_values)

7045

param.current_ffegain=Gffe_values(Gffe_index);

6960

param.current_ffegain=Gffe_values(Gffe_index);

7046

for ctle_index=1:length(gdc_values)

6961

for ctle_index=1:length(gdc_values)

7047

g_dc = gdc_values(ctle_index);

6962

g_dc = gdc_values(ctle_index);

7048

kacdc = 10^(g_dc/20);

6963

kacdc = 10^(g_dc/20);

7049

CTLE_fp1 = param.CTLE_fp1(ctle_index);

6964

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7050

CTLE_fp2 = param.CTLE_fp2(ctle_index);

6965

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7051

CTLE_fz = param.CTLE_fz(ctle_index);

6966

CTLE_fz = param.CTLE_fz(ctle_index);

7052

switch param.CTLE_type

6967

switch param.CTLE_type

7053

case 'CL93'

6968

case 'CL93'

7054

%

6969

%

7055

case 'CL120d'

6970

case 'CL120d'

7056

%

6971

%

7057

case 'CL120e'

6972

case 'CL120e'

7058

HP_Z = param.f_HP_Z(ctle_index);

6973

HP_Z = param.f_HP_Z(ctle_index);

7059

HP_P = param.f_HP_P(ctle_index);

6974

HP_P = param.f_HP_P(ctle_index);

7060

end

6975

end

7061

%% HF Boost

6976

%% HF Boost

7062

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

6977

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7063

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

6978

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7064

%% Mid Frequency Boost

6979

%% Mid Frequency Boost

7065

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

6980

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7066

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

6981

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7067

for g_LP_index=1:lf_indx

6982

for g_LP_index=1:lf_indx

7068

6983

7069

%GDC Qual Check

6984

%GDC Qual Check

7070

if qual(g_LP_index,ctle_index)==0

6985

if qual(g_LP_index,ctle_index)==0

7071

pxi=pxi+num_txffe_runs;

6986

pxi=pxi+num_txffe_runs;

7072

continue;

6987

continue;

7073

end

6988

end

7074

6989

7075

switch param.CTLE_type

6990

switch param.CTLE_type

7076

case 'CL93'

6991

case 'CL93'

7077

H_low=1;

6992

H_low=1;

7078

kacde_DC_low=1;

6993

kacde_DC_low=1;

7079

case 'CL120d'

6994

case 'CL120d'

7080

g_DC_low = g_DC_HP_values(g_LP_index);

6995

g_DC_low = g_DC_HP_values(g_LP_index);

7081

f_HP=param.f_HP(g_LP_index);

6996

f_HP=param.f_HP(g_LP_index);

7082

kacde_DC_low = 10^(g_DC_low/20);

6997

kacde_DC_low = 10^(g_DC_low/20);

7083

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

6998

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7084

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

6999

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7085

case 'CL120e' % z1 has been adusted on read in

7000

case 'CL120e' % z1 has been adusted on read in

7086

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7001

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7087

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7002

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7088

end

7003

end

7089

H_ctf=H_low.*ctle_gain;

7004

H_ctf=H_low.*ctle_gain;

7090

switch upper(OP.FFE_OPT_METHOD)

7005

switch upper(OP.FFE_OPT_METHOD)

7091

case 'WIENER-HOPF'

7006

case 'WIENER-HOPF'

7092

%% Bill Kirkland

7007

%% Bill Kirkland

7093

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7008

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7094

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7009

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7095

% use Fourier Transform pair for correlation as we have to

7010

% use Fourier Transform pair for correlation as we have to

7096

% take ifft of H_r anyways.

7011

% take ifft of H_r anyways.

7097

% onesided and two sided responses - tricky, tricky, tricky

7012

% onesided and two sided responses - tricky, tricky, tricky

7098

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7013

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7099

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7014

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7100

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7015

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7101

7016

7102

if OP.Do_White_Noise

7017

if OP.Do_White_Noise

7103

Noise_XC = Noise_XC(1);

7018

Noise_XC = Noise_XC(1);

7104

end

7019

end

7105

otherwise

7020

otherwise

7106

Noise_XC=[];

7021

Noise_XC=[];

7107

end

7022

end

7108

7023

7109

7024

7110

7025

7111

if OP.INCLUDE_CTLE==1

7026

if OP.INCLUDE_CTLE==1

7112

for k=1:param.num_s4p_files

7027

for k=1:param.num_s4p_files

7113

ir_peak = max(abs(chdata(k).(uneq_field)));

7028

ir_peak = max(abs(chdata(k).(uneq_field)));

7114

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7029

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7115

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7030

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7116

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7031

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7117

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7032

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7118

switch param.CTLE_type

7033

switch param.CTLE_type

7119

case 'CL93'

7034

case 'CL93'

7120

case 'CL120d'

7035

case 'CL120d'

7121

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7036

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7122

case 'CL120e' % z1 has been adusted on read in

7037

case 'CL120e' % z1 has been adusted on read in

7123

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7038

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7124

end

7039

end

7125

end

7040

end

7126

%set the flag to show ctle response was updated

7041

%set the flag to show ctle response was updated

7127

ctle_response_updated=1;

7042

ctle_response_updated=1;

7128

else

7043

else

7129

for k=1:param.num_s4p_files

7044

for k=1:param.num_s4p_files

7130

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7045

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7131

end

7046

end

7132

end

7047

end

7133

for k=1:param.num_s4p_files

7048

for k=1:param.num_s4p_files

7134

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7049

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7135

end

7050

end

7136

%% Equation 93A-22 %%

7051

%% Equation 93A-22 %%

7137

% figure(1000)

7052

% figure(1000)

7138

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7053

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7139

% hold on

7054

% hold on

7140

if OP.RX_CALIBRATION

7055

if OP.RX_CALIBRATION

7141

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7056

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7142

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7057

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7143

switch param.CTLE_type

7058

switch param.CTLE_type

7144

case 'CL93'

7059

case 'CL93'

7145

H_low2=1;

7060

H_low2=1;

7146

case 'CL120d'

7061

case 'CL120d'

7147

g_DC_low = g_DC_HP_values(g_LP_index);

7062

g_DC_low = g_DC_HP_values(g_LP_index);

7148

f_HP=param.f_HP(g_LP_index);

7063

f_HP=param.f_HP(g_LP_index);

7149

kacde_DC_low = 10^(g_DC_low/20);

7064

kacde_DC_low = 10^(g_DC_low/20);

7150

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7065

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7151

case 'CL120e' % z1 has been adusted on read in

7066

case 'CL120e' % z1 has been adusted on read in

7152

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7067

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7153

end

7068

end

7154

H_ctf2=H_low2.*ctle_gain2;

7069

H_ctf2=H_low2.*ctle_gain2;

7155

end

7070

end

7156

% RIM 11-30-2020 moved to a subfunction

7071

% RIM 11-30-2020 moved to a subfunction

7157

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7072

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7158

if OP.RX_CALIBRATION

7073

if OP.RX_CALIBRATION

7159

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7074

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7160

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

7075

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

7161

else

7076

else

7162

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7077

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7163

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7078

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7164

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7079

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7165

sigma_ne=0;

7080

sigma_ne=0;

7166

end

7081

end

7167

7082

7168

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7083

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7169

pxi=pxi+num_txffe_runs;

7084

pxi=pxi+num_txffe_runs;

7170

continue; % change per 0.3k draft 2.3

7085

continue; % change per 0.3k draft 2.3

7171

end

7086

end

7172

%%

7087

%%

7173

PSD_results=[];

7088

PSD_results=[];

7174

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7089

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7175

OP.WO_TXFFE=1;

7090

OP.WO_TXFFE=1;

7176

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7091

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7177

end

7092

end

7178

%TXFFE Loop

7093

%TXFFE Loop

7179

%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

7094

%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

7180

for TK=1:size(TXFFE_grid,1)

7095

for TK=1:size(TXFFE_grid,1)

7181

7096

7182

pxi=pxi+1;

7097

pxi=pxi+1;

7183

progress = pxi/runs;

7098

progress = pxi/runs;

7184

if OP.DISPLAY_WINDOW

7099

if OP.DISPLAY_WINDOW

7185

if ~mod(pxi,floor(runs*progress_interval))

7100

if ~mod(pxi,floor(runs*progress_interval))

7186

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7101

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7187

end

7102

end

7188

else

7103

else

7189

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7104

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7190

end

7105

end

7191

7106

7192

%get the cursor for this iteration

7107

%get the cursor for this iteration

7193

txffe_cur=txffe_cursor_vector(TK);

7108

txffe_cur=txffe_cursor_vector(TK);

7194

7109

7195

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7110

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7196

if txffe_cur<param.tx_ffe_c0_min

7111

if txffe_cur<param.tx_ffe_c0_min

7197

continue;

7112

continue;

7198

end

7113

end

7199

old_loops=old_loops+1;

7114

old_loops=old_loops+1;

7200

7115

7201

%get the index used for each tap on this iteration

7116

%get the index used for each tap on this iteration

7202

%this is needed for the LOCAL SEARCH block

7117

%this is needed for the LOCAL SEARCH block

7203

tx_index_vector=FULL_tx_index_vector(TK,:);

7118

tx_index_vector=FULL_tx_index_vector(TK,:);

7204

7119

7205

%Original LOCAL SEARCH Block:

7120

%Original LOCAL SEARCH Block:

7206

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7121

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7207

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7122

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7208

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7123

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7209

% % skip configurations more than

7124

% % skip configurations more than

7210

% % 2 steps away from current "best" point on any grid direction

7125

% % 2 steps away from current "best" point on any grid direction

7211

% % Matt Brown 11/19/2021 for cp2 and cp3

7126

% % Matt Brown 11/19/2021 for cp2 and cp3

7212

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7127

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7213

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7128

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7214

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7129

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7215

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7130

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7216

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7131

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7217

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7132

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7218

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7133

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7219

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7134

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7220

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7135

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7221

%

7136

%

7222

% continue;

7137

% continue;

7223

% end

7138

% end

7224

7139

7225

%Modular LOCAL_SEARCH block:

7140

%Modular LOCAL_SEARCH block:

7226

% speedup "local search" heuristic - Adee Ran 03-17-2020

7141

% speedup "local search" heuristic - Adee Ran 03-17-2020

7227

% skip configurations more than 2 steps away from current "best" point on any grid direction

7142

% skip configurations more than 2 steps away from current "best" point on any grid direction

7228

skip_it=0;

7143

skip_it=0;

7229

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7144

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7230

%instead of looping across all taps, only loop across

7145

%instead of looping across all taps, only loop across

7231

%those with length>1 (txffe_sweep_indices).

7146

%those with length>1 (txffe_sweep_indices).

7232

%It saves time since this block is encountered so often

7147

%It saves time since this block is encountered so often

7233

for kj=1:num_txffe_sweep_indices

7148

for kj=1:num_txffe_sweep_indices

7234

kv=txffe_sweep_indices(kj);

7149

kv=txffe_sweep_indices(kj);

7235

if kv==1

7150

if kv==1

7236

previous_loop_val=g_LP_index;

7151

previous_loop_val=g_LP_index;

7237

else

7152

else

7238

previous_loop_val=tx_index_vector(kv-1);

7153

previous_loop_val=tx_index_vector(kv-1);

7239

end

7154

end

7240

if previous_loop_val>1

7155

if previous_loop_val>1

7241

best_index_this_tap=best_txffe_index(kv);

7156

best_index_this_tap=best_txffe_index(kv);

7242

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7157

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7243

skip_it=1;

7158

skip_it=1;

7244

break;

7159

break;

7245

end

7160

end

7246

end

7161

end

7247

end

7162

end

7248

7163

7249

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7164

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7250

skip_it=1;

7165

skip_it=1;

7251

end

7166

end

7252

end

7167

end

7253

if skip_it

7168

if skip_it

7254

continue;

7169

continue;

7255

end

7170

end

7256

%End Modular LOCAL SEARCH block

7171

%End Modular LOCAL SEARCH block

7257

7172

7258

new_loops=new_loops+1;

7173

new_loops=new_loops+1;

7259

7174

7260

%fetch txffe for this iteration

7175

%fetch txffe for this iteration

7261

txffe=txffe_matrix(TK,:);

7176

txffe=txffe_matrix(TK,:);

7262

7177

7263

%The phase shift exponentials used in get_xtlk_noise are independent of

7178

%The phase shift exponentials used in get_xtlk_noise are independent of

7264

%everything except number of taps and cursor position

7179

%everything except number of taps and cursor position

7265

%So it can be calculated 1 time here to avoid thousands of re-calcs

7180

%So it can be calculated 1 time here to avoid thousands of re-calcs

7266

if ~calc_exp_phase

7181

if ~calc_exp_phase

7267

calc_exp_phase=1;

7182

calc_exp_phase=1;

7268

for k=1:length(txffe)

7183

for k=1:length(txffe)

7269

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7184

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7270

end

7185

end

7271

if OP.RxFFE

7186

if OP.RxFFE

7272

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7187

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7273

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7188

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7274

end

7189

end

7275

phase_memory=[phase_memory phase_memoryRXFFE];

7190

phase_memory=[phase_memory phase_memoryRXFFE];

7276

end

7191

end

7277

end

7192

end

7278

7193

7279

%% Unequalized Pulse Reponse & circshift for FFE

7194

%% Unequalized Pulse Reponse & circshift for FFE

7280

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7195

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7281

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7196

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7282

if ctle_response_updated

7197

if ctle_response_updated

7283

ctle_response_updated=0;

7198

ctle_response_updated=0;

7284

num_pre=cur-1;

7199

num_pre=cur-1;

7285

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7200

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7286

%Calculating here reduces number of convolutions by thousands

7201

%Calculating here reduces number of convolutions by thousands

7287

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7202

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7288

ich=1;

7203

ich=1;

7289

else

7204

else

7290

ich=param.num_s4p_files;

7205

ich=param.num_s4p_files;

7291

end

7206

end

7292

for ii=1:ich

7207

for ii=1:ich

7293

if OP.TDMODE

7208

if OP.TDMODE

7294

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7209

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7295

else

7210

else

7296

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7211

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7297

%"conv2" is faster than filter. Just need to chop off extra points at the end

7212

%"conv2" is faster than filter. Just need to chop off extra points at the end

7298

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7213

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7299

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7214

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7300

end

7215

end

7301

for k=1:length(txffe)

7216

for k=1:length(txffe)

7302

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7217

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7303

end

7218

end

7304

end

7219

end

7305

end

7220

end

7306

7221

7307

%% Apply TXFFE to pre-shifted pulse response

7222

%% Apply TXFFE to pre-shifted pulse response

7308

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7223

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7309

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7224

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7310

sbr_from_txffe=sbr;

7225

sbr_from_txffe=sbr;

7311

for ii=1:ich

7226

for ii=1:ich

7312

% this is sbr when ii=1; to be used in get_PSDs

7227

% this is sbr when ii=1; to be used in get_PSDs

7313

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7228

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7314

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7229

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7315

else

7230

else

7316

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7231

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7317

end

7232

end

7318

end

7233

end

7319

7234

7320

%% Find Sample Location

7235

%% Find Sample Location

7321

% If RXFFE is included, the sample location will be found again below

7236

% If RXFFE is included, the sample location will be found again below

7322

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7237

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7323

if param.ts_anchor==0

7238

if param.ts_anchor==0

7324

%keep MM

7239

%keep MM

7325

elseif param.ts_anchor==1

7240

elseif param.ts_anchor==1

7326

%peak sample

7241

%peak sample

7327

cursor_i=sbr_peak_i;

7242

cursor_i=sbr_peak_i;

7328

no_zero_crossing=0;

7243

no_zero_crossing=0;

7329

elseif param.ts_anchor==2

7244

elseif param.ts_anchor==2

7330

%max DV

7245

%max DV

7331

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7246

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7332

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7247

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7333

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7248

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7334

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7249

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7335

no_zero_crossing=0;

7250

no_zero_crossing=0;

7336

else

7251

else

7337

error('ts_anchor parameter must be 0, 1, or 2');

7252

error('ts_anchor parameter must be 0, 1, or 2');

7338

end

7253

end

7339

if no_zero_crossing

7254

if no_zero_crossing

7340

continue;

7255

continue;

7341

end

7256

end

7342

raw_cursor_i=cursor_i;

7257

raw_cursor_i=cursor_i;

7343

7258

7344

%%%%%%%%%%

7259

%%%%%%%%%%

7345

%%%%%%%%%%

7260

%%%%%%%%%%

7346

%%%%%%%%%%

7261

%%%%%%%%%%

7347

%NEW ITICK LOOP (not indenting everything yet)

7262

%NEW ITICK LOOP (not indenting everything yet)

7348

[~,si]=sort(abs(full_sample_range));

7263

[~,si]=sort(abs(full_sample_range));

7349

best_positive_itick_FOM=-inf;

7264

best_positive_itick_FOM=-inf;

7350

best_negative_itick_FOM=-inf;

7265

best_negative_itick_FOM=-inf;

7351

best_positive_itick_in_loop=[];

7266

best_positive_itick_in_loop=[];

7352

best_negative_itick_in_loop=[];

7267

best_negative_itick_in_loop=[];

7353

best_itick_FOM=-inf;

7268

best_itick_FOM=-inf;

7354

best_itick_in_cluster=[];

7269

best_itick_in_cluster=[];

7355

best_cluster=[];

7270

best_cluster=[];

7356

7271

7357

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7272

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7358

%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)

7273

%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)

7359

% Commit request4p4_7 healey_3dj_COM_01_240416

7274

% Commit request4p4_7 healey_3dj_COM_01_240416

7360

%box_search=0;

7275

%box_search=0;

7361

%middle_search=1;% should set 0 so all Ts sample points are used

7276

%middle_search=1;% should set 0 so all Ts sample points are used

7362

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7277

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7363

case 'full-sweep'

7278

case 'full-sweep'

7364

box_search=0;

7279

box_search=0;

7365

middle_search=0;

7280

middle_search=0;

7366

case 'middle'

7281

case 'middle'

7367

box_search=0;

7282

box_search=0;

7368

middle_search=1;

7283

middle_search=1;

7369

otherwise

7284

otherwise

7370

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7285

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7371

end

7286

end

7372

if box_search

7287

if box_search

7373

box_size=5;

7288

box_size=5;

7374

box_mid=floor(box_size/2);

7289

box_mid=floor(box_size/2);

7375

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7290

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7376

CL=length(cluster);

7291

CL=length(cluster);

7377

loop_range=1:CL+box_mid*2;

7292

loop_range=1:CL+box_mid*2;

7378

elseif middle_search

7293

elseif middle_search

7379

loop_range=si;

7294

loop_range=si;

7380

else

7295

else

7381

loop_range=1:length(full_sample_range);

7296

loop_range=1:length(full_sample_range);

7382

end

7297

end

7383

7298

7384

for itickn=loop_range

7299

for itickn=loop_range

7385

if box_search

7300

if box_search

7386

if itickn<=CL

7301

if itickn<=CL

7387

itick=cluster(itickn);

7302

itick=cluster(itickn);

7388

else

7303

else

7389

if itickn==CL+1

7304

if itickn==CL+1

7390

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7305

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7391

end

7306

end

7392

if isempty(best_cluster)

7307

if isempty(best_cluster)

7393

continue;

7308

continue;

7394

end

7309

end

7395

itick=best_cluster(itickn-CL);

7310

itick=best_cluster(itickn-CL);

7396

end

7311

end

7397

else

7312

else

7398

itick=full_sample_range(itickn);

7313

itick=full_sample_range(itickn);

7399

end

7314

end

7400

7315

7401

itick_cases=itick_cases+1;

7316

itick_cases=itick_cases+1;

7402

7317

7403

sbr=sbr_from_txffe;

7318

sbr=sbr_from_txffe;

7404

cursor_i = raw_cursor_i+itick;

7319

cursor_i = raw_cursor_i+itick;

7405

7320

7406

%Local Search for +/- itick sweep

7321

%Local Search for +/- itick sweep

7407

if middle_search && param.LOCAL_SEARCH>0

7322

if middle_search && param.LOCAL_SEARCH>0

7408

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7323

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7409

itick_skips=itick_skips+1;

7324

itick_skips=itick_skips+1;

7410

continue;

7325

continue;

7411

end

7326

end

7412

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7327

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7413

itick_skips=itick_skips+1;

7328

itick_skips=itick_skips+1;

7414

continue;

7329

continue;

7415

end

7330

end

7416

end

7331

end

7417

7332

7418

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7333

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7419

if min_number_of_UI_in_response < triple_transit_time

7334

if min_number_of_UI_in_response < triple_transit_time

7420

min_number_of_UI_in_response = triple_transit_time;

7335

min_number_of_UI_in_response = triple_transit_time;

7421

end

7336

end

7422

7337

7423

cursor = sbr(cursor_i);

7338

cursor = sbr(cursor_i);

7424

7339

7425

%% RXFFE

7340

%% RXFFE

7426

if OP.RxFFE

7341

if OP.RxFFE

7427

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7342

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7428

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7343

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7429

%if isrow(sbr), sbr=sbr';end

7344

%if isrow(sbr), sbr=sbr';end

7430

7345

7431

%AJG: do not return sbr here (run time improvement)

7346

%AJG: do not return sbr here (run time improvement)

7432

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7347

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7433

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7348

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7434

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7349

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7435

% sbr at this point include the current setting

7350

% sbr at this point include the current setting

7436

% under consideration of txffe h21 ctf and fr

7351

% under consideration of txffe h21 ctf and fr

7437

switch upper(OP.FFE_OPT_METHOD)

7352

switch upper(OP.FFE_OPT_METHOD)

7438

case 'MMSE'

7353

case 'MMSE'

7439

OP.WO_TXFFE=0;

7354

OP.WO_TXFFE=0;

7440

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7355

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7441

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn+ PSD_results.S_qn ;

7356

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn;

7442

if 0 % for debug

7357

if 0 % for debug

7443

figure(1010132)

7444

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7358

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7445

hold on

7359

hold on

7446

if(PSD_results.S_xn~=0)

7447

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7360

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7448

end

7449

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7361

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7450

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7362

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7451

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7363

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7452

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_qn*1000/100) ,'disp','Sqn')

7453

xlim([0 0.5])

7364

xlim([0 0.5])

7454

% ylim([-190 -160])

7365

% ylim([-190 -160])

7455

set(gcf,'defaulttextinterpreter','none')

7366

set(gcf,'defaulttextinterpreter','none')

7456

xlabel('Normalized Frequency')

7367

xlabel('Normalized Frequency')

7457

ylabel('PSD dBm/Hz')

7368

ylabel('PSD dBm/Hz')

7458

hold on

7369

hold on

7459

grid on

7370

grid on

7460

legend show

7371

legend show

7461

title('PSD')

7372

title('PSD')

7462

end

7373

end

7463

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7374

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7464

% floating_tap_locations=MMSE_results.MLSE_results;

7375

% floating_tap_locations=MMSE_results.MLSE_results;

7465

C=MMSE_results.C;

7376

C=MMSE_results.C;

7466

FOM=MMSE_results.FOM;

7377

FOM=MMSE_results.FOM;

7467

floating_tap_locations=MMSE_results.floating_tap_locations;

7378

floating_tap_locations=MMSE_results.floating_tap_locations;

7468

otherwise

7379

otherwise

7469

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7380

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7470

end

7381

end

7471

%Now there is a stand alone function for determining if RXFFE taps are illegal

7382

%Now there is a stand alone function for determining if RXFFE taps are illegal

7472

%This is because the "force" function will also do a legality check when "backoff" is enabled

7383

%This is because the "force" function will also do a legality check when "backoff" is enabled

7473

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7384

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7474

if RXFFE_Illegal(C,param)

7385

if RXFFE_Illegal(C,param)

7475

continue;

7386

continue;

7476

end

7387

end

7477

end

7388

end

7478

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7389

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7479

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7390

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7480

if isrow(sbr), sbr=sbr';end

7391

if isrow(sbr), sbr=sbr';end

7481

7392

7482

%% second guess at cursor location (t_s) - based on approximate zero crossing

7393

%% second guess at cursor location (t_s) - based on approximate zero crossing

7483

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7394

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7484

%UPDATE: NOT RESAMPLING AFTER RXFFE

7395

%UPDATE: NOT RESAMPLING AFTER RXFFE

7485

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7396

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7486

% if no_zero_crossing

7397

% if no_zero_crossing

7487

% continue;

7398

% continue;

7488

% end

7399

% end

7489

7400

7490

cursor = sbr(cursor_i);

7401

cursor = sbr(cursor_i);

7491

end

7402

end

7492

A_p=sbr(sbr_peak_i);

7403

A_p=sbr(sbr_peak_i);

7493

%% 93A.1.6 step c defines A_s %%

7404

%% 93A.1.6 step c defines A_s %%

7494

A_s = param.R_LM*cursor/(param.levels-1);

7405

A_s = param.R_LM*cursor/(param.levels-1);

7495

if isempty(delta_sbr)

7406

if isempty(delta_sbr)

7496

delta_sbr = sbr;

7407

delta_sbr = sbr;

7497

end

7408

end

7498

sbr=sbr(:);

7409

sbr=sbr(:);

7499

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7410

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7500

7411

7501

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7412

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7502

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7413

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7503

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)))*...

7414

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)))*...

7504

param.ui/param.samples_per_ui;

7415

param.ui/param.samples_per_ui;

7505

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7416

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7506

precursors = precursors(end:-1:1);

7417

precursors = precursors(end:-1:1);

7507

7418

7508

% % Error message if the sbr is not long enough for the specified range of Nb

7419

% % Error message if the sbr is not long enough for the specified range of Nb

7509

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7420

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7510

% close(hwaitbar);

7421

% close(hwaitbar);

7511

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7422

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7512

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7423

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7513

% end

7424

% end

7514

7425

7515

7426

7516

7427

7517

%% skip this case if FOM has no chance of beating old FOM

7428

%% skip this case if FOM has no chance of beating old FOM

7518

%this is also done below but with excess_dfe_cursors included.

7429

%this is also done below but with excess_dfe_cursors included.

7519

%excess_dfe_cursors requires the floating DFE computation which is

7430

%excess_dfe_cursors requires the floating DFE computation which is

7520

%time consuming, so checking here can have significant run time improvements

7431

%time consuming, so checking here can have significant run time improvements

7521

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7432

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7522

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7433

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7523

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7434

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7524

continue

7435

continue

7525

end

7436

end

7526

end

7437

end

7527

7438

7528

%% Equation 93A-27, when 1<=n<=N_b

7439

%% Equation 93A-27, when 1<=n<=N_b

7529

%required length = cursor + all DFE UI + 1 additional UI

7440

%required length = cursor + all DFE UI + 1 additional UI

7530

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7441

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7531

if length(sbr)<sbr_required_length

7442

if length(sbr)<sbr_required_length

7532

sbr(end+1:sbr_required_length)=0;

7443

sbr(end+1:sbr_required_length)=0;

7533

end

7444

end

7534

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7445

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7535

if param.dfe_delta ~= 0

7446

if param.dfe_delta ~= 0

7536

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7447

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7537

7448

7538

else

7449

else

7539

dfecursors_q=dfecursors;

7450

dfecursors_q=dfecursors;

7540

end

7451

end

7541

if param.Floating_DFE

7452

if param.Floating_DFE

7542

%% floating taps

7453

%% floating taps

7543

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7454

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7544

7455

7545

[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 );

7456

[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 );

7546

7457

7547

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7458

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7548

param.use_bmax=newbmax;

7459

param.use_bmax=newbmax;

7549

%AJG021820

7460

%AJG021820

7550

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7461

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7551

else

7462

else

7552

param.use_bmax=param.bmax;

7463

param.use_bmax=param.bmax;

7553

%AJG021820

7464

%AJG021820

7554

param.use_bmin=param.bmin;

7465

param.use_bmin=param.bmin;

7555

end

7466

end

7556

7467

7557

%AJG021820

7468

%AJG021820

7558

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7469

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7559

if do_C2M

7470

if do_C2M

7560

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);

7471

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);

7561

% readjust SBR

7472

% readjust SBR

7562

if 0

7473

if 0

7563

%PR_DFE_center not currently used, so this is in "if 0" statement

7474

%PR_DFE_center not currently used, so this is in "if 0" statement

7564

PR_DFE_center=sbr;

7475

PR_DFE_center=sbr;

7565

for n=1:param.ndfe

7476

for n=1:param.ndfe

7566

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7477

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7567

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7478

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7568

% dper=sbr(i_sample)- actual_dfecursors(n);

7479

% dper=sbr(i_sample)- actual_dfecursors(n);

7569

% PR_DFE_center(i_sample)=dper;

7480

% PR_DFE_center(i_sample)=dper;

7570

% end

7481

% end

7571

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7482

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7572

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7483

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7573

end

7484

end

7574

end

7485

end

7575

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7486

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7576

else

7487

else

7577

excess_dfe_cursors=dfecursors-actual_dfecursors;

7488

excess_dfe_cursors=dfecursors-actual_dfecursors;

7578

end

7489

end

7579

dfetaps=actual_dfecursors/sbr(cursor_i);

7490

dfetaps=actual_dfecursors/sbr(cursor_i);

7580

7491

7581

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7492

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7582

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7493

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7583

if tail_RSS ~= 0

7494

if tail_RSS ~= 0

7584

if tail_RSS >= param.B_float_RSS_MAX

7495

if tail_RSS >= param.B_float_RSS_MAX

7585

param.use_bmax(param.N_tail_start:end)= ...

7496

param.use_bmax(param.N_tail_start:end)= ...

7586

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7497

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7587

%AJG021820

7498

%AJG021820

7588

param.use_bmin(param.N_tail_start:end)= ...

7499

param.use_bmin(param.N_tail_start:end)= ...

7589

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7500

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7590

end

7501

end

7591

end

7502

end

7592

7503

7593

%AJG021820

7504

%AJG021820

7594

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7505

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7595

if do_C2M

7506

if do_C2M

7596

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7507

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7597

else

7508

else

7598

excess_dfe_cursors=dfecursors-actual_dfecursors;

7509

excess_dfe_cursors=dfecursors-actual_dfecursors;

7599

end

7510

end

7600

dfetaps=actual_dfecursors/sbr(cursor_i);

7511

dfetaps=actual_dfecursors/sbr(cursor_i);

7601

7512

7602

else

7513

else

7603

tail_RSS=0;

7514

tail_RSS=0;

7604

end

7515

end

7605

%% Eq. 93A-28 %%

7516

%% Eq. 93A-28 %%

7606

sampling_offset = mod(cursor_i, param.samples_per_ui);

7517

sampling_offset = mod(cursor_i, param.samples_per_ui);

7607

%ensure we can take early sample

7518

%ensure we can take early sample

7608

if sampling_offset<=1

7519

if sampling_offset<=1

7609

sampling_offset=sampling_offset+param.samples_per_ui;

7520

sampling_offset=sampling_offset+param.samples_per_ui;

7610

end

7521

end

7611

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7522

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7612

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7523

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7613

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7524

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7614

else

7525

else

7615

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7526

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7616

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7527

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7617

end

7528

end

7618

% ensure lengths are equal

7529

% ensure lengths are equal

7619

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7530

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7620

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7531

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7621

if ~OP.SNR_TXwC0

7532

if ~OP.SNR_TXwC0

7622

%% Equation 93A-30 %%

7533

%% Equation 93A-30 %%

7623

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7534

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7624

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7535

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7625

else

7536

else

7626

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7537

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7627

end

7538

end

7628

%% Equation 93A-31 %%

7539

%% Equation 93A-31 %%

7629

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7540

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7630

ISI_N=param.sigma_X*norm( far_cursors);

7541

ISI_N=param.sigma_X*norm( far_cursors);

7631

%% break if FOM has no chance of beating old e

7542

%% break if FOM has no chance of beating old e

7632

OP.exe_mode=1;

7543

OP.exe_mode=1;

7633

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7544

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7634

switch OP.EXE_MODE

7545

switch OP.EXE_MODE

7635

case 0

7546

case 0

7636

case 1

7547

case 1

7637

if (20*log10(A_s/sigma_ISI) < best_FOM)

7548

if (20*log10(A_s/sigma_ISI) < best_FOM)

7638

continue

7549

continue

7639

end

7550

end

7640

case 2

7551

case 2

7641

if (20*log10(A_s/sigma_ISI) < best_FOM)

7552

if (20*log10(A_s/sigma_ISI) < best_FOM)

7642

break

7553

break

7643

end

7554

end

7644

end

7555

end

7645

end

7556

end

7646

%% Equation 93A-32 %%

7557

%% Equation 93A-32 %%

7647

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7558

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7648

7559

7649

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7560

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7650

if OP.RX_CALIBRATION

7561

if OP.RX_CALIBRATION

7651

sigma_XT=0;

7562

sigma_XT=0;

7652

else

7563

else

7653

if ~OP.RxFFE

7564

if ~OP.RxFFE

7654

[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

7565

[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

7655

%% Equation 93A-36 denominator (actually its sqrt)

7566

%% Equation 93A-36 denominator (actually its sqrt)

7656

else % John Ewen: 13/12/20018

7567

else % John Ewen: 13/12/20018

7657

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7568

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7658

[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

7569

[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

7659

else % use results from get_PSDs RIM 3/28/2024

7570

else % use results from get_PSDs RIM 3/28/2024

7660

sigma_XT=PSD_results.S_xn_rms;

7571

sigma_XT=PSD_results.S_xn_rms;

7661

end

7572

end

7662

end

7573

end

7663

end

7574

end

7664

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7575

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7665

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7576

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7666

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7577

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7667

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7578

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7668

f=chdata(1).faxis;

7579

f=chdata(1).faxis;

7669

H_Rx_FFE=zeros(1,length(f));

7580

H_Rx_FFE=zeros(1,length(f));

7670

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7581

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7671

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7582

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7672

if C(ii+param.RxFFE_cmx+1)==0

7583

if C(ii+param.RxFFE_cmx+1)==0

7673

%speed up: skip cases when rxffe=0

7584

%speed up: skip cases when rxffe=0

7674

continue;

7585

continue;

7675

end

7586

end

7676

if ii+1==0

7587

if ii+1==0

7677

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7588

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7678

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7589

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7679

else

7590

else

7680

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7591

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7681

end

7592

end

7682

end

7593

end

7683

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

7594

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

7684

end

7595

end

7685

end

7596

end

7686

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7597

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7687

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7598

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7688

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7599

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7689

else

7600

else

7690

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7601

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7691

end

7602

end

7692

if do_C2M

7603

if do_C2M

7693

if param.Noise_Crest_Factor == 0

7604

if param.Noise_Crest_Factor == 0

7694

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7605

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7695

else

7606

else

7696

ber_q=param.Noise_Crest_Factor;

7607

ber_q=param.Noise_Crest_Factor;

7697

end

7608

end

7698

if OP.force_pdf_bin_size

7609

if OP.force_pdf_bin_size

7699

delta_y = OP.BinSize;

7610

delta_y = OP.BinSize;

7700

else

7611

else

7701

delta_y = min(A_s/1000, OP.BinSize);

7612

delta_y = min(A_s/1000, OP.BinSize);

7702

end

7613

end

7703

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7614

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7704

cci_pdf = normal_dist(0, ber_q, delta_y);

7615

cci_pdf = normal_dist(0, ber_q, delta_y);

7705

chdata(1).eq_pulse_response=sbr;

7616

chdata(1).eq_pulse_response=sbr;

7706

tmp_result.t_s= cursor_i;

7617

tmp_result.t_s= cursor_i;

7707

tmp_result.A_s=A_s;

7618

tmp_result.A_s=A_s;

7708

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7619

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7709

if EH_1st <= param.Min_VEO_Test/1000 -.001

7620

if EH_1st <= param.Min_VEO_Test/1000 -.001

7710

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7621

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7711

continue

7622

continue

7712

else

7623

else

7713

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7624

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7714

end

7625

end

7715

Struct_Noise.sigma_N=sigma_N;

7626

Struct_Noise.sigma_N=sigma_N;

7716

Struct_Noise.sigma_TX=sigma_TX;

7627

Struct_Noise.sigma_TX=sigma_TX;

7717

Struct_Noise.cci_pdf=cci_pdf;

7628

Struct_Noise.cci_pdf=cci_pdf;

7718

Struct_Noise.ber_q=ber_q;

7629

Struct_Noise.ber_q=ber_q;

7719

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7630

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7720

[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);

7631

[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);

7721

EH=EH_T_C2M-EH_B_C2M;

7632

EH=EH_T_C2M-EH_B_C2M;

7722

N_i=(A_s*2-EH)/2;

7633

N_i=(A_s*2-EH)/2;

7723

if EH <= param.Min_VEO_Test/1000

7634

if EH <= param.Min_VEO_Test/1000

7724

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7635

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7725

continue

7636

continue

7726

else

7637

else

7727

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

7638

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

7728

end

7639

end

7729

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7640

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7730

FOM =20*log10(A_s/N_i);

7641

FOM =20*log10(A_s/N_i);

7731

end

7642

end

7732

else

7643

else

7733

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7644

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7734

FOM = 20*log10(A_s/total_noise_rms);

7645

FOM = 20*log10(A_s/total_noise_rms);

7735

end

7646

end

7736

% if strfind(param.CTLE_type,'CL120e')

7647

% if strfind(param.CTLE_type,'CL120e')

7737

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

7648

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

7738

end

7649

end

7739

if 0 % for loop analysis

7650

if 0 % for loop analysis

7740

result.FOM_array(new_loops)=FOM;

7651

result.FOM_array(new_loops)=FOM;

7741

end

7652

end

7742

7653

7743

if FOM>best_itick_FOM

7654

if FOM>best_itick_FOM

7744

best_itick_FOM=FOM;

7655

best_itick_FOM=FOM;

7745

best_itick_in_cluster=itick;

7656

best_itick_in_cluster=itick;

7746

end

7657

end

7747

7658

7748

if itick>=0 && FOM>best_positive_itick_FOM

7659

if itick>=0 && FOM>best_positive_itick_FOM

7749

best_positive_itick_FOM=FOM;

7660

best_positive_itick_FOM=FOM;

7750

best_positive_itick_in_loop=itick;

7661

best_positive_itick_in_loop=itick;

7751

end

7662

end

7752

if itick<=0 && FOM>best_negative_itick_FOM

7663

if itick<=0 && FOM>best_negative_itick_FOM

7753

best_negative_itick_FOM=FOM;

7664

best_negative_itick_FOM=FOM;

7754

best_negative_itick_in_loop=itick;

7665

best_negative_itick_in_loop=itick;

7755

end

7666

end

7756

7667

7757

itick_index=find(itick==full_sample_range);

7668

itick_index=find(itick==full_sample_range);

7758

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

7669

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

7759

7670

7760

if (FOM > best_FOM)

7671

if (FOM > best_FOM)

7761

best_current_ffegain=param.current_ffegain;

7672

best_current_ffegain=param.current_ffegain;

7762

best_txffe = txffe;

7673

best_txffe = txffe;

7763

%along with best_txffe, save the indices of the best_txffe

7674

%along with best_txffe, save the indices of the best_txffe

7764

%(saves time in LOCAL SEARCH block)

7675

%(saves time in LOCAL SEARCH block)

7765

best_txffe_index=tx_index_vector;

7676

best_txffe_index=tx_index_vector;

7766

best_sbr = sbr;

7677

best_sbr = sbr;

7767

best_ctle = ctle_index;

7678

best_ctle = ctle_index;

7768

best_G_high_pass =g_LP_index;

7679

best_G_high_pass =g_LP_index;

7769

best_FOM = FOM;

7680

best_FOM = FOM;

7770

best_cursor_i = cursor_i;

7681

best_cursor_i = cursor_i;

7771

best_itick = itick;

7682

best_itick = itick;

7772

if ~OP.TDMODE

7683

if ~OP.TDMODE

7773

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7684

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7774

best_IR=effective_channel;

7685

best_IR=effective_channel;

7775

end

7686

end

7776

best_sigma_N = sigma_N;

7687

best_sigma_N = sigma_N;

7777

best_h_J = h_J;

7688

best_h_J = h_J;

7778

best_A_s=A_s;

7689

best_A_s=A_s;

7779

best_A_p=A_p;

7690

best_A_p=A_p;

7780

best_ISI=ISI_N;

7691

best_ISI=ISI_N;

7781

best_bmax=param.use_bmax;

7692

best_bmax=param.use_bmax;

7782

%AJG021820

7693

%AJG021820

7783

best_bmin=param.use_bmin;

7694

best_bmin=param.use_bmin;

7784

best_tail_RSS=tail_RSS;

7695

best_tail_RSS=tail_RSS;

7785

best_dfetaps=dfetaps;

7696

best_dfetaps=dfetaps;

7786

if param.Floating_DFE

7697

if param.Floating_DFE

7787

best_floating_tap_locations=floating_tap_locations;

7698

best_floating_tap_locations=floating_tap_locations;

7788

best_floating_tap_coef=floating_tap_coef;

7699

best_floating_tap_coef=floating_tap_coef;

7789

end

7700

end

7790

if param.Floating_RXFFE

7701

if param.Floating_RXFFE

7791

best_floating_tap_locations=floating_tap_locations;

7702

best_floating_tap_locations=floating_tap_locations;

7792

% best_floating_tap_coef=floating_tap_coef;

7703

% best_floating_tap_coef=floating_tap_coef;

7793

end

7704

end

7794

if OP.RxFFE

7705

if OP.RxFFE

7795

best_RxFFE=C;

7706

best_RxFFE=C;

7796

best_PSD_results=PSD_results;

7707

best_PSD_results=PSD_results;

7797

best_MMSE_results=MMSE_results;

7708

best_MMSE_results=MMSE_results;

7798

end

7709

end

7799

end

7710

end

7800

end

7711

end

7801

end

7712

end

7802

7713

7803

end

7714

end

7804

end

7715

end

7805

end

7716

end

7806

if do_C2M

7717

if do_C2M

7807

if best_FOM == -inf

7718

if best_FOM == -inf

7808

param.Min_VEO_Test=0;

7719

param.Min_VEO_Test=0;

7809

else

7720

else

7810

break

7721

break

7811

end

7722

end

7812

end

7723

end

7813

end

7724

end

7814

if 0

7725

if 0

7815

fprintf('old loops = %d\n',old_loops);

7726

fprintf('old loops = %d\n',old_loops);

7816

fprintf('new loops = %d\n',new_loops);

7727

fprintf('new loops = %d\n',new_loops);

7817

display(sprintf('\n :loops = %g',pxi))

7728

display(sprintf('\n :loops = %g',pxi))

7818

end

7729

end

7819

7730

7820

%turn this on to review if FOM changes sign more than once in an itick loop

7731

%turn this on to review if FOM changes sign more than once in an itick loop

7821

if 0

7732

if 0

7822

DIR_CHANGE={};

7733

DIR_CHANGE={};

7823

for m=1:length(Gffe_values)

7734

for m=1:length(Gffe_values)

7824

for n=1:length(gdc_values)

7735

for n=1:length(gdc_values)

7825

for k=1:lf_indx

7736

for k=1:lf_indx

7826

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

7737

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

7827

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

7738

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

7828

%1 = goes up, -1=goes down

7739

%1 = goes up, -1=goes down

7829

x=sign(diff(FOM_this_mat')');

7740

x=sign(diff(FOM_this_mat')');

7830

%y = change in sign on x. the location of a "2" is where FOM changes direction

7741

%y = change in sign on x. the location of a "2" is where FOM changes direction

7831

y=abs(diff(x'))';

7742

y=abs(diff(x'))';

7832

%the goal is the FOM only changes direction once. so count the occurences of the 2

7743

%the goal is the FOM only changes direction once. so count the occurences of the 2

7833

for j=1:size(FOM_this_mat,1)

7744

for j=1:size(FOM_this_mat,1)

7834

z{j}=find(y(j,:)==2);

7745

z{j}=find(y(j,:)==2);

7835

end

7746

end

7836

zL=cellfun('length',z);

7747

zL=cellfun('length',z);

7837

%return any row where FOM changed direction more than once

7748

%return any row where FOM changed direction more than once

7838

DIR_CHANGE{j,k}=find(zL>1);

7749

DIR_CHANGE{j,k}=find(zL>1);

7839

end

7750

end

7840

end

7751

end

7841

end

7752

end

7842

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

7753

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

7843

end

7754

end

7844

7755

7845

if ~exist('best_cursor_i', 'var')% take last setting

7756

if ~exist('best_cursor_i', 'var')% take last setting

7846

result.eq_failed=true;

7757

result.eq_failed=true;

7847

display('equalization failed')

7758

display('equalization failed')

7848

best_bmax=param.bmax;

7759

best_bmax=param.bmax;

7849

%AJG021820

7760

%AJG021820

7850

best_bmin=param.bmin;

7761

best_bmin=param.bmin;

7851

best_tail_RSS=0;

7762

best_tail_RSS=0;

7852

best_current_ffegain=0;

7763

best_current_ffegain=0;

7853

best_txffe = txffe;

7764

best_txffe = txffe;

7854

best_sbr = sbr;

7765

best_sbr = sbr;

7855

best_ctle = ctle_index;

7766

best_ctle = ctle_index;

7856

if OP.RxFFE

7767

if OP.RxFFE

7857

best_PSD_results=PSD_results;

7768

best_PSD_results=PSD_results;

7858

best_MMSE_results=MMSE_results;

7769

best_MMSE_results=MMSE_results;

7859

best_RxFFE=C;

7770

best_RxFFE=C;

7860

end

7771

end

7861

best_G_high_pass =g_LP_index;

7772

best_G_high_pass =g_LP_index;

7862

best_FOM = FOM;

7773

best_FOM = FOM;

7863

%if this block is reached, the last encountered EQ parameters are used

7774

%if this block is reached, the last encountered EQ parameters are used

7864

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

7775

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

7865

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

7776

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

7866

if isempty(cursor_i)

7777

if isempty(cursor_i)

7867

[~,cursor_i]=max(sbr);

7778

[~,cursor_i]=max(sbr);

7868

end

7779

end

7869

best_cursor_i = cursor_i;

7780

best_cursor_i = cursor_i;

7870

best_itick = itick;

7781

best_itick = itick;

7871

if ~OP.TDMODE

7782

if ~OP.TDMODE

7872

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7783

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7873

best_IR=effective_channel;

7784

best_IR=effective_channel;

7874

end

7785

end

7875

best_sigma_N = sigma_N;

7786

best_sigma_N = sigma_N;

7876

best_h_J = h_J;

7787

best_h_J = h_J;

7877

best_A_p=max(sbr);

7788

best_A_p=max(sbr);

7878

best_ISI=1;

7789

best_ISI=1;

7879

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) ;

7790

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) ;

7880

best_A_s= sbr( cursor_i);

7791

best_A_s= sbr( cursor_i);

7881

if param.Floating_DFE

7792

if param.Floating_DFE

7882

best_floating_tap_locations=[];

7793

best_floating_tap_locations=[];

7883

best_floating_tap_coef=[];

7794

best_floating_tap_coef=[];

7884

end

7795

end

7885

if do_C2M

7796

if do_C2M

7886

return

7797

return

7887

end

7798

end

7888

% return

7799

% return

7889

else

7800

else

7890

result.eq_failed=false; % RIM 12/30/2023

7801

result.eq_failed=false; % RIM 12/30/2023

7891

end

7802

end

7892

7803

7893

best_cursor = best_sbr(best_cursor_i);

7804

best_cursor = best_sbr(best_cursor_i);

7894

% report during debug

7805

% report during debug

7895

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

7806

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

7896

%If sbr was zero padded, then PRin needs to do so as well)

7807

%If sbr was zero padded, then PRin needs to do so as well)

7897

if length(PRin)<length(best_sbr)

7808

if length(PRin)<length(best_sbr)

7898

PRin(end+1:length(best_sbr))=0;

7809

PRin(end+1:length(best_sbr))=0;

7899

end

7810

end

7900

f=1e8:1e8:100e9;

7811

f=1e8:1e8:100e9;

7901

7812

7902

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

7813

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

7903

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

7814

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

7904

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7815

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7905

% need to include H_RCos in noise and when computing the system ir for thru

7816

% need to include H_RCos in noise and when computing the system ir for thru

7906

% and crosstalk

7817

% and crosstalk

7907

H_r=H_bw.*H_bt.*H_RCos;

7818

H_r=H_bw.*H_bt.*H_RCos;

7908

7819

7909

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

7820

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

7910

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

7821

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

7911

7822

7912

switch param.CTLE_type

7823

switch param.CTLE_type

7913

case 'CL93'

7824

case 'CL93'

7914

H_low=1;

7825

H_low=1;

7915

case 'CL120d'

7826

case 'CL120d'

7916

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));

7827

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));

7917

case 'CL120e'

7828

case 'CL120e'

7918

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

7829

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

7919

end

7830

end

7920

ctle_gain=H_low.*ctle_gain1.*H_r;

7831

ctle_gain=H_low.*ctle_gain1.*H_r;

7921

7832

7922

7833

7923

7834

7924

%lsbr=length(sbr);

7835

%lsbr=length(sbr);

7925

%use length of best_sbr in case zero padding was performed

7836

%use length of best_sbr in case zero padding was performed

7926

%check "sbr_required_length" variable

7837

%check "sbr_required_length" variable

7927

lsbr=length(best_sbr);

7838

lsbr=length(best_sbr);

7928

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

7839

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

7929

7840

7930

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

7841

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

7931

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

7842

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

7932

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

7843

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

7933

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

7844

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

7934

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

7845

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

7935

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

7846

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

7936

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

7847

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

7937

if param.Floating_DFE

7848

if param.Floating_DFE

7938

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

7849

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

7939

end

7850

end

7940

% apply max tap value constraint

7851

% apply max tap value constraint

7941

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

7852

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

7942

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

7853

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

7943

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

7854

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

7944

7855

7945

%AJG021820

7856

%AJG021820

7946

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

7857

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

7947

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

7858

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

7948

if param.Floating_DFE

7859

if param.Floating_DFE

7949

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

7860

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

7950

end

7861

end

7951

7862

7952

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

7863

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

7953

Symbol_Adj = (param.levels-1);% 3A.1.6

7864

Symbol_Adj = (param.levels-1);% 3A.1.6

7954

if OP.DEBUG ~=0

7865

if OP.DEBUG ~=0

7955

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

7866

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

7956

% display pulse responses in one axis per test case.

7867

% display pulse responses in one axis per test case.

7957

switch upper(OP.TIME_AXIS)

7868

switch upper(OP.TIME_AXIS)

7958

case 'S' % RIM 11-13-2023 added user selectable xaxis

7869

case 'S' % RIM 11-13-2023 added user selectable xaxis

7959

xnorm=1;

7870

xnorm=1;

7960

xaxis_label='seconds';

7871

xaxis_label='seconds';

7961

offset=0;

7872

offset=0;

7962

case 'UI'

7873

case 'UI'

7963

xnorm=param.ui;

7874

xnorm=param.ui;

7964

xaxis_label='UI';

7875

xaxis_label='UI';

7965

offset=t(best_cursor_i)/xnorm;

7876

offset=t(best_cursor_i)/xnorm;

7966

otherwise

7877

otherwise

7967

xnorm=1;

7878

xnorm=1;

7968

xaxis_label='seconds';

7879

xaxis_label='seconds';

7969

offset=0;

7880

offset=0;

7970

end

7881

end

7971

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

7882

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

7972

fig=findobj('Name', figure_name);

7883

fig=findobj('Name', figure_name);

7973

if isempty(fig), fig=figure('Name', figure_name); end

7884

if isempty(fig), fig=figure('Name', figure_name); end

7974

figure(fig);set(gcf,'Tag','COM');

7885

figure(fig);set(gcf,'Tag','COM');

7975

movegui(fig,'north')

7886

movegui(fig,'north')

7976

%figure(fig.Number);

7887

%figure(fig.Number);

7977

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

7888

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

7978

if OP.RxFFE

7889

if OP.RxFFE

7979

ax1=subplot(2,1,1);

7890

ax1=subplot(2,1,1);

7980

end

7891

end

7981

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

7892

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

7982

hold on

7893

hold on

7983

7894

7984

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

7895

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

7985

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

7896

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

7986

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

7897

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

7987

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

7898

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

7988

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

7899

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

7989

ylabel('volts')

7900

ylabel('volts')

7990

xlabel(xaxis_label)

7901

xlabel(xaxis_label)

7991

grid on

7902

grid on

7992

legend show

7903

legend show

7993

legend( 'Location', 'best')

7904

legend( 'Location', 'best')

7994

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

7905

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

7995

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

7906

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

7996

if param.ndfe_passed ~=0

7907

if param.ndfe_passed ~=0

7997

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');

7908

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');

7998

end

7909

end

7999

if param.Floating_DFE

7910

if param.Floating_DFE

8000

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');

7911

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');

8001

end

7912

end

8002

if OP.RxFFE

7913

if OP.RxFFE

8003

ax2=subplot(2,1,2);

7914

ax2=subplot(2,1,2);

8004

if param.Floating_RXFFE

7915

if param.Floating_RXFFE

8005

%AJG: floating tap x-axis location needs offset by -(RxFFE_cmx+1) because the floating tap indices include precursor indices

7916

%AJG: floating tap x-axis location needs offset by -(RxFFE_cmx+1) because the floating tap indices include precursor indices

8006

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)...

7917

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)...

8007

,'filled','disp','RxFFE floating FFE taps')

7918

,'filled','disp','RxFFE floating FFE taps')

8008

hold on

7919

hold on

8009

end

7920

end

8010

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)...

7921

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)...

8011

,'filled','disp','RxFFE fixted FFE taps')

7922

,'filled','disp','RxFFE fixted FFE taps')

8012

legend show

7923

legend show

8013

zoom xon

7924

zoom xon

8014

linkaxes([ax1 ax2],'x')

7925

linkaxes([ax1 ax2],'x')

8015

end

7926

end

8016

7927

8017

7928

8018

grid on

7929

grid on

8019

legend show

7930

legend show

8020

legend( 'Location', 'best')

7931

legend( 'Location', 'best')

8021

zoom xon

7932

zoom xon

8022

% set(hax, 'tag', 'EQE');

7933

% set(hax, 'tag', 'EQE');

8023

%

7934

%

8024

figure(110);set(gcf,'Tag','COM');

7935

figure(110);set(gcf,'Tag','COM');

8025

set(gcf, 'Name', 'CTLE selection');

7936

set(gcf, 'Name', 'CTLE selection');

8026

movegui(gcf, 'southeast');

7937

movegui(gcf, 'southeast');

8027

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

7938

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8028

hold on

7939

hold on

8029

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

7940

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8030

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

7941

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8031

fbaud_tick=find(f >= baud_rate, 1);

7942

fbaud_tick=find(f >= baud_rate, 1);

8032

fnq_tick=find(f >= baud_rate/2, 1);

7943

fnq_tick=find(f >= baud_rate/2, 1);

8033

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

7944

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8034

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

7945

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8035

recolor_plots(gca);

7946

recolor_plots(gca);

8036

title('CTF/w Rx Filter Response')

7947

title('CTF/w Rx Filter Response')

8037

ylabel('dB')

7948

ylabel('dB')

8038

xlabel('Hz')

7949

xlabel('Hz')

8039

legend show

7950

legend show

8040

end

7951

end

8041

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

7952

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8042

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

7953

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8043

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

7954

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8044

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

7955

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8045

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

7956

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8046

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

7957

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8047

end

7958

end

8048

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

7959

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

8049

eqe_axes = findobj('tag', 'EQE');

7960

eqe_axes = findobj('tag', 'EQE');

8050

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

7961

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8051

end

7962

end

8052

if OP.DISPLAY_WINDOW

7963

if OP.DISPLAY_WINDOW

8053

close(hwaitbar);

7964

close(hwaitbar);

8054

else

7965

else

8055

fprintf('\n');

7966

fprintf('\n');

8056

end

7967

end

8057

7968

8058

% % eq_data

7969

% % eq_data

8059

result.cur=cur;

7970

result.cur=cur;

8060

result.txffe = best_txffe;

7971

result.txffe = best_txffe;

8061

result.ctle = best_ctle;

7972

result.ctle = best_ctle;

8062

result.best_G_high_pass=best_G_high_pass;

7973

result.best_G_high_pass=best_G_high_pass;

8063

result.DFE_taps = best_dfetaps; %relative

7974

result.DFE_taps = best_dfetaps; %relative

8064

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

7975

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8065

if param.Floating_DFE

7976

if param.Floating_DFE

8066

result.floating_tap_locations=best_floating_tap_locations;

7977

result.floating_tap_locations=best_floating_tap_locations;

8067

result.floating_tap_coef=best_floating_tap_coef;

7978

result.floating_tap_coef=best_floating_tap_coef;

8068

end

7979

end

8069

if param.Floating_RXFFE

7980

if param.Floating_RXFFE

8070

result.floating_tap_locations=best_floating_tap_locations;

7981

result.floating_tap_locations=best_floating_tap_locations;

8071

end

7982

end

8072

result.A_s = best_A_s;

7983

result.A_s = best_A_s;

8073

result.t_s = best_cursor_i;

7984

result.t_s = best_cursor_i;

8074

result.itick = best_itick;

7985

result.itick = best_itick;

8075

result.sigma_N = best_sigma_N;

7986

result.sigma_N = best_sigma_N;

8076

result.h_J = best_h_J;

7987

result.h_J = best_h_J;

8077

result.FOM = best_FOM;

7988

result.FOM = best_FOM;

8078

if ~OP.TDMODE

7989

if ~OP.TDMODE

8079

%If sbr was zero padded, then best_IR needs to do so as well)

7990

%If sbr was zero padded, then best_IR needs to do so as well)

8080

if length(best_IR)<length(best_sbr)

7991

if length(best_IR)<length(best_sbr)

8081

best_IR(end+1:length(best_sbr))=0;

7992

best_IR(end+1:length(best_sbr))=0;

8082

end

7993

end

8083

result.IR = best_IR;

7994

result.IR = best_IR;

8084

end

7995

end

8085

result.t=t;

7996

result.t=t;

8086

result.sbr=best_sbr;

7997

result.sbr=best_sbr;

8087

if OP.RxFFE

7998

if OP.RxFFE

8088

result.RxFFE=best_RxFFE;

7999

result.RxFFE=best_RxFFE;

8089

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8000

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8090

result.PSD_results=best_PSD_results;

8001

result.PSD_results=best_PSD_results;

8091

result.MMSE_results=best_MMSE_results;

8002

result.MMSE_results=best_MMSE_results;

8092

end

8003

end

8093

end

8004

end

8094

8005

8095

8006

8096

8007

8097

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8008

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8098

% updated RIM 12/17/2021

8009

% updated RIM 12/17/2021

8099

result.A_p = max(chdata(1).uneq_pulse_response);

8010

result.A_p = max(chdata(1).uneq_pulse_response);

8100

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8011

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8101

PR=chdata(1).uneq_pulse_response;

8012

PR=chdata(1).uneq_pulse_response;

8102

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8013

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8103

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8014

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8104

if iend >= length(PR)

8015

if iend >= length(PR)

8105

iend = length (PR);

8016

iend = length (PR);

8106

end

8017

end

8107

if ibeg < 1

8018

if ibeg < 1

8108

ibeg = 1;

8019

ibeg = 1;

8109

end

8020

end

8110

PR=PR(ibeg:iend);

8021

PR=PR(ibeg:iend);

8111

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8022

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8112

SRn=PR;

8023

SRn=PR;

8113

for ik=1:floor(length(PR)/param.samples_per_ui)

8024

for ik=1:floor(length(PR)/param.samples_per_ui)

8114

SPR=circshift(PR,param.samples_per_ui*ik);

8025

SPR=circshift(PR,param.samples_per_ui*ik);

8115

SPR(1:ik*param.samples_per_ui)=0;

8026

SPR(1:ik*param.samples_per_ui)=0;

8116

SRn=SRn+ SPR;

8027

SRn=SRn+ SPR;

8117

end

8028

end

8118

codedebug=0;

8029

codedebug=0;

8119

if codedebug

8030

if codedebug

8120

fig=figure('Name', 'step and pulse response for code debug');

8031

fig=figure('Name', 'step and pulse response for code debug');

8121

figure(fig);set(gcf,'Tag','COM');

8032

figure(fig);set(gcf,'Tag','COM');

8122

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8033

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8123

plot(UI,SRn)

8034

plot(UI,SRn)

8124

hold on

8035

hold on

8125

plot(UI,PR)

8036

plot(UI,PR)

8126

xlim([-param.D_p param.N_v])

8037

xlim([-param.D_p param.N_v])

8127

grid on;hold off;

8038

grid on;hold off;

8128

result.step=SRn;

8039

result.step=SRn;

8129

end

8040

end

8130

i20=find(SRn>=0.20*result.A_f,1,'first');

8041

i20=find(SRn>=0.20*result.A_f,1,'first');

8131

i80=find(SRn>=0.80*result.A_f,1,'first');

8042

i80=find(SRn>=0.80*result.A_f,1,'first');

8132

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8043

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8133

result.Pmax_by_Vf=result.A_p/result.A_f;

8044

result.Pmax_by_Vf=result.A_p/result.A_f;

8134

result.ISI =best_ISI;

8045

result.ISI =best_ISI;

8135

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8046

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8136

result.best_current_ffegain=best_current_ffegain;

8047

result.best_current_ffegain=best_current_ffegain;

8137

result.best_bmax=best_bmax;

8048

result.best_bmax=best_bmax;

8138

%AJG021820

8049

%AJG021820

8139

result.best_bmin=best_bmin;

8050

result.best_bmin=best_bmin;

8140

result.tail_RSS=best_tail_RSS;

8051

result.tail_RSS=best_tail_RSS;

8141

result.sampled_best_sbr_precursors_t=sampled_best_sbr_precursors_t;

8142

result.sampled_best_sbr_postcursors_t=sampled_best_sbr_postcursors_t;

8143

function param=parameter_size_adjustment(param,OP)

8052

function param=parameter_size_adjustment(param,OP)

8144

8053

8145

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'};

8054

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'};

8146

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8055

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8147

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8056

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8148

make_length_DCHP={'f_HP'};

8057

make_length_DCHP={'f_HP'};

8149

make_length_ncases={'AC_CM_RMS'};

8058

make_length_ncases={'AC_CM_RMS'};

8150

8059

8151

%ncases used by make_length_ncases fields

8060

%ncases used by make_length_ncases fields

8152

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8061

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8153

8062

8154

%PORTZ_mult used by make_length_WCPORTZ fields

8063

%PORTZ_mult used by make_length_WCPORTZ fields

8155

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8064

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8156

if OP.WC_PORTZ

8065

if OP.WC_PORTZ

8157

PORTZ_mult=[1 1];

8066

PORTZ_mult=[1 1];

8158

else

8067

else

8159

PORTZ_mult=pkg_sel_vec;

8068

PORTZ_mult=pkg_sel_vec;

8160

end

8069

end

8161

8070

8162

%Parameters that have length = 2

8071

%Parameters that have length = 2

8163

for j=1:length(make_length2)

8072

for j=1:length(make_length2)

8164

if numel(param.(make_length2{j}))==1

8073

if numel(param.(make_length2{j}))==1

8165

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8074

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8166

end

8075

end

8167

end

8076

end

8168

8077

8169

%Parameters that have length = ncases

8078

%Parameters that have length = ncases

8170

for j=1:length(make_length_ncases)

8079

for j=1:length(make_length_ncases)

8171

if numel(param.(make_length_ncases{j}))==1

8080

if numel(param.(make_length_ncases{j}))==1

8172

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8081

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8173

end

8082

end

8174

end

8083

end

8175

8084

8176

%Parameters that have length = length(ctle_gdc_values)

8085

%Parameters that have length = length(ctle_gdc_values)

8177

for j=1:length(make_length_GDC)

8086

for j=1:length(make_length_GDC)

8178

if numel(param.(make_length_GDC{j}))==1

8087

if numel(param.(make_length_GDC{j}))==1

8179

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8088

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8180

end

8089

end

8181

end

8090

end

8182

8091

8183

%Parameters that have length = length(g_DC_HP_values)

8092

%Parameters that have length = length(g_DC_HP_values)

8184

for j=1:length(make_length_DCHP)

8093

for j=1:length(make_length_DCHP)

8185

if numel(param.(make_length_DCHP{j}))==1

8094

if numel(param.(make_length_DCHP{j}))==1

8186

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8095

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8187

end

8096

end

8188

end

8097

end

8189

8098

8190

%Parameters that have length associated with PORTZ_mult

8099

%Parameters that have length associated with PORTZ_mult

8191

for j=1:length(make_length_WCPORTZ)

8100

for j=1:length(make_length_WCPORTZ)

8192

if numel(param.(make_length_WCPORTZ{j}))==1

8101

if numel(param.(make_length_WCPORTZ{j}))==1

8193

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8102

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8194

end

8103

end

8195

end

8104

end

8196

function sgm = pdf2sgm(pdf)

8105

function sgm = pdf2sgm(pdf)

8197

avg = sum(pdf.x .* pdf.y);

8106

avg = sum(pdf.x .* pdf.y);

8198

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8107

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8199

% end yasuo patch

8108

% end yasuo patch

8200

8109

8201

8110

8202

%% adding tx packgage

8111

%% adding tx packgage

8203

function cdf=pdf_to_cdf(pdf)

8112

function cdf=pdf_to_cdf(pdf)

8204

8113

8205

%Transform PDF to CDF

8114

%Transform PDF to CDF

8206

%The CDF is natively calculated from negative-to-positive voltage.

8115

%The CDF is natively calculated from negative-to-positive voltage.

8207

%This only gives BER calculation for bottom eye. Need to also

8116

%This only gives BER calculation for bottom eye. Need to also

8208

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8117

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8209

%min of top and bottom CDF values.

8118

%min of top and bottom CDF values.

8210

%If only interested in one side, a simple cumsum on y is all that is needed.

8119

%If only interested in one side, a simple cumsum on y is all that is needed.

8211

8120

8212

cdf.yB=cumsum(pdf.y);

8121

cdf.yB=cumsum(pdf.y);

8213

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8122

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8214

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8123

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8215

cdf.x=pdf.x;

8124

cdf.x=pdf.x;

8216

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)

8125

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)

8217

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8126

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8218

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8127

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8219

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8128

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8220

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8129

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8221

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8130

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8222

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8131

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8223

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8132

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8224

%% Added by Bill Kirkland, June 14, 2017

8133

%% Added by Bill Kirkland, June 14, 2017

8225

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8134

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8226

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8135

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8227

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8136

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8228

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8137

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8229

8138

8230

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8139

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8231

hold on

8140

hold on

8232

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8141

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8233

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8142

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8234

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)

8143

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)

8235

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8144

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8236

8145

8237

%% Added by Bill Kirkland, June 14, 2017

8146

%% Added by Bill Kirkland, June 14, 2017

8238

% modification allows bathtub curves to cross over and hence one can

8147

% modification allows bathtub curves to cross over and hence one can

8239

% directly read the noise component.

8148

% directly read the noise component.

8240

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8149

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8241

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8150

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8242

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8151

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8243

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8152

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8244

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8153

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8245

8154

8246

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8155

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8247

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8156

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8248

8157

8249

ylabel(hax, 'Probability')

8158

ylabel(hax, 'Probability')

8250

xlabel(hax, 'volts')

8159

xlabel(hax, 'volts')

8251

legend(hax, 'show')

8160

legend(hax, 'show')

8252

% testing code

8161

% testing code

8253

if 0

8162

if 0

8254

figure_name = 'COM curves';

8163

figure_name = 'COM curves';

8255

fig=findobj('Name', figure_name);

8164

fig=findobj('Name', figure_name);

8256

if isempty(fig), fig=figure('Name', figure_name); end

8165

if isempty(fig), fig=figure('Name', figure_name); end

8257

figure(fig);set(gcf,'Tag','COM');

8166

figure(fig);set(gcf,'Tag','COM');

8258

grid on

8167

grid on

8259

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8168

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8260

hold on

8169

hold on

8261

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8170

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8262

ylim([ 1e-6 0.25])

8171

ylim([ 1e-6 0.25])

8263

xlim([0 30])

8172

xlim([0 30])

8264

grid on

8173

grid on

8265

end

8174

end

8266

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)

8175

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)

8267

BER=param.specBER;

8176

BER=param.specBER;

8268

delta_dB=param.delta_IL;

8177

delta_dB=param.delta_IL;

8269

8178

8270

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8179

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8271

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8180

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8272

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8181

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8273

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8182

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8274

8183

8275

8184

8276

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8185

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8277

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8186

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8278

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8187

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8279

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8188

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8280

8189

8281

COM=20*log10(max_signal/maxn_tot);

8190

COM=20*log10(max_signal/maxn_tot);

8282

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8191

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8283

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8192

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8284

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8193

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8285

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8194

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8286

8195

8287

pfctr=exp(-0.09054*delta_dB);% less loss

8196

pfctr=exp(-0.09054*delta_dB);% less loss

8288

mfctr=exp(0.09054*delta_dB); % more loss

8197

mfctr=exp(0.09054*delta_dB); % more loss

8289

8198

8290

%less loss

8199

%less loss

8291

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8200

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8292

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8201

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8293

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8202

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8294

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8203

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8295

plus_maxn_tot=norm(plus_maxn);

8204

plus_maxn_tot=norm(plus_maxn);

8296

8205

8297

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8206

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8298

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8207

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8299

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8208

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8300

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8209

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8301

minus_maxn_tot=norm(minus_maxn);

8210

minus_maxn_tot=norm(minus_maxn);

8302

8211

8303

% more loss

8212

% more loss

8304

COMp=20*log10(max_signal*pfctr/maxn_tot);

8213

COMp=20*log10(max_signal*pfctr/maxn_tot);

8305

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8214

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8306

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8215

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8307

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8216

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8308

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8217

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8309

% less loss

8218

% less loss

8310

COMm=20*log10(max_signal*mfctr/maxn_tot);

8219

COMm=20*log10(max_signal*mfctr/maxn_tot);

8311

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8220

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8312

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8221

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8313

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8222

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8314

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8223

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8315

8224

8316

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8225

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8317

8226

8318

8227

8319

if(COM<0)

8228

if(COM<0)

8320

return

8229

return

8321

end

8230

end

8322

8231

8323

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8232

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8324

8233

8325

% pie(COM_per_noise,labels)

8234

% pie(COM_per_noise,labels)

8326

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8235

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8327

% legend('show','Location','bestoutside')

8236

% legend('show','Location','bestoutside')

8328

nullbar= [ 0 0 0 ];

8237

nullbar= [ 0 0 0 ];

8329

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8238

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8330

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8239

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8331

hold on

8240

hold on

8332

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8241

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8333

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8242

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8334

8243

8335

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8244

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8336

% ax=gca;

8245

% ax=gca;

8337

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8246

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8338

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8247

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8339

grid on

8248

grid on

8340

legend(labels,'Location','north')

8249

legend(labels,'Location','north')

8341

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8250

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8342

ylabel('COM (dB)')

8251

ylabel('COM (dB)')

8343

hold off

8252

hold off

8344

8253

8345

8254

8346

8255

8347

8256

8348

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8257

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8349

num_files=length(chdata);

8258

num_files=length(chdata);

8350

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8259

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8351

for i=1:num_files

8260

for i=1:num_files

8352

if param.package_testcase_i==1 && i==1

8261

if param.package_testcase_i==1 && i==1

8353

if OP.TDR && i==1

8262

if OP.TDR && i==1

8354

S.Frequencies=chdata(i).faxis;

8263

S.Frequencies=chdata(i).faxis;

8355

S.Impedance=100;

8264

S.Impedance=100;

8356

if ~OP.SHOW_BRD

8265

if ~OP.SHOW_BRD

8357

Sfield='_orig';

8266

Sfield='_orig';

8358

else

8267

else

8359

Sfield='_raw';

8268

Sfield='_raw';

8360

end

8269

end

8361

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8270

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8362

if ~param.FLAG.S2P

8271

if ~param.FLAG.S2P

8363

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8272

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8364

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8273

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8365

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8274

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8366

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8275

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8367

else

8276

else

8368

S.NumPorts=1;

8277

S.NumPorts=1;

8369

end

8278

end

8370

if OP.TDR_W_TXPKG

8279

if OP.TDR_W_TXPKG

8371

if OP.ERL == 2

8280

if OP.ERL == 2

8372

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8281

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8373

end

8282

end

8374

R_diepad = param.R_diepad;

8283

R_diepad = param.R_diepad;

8375

% RX package length is assumed to be the same for all

8284

% RX package length is assumed to be the same for all

8376

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8285

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8377

% for Rx pkg

8286

% for Rx pkg

8378

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8287

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8379

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8288

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8380

combines4p( s11in, s12in, s21in, s22in, ...

8289

combines4p( s11in, s12in, s21in, s22in, ...

8381

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8290

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8382

% S=sparameters(S.Parameters,S.Frequencies,100);

8291

% S=sparameters(S.Parameters,S.Frequencies,100);

8383

S=SL(S,S.Frequencies,R_diepad(1)*2);

8292

S=SL(S,S.Frequencies,R_diepad(1)*2);

8384

chdata(i).TX_RL=S.Parameters(2,2,:);

8293

chdata(i).TX_RL=S.Parameters(2,2,:);

8385

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8294

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8386

end

8295

end

8387

8296

8388

% need to combine S wiht is page and channel

8297

% need to combine S wiht is page and channel

8389

if param.FLAG.S2P

8298

if param.FLAG.S2P

8390

port_sel=1;

8299

port_sel=1;

8391

else

8300

else

8392

port_sel=[1 2];

8301

port_sel=[1 2];

8393

if OP.AUTO_TFX

8302

if OP.AUTO_TFX

8394

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8303

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8395

pix=find(fir4del==max(fir4del),1);

8304

pix=find(fir4del==max(fir4del),1);

8396

param.tfx(2)=2*tu(pix);

8305

param.tfx(2)=2*tu(pix);

8397

end

8306

end

8398

end

8307

end

8399

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8308

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8400

for ipsl=1:length(port_sel) % do for both port if s4p

8309

for ipsl=1:length(port_sel) % do for both port if s4p

8401

for izt=1:length(param.Z_t) % do for all tdr impedances

8310

for izt=1:length(param.Z_t) % do for all tdr impedances

8402

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8311

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8403

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8312

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8404

% OP.interp_sparam_mag='trend_to_DC';

8313

% OP.interp_sparam_mag='trend_to_DC';

8405

OP.interp_sparam_mag='linear_trend_to_DC';

8314

OP.interp_sparam_mag='linear_trend_to_DC';

8406

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8315

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8407

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8316

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8408

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8317

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8409

if ipsl ==1

8318

if ipsl ==1

8410

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8319

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8411

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8320

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8412

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8321

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8413

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8322

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8414

else

8323

else

8415

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8324

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8416

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8325

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8417

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8326

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8418

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8327

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8419

end

8328

end

8420

if OP.PTDR && i==1

8329

if OP.PTDR && i==1

8421

if ipsl ==1

8330

if ipsl ==1

8422

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8331

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8423

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8332

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8424

else

8333

else

8425

if ~param.FLAG.S2P

8334

if ~param.FLAG.S2P

8426

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8335

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8427

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8336

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8428

else

8337

else

8429

chdata(i).TDR22(izt).ERL=[];

8338

chdata(i).TDR22(izt).ERL=[];

8430

chdata(i).TDR22(izt).ERLRMS=[];

8339

chdata(i).TDR22(izt).ERLRMS=[];

8431

end

8340

end

8432

end

8341

end

8433

else

8342

else

8434

chdata(i).TDR11(izt).ERL=[];

8343

chdata(i).TDR11(izt).ERL=[];

8435

chdata(i).TDR22(izt).ERL=[];

8344

chdata(i).TDR22(izt).ERL=[];

8436

chdata(i).TDR11(izt).ERLRMS=[];

8345

chdata(i).TDR11(izt).ERLRMS=[];

8437

chdata(i).TDR22(izt).ERLRMS=[];

8346

chdata(i).TDR22(izt).ERLRMS=[];

8438

end

8347

end

8439

end

8348

end

8440

end

8349

end

8441

end

8350

end

8442

8351

8443

end

8352

end

8444

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8353

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8445

h=figure(180);set(gcf,'Tag','COM');

8354

h=figure(180);set(gcf,'Tag','COM');

8446

if param.package_testcase_i==1 && i == 1

8355

if param.package_testcase_i==1 && i == 1

8447

if i==1

8356

if i==1

8448

htabgroup = uitabgroup(h);

8357

htabgroup = uitabgroup(h);

8449

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8358

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8450

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8359

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8451

hax1 = axes('Parent', htab1);

8360

hax1 = axes('Parent', htab1);

8452

hax3 = axes('Parent', htab3);

8361

hax3 = axes('Parent', htab3);

8453

if ~param.FLAG.S2P

8362

if ~param.FLAG.S2P

8454

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8363

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8455

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8364

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8456

hax2 = axes('Parent', htab2);

8365

hax2 = axes('Parent', htab2);

8457

hax4 = axes('Parent', htab4);

8366

hax4 = axes('Parent', htab4);

8458

end

8367

end

8459

end

8368

end

8460

set(h,'CurrentAxes',hax1)

8369

set(h,'CurrentAxes',hax1)

8461

hold on

8370

hold on

8462

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8371

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8463

hold off

8372

hold off

8464

legend (hax1, 'off');grid on;zoom xon;

8373

legend (hax1, 'off');grid on;zoom xon;

8465

set(legend (hax1, 'show'), 'interp', 'none');

8374

set(legend (hax1, 'show'), 'interp', 'none');

8466

8375

8467

if ~param.FLAG.S2P

8376

if ~param.FLAG.S2P

8468

set(h,'CurrentAxes',hax2)

8377

set(h,'CurrentAxes',hax2)

8469

hold on

8378

hold on

8470

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8379

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8471

hold off

8380

hold off

8472

legend (hax2, 'off');grid on;zoom xon;

8381

legend (hax2, 'off');grid on;zoom xon;

8473

set(legend (hax2, 'show'), 'interp', 'none');

8382

set(legend (hax2, 'show'), 'interp', 'none');

8474

end

8383

end

8475

8384

8476

set(h,'CurrentAxes',hax3)

8385

set(h,'CurrentAxes',hax3)

8477

hold on

8386

hold on

8478

if OP.PTDR

8387

if OP.PTDR

8479

for izt=1:length(param.Z_t)

8388

for izt=1:length(param.Z_t)

8480

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8389

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8481

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8390

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8482

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8391

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8483

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8392

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8484

end

8393

end

8485

end

8394

end

8486

hold off

8395

hold off

8487

legend (hax3, 'off');grid on;zoom xon;

8396

legend (hax3, 'off');grid on;zoom xon;

8488

set(legend (hax3, 'show'), 'interp', 'none');

8397

set(legend (hax3, 'show'), 'interp', 'none');

8489

if ~param.FLAG.S2P

8398

if ~param.FLAG.S2P

8490

set(h,'CurrentAxes',hax4)

8399

set(h,'CurrentAxes',hax4)

8491

hold on

8400

hold on

8492

if OP.PTDR

8401

if OP.PTDR

8493

for izt=1:length(param.Z_t)

8402

for izt=1:length(param.Z_t)

8494

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8403

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8495

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8404

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8496

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8405

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8497

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8406

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8498

end

8407

end

8499

end

8408

end

8500

hold off

8409

hold off

8501

legend (hax4, 'off');grid on;zoom xon;

8410

legend (hax4, 'off');grid on;zoom xon;

8502

set(legend (hax4, 'show'), 'interp', 'none');

8411

set(legend (hax4, 'show'), 'interp', 'none');

8503

end

8412

end

8504

end

8413

end

8505

end

8414

end

8506

if param.FLAG.S2P, return; end

8415

if param.FLAG.S2P, return; end

8507

end

8416

end

8508

function S =r_parrelell2(zref,f,rpad)

8417

function S =r_parrelell2(zref,f,rpad)

8509

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8418

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8510

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8419

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8511

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8420

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8512

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8421

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8513

% Sm=sparameters(S.Parameters,f,zref);

8422

% Sm=sparameters(S.Parameters,f,zref);

8514

8423

8515

8424

8516

8425

8517

8426

8518

8427

8519

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8428

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8520

8429

8521

%touchstone_file: .sNp touchstone file to read

8430

%touchstone_file: .sNp touchstone file to read

8522

%port_order: port reorder vector

8431

%port_order: port reorder vector

8523

%

8432

%

8524

%sch: sparameter matrix

8433

%sch: sparameter matrix

8525

%schFreqAxis: frequency axis

8434

%schFreqAxis: frequency axis

8526

8435

8527

[file_path,root_name,extension]=fileparts(touchstone_file);

8436

[file_path,root_name,extension]=fileparts(touchstone_file);

8528

fid=fopen(touchstone_file);

8437

fid=fopen(touchstone_file);

8529

8438

8530

%fetch number of ports from extension

8439

%fetch number of ports from extension

8531

num_ports=str2num(char(regexp(extension,'\d*','match')));

8440

num_ports=str2num(char(regexp(extension,'\d*','match')));

8532

8441

8533

%Get option line

8442

%Get option line

8534

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8443

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8535

optcell=textscan(optstr{1}{1},'%s');

8444

optcell=textscan(optstr{1}{1},'%s');

8536

optcell=optcell{1};

8445

optcell=optcell{1};

8537

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8446

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8538

%Some touchstone files need this. can't remember why now. maybe lines

8447

%Some touchstone files need this. can't remember why now. maybe lines

8539

%with whitespace but not empty but not commented

8448

%with whitespace but not empty but not commented

8540

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8449

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8541

optcell=textscan(optstr{1}{1},'%s');

8450

optcell=textscan(optstr{1}{1},'%s');

8542

optcell=optcell{1};

8451

optcell=optcell{1};

8543

end

8452

end

8544

8453

8545

%read the entire file

8454

%read the entire file

8546

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8455

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8547

raw_column_data=raw_read_data{1};

8456

raw_column_data=raw_read_data{1};

8548

fclose(fid);

8457

fclose(fid);

8549

8458

8550

%number of columns for 2D matrix

8459

%number of columns for 2D matrix

8551

columns=num_ports*num_ports*2+1;

8460

columns=num_ports*num_ports*2+1;

8552

8461

8553

%find the frequency lines by searching for the right number of NaN

8462

%find the frequency lines by searching for the right number of NaN

8554

a=sum(isnan(raw_column_data),2);

8463

a=sum(isnan(raw_column_data),2);

8555

if num_ports==3

8464

if num_ports==3

8556

b=find(a==2);

8465

b=find(a==2);

8557

elseif num_ports==1

8466

elseif num_ports==1

8558

b=find(a==6);

8467

b=find(a==6);

8559

else

8468

else

8560

b=find(a==0);

8469

b=find(a==0);

8561

end

8470

end

8562

8471

8563

num_freq=length(b);

8472

num_freq=length(b);

8564

8473

8565

%toss out the NaN and reshape into a 2D matrix

8474

%toss out the NaN and reshape into a 2D matrix

8566

raw_input = raw_column_data.';

8475

raw_input = raw_column_data.';

8567

raw_input = raw_input(~isnan(raw_input));

8476

raw_input = raw_input(~isnan(raw_input));

8568

raw_input = reshape(raw_input,columns,num_freq).';

8477

raw_input = reshape(raw_input,columns,num_freq).';

8569

8478

8570

%get the frequency mult

8479

%get the frequency mult

8571

frequency_mult_text=optcell{2};

8480

frequency_mult_text=optcell{2};

8572

if(strcmpi(frequency_mult_text,'hz'))

8481

if(strcmpi(frequency_mult_text,'hz'))

8573

frequency_mult=1;

8482

frequency_mult=1;

8574

elseif(strcmpi(frequency_mult_text,'khz'))

8483

elseif(strcmpi(frequency_mult_text,'khz'))

8575

frequency_mult=1e3;

8484

frequency_mult=1e3;

8576

elseif(strcmpi(frequency_mult_text,'mhz'))

8485

elseif(strcmpi(frequency_mult_text,'mhz'))

8577

frequency_mult=1e6;

8486

frequency_mult=1e6;

8578

elseif(strcmpi(frequency_mult_text,'ghz'))

8487

elseif(strcmpi(frequency_mult_text,'ghz'))

8579

frequency_mult=1e9;

8488

frequency_mult=1e9;

8580

else

8489

else

8581

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8490

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8582

end

8491

end

8583

8492

8584

%get the RI/MA/DB format

8493

%get the RI/MA/DB format

8585

format=optcell{4};

8494

format=optcell{4};

8586

%get Z0

8495

%get Z0

8587

port_impedance=str2double(optcell(6:end))';

8496

port_impedance=str2double(optcell(6:end))';

8588

8497

8589

8498

8590

%grab frequency

8499

%grab frequency

8591

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8500

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8592

Spar.F=raw_input(:,1);

8501

Spar.F=raw_input(:,1);

8593

Spar.F=transpose(Spar.F(:));

8502

Spar.F=transpose(Spar.F(:));

8594

8503

8595

8504

8596

%transform data to real imaginary

8505

%transform data to real imaginary

8597

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8506

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8598

if(strcmpi(format,'ri'))

8507

if(strcmpi(format,'ri'))

8599

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8508

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8600

elseif(strcmpi(format,'ma'))

8509

elseif(strcmpi(format,'ma'))

8601

mag_data=raw_input(:,2:2:end);

8510

mag_data=raw_input(:,2:2:end);

8602

rad_data=raw_input(:,3:2:end)*pi/180;

8511

rad_data=raw_input(:,3:2:end)*pi/180;

8603

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8512

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8604

elseif(strcmpi(format,'db'))

8513

elseif(strcmpi(format,'db'))

8605

mag_data=10.^(raw_input(:,2:2:end)/20);

8514

mag_data=10.^(raw_input(:,2:2:end)/20);

8606

rad_data=raw_input(:,3:2:end)*pi/180;

8515

rad_data=raw_input(:,3:2:end)*pi/180;

8607

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8516

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8608

else

8517

else

8609

error('Format %s is not supported. Use RI MA or DB',format);

8518

error('Format %s is not supported. Use RI MA or DB',format);

8610

end

8519

end

8611

8520

8612

8521

8613

8522

8614

%transform to 3D

8523

%transform to 3D

8615

%allow for upper/lower matrix specification for touchstone 2.0 support

8524

%allow for upper/lower matrix specification for touchstone 2.0 support

8616

matrix_format=0;

8525

matrix_format=0;

8617

if(matrix_format==0)

8526

if(matrix_format==0)

8618

%full

8527

%full

8619

for j=1:num_ports

8528

for j=1:num_ports

8620

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8529

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8621

end

8530

end

8622

elseif(matrix_format==1)

8531

elseif(matrix_format==1)

8623

%upper

8532

%upper

8624

used_ports=0;

8533

used_ports=0;

8625

for j=1:num_ports

8534

for j=1:num_ports

8626

stated_ports=num_ports-j+1;

8535

stated_ports=num_ports-j+1;

8627

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8536

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8628

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8537

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8629

used_ports=used_ports+stated_ports;

8538

used_ports=used_ports+stated_ports;

8630

end

8539

end

8631

elseif(matrix_format==2)

8540

elseif(matrix_format==2)

8632

%lower

8541

%lower

8633

used_ports=0;

8542

used_ports=0;

8634

for j=1:num_ports

8543

for j=1:num_ports

8635

stated_ports=j;

8544

stated_ports=j;

8636

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8545

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8637

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8546

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8638

used_ports=used_ports+stated_ports;

8547

used_ports=used_ports+stated_ports;

8639

end

8548

end

8640

else

8549

else

8641

error('Matrix format is not supported. Use Full, Lower, or Upper');

8550

error('Matrix format is not supported. Use Full, Lower, or Upper');

8642

end

8551

end

8643

8552

8644

8553

8645

%check for swapping the 2 port matrix (required on 1.x spec)

8554

%check for swapping the 2 port matrix (required on 1.x spec)

8646

two_port_swap=1;

8555

two_port_swap=1;

8647

if(num_ports==2 && two_port_swap==1)

8556

if(num_ports==2 && two_port_swap==1)

8648

temp=pre_out.sp(1,2,:);

8557

temp=pre_out.sp(1,2,:);

8649

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8558

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8650

pre_out.sp(2,1,:)=temp;

8559

pre_out.sp(2,1,:)=temp;

8651

end

8560

end

8652

8561

8653

Spar.S=pre_out.sp;

8562

Spar.S=pre_out.sp;

8654

Spar.Z0=transpose(port_impedance(:));

8563

Spar.Z0=transpose(port_impedance(:));

8655

8564

8656

if length(Spar.Z0)>1

8565

if length(Spar.Z0)>1

8657

error('Each port must have the same reference impedance');

8566

error('Each port must have the same reference impedance');

8658

end

8567

end

8659

if ~isequal(Spar.Z0,50)

8568

if ~isequal(Spar.Z0,50)

8660

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8569

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8661

%Renormalize to 50 ohms

8570

%Renormalize to 50 ohms

8662

rho=(50-Spar.Z0)/(50+Spar.Z0);

8571

rho=(50-Spar.Z0)/(50+Spar.Z0);

8663

p=num_ports;

8572

p=num_ports;

8664

s_old=Spar.S;

8573

s_old=Spar.S;

8665

for k=1:num_freq

8574

for k=1:num_freq

8666

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8575

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8667

end

8576

end

8668

end

8577

end

8669

8578

8670

%These operations sync up with COM style Spar matrix

8579

%These operations sync up with COM style Spar matrix

8671

%1: put frequency as first dimension

8580

%1: put frequency as first dimension

8672

sch=shiftdim(Spar.S,2);

8581

sch=shiftdim(Spar.S,2);

8673

%2: reorder ports according to "ports" input

8582

%2: reorder ports according to "ports" input

8674

sch=sch(:,port_order,port_order);

8583

sch=sch(:,port_order,port_order);

8675

schFreqAxis=Spar.F;

8584

schFreqAxis=Spar.F;

8676

function [chdata, param] = read_PR_files(param, OP, chdata)

8585

function [chdata, param] = read_PR_files(param, OP, chdata)

8677

%% Read in pulse response

8586

%% Read in pulse response

8678

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8587

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8679

num_files=length(chdata);

8588

num_files=length(chdata);

8680

M=param.samples_per_ui;

8589

M=param.samples_per_ui;

8681

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8590

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8682

for i=1:num_files

8591

for i=1:num_files

8683

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8592

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8684

progress = i/num_files;

8593

progress = i/num_files;

8685

if OP.DISPLAY_WINDOW

8594

if OP.DISPLAY_WINDOW

8686

[~,a]=fileparts(chdata(i).filename);

8595

[~,a]=fileparts(chdata(i).filename);

8687

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8596

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8688

else

8597

else

8689

fprintf('%i ',i);

8598

fprintf('%i ',i);

8690

end

8599

end

8691

switch chdata(i).ext

8600

switch chdata(i).ext

8692

case '.csv'

8601

case '.csv'

8693

vt=load(chdata(i).filename);

8602

vt=load(chdata(i).filename);

8694

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8603

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8695

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8604

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8696

dt=vt(2,1)-vt(1,1);

8605

dt=vt(2,1)-vt(1,1);

8697

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8606

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8698

8607

8699

8608

8700

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8609

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8701

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8610

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8702

Vf=step_response(end);

8611

Vf=step_response(end);

8703

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8612

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8704

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8613

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8705

8614

8706

end

8615

end

8707

end

8616

end

8708

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8617

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8709

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8618

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8710

[filepath,name,ext] = fileparts(paramFile);

8619

[filepath,name,ext] = fileparts(paramFile);

8711

if ~isempty(filepath)

8620

if ~isempty(filepath)

8712

filepath=[filepath '\'];

8621

filepath=[filepath '\'];

8713

end

8622

end

8714

matcongfile=[filepath name '.mat'];

8623

matcongfile=[filepath name '.mat'];

8715

try

8624

try

8716

switch upper(ext)

8625

switch upper(ext)

8717

case upper('.mat')

8626

case upper('.mat')

8718

load(matcongfile)

8627

load(matcongfile)

8719

case upper('.csv')

8628

case upper('.csv')

8720

[na1, na2, parameter] = xlsread(paramFile);

8629

[na1, na2, parameter] = xlsread(paramFile);

8721

otherwise

8630

otherwise

8722

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8631

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8723

end

8632

end

8724

8633

8725

catch ME %#ok<NASGU>

8634

catch ME %#ok<NASGU>

8726

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8635

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8727

switch upper(ext)

8636

switch upper(ext)

8728

case upper('.mat')

8637

case upper('.mat')

8729

load(matcongfile)

8638

load(matcongfile)

8730

case upper('.csv')

8639

case upper('.csv')

8731

[na1, na2, parameter] = xlsread(paramFile);

8640

[na1, na2, parameter] = xlsread(paramFile);

8732

otherwise

8641

otherwise

8733

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8642

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8734

end

8643

end

8735

end

8644

end

8736

8645

8737

%% New section to parse .START package data

8646

%% New section to parse .START package data

8738

first_column_data = parameter(:,1);

8647

first_column_data = parameter(:,1);

8739

start_data_rows = find(strcmp(first_column_data,'.START'));

8648

start_data_rows = find(strcmp(first_column_data,'.START'));

8740

if ~isempty(start_data_rows)

8649

if ~isempty(start_data_rows)

8741

end_data_rows = find(strcmp(first_column_data,'.END'));

8650

end_data_rows = find(strcmp(first_column_data,'.END'));

8742

if length(start_data_rows) ~= length(end_data_rows)

8651

if length(start_data_rows) ~= length(end_data_rows)

8743

error('Number of .START and .END must be the same');

8652

error('Number of .START and .END must be the same');

8744

end

8653

end

8745

first_start_row = start_data_rows(1);

8654

first_start_row = start_data_rows(1);

8746

special_parameter = parameter;

8655

special_parameter = parameter;

8747

parameter = parameter(1:first_start_row-1,:);

8656

parameter = parameter(1:first_start_row-1,:);

8748

for j=1:length(start_data_rows)

8657

for j=1:length(start_data_rows)

8749

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

8658

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

8750

pkg_name = special_parameter{start_data_rows(j),2};

8659

pkg_name = special_parameter{start_data_rows(j),2};

8751

8660

8752

%Read all the parameters that make up a package

8661

%Read all the parameters that make up a package

8753

PKG_param = read_package_parameters(this_block);

8662

PKG_param = read_package_parameters(this_block);

8754

8663

8755

%save the data in a field revealed by pkg_name

8664

%save the data in a field revealed by pkg_name

8756

param.PKG.(pkg_name) = PKG_param;

8665

param.PKG.(pkg_name) = PKG_param;

8757

8666

8758

8667

8759

end

8668

end

8760

end

8669

end

8761

%Allow specification of TX and RX package section through PKG_NAME keyword

8670

%Allow specification of TX and RX package section through PKG_NAME keyword

8762

%the values must match package blocks specified in .START sections

8671

%the values must match package blocks specified in .START sections

8763

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

8672

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

8764

if isnan(param.PKG_NAME)

8673

if isnan(param.PKG_NAME)

8765

param.PKG_NAME = '';

8674

param.PKG_NAME = '';

8766

end

8675

end

8767

if isempty(param.PKG_NAME)

8676

if isempty(param.PKG_NAME)

8768

param.PKG_NAME = {};

8677

param.PKG_NAME = {};

8769

else

8678

else

8770

param.PKG_NAME = strsplit(param.PKG_NAME);

8679

param.PKG_NAME = strsplit(param.PKG_NAME);

8771

end

8680

end

8772

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

8681

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

8773

error('PKG_NAME can only be used if .START blocks for package parameters are used');

8682

error('PKG_NAME can only be used if .START blocks for package parameters are used');

8774

end

8683

end

8775

for j=1:length(param.PKG_NAME)

8684

for j=1:length(param.PKG_NAME)

8776

if ~isfield(param.PKG,param.PKG_NAME{j})

8685

if ~isfield(param.PKG,param.PKG_NAME{j})

8777

error('Package Block "%s" not found',param.PKG_NAME{j});

8686

error('Package Block "%s" not found',param.PKG_NAME{j});

8778

end

8687

end

8779

end

8688

end

8780

8689

8781

%%

8690

%%

8782

% just need to define so we can pass

8691

% just need to define so we can pass

8783

param.c=[.4e-12 .4e-12];

8692

param.c=[.4e-12 .4e-12];

8784

param.alen=[ 20 30 550 ];

8693

param.alen=[ 20 30 550 ];

8785

param.az=[100 120 100];

8694

param.az=[100 120 100];

8786

8695

8787

% make control for package/channel reflection control

8696

% make control for package/channel reflection control

8788

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

8697

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

8789

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

8698

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

8790

8699

8791

% make compatible with presentation of kappa

8700

% make compatible with presentation of kappa

8792

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

8701

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

8793

8702

8794

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

8703

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

8795

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

8704

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

8796

8705

8797

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

8706

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

8798

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

8707

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

8799

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

8708

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

8800

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

8709

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

8801

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

8710

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

8802

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

8711

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

8803

8712

8804

if OP.dynamic_txffe

8713

if OP.dynamic_txffe

8805

found_pre=1;

8714

found_pre=1;

8806

pre_count=1;

8715

pre_count=1;

8807

while found_pre

8716

while found_pre

8808

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

8717

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

8809

if found_pre

8718

if found_pre

8810

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

8719

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

8811

param.(field_name)=p;

8720

param.(field_name)=p;

8812

pre_count=pre_count+1;

8721

pre_count=pre_count+1;

8813

end

8722

end

8814

end

8723

end

8815

found_post=1;

8724

found_post=1;

8816

post_count=1;

8725

post_count=1;

8817

while found_post

8726

while found_post

8818

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

8727

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

8819

if found_post

8728

if found_post

8820

field_name=sprintf('tx_ffe_cp%d_values',post_count);

8729

field_name=sprintf('tx_ffe_cp%d_values',post_count);

8821

param.(field_name)=p;

8730

param.(field_name)=p;

8822

post_count=post_count+1;

8731

post_count=post_count+1;

8823

end

8732

end

8824

end

8733

end

8825

else

8734

else

8826

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

8735

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

8827

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

8736

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

8828

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

8737

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

8829

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

8738

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

8830

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

8739

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

8831

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

8740

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

8832

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

8741

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

8833

end

8742

end

8834

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

8743

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

8835

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

8744

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

8836

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

8745

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

8837

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

8746

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

8838

% support for floating taps

8747

% support for floating taps

8839

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

8748

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

8840

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

8749

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

8841

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

8750

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

8842

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

8751

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

8843

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

8752

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

8844

if param.N_bg == 0, param.N_bmax=param.ndfe; end

8753

if param.N_bg == 0, param.N_bmax=param.ndfe; end

8845

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

8754

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

8846

8755

8847

% support for tail tap power limitations

8756

% support for tail tap power limitations

8848

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

8757

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

8849

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

8758

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

8850

%

8759

%

8851

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

8760

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

8852

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

8761

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

8853

param.RxFFE_cmx=param.ffe_pre_tap_len;

8762

param.RxFFE_cmx=param.ffe_pre_tap_len;

8854

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

8763

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

8855

param.RxFFE_cpx=param.ffe_post_tap_len;

8764

param.RxFFE_cpx=param.ffe_post_tap_len;

8856

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

8765

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

8857

param.RxFFE_stepz=param.ffe_tap_step_size;

8766

param.RxFFE_stepz=param.ffe_tap_step_size;

8858

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

8767

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

8859

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

8768

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

8860

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

8769

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

8861

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

8770

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

8862

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

8771

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

8863

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

8772

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

8864

OP.RxFFE= true;

8773

OP.RxFFE= true;

8865

else

8774

else

8866

OP.RxFFE=false;

8775

OP.RxFFE=false;

8867

end

8776

end

8868

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

8777

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

8869

8778

8870

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

8779

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

8871

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

8780

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

8872

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

8781

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

8873

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

8782

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

8874

8783

8875

8784

8876

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

8785

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

8877

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

8786

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

8878

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)

8787

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)

8879

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

8788

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

8880

8789

8881

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)

8790

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)

8882

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

8791

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

8883

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

8792

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

8884

% always read in main ctle values. They would be interpreted different baseed

8793

% always read in main ctle values. They would be interpreted different baseed

8885

% on the clause they apply because of different CTF equations

8794

% on the clause they apply because of different CTF equations

8886

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

8795

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

8887

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8796

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8888

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8797

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8889

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8798

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8890

% the contex of the poles an zeros are determined by the clause

8799

% the contex of the poles an zeros are determined by the clause

8891

switch param.CTLE_type

8800

switch param.CTLE_type

8892

case 'CL93'

8801

case 'CL93'

8893

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

8802

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

8894

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8803

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8895

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8804

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8896

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8805

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8897

case 'CL120d'

8806

case 'CL120d'

8898

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

8807

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

8899

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

8808

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

8900

case 'CL120e'

8809

case 'CL120e'

8901

% re adjust to get TD_CTLE to work with C:120e equation without

8810

% re adjust to get TD_CTLE to work with C:120e equation without

8902

% changing TD_CTLE code

8811

% changing TD_CTLE code

8903

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

8812

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

8904

end

8813

end

8905

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

8814

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

8906

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

8815

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

8907

%% addd default to support multiple packages

8816

%% addd default to support multiple packages

8908

param.a_thru = xls_parameter(parameter, 'A_v', true, 0.5); % Victim differential peak source output voltage (half of peak to peak)

8817

param.a_thru = xls_parameter(parameter, 'A_v', true, 0.5); % Victim differential peak source output voltage (half of peak to peak)

8909

param.a_fext = xls_parameter(parameter, 'A_fe', true,0.5); % FEXT aggressor differential peak source output voltage (half of peak to peak)

8818

param.a_fext = xls_parameter(parameter, 'A_fe', true,0.5); % FEXT aggressor differential peak source output voltage (half of peak to peak)

8910

param.a_next = xls_parameter(parameter, 'A_ne', true,0.5); % NEXT aggressor differential peak source output voltage (half of peak to peak)

8819

param.a_next = xls_parameter(parameter, 'A_ne', true,0.5); % NEXT aggressor differential peak source output voltage (half of peak to peak)

8911

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

8820

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

8912

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

8821

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

8913

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

8822

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

8914

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

8823

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

8915

param.DER_CDR = xls_parameter(parameter, 'DER_CDR',true,1e-2); % min DER required for a CDR

8824

param.DER_CDR = xls_parameter(parameter, 'DER_CDR',true,1e-2); % min DER required for a CDR

8916

param.N_qb = xls_parameter(parameter, 'N_qb',true,0); % adc number of bits if 0 do not apply quantization

8917

param.P_qc= xls_parameter(parameter, 'P_qc',true,2*param.specBER); % adc clipping probability

8918

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

8825

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

8919

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

8826

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

8920

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

8827

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

8921

8828

8922

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

8829

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

8923

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

8830

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

8924

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

8831

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

8925

% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

8832

% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

8926

param.trunc = xls_parameter(parameter, 'trunc', true, 128); % MLSE sequence truncation length

8833

param.trunc = xls_parameter(parameter, 'trunc', true, 128); % MLSE sequence truncation length

8927

param.trunc = xls_parameter(parameter, 'N_tc', true, param.trunc); % MLSE sequence truncation length

8834

param.trunc = xls_parameter(parameter, 'N_tc', true, param.trunc); % MLSE sequence truncation length

8928

8835

8929

% healey_3dj_01a_2407 adjust MLSE for COM_DFE

8836

% healey_3dj_01a_2407 adjust MLSE for COM_DFE

8930

param.Q_budget_adj = xls_parameter(parameter, 'Q_budget_adj', true, 0); % MLSE sequence truncation length

8837

param.Q_budget_adj = xls_parameter(parameter, 'Q_budget_adj', true, 0); % MLSE sequence truncation length

8931

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

8838

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

8932

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

8839

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

8933

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

8840

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

8934

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

8841

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

8935

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)

8842

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)

8936

% This will keep bmax length 0 if Nb=0

8843

% This will keep bmax length 0 if Nb=0

8937

8844

8938

%AJG021820

8845

%AJG021820

8939

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

8846

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

8940

if isempty(param.bmax)

8847

if isempty(param.bmax)

8941

param.bmin=param.bmax;

8848

param.bmin=param.bmax;

8942

else

8849

else

8943

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.

8850

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.

8944

8851

8945

end

8852

end

8946

if param.ndfe >= 2

8853

if param.ndfe >= 2

8947

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

8854

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

8948

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)

8855

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)

8949

end

8856

end

8950

8857

8951

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)

8858

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)

8952

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

8859

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

8953

%verify gqual and gqual2 input

8860

%verify gqual and gqual2 input

8954

if ~isempty(param.gqual) || ~isempty(param.g2qual)

8861

if ~isempty(param.gqual) || ~isempty(param.g2qual)

8955

if size(param.gqual,1)~=length(param.g2qual)

8862

if size(param.gqual,1)~=length(param.g2qual)

8956

error('gqual and g2qual size mismatch');

8863

error('gqual and g2qual size mismatch');

8957

end

8864

end

8958

if size(param.gqual,2)~=2

8865

if size(param.gqual,2)~=2

8959

error('gqual must be Nx2 matrix');

8866

error('gqual must be Nx2 matrix');

8960

end

8867

end

8961

end

8868

end

8962

8869

8963

8870

8964

% eval if string for all three - can use different for TX and RX

8871

% eval if string for all three - can use different for TX and RX

8965

param.C_pkg_board = xls_parameter(parameter, 'C_p', true,0)*1e-9; % C_p in nF (single sided)

8872

param.C_pkg_board = xls_parameter(parameter, 'C_p', true,0)*1e-9; % C_p in nF (single sided)

8966

param.C_diepad = xls_parameter(parameter, 'C_d', true,0)*1e-9; % C_d in nF (single sided)

8873

param.C_diepad = xls_parameter(parameter, 'C_d', true,0)*1e-9; % C_d in nF (single sided)

8967

% [ahealey] Read values for optional compensating L and "bump" C

8874

% [ahealey] Read values for optional compensating L and "bump" C

8968

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

8875

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

8969

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

8876

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

8970

% [ahealey] End of modification

8877

% [ahealey] End of modification

8971

% added default to support multiple packages

8878

% added default to support multiple packages

8972

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

8879

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

8973

param.R_diepad = xls_parameter(parameter, 'R_d', true, [50,50]); % Die source termination resistance (single sided)

8880

param.R_diepad = xls_parameter(parameter, 'R_d', true, [50,50]); % Die source termination resistance (single sided)

8974

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

8881

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

8975

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

8882

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

8976

8883

8977

8884

8978

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

8885

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

8979

% added default to support multiple packages

8886

% added default to support multiple packages

8980

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

8887

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

8981

[ncases, mele]=size(param.z_p_tx_cases);

8888

[ncases, mele]=size(param.z_p_tx_cases);

8982

if mele ==2

8889

if mele ==2

8983

param.flex=2;

8890

param.flex=2;

8984

elseif mele==4

8891

elseif mele==4

8985

param.flex=4;

8892

param.flex=4;

8986

elseif mele==1

8893

elseif mele==1

8987

param.flex=1;

8894

param.flex=1;

8988

else

8895

else

8989

error(sprintf('config file syntax error'))

8896

error(sprintf('config file syntax error'))

8990

end

8897

end

8991

8898

8992

% board parameters

8899

% board parameters

8993

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

8900

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

8994

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

8901

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

8995

% added default to support multiple packages

8902

% added default to support multiple packages

8996

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

8903

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

8997

[ncases1, mele1]=size(param.z_p_next_cases);

8904

[ncases1, mele1]=size(param.z_p_next_cases);

8998

if ncases ~= ncases1 || mele ~= mele1

8905

if ncases ~= ncases1 || mele ~= mele1

8999

error('All TX, NEXT, FEXT, Rx cases must agree');

8906

error('All TX, NEXT, FEXT, Rx cases must agree');

9000

else

8907

else

9001

end

8908

end

9002

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

8909

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

9003

[ncases1, mele1]=size(param.z_p_fext_cases);

8910

[ncases1, mele1]=size(param.z_p_fext_cases);

9004

if ncases ~= ncases1 || mele ~= mele1

8911

if ncases ~= ncases1 || mele ~= mele1

9005

error('All TX, NEXT, FEXT, Rx cases must agree');

8912

error('All TX, NEXT, FEXT, Rx cases must agree');

9006

else

8913

else

9007

end

8914

end

9008

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

8915

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

9009

[ncases1, mele1]=size(param.z_p_rx_cases);

8916

[ncases1, mele1]=size(param.z_p_rx_cases);

9010

if ncases ~= ncases1 || mele ~= mele1

8917

if ncases ~= ncases1 || mele ~= mele1

9011

error('All TX, NEXT, FEXT, Rx cases must agree');

8918

error('All TX, NEXT, FEXT, Rx cases must agree');

9012

else

8919

else

9013

end

8920

end

9014

% Table 93A-3 parameters

8921

% Table 93A-3 parameters

9015

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.

8922

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.

9016

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

8923

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9017

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 ]

8924

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 ]

9018

[ ncases1, mele1]=size(param.pkg_Z_c);%

8925

[ ncases1, mele1]=size(param.pkg_Z_c);%

9019

if mele ~= mele1

8926

if mele ~= mele1

9020

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

8927

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9021

else

8928

else

9022

end

8929

end

9023

if mele1==2 % fuill in a array if only a 2 element flex package is specified

8930

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9024

for ii=1:ncases

8931

for ii=1:ncases

9025

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

8932

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9026

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

8933

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9027

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

8934

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9028

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

8935

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9029

end

8936

end

9030

param.z_p_fext_cases = param.z_p_fext_casesx;

8937

param.z_p_fext_cases = param.z_p_fext_casesx;

9031

param.z_p_next_cases= param.z_p_next_casesx;

8938

param.z_p_next_cases= param.z_p_next_casesx;

9032

param.z_p_tx_cases= param.z_p_tx_casesx;

8939

param.z_p_tx_cases= param.z_p_tx_casesx;

9033

param.z_p_rx_cases= param.z_p_rx_casesx;

8940

param.z_p_rx_cases= param.z_p_rx_casesx;

9034

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

8941

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9035

end

8942

end

9036

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

8943

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9037

8944

9038

% Table 92-12 parameters

8945

% Table 92-12 parameters

9039

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.

8946

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.

9040

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

8947

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9041

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

8948

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9042

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

8949

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9043

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

8950

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9044

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

8951

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9045

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

8952

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9046

8953

9047

% Unofficial parameters

8954

% Unofficial parameters

9048

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

8955

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9049

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

8956

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9050

% Deprecated parameters - affect only frequency domain analysis.

8957

% Deprecated parameters - affect only frequency domain analysis.

9051

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

8958

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

9052

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

8959

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

9053

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

8960

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

9054

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

8961

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

9055

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

8962

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

9056

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

8963

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9057

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

8964

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9058

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

8965

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9059

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

8966

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9060

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

8967

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9061

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

8968

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9062

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

8969

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9063

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

8970

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9064

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

8971

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9065

switch param.Gx

8972

switch param.Gx

9066

case 0

8973

case 0

9067

param.Grr=param.Grr; % just use older Grr ir gx not specified

8974

param.Grr=param.Grr; % just use older Grr ir gx not specified

9068

case 1

8975

case 1

9069

param.Grr=2; % use newer Grr

8976

param.Grr=2; % use newer Grr

9070

end

8977

end

9071

8978

9072

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

8979

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

9073

% Operational control variables

8980

% Operational control variables

9074

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

8981

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9075

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

8982

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9076

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

8983

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

9077

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

8984

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

9078

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

8985

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9079

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.

8986

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.

9080

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.

8987

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.

9081

8988

9082

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

8989

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9083

8990

9084

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)

8991

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)

9085

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

8992

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9086

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

8993

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9087

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

8994

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

9088

8995

9089

%%

8996

%%

9090

8997

9091

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

8998

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9092

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

8999

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9093

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9000

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9094

param.awgn_mv=param.AC_CM_RMS;

9001

param.awgn_mv=param.AC_CM_RMS;

9095

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9002

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9096

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

9003

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

9097

param.Q=xls_parameter(parameter, 'Q', true, 0 ); % Implementation penalty for MLSE in EQ 178a-36

9004

param.Q=xls_parameter(parameter, 'Q', true, 0 ); % Implementation penalty for MLSE in EQ 178a-36

9098

9005

9099

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9006

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9100

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9007

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9101

param.Floating_RXFFE=false;

9008

param.Floating_RXFFE=false;

9102

param.Floating_DFE=false;

9009

param.Floating_DFE=false;

9103

if param.N_bg > 0

9010

if param.N_bg > 0

9104

param.Floating_DFE=true;

9011

param.Floating_DFE=true;

9105

end

9012

end

9106

if OP.RxFFE

9013

if OP.RxFFE

9107

param.Floating_DFE=false;

9014

param.Floating_DFE=false;

9108

if param.N_bg > 0

9015

if param.N_bg > 0

9109

param.Floating_RXFFE=true;

9016

param.Floating_RXFFE=true;

9110

end

9017

end

9111

end

9018

end

9112

%% for introducing Tx or Rx skew on p leg or n leg

9019

%% for introducing Tx or Rx skew on p leg or n leg

9113

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9020

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9114

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9021

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9115

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9022

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9116

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9023

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9117

9024

9118

%%

9025

%%

9119

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9026

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9120

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9027

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9121

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9028

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9122

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9029

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9123

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9030

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9124

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9031

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9125

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9032

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9126

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9033

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9127

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9034

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9128

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

9035

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

9129

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9036

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9130

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9037

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9131

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9038

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9132

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

9039

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

9133

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

9040

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

9134

if ~OP.INC_PACKAGE

9041

if ~OP.INC_PACKAGE

9135

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');

9042

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');

9136

end

9043

end

9137

9044

9138

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9045

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9139

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9046

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9140

if OP.IDEAL_TX_TERM

9047

if OP.IDEAL_TX_TERM

9141

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9048

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9142

end

9049

end

9143

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9050

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9144

if OP.IDEAL_RX_TERM

9051

if OP.IDEAL_RX_TERM

9145

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9052

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9146

end

9053

end

9147

9054

9148

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.

9055

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.

9149

9056

9150

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9057

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9151

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9058

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9152

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9059

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9153

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

9060

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

9154

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9061

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9155

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

9062

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

9156

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9063

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9157

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

9064

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

9158

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

9065

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

9159

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

9066

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

9160

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9067

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9161

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9068

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9162

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

9069

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

9163

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.

9070

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.

9164

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9071

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9165

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9072

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9166

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9073

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9167

9074

9168

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9075

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9169

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9076

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9170

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.

9077

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.

9171

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9078

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9172

% compatibility

9079

% compatibility

9173

if OP.FORCE_TR

9080

if OP.FORCE_TR

9174

OP.T_r_meas_point=0;

9081

OP.T_r_meas_point=0;

9175

OP.T_r_filter_type=1;

9082

OP.T_r_filter_type=1;

9176

end

9083

end

9177

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9084

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9178

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.

9085

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.

9179

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9086

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9180

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9087

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9181

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.

9088

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.

9182

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9089

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9183

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9090

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9184

if OP.ERL

9091

if OP.ERL

9185

OP.PTDR=1;

9092

OP.PTDR=1;

9186

else

9093

else

9187

OP.PTDR=0;

9094

OP.PTDR=0;

9188

end % ERL needs to do a TDR

9095

end % ERL needs to do a TDR

9189

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9096

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9190

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9097

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9191

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9098

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9192

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9099

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9193

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9100

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9194

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9101

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9195

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9102

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9196

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9103

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9197

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.

9104

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.

9198

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9105

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9199

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9106

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9200

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.

9107

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.

9201

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9108

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9202

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9109

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9203

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9110

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9204

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9111

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9205

if strcmpi(OP.PHY,'C2M')

9112

if strcmpi(OP.PHY,'C2M')

9206

OP.EW=true;

9113

OP.EW=true;

9207

else

9114

else

9208

param.T_O=0; % make sure when c2c that sample is at Ts

9115

param.T_O=0; % make sure when c2c that sample is at Ts

9209

end

9116

end

9210

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9117

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9211

OP.PHY='C2Mcom';

9118

OP.PHY='C2Mcom';

9212

end

9119

end

9213

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9120

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9214

switch lower(OP.TDECQ)

9121

switch lower(OP.TDECQ)

9215

case {false 'none' 'vma'}

9122

case {false 'none' 'vma'}

9216

otherwise

9123

otherwise

9217

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9124

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9218

end

9125

end

9219

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9126

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9220

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9127

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9221

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9128

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9222

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9129

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9223

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

9130

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

9224

% Parameters for error burst probability calculation. Not officially used

9131

% Parameters for error burst probability calculation. Not officially used

9225

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9132

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9226

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9133

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9227

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9134

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9228

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.

9135

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.

9229

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.

9136

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.

9230

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9137

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9231

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.

9138

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.

9232

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9139

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9233

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9140

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9234

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9141

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9235

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9142

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9236

OP.MLSD = xls_parameter(parameter, 'MLSD', false, 0); % not 0 or missing means use MLSD

9143

OP.MLSD = xls_parameter(parameter, 'MLSD', false, 0); % not 0 or missing means use MLSD

9237

OP.MLSE = xls_parameter(parameter, 'MLSE', false, OP.MLSD ); % MSLD Synonym support

9144

OP.MLSE = xls_parameter(parameter, 'MLSE', false, OP.MLSD ); % MSLD Synonym support

9238

if OP.MLSE ~=0

9145

if OP.MLSE ~=0

9239

if param.T_O ~= 0

9146

if param.T_O ~= 0

9240

error('MLSD nnot presently no supported for VEC')

9147

error('MLSD nnot presently no supported for VEC')

9241

end

9148

end

9242

if OP.COM_CONTRIBUTION_CURVES ~=0

9149

if OP.COM_CONTRIBUTION_CURVES ~=0

9243

warning('COM_CONTRIBUTION_CURVES not functional yet with MLSE')

9150

warning("COM_CONTRIBUTION_CURVES not functional yet with MLSE")

9244

OP.COM_CONTRIBUTION_CURVES=0;

9151

OP.COM_CONTRIBUTION_CURVES=0;

9245

end

9152

end

9246

end

9153

end

9247

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9154

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9248

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9155

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9249

if OP.MLSE && param.ndfe==0

9156

if OP.MLSE && param.ndfe==0

9250

error('At least DFE 1 must be set to use MLSE');

9157

error('At least DFE 1 must be set to use MLSE');

9251

end

9158

end

9252

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9159

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9253

% MNSE parameters

9160

% MNSE parameters

9254

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9161

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9255

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9162

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9256

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9163

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9257

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9164

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9258

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9165

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9259

% Commit request 4p4_7, healey_3dj_COM_01_240416

9166

% Commit request 4p4_7, healey_3dj_COM_01_240416

9260

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

9167

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

9261

% need to make sure TD mode does not invoke FD operations

9168

% need to make sure TD mode does not invoke FD operations

9262

if OP.TDMODE % need to set GET_FD false of TDMODE

9169

if OP.TDMODE % need to set GET_FD false of TDMODE

9263

OP.GET_FD=false;

9170

OP.GET_FD=false;

9264

OP.ERL_ONLY=0;

9171

OP.ERL_ONLY=0;

9265

OP.ERL=0;

9172

OP.ERL=0;

9266

OP.PTDR=0;

9173

OP.PTDR=0;

9267

OP.TDR=0;

9174

OP.TDR=0;

9268

OP.RX_CALIBRATION=0;

9175

OP.RX_CALIBRATION=0;

9269

end

9176

end

9270

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9177

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9271

save(matcongfile ,'parameter');

9178

save(matcongfile ,'parameter');

9272

end

9179

end

9273

9180

9274

9181

9275

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9182

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9276

if ~isempty(param.PKG_NAME)

9183

if ~isempty(param.PKG_NAME)

9277

if length(param.PKG_NAME) == 1

9184

if length(param.PKG_NAME) == 1

9278

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9185

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9279

end

9186

end

9280

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9187

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9281

tx_rx_fields_matrix = {'pkg_Z_c'};

9188

tx_rx_fields_matrix = {'pkg_Z_c'};

9282

tx_fields = {'z_p_tx_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9189

tx_fields = {'z_p_tx_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9283

rx_fields = {'z_p_rx_cases' 'a_next' 'z_p_next_cases'};

9190

rx_fields = {'z_p_rx_cases' 'a_next' 'z_p_next_cases'};

9284

tx_pkg_name=param.PKG_NAME{1};

9191

tx_pkg_name=param.PKG_NAME{1};

9285

rx_pkg_name=param.PKG_NAME{2};

9192

rx_pkg_name=param.PKG_NAME{2};

9286

tx_pkg_struct=param.PKG.(tx_pkg_name);

9193

tx_pkg_struct=param.PKG.(tx_pkg_name);

9287

rx_pkg_struct=param.PKG.(rx_pkg_name);

9194

rx_pkg_struct=param.PKG.(rx_pkg_name);

9288

9195

9289

%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

9196

%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

9290

for j=1:length(tx_rx_fields)

9197

for j=1:length(tx_rx_fields)

9291

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9198

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9292

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9199

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9293

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9200

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9294

end

9201

end

9295

9202

9296

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9203

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9297

for j=1:length(tx_rx_fields_matrix)

9204

for j=1:length(tx_rx_fields_matrix)

9298

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9205

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9299

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9206

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9300

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9207

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9301

end

9208

end

9302

9209

9303

%tx_fields: use only the tx package values

9210

%tx_fields: use only the tx package values

9304

for j=1:length(tx_fields)

9211

for j=1:length(tx_fields)

9305

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9212

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9306

end

9213

end

9307

9214

9308

%rx_fields: use only the rx package values

9215

%rx_fields: use only the rx package values

9309

for j=1:length(rx_fields)

9216

for j=1:length(rx_fields)

9310

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9217

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9311

end

9218

end

9312

9219

9313

end

9220

end

9314

9221

9315

9222

9316

%%

9223

%%

9317

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9224

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9318

%% FUNCTION :: read_sp4_sparams

9225

%% FUNCTION :: read_sp4_sparams

9319

%

9226

%

9320

% Description

9227

% Description

9321

% Read the fid of single-ended 4-port complex S-parameters

9228

% Read the fid of single-ended 4-port complex S-parameters

9322

% in Touchstone format 'file' and convert to the internal

9229

% in Touchstone format 'file' and convert to the internal

9323

% format using the port transform 'ports'

9230

% format using the port transform 'ports'

9324

%

9231

%

9325

% Created by Mike Y. He

9232

% Created by Mike Y. He

9326

% April 22, 2005

9233

% April 22, 2005

9327

%

9234

%

9328

% Reused some code from

9235

% Reused some code from

9329

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9236

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9330

% for touchstone 4-port S-matrix import.

9237

% for touchstone 4-port S-matrix import.

9331

%

9238

%

9332

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9239

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9333

% optimized for quicker parameter matching and parsing. also, separated out

9240

% optimized for quicker parameter matching and parsing. also, separated out

9334

% the plotting algorithms into their own sub-function routines

9241

% the plotting algorithms into their own sub-function routines

9335

%

9242

%

9336

% Modified December 2021 to use read_Nport_touchstone

9243

% Modified December 2021 to use read_Nport_touchstone

9337

% This is faster reader that is capable of reading touchstone with any number of ports

9244

% This is faster reader that is capable of reading touchstone with any number of ports

9338

%

9245

%

9339

% Input Variables (required)

9246

% Input Variables (required)

9340

% infile -- The s4p file to be read and converted

9247

% infile -- The s4p file to be read and converted

9341

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9248

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9342

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9249

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9343

% ports -- Re-order the port layout

9250

% ports -- Re-order the port layout

9344

%

9251

%

9345

% Output/Return Variables

9252

% Output/Return Variables

9346

% data -- structure containing network parameter data points and frequency axis

9253

% data -- structure containing network parameter data points and frequency axis

9347

% sdc -- the differential in/common-mode out s-parameter data matrix

9254

% sdc -- the differential in/common-mode out s-parameter data matrix

9348

% sdd -- the differential in/differential out s-parameter data matrix

9255

% sdd -- the differential in/differential out s-parameter data matrix

9349

%

9256

%

9350

9257

9351

9258

9352

% backwards compatibility settings. can be removed in updated code.

9259

% backwards compatibility settings. can be removed in updated code.

9353

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9260

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9354

if isempty(ports); ports = [1 2]; end % default order normally used.

9261

if isempty(ports); ports = [1 2]; end % default order normally used.

9355

ports = [1 2];

9262

ports = [1 2];

9356

9263

9357

9264

9358

if OP.DISPLAY_WINDOW

9265

if OP.DISPLAY_WINDOW

9359

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9266

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9360

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9267

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9361

end

9268

end

9362

9269

9363

%AJG: fast touchstone read for any number of ports

9270

%AJG: fast touchstone read for any number of ports

9364

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9271

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9365

9272

9366

9273

9367

9274

9368

D=NaN(size(sch));

9275

D=NaN(size(sch));

9369

% calculate differential s parameter matrix from single ended

9276

% calculate differential s parameter matrix from single ended

9370

for i=1:size(sch,1)

9277

for i=1:size(sch,1)

9371

S(:,:) = sch(i,:,:);

9278

S(:,:) = sch(i,:,:);

9372

T = [1 1 ; 1 -1 ];

9279

T = [1 1 ; 1 -1 ];

9373

W = T * (S / T);

9280

W = T * (S / T);

9374

D(i,:,:) = W(:,:);

9281

D(i,:,:) = W(:,:);

9375

end

9282

end

9376

9283

9377

% D matrix should be

9284

% D matrix should be

9378

% Scc11 Scd11 Scc12 Scd21

9285

% Scc11 Scd11 Scc12 Scd21

9379

% Sdc11 Sdd11 Sdc12 Sdd12

9286

% Sdc11 Sdd11 Sdc12 Sdd12

9380

% Scc21 Scd21 Scc22 Scd22

9287

% Scc21 Scd21 Scc22 Scd22

9381

% Sdc21 Sdd21 Sdc22 Sdd22

9288

% Sdc21 Sdd21 Sdc22 Sdd22

9382

9289

9383

% proper values

9290

% proper values

9384

%AJG: matrix can be properly referenced after fixing mapping

9291

%AJG: matrix can be properly referenced after fixing mapping

9385

SDD(:,1,1) = D(:,2,2);

9292

SDD(:,1,1) = D(:,2,2);

9386

SDC(:,1,1)= D(:,2,1);

9293

SDC(:,1,1)= D(:,2,1);

9387

SCC(:,1,1)= D(:,1,1);

9294

SCC(:,1,1)= D(:,1,1);

9388

SCD(:,1,1)= D(:,1,2);

9295

SCD(:,1,1)= D(:,1,2);

9389

9296

9390

9297

9391

9298

9392

% backwards compatibility output variables

9299

% backwards compatibility output variables

9393

data.m = sch;

9300

data.m = sch;

9394

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9301

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9395

data.freq = schFreqAxis;

9302

data.freq = schFreqAxis;

9396

colors = 'rgbk';

9303

colors = 'rgbk';

9397

9304

9398

if (plot_ini_s_params == 1)

9305

if (plot_ini_s_params == 1)

9399

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9306

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9400

for mj=1:4

9307

for mj=1:4

9401

% subplot(2,2,mj);

9308

% subplot(2,2,mj);

9402

for mi=1:4

9309

for mi=1:4

9403

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9310

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9404

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9311

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9405

hold on

9312

hold on

9406

end

9313

end

9407

xlabel('Frequency (Hz)');

9314

xlabel('Frequency (Hz)');

9408

ylabel('Magnitude (dB)');

9315

ylabel('Magnitude (dB)');

9409

legend show

9316

legend show

9410

grid on

9317

grid on

9411

title(sprintf('Output port %d', mj));

9318

title(sprintf('Output port %d', mj));

9412

end

9319

end

9413

end

9320

end

9414

plot_dif_s_params =0;

9321

plot_dif_s_params =0;

9415

if (plot_dif_s_params == 1)

9322

if (plot_dif_s_params == 1)

9416

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9323

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9417

% subplot(2,1,1);

9324

% subplot(2,1,1);

9418

for mj=1:1

9325

for mj=1:1

9419

for mi=1:1

9326

for mi=1:1

9420

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9327

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9421

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9328

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9422

hold on

9329

hold on

9423

end

9330

end

9424

end

9331

end

9425

xlabel('Frequency (Hz)');

9332

xlabel('Frequency (Hz)');

9426

ylabel('Magnitude (dB)');

9333

ylabel('Magnitude (dB)');

9427

legend show

9334

legend show

9428

grid on

9335

grid on

9429

title(infile);

9336

title(infile);

9430

9337

9431

% subplot(2,1,2);

9338

% subplot(2,1,2);

9432

% for mj=1:2

9339

% for mj=1:2

9433

% for mi=1:2

9340

% for mi=1:2

9434

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9341

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9435

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9342

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9436

% hold on

9343

% hold on

9437

% end

9344

% end

9438

% end

9345

% end

9439

% xlabel('Frequency (Hz)');

9346

% xlabel('Frequency (Hz)');

9440

% ylabel('Magnitude (dB)');

9347

% ylabel('Magnitude (dB)');

9441

% legend show

9348

% legend show

9442

% grid on

9349

% grid on

9443

end

9350

end

9444

9351

9445

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9352

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9446

% end read_sp2_sparam

9353

% end read_sp2_sparam

9447

9354

9448

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9355

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9449

%% FUNCTION :: read_sp4_sparams

9356

%% FUNCTION :: read_sp4_sparams

9450

%

9357

%

9451

% Description

9358

% Description

9452

% Read the fid of single-ended 4-port complex S-parameters

9359

% Read the fid of single-ended 4-port complex S-parameters

9453

% in Touchstone format 'file' and convert to the internal

9360

% in Touchstone format 'file' and convert to the internal

9454

% format using the port transform 'ports'

9361

% format using the port transform 'ports'

9455

%

9362

%

9456

% Created by Mike Y. He

9363

% Created by Mike Y. He

9457

% April 22, 2005

9364

% April 22, 2005

9458

%

9365

%

9459

% Reused some code from

9366

% Reused some code from

9460

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9367

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9461

% for touchstone 4-port S-matrix import.

9368

% for touchstone 4-port S-matrix import.

9462

%

9369

%

9463

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9370

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9464

% optimized for quicker parameter matching and parsing. also, separated out

9371

% optimized for quicker parameter matching and parsing. also, separated out

9465

% the plotting algorithms into their own sub-function routines

9372

% the plotting algorithms into their own sub-function routines

9466

%

9373

%

9467

% Modified December 2021 to use read_Nport_touchstone

9374

% Modified December 2021 to use read_Nport_touchstone

9468

% This is faster reader that is capable of reading touchstone with any number of ports

9375

% This is faster reader that is capable of reading touchstone with any number of ports

9469

%

9376

%

9470

% Input Variables (required)

9377

% Input Variables (required)

9471

% infile -- The s4p file to be read and converted

9378

% infile -- The s4p file to be read and converted

9472

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9379

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9473

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9380

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9474

% ports -- Re-order the port layout

9381

% ports -- Re-order the port layout

9475

% OP

9382

% OP

9476

% param

9383

% param

9477

% Output/Return Variables

9384

% Output/Return Variables

9478

% data -- structure containing network parameter data points and frequency axis

9385

% data -- structure containing network parameter data points and frequency axis

9479

% sdd -- the differential in/differential out s-parameter data matrix

9386

% sdd -- the differential in/differential out s-parameter data matrix

9480

% sdc -- the differential in/common-mode out s-parameter data matrix

9387

% sdc -- the differential in/common-mode out s-parameter data matrix

9481

% scc -- the common mode in/common-mode out s-parameter data matrix

9388

% scc -- the common mode in/common-mode out s-parameter data matrix

9482

%

9389

%

9483

%

9390

%

9484

9391

9485

9392

9486

% backwards compatibility settings. can be removed in updated code.

9393

% backwards compatibility settings. can be removed in updated code.

9487

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9394

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9488

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9395

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9489

9396

9490

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9397

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9491

% pair is reversed.

9398

% pair is reversed.

9492

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9399

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9493

9400

9494

if OP.DISPLAY_WINDOW

9401

if OP.DISPLAY_WINDOW

9495

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9402

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9496

end

9403

end

9497

9404

9498

%AJG: fast touchstone read for any number of ports

9405

%AJG: fast touchstone read for any number of ports

9499

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9406

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9500

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9407

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9501

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9408

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9502

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9409

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9503

Sigfct = ...

9410

Sigfct = ...

9504

@(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]);

9411

@(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]);

9505

D=NaN(size(sch));

9412

D=NaN(size(sch));

9506

% calculate differential s parameter matrix from single ended

9413

% calculate differential s parameter matrix from single ended

9507

% skew added RIM 12/29/2023

9414

% skew added RIM 12/29/2023

9508

for i=1:size(sch,1)

9415

for i=1:size(sch,1)

9509

f=schFreqAxis(i);

9416

f=schFreqAxis(i);

9510

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) );

9417

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) );

9511

S(:,:) = sch(i,:,:);

9418

S(:,:) = sch(i,:,:);

9512

Snew=sigma_matrix.*S;

9419

Snew=sigma_matrix.*S;

9513

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9420

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9514

W = T * (Snew / T);

9421

W = T * (Snew / T);

9515

D(i,:,:) = W(:,:);

9422

D(i,:,:) = W(:,:);

9516

end

9423

end

9517

9424

9518

% D matrix should be

9425

% D matrix should be

9519

% Scc11 Scd11 Scc12 Scd21

9426

% Scc11 Scd11 Scc12 Scd21

9520

% Sdc11 Sdd11 Sdc12 Sdd12

9427

% Sdc11 Sdd11 Sdc12 Sdd12

9521

% Scc21 Scd21 Scc22 Scd22

9428

% Scc21 Scd21 Scc22 Scd22

9522

% Sdc21 Sdd21 Sdc22 Sdd22

9429

% Sdc21 Sdd21 Sdc22 Sdd22

9523

9430

9524

% proper values

9431

% proper values

9525

SDD(:,1,1) = D(:,2,2);

9432

SDD(:,1,1) = D(:,2,2);

9526

SDD(:,2,2) = D(:,4,4);

9433

SDD(:,2,2) = D(:,4,4);

9527

SDD(:,1,2) = D(:,2,4);

9434

SDD(:,1,2) = D(:,2,4);

9528

SDD(:,2,1) = D(:,4,2);

9435

SDD(:,2,1) = D(:,4,2);

9529

9436

9530

SDC(:,1,1) = D(:,2,1);

9437

SDC(:,1,1) = D(:,2,1);

9531

SDC(:,2,2) = D(:,4,3);

9438

SDC(:,2,2) = D(:,4,3);

9532

SDC(:,1,2) = D(:,2,3);

9439

SDC(:,1,2) = D(:,2,3);

9533

SDC(:,2,1) = D(:,4,1);

9440

SDC(:,2,1) = D(:,4,1);

9534

9441

9535

SCC(:,1,1) = D(:,1,1);

9442

SCC(:,1,1) = D(:,1,1);

9536

SCC(:,2,2) = D(:,3,3);

9443

SCC(:,2,2) = D(:,3,3);

9537

SCC(:,1,2) = D(:,1,3);

9444

SCC(:,1,2) = D(:,1,3);

9538

SCC(:,2,1) = D(:,3,1);

9445

SCC(:,2,1) = D(:,3,1);

9539

9446

9540

% backwards compatibility output variables

9447

% backwards compatibility output variables

9541

data.m = sch;

9448

data.m = sch;

9542

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9449

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9543

data.freq = schFreqAxis;

9450

data.freq = schFreqAxis;

9544

colors = 'rgbk';

9451

colors = 'rgbk';

9545

9452

9546

if (plot_ini_s_params == 1)

9453

if (plot_ini_s_params == 1)

9547

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9454

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9548

for mj=1:4

9455

for mj=1:4

9549

subplot(2,2,mj);

9456

subplot(2,2,mj);

9550

for mi=1:4

9457

for mi=1:4

9551

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9458

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9552

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9459

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9553

hold on

9460

hold on

9554

end

9461

end

9555

xlabel('Frequency (Hz)');

9462

xlabel('Frequency (Hz)');

9556

ylabel('Magnitude (dB)');

9463

ylabel('Magnitude (dB)');

9557

legend show

9464

legend show

9558

grid on

9465

grid on

9559

title(sprintf('Output port %d', mj));

9466

title(sprintf('Output port %d', mj));

9560

end

9467

end

9561

end

9468

end

9562

plot_dif_s_params =0;

9469

plot_dif_s_params =0;

9563

if (plot_dif_s_params == 1)

9470

if (plot_dif_s_params == 1)

9564

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9471

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9565

% subplot(2,1,1);

9472

% subplot(2,1,1);

9566

for mj=1:2

9473

for mj=1:2

9567

for mi=1:2

9474

for mi=1:2

9568

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9475

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9569

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9476

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9570

hold on

9477

hold on

9571

end

9478

end

9572

end

9479

end

9573

xlabel('Frequency (Hz)');

9480

xlabel('Frequency (Hz)');

9574

ylabel('Magnitude (dB)');

9481

ylabel('Magnitude (dB)');

9575

legend show

9482

legend show

9576

grid on

9483

grid on

9577

title(infile);

9484

title(infile);

9578

%

9485

%

9579

% subplot(2,1,2);

9486

% subplot(2,1,2);

9580

% for mj=1:2

9487

% for mj=1:2

9581

% for mi=1:2

9488

% for mi=1:2

9582

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9489

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9583

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9490

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9584

% hold on

9491

% hold on

9585

% end

9492

% end

9586

% end

9493

% end

9587

% xlabel('Frequency (Hz)');

9494

% xlabel('Frequency (Hz)');

9588

% ylabel('Magnitude (dB)');

9495

% ylabel('Magnitude (dB)');

9589

% legend show

9496

% legend show

9590

% grid on

9497

% grid on

9591

end

9498

end

9592

9499

9593

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9500

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9594

% end read_sp4_sparam

9501

% end read_sp4_sparam

9595

function param_struct = read_package_parameters(parameter,param_struct)

9502

function param_struct = read_package_parameters(parameter,param_struct)

9596

9503

9597

%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

9504

%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

9598

%This block should eventually replace what is in read_ParamConfigFile

9505

%This block should eventually replace what is in read_ParamConfigFile

9599

%It can be called as: param = read_package_parameters(parameter, param)

9506

%It can be called as: param = read_package_parameters(parameter, param)

9600

9507

9601

if nargin<2

9508

if nargin<2

9602

%param_struct doesn't need to be passed when building a new package structure

9509

%param_struct doesn't need to be passed when building a new package structure

9603

%it is only needed when appending to regular param structure

9510

%it is only needed when appending to regular param structure

9604

param_struct=struct;

9511

param_struct=struct;

9605

end

9512

end

9606

9513

9607

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9514

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9608

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9515

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9609

9516

9610

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9517

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9611

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9518

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9612

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9519

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9613

9520

9614

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

9521

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

9615

[ncases, mele]=size(param_struct.z_p_tx_cases);

9522

[ncases, mele]=size(param_struct.z_p_tx_cases);

9616

if mele ==2

9523

if mele ==2

9617

param_struct.flex=2;

9524

param_struct.flex=2;

9618

elseif mele==4

9525

elseif mele==4

9619

param_struct.flex=4;

9526

param_struct.flex=4;

9620

elseif mele==1

9527

elseif mele==1

9621

param_struct.flex=1;

9528

param_struct.flex=1;

9622

else

9529

else

9623

error('config file syntax error')

9530

error('config file syntax error')

9624

end

9531

end

9625

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

9532

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

9626

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9533

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9627

if ncases ~= ncases1 || mele ~= mele1

9534

if ncases ~= ncases1 || mele ~= mele1

9628

error('All TX, NEXT, FEXT, Rx cases must agree');

9535

error('All TX, NEXT, FEXT, Rx cases must agree');

9629

else

9536

else

9630

end

9537

end

9631

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

9538

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

9632

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9539

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9633

if ncases ~= ncases1 || mele ~= mele1

9540

if ncases ~= ncases1 || mele ~= mele1

9634

error('All TX, NEXT, FEXT, Rx cases must agree');

9541

error('All TX, NEXT, FEXT, Rx cases must agree');

9635

else

9542

else

9636

end

9543

end

9637

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

9544

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

9638

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9545

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9639

if ncases ~= ncases1 || mele ~= mele1

9546

if ncases ~= ncases1 || mele ~= mele1

9640

error('All TX, NEXT, FEXT, Rx cases must agree');

9547

error('All TX, NEXT, FEXT, Rx cases must agree');

9641

else

9548

else

9642

end

9549

end

9643

% Table 93A-3 parameters

9550

% Table 93A-3 parameters

9644

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.

9551

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.

9645

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9552

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9646

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9553

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9647

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9554

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9648

if mele ~= mele1

9555

if mele ~= mele1

9649

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9556

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9650

else

9557

else

9651

end

9558

end

9652

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9559

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9653

for ii=1:ncases

9560

for ii=1:ncases

9654

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9561

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9655

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9562

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9656

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9563

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9657

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9564

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9658

end

9565

end

9659

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9566

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9660

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9567

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9661

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9568

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9662

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9569

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9663

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9570

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9664

end

9571

end

9665

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9572

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9666

%% extract s-parameter and convert to differential mode

9573

%% extract s-parameter and convert to differential mode

9667

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9574

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9668

num_files=length(chdata);

9575

num_files=length(chdata);

9669

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9576

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9670

for i=1:num_files

9577

for i=1:num_files

9671

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9578

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9672

progress = i/num_files;

9579

progress = i/num_files;

9673

if OP.DISPLAY_WINDOW

9580

if OP.DISPLAY_WINDOW

9674

[~,a]=fileparts(chdata(i).filename);

9581

[~,a]=fileparts(chdata(i).filename);

9675

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9582

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9676

else

9583

else

9677

fprintf('%i ',i);

9584

fprintf('%i ',i);

9678

end

9585

end

9679

9586

9680

% Skip reading file if it was already read (multiple test cases)

9587

% Skip reading file if it was already read (multiple test cases)

9681

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9588

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9682

switch lower(chdata(i).ext)

9589

switch lower(chdata(i).ext)

9683

case '.s2p' % for differential return loss

9590

case '.s2p' % for differential return loss

9684

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9591

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9685

chdata(i).fmaxi = length(Sch.freq);

9592

chdata(i).fmaxi = length(Sch.freq);

9686

chdata(i).faxis = Sch.freq;

9593

chdata(i).faxis = Sch.freq;

9687

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9594

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9688

SDDp2p(i)=NaN;

9595

SDDp2p(i)=NaN;

9689

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9596

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9690

chdata(i).sdd11=chdata(i).sdd11_raw;

9597

chdata(i).sdd11=chdata(i).sdd11_raw;

9691

case '.s4p'

9598

case '.s4p'

9692

if length(param.snpPortsOrder) ~= 4

9599

if length(param.snpPortsOrder) ~= 4

9693

error( 'warning:sNpFilePortMismatch', ...

9600

error( 'warning:sNpFilePortMismatch', ...

9694

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9601

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9695

length(param.snpPortsOrder), ...

9602

length(param.snpPortsOrder), ...

9696

chdata(i).ext ...

9603

chdata(i).ext ...

9697

);

9604

);

9698

end

9605

end

9699

% read function returns differnetial mode parameters

9606

% read function returns differnetial mode parameters

9700

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9607

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9701

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9608

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9702

% param.holdsdata(i).Sch= Sch;

9609

% param.holdsdata(i).Sch= Sch;

9703

% param.holdsdata(i).SDDch= SDDch;

9610

% param.holdsdata(i).SDDch= SDDch;

9704

% param.holdsdata(i).SDCch= SDCch;

9611

% param.holdsdata(i).SDCch= SDCch;

9705

else

9612

else

9706

error('If this line is reached, there is a logic error');

9613

error('If this line is reached, there is a logic error');

9707

% Sch=param.holdsdata(i).Sch;

9614

% Sch=param.holdsdata(i).Sch;

9708

% SDDch=param.holdsdata(i).SDDch;

9615

% SDDch=param.holdsdata(i).SDDch;

9709

% SDCch=param.holdsdata(i).SDCch;

9616

% SDCch=param.holdsdata(i).SDCch;

9710

end

9617

end

9711

chdata(i).fmaxi = length(Sch.freq);

9618

chdata(i).fmaxi = length(Sch.freq);

9712

9619

9713

9620

9714

if Sch.freq(chdata(i).fmaxi) < param.fb

9621

if Sch.freq(chdata(i).fmaxi) < param.fb

9715

warning('COM:read_s4p:MaxFreqTooLow', ...

9622

warning('COM:read_s4p:MaxFreqTooLow', ...

9716

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9623

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9717

chdata(i).filename, Sch.freq(end), param.fb);

9624

chdata(i).filename, Sch.freq(end), param.fb);

9718

end

9625

end

9719

if Sch.freq(1) > param.max_start_freq

9626

if Sch.freq(1) > param.max_start_freq

9720

warning('COM:read_s4p:StartFreqTooHigh', ...

9627

warning('COM:read_s4p:StartFreqTooHigh', ...

9721

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9628

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9722

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9629

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9723

end

9630

end

9724

freqstep=diff(Sch.freq);

9631

freqstep=diff(Sch.freq);

9725

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9632

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9726

if max(freqstep)-min(freqstep) > 1

9633

if max(freqstep)-min(freqstep) > 1

9727

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9634

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9728

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9635

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9729

end

9636

end

9730

if max(freqstep) - param.max_freq_step > 1

9637

if max(freqstep) - param.max_freq_step > 1

9731

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9638

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9732

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9639

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9733

end

9640

end

9734

9641

9735

chdata(i).faxis = Sch.freq;

9642

chdata(i).faxis = Sch.freq;

9736

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9643

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9737

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9644

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9738

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9645

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9739

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9646

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9740

% mode conversion

9647

% mode conversion

9741

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9648

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9742

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9649

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9743

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9650

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9744

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9651

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9745

%save original and add board (if required)

9652

%save original and add board (if required)

9746

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9653

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9747

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

9654

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

9748

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

9655

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

9749

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

9656

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

9750

if OP.include_pcb

9657

if OP.include_pcb

9751

% add boards to sdd

9658

% add boards to sdd

9752

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

9659

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

9753

9660

9754

end

9661

end

9755

%save final return loss (after the boards were included)

9662

%save final return loss (after the boards were included)

9756

chdata(i).sdd11=chdata(i).sdd11_raw;

9663

chdata(i).sdd11=chdata(i).sdd11_raw;

9757

chdata(i).sdd22=chdata(i).sdd22_raw;

9664

chdata(i).sdd22=chdata(i).sdd22_raw;

9758

otherwise

9665

otherwise

9759

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

9666

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

9760

end

9667

end

9761

9668

9762

%Crosstalk frequency axis must be the same as Thru

9669

%Crosstalk frequency axis must be the same as Thru

9763

if i>1

9670

if i>1

9764

%error on length difference

9671

%error on length difference

9765

if length(chdata(i).faxis)~=length(chdata(1).faxis)

9672

if length(chdata(i).faxis)~=length(chdata(1).faxis)

9766

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

9673

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

9767

end

9674

end

9768

%error if any value > 1Hz (don't want to check for exact

9675

%error if any value > 1Hz (don't want to check for exact

9769

%equality in case of floating point error)

9676

%equality in case of floating point error)

9770

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

9677

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

9771

if max(Fdiff)>1

9678

if max(Fdiff)>1

9772

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

9679

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

9773

end

9680

end

9774

end

9681

end

9775

else

9682

else

9776

SDDch(:,1,2)=chdata(i).sdd12_raw;

9683

SDDch(:,1,2)=chdata(i).sdd12_raw;

9777

SDDch(:,2,1)=chdata(i).sdd21_raw;

9684

SDDch(:,2,1)=chdata(i).sdd21_raw;

9778

SDDch(:,1,1)=chdata(i).sdd11_raw;

9685

SDDch(:,1,1)=chdata(i).sdd11_raw;

9779

SDDch(:,2,2)=chdata(i).sdd22_raw;

9686

SDDch(:,2,2)=chdata(i).sdd22_raw;

9780

end

9687

end

9781

chdata(i).sigma_ACCM_at_tp0=0;

9688

chdata(i).sigma_ACCM_at_tp0=0;

9782

if ~param.FLAG.S2P

9689

if ~param.FLAG.S2P

9783

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

9690

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

9784

if (OP.RX_CALIBRATION == 1 && i==2)

9691

if (OP.RX_CALIBRATION == 1 && i==2)

9785

chdata(i).sdd21=chdata(i).sdd21_raw;

9692

chdata(i).sdd21=chdata(i).sdd21_raw;

9786

else

9693

else

9787

%updated package construction with single function for both DD and DC

9694

%updated package construction with single function for both DD and DC

9788

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

9695

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

9789

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

9696

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

9790

chdata(i).sdd21=chdata(i).sdd21p;

9697

chdata(i).sdd21=chdata(i).sdd21p;

9791

if 1 % for AC CM noise inclusion

9698

if 1 % for AC CM noise inclusion

9792

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

9699

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

9793

chdata(i).sdc21=chdata(i).sdc21p;

9700

chdata(i).sdc21=chdata(i).sdc21p;

9794

end

9701

end

9795

end

9702

end

9796

else

9703

else

9797

chdata(i).sdd21=chdata(i).sdd21_raw;

9704

chdata(i).sdd21=chdata(i).sdd21_raw;

9798

end

9705

end

9799

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

9706

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

9800

end

9707

end

9801

end

9708

end

9802

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

9709

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

9803

9710

9804

function result = readdataSnPx(filename, nport)

9711

function result = readdataSnPx(filename, nport)

9805

%function [freq, cs] = readdataSnPx(filename, nport)

9712

%function [freq, cs] = readdataSnPx(filename, nport)

9806

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

9713

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

9807

%

9714

%

9808

% Read Touchstone file with frequencies in units of Hertz

9715

% Read Touchstone file with frequencies in units of Hertz

9809

%

9716

%

9810

% Input:

9717

% Input:

9811

% ======

9718

% ======

9812

% filename: Name of the Touchstone/SnP file

9719

% filename: Name of the Touchstone/SnP file

9813

% nport: Number of ports

9720

% nport: Number of ports

9814

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

9721

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

9815

% Touchstone file)

9722

% Touchstone file)

9816

% nheader: Number of header lines (comment lines plus option line in the

9723

% nheader: Number of header lines (comment lines plus option line in the

9817

% Touchstone file)

9724

% Touchstone file)

9818

%

9725

%

9819

% Output:

9726

% Output:

9820

% =======

9727

% =======

9821

% freq: Vector of frequencies [Hz]

9728

% freq: Vector of frequencies [Hz]

9822

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

9729

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

9823

% at frequency freq(k)

9730

% at frequency freq(k)

9824

%

9731

%

9825

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

9732

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

9826

% frequencies appropriately after reading the data.

9733

% frequencies appropriately after reading the data.

9827

%

9734

%

9828

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

9735

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

9829

% EIA/IBIS Open Forum, 2002.

9736

% EIA/IBIS Open Forum, 2002.

9830

%

9737

%

9831

% Written by Henning Braunisch, September 2004.

9738

% Written by Henning Braunisch, September 2004.

9832

% Updated by Steven Krooswyk, April 2006.

9739

% Updated by Steven Krooswyk, April 2006.

9833

9740

9834

9741

9835

fid = fopen(filename, 'r');

9742

fid = fopen(filename, 'r');

9836

9743

9837

9744

9838

% Skip header lines

9745

% Skip header lines

9839

str = ' ';

9746

str = ' ';

9840

n = 0;

9747

n = 0;

9841

while ~strcmp(str(1),'#')

9748

while ~strcmp(str(1),'#')

9842

str = fgetl(fid);

9749

str = fgetl(fid);

9843

if isempty(str)

9750

if isempty(str)

9844

str=' ' ;

9751

str=' ' ;

9845

if n > 1000

9752

if n > 1000

9846

display('error: could not find config line (#)')

9753

display('error: could not find config line (#)')

9847

break

9754

break

9848

end

9755

end

9849

end

9756

end

9850

n = n + 1;

9757

n = n + 1;

9851

end

9758

end

9852

9759

9853

% parse configuration line

9760

% parse configuration line

9854

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

9761

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

9855

p = find(A=='S'); %position of 'S'

9762

p = find(A=='S'); %position of 'S'

9856

units = lower(A(2:p-1)); %units before 'S'

9763

units = lower(A(2:p-1)); %units before 'S'

9857

format = A(p+1:p+2); %format after 'S'

9764

format = A(p+1:p+2); %format after 'S'

9858

9765

9859

% skip any more header lines

9766

% skip any more header lines

9860

%while ~str

9767

%while ~str

9861

9768

9862

nk = 0; % frequency counter

9769

nk = 0; % frequency counter

9863

while 1

9770

while 1

9864

9771

9865

[temp, count] = fscanf(fid, '%f', 1);

9772

[temp, count] = fscanf(fid, '%f', 1);

9866

if count == 0

9773

if count == 0

9867

temp2 = fscanf(fid, '%s', 1);

9774

temp2 = fscanf(fid, '%s', 1);

9868

if ~isempty(temp2), fgetl(fid); continue, end;

9775

if ~isempty(temp2), fgetl(fid); continue, end;

9869

break

9776

break

9870

end

9777

end

9871

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

9778

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

9872

for ni = 1:nport

9779

for ni = 1:nport

9873

for nj = 1:nport

9780

for nj = 1:nport

9874

switch lower(format)

9781

switch lower(format)

9875

case 'ma'

9782

case 'ma'

9876

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9783

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9877

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

9784

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

9878

case 'ri'

9785

case 'ri'

9879

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

9786

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

9880

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9787

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9881

case 'db'

9788

case 'db'

9882

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9789

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9883

M = 10^(db/20);

9790

M = 10^(db/20);

9884

%re = M*cos(ang);

9791

%re = M*cos(ang);

9885

%im = M*sin(ang);

9792

%im = M*sin(ang);

9886

re = M*cos(ang * pi / 180);

9793

re = M*cos(ang * pi / 180);

9887

im = M*sin(ang * pi / 180);

9794

im = M*sin(ang * pi / 180);

9888

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9795

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9889

otherwise

9796

otherwise

9890

error('readdataSnP: Unknown data format');

9797

error('readdataSnP: Unknown data format');

9891

end

9798

end

9892

end

9799

end

9893

end

9800

end

9894

end

9801

end

9895

9802

9896

fclose(fid);

9803

fclose(fid);

9897

9804

9898

% If 2-port then swap S_12 and S_21 per Touchstone spec

9805

% If 2-port then swap S_12 and S_21 per Touchstone spec

9899

if nport == 2

9806

if nport == 2

9900

temp = cs(2,1,:);

9807

temp = cs(2,1,:);

9901

cs(2,1,:) = cs(1,2,:);

9808

cs(2,1,:) = cs(1,2,:);

9902

cs(1,2,:) = temp;

9809

cs(1,2,:) = temp;

9903

end

9810

end

9904

9811

9905

% Update freq units to Hz

9812

% Update freq units to Hz

9906

switch lower(units)

9813

switch lower(units)

9907

case 'hz'

9814

case 'hz'

9908

9815

9909

case 'khz'

9816

case 'khz'

9910

freq=freq.*1e3;

9817

freq=freq.*1e3;

9911

case 'mhz'

9818

case 'mhz'

9912

freq=freq.*1e6;

9819

freq=freq.*1e6;

9913

case 'ghz'

9820

case 'ghz'

9914

freq=freq.*1e9;

9821

freq=freq.*1e9;

9915

end

9822

end

9916

9823

9917

% passivity check

9824

% passivity check

9918

result.freq = freq;

9825

result.freq = freq;

9919

result.cs = cs;

9826

result.cs = cs;

9920

9827

9921

function recolor_plots(ax)

9828

function recolor_plots(ax)

9922

9829

9923

if ~verLessThan('matlab', '8.4.0')

9830

if ~verLessThan('matlab', '8.4.0')

9924

return

9831

return

9925

end

9832

end

9926

colors='brgcmk';

9833

colors='brgcmk';

9927

ch=flipud(get(ax, 'children'));

9834

ch=flipud(get(ax, 'children'));

9928

9835

9929

for k=1:length(ch)

9836

for k=1:length(ch)

9930

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

9837

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

9931

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

9838

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

9932

end

9839

end

9933

legend (ax, 'off');

9840

legend (ax, 'off');

9934

warning('off', 'MATLAB:legend:PlotEmpty');

9841

warning('off', 'MATLAB:legend:PlotEmpty');

9935

set(legend (ax, 'show'), 'interp', 'none');

9842

set(legend (ax, 'show'), 'interp', 'none');

9936

9843

+9844

function result = reduce(var1)

9845

% --- Reduce 1x1xn array to 1xn (aka squeeze)

9846

out = zeros(1,length(var1));

9847

out(1,:) = var1(1,1,:);

9848

result=out;

9849

9937

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

9850

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

9938

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

9851

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

9939

% faxis is the frequency array

9852

% faxis is the frequency array

9940

% s21, s11, s22 are the corresponding array of differential parameters

9853

% s21, s11, s22 are the corresponding array of differential parameters

9941

% s21p includes the VFT and Tx filter if include_die=1

9854

% s21p includes the VFT and Tx filter if include_die=1

9942

if nargin<6

9855

if nargin<6

9943

include_die=1;

9856

include_die=1;

9944

end

9857

end

9945

if nargin<5

9858

if nargin<5

9946

mode='dd';

9859

mode='dd';

9947

end

9860

end

9948

9861

9949

s21=chdata.(['s' mode '21_raw']);

9862

s21=chdata.(['s' mode '21_raw']);

9950

s12=chdata.(['s' mode '12_raw']);

9863

s12=chdata.(['s' mode '12_raw']);

9951

s11=chdata.(['s' mode '11_raw']);

9864

s11=chdata.(['s' mode '11_raw']);

9952

s22=chdata.(['s' mode '22_raw']);

9865

s22=chdata.(['s' mode '22_raw']);

9953

faxis=chdata.faxis;

9866

faxis=chdata.faxis;

9954

channel_type=chdata.type;

9867

channel_type=chdata.type;

9955

9868

9956

if strcmpi(mode,'dd')

9869

if strcmpi(mode,'dd')

9957

s11=s11*param.kappa1;

9870

s11=s11*param.kappa1;

9958

s22=s22*param.kappa2;

9871

s22=s22*param.kappa2;

9959

end

9872

end

9960

9873

9961

9874

9962

Z0=param.Z0;

9875

Z0=param.Z0;

9963

%sigma_ACCM_at_tp0 is only used when mode=DC

9876

%sigma_ACCM_at_tp0 is only used when mode=DC

9964

sigma_ACCM_at_tp0=0;

9877

sigma_ACCM_at_tp0=0;

9965

9878

9966

% The following three parameters have possibly different valuesF for TX and

9879

% The following three parameters have possibly different valuesF for TX and

9967

% RX (so can be 2-element vectors).

9880

% RX (so can be 2-element vectors).

9968

R_diepad = param.R_diepad;

9881

R_diepad = param.R_diepad;

9969

9882

9970

%Make TX Package

9883

%Make TX Package

9971

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

9884

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

9972

9885

9973

%Make RX Package

9886

%Make RX Package

9974

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

9887

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

9975

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

9888

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

9976

9889

9977

9890

9978

% p(1 ,1, :)=s11in;

9891

% p(1 ,1, :)=s11in;

9979

% p(2 ,2, :)=s22in;

9892

% p(2 ,2, :)=s22in;

9980

% p(1 ,2, :)=s12in;

9893

% p(1 ,2, :)=s12in;

9981

% p(2 ,1, :)=s21in;

9894

% p(2 ,1, :)=s21in;

9982

%

9895

%

9983

% S=sparameters(p,faxis);

9896

% S=sparameters(p,faxis);

9984

% rfwrite(S,'temp.s4p');

9897

% rfwrite(S,'temp.s4p');

9985

9898

9986

if strcmpi(mode,'dc')

9899

if strcmpi(mode,'dc')

9987

RTX=R_diepad(param.Tx_rd_sel)/2;

9900

RTX=R_diepad(param.Tx_rd_sel)/2;

9988

RRX=R_diepad(param.Rx_rd_sel)/2;

9901

RRX=R_diepad(param.Rx_rd_sel)/2;

9989

Z0gamma=Z0/2;

9902

Z0gamma=Z0/2;

9990

else

9903

else

9991

RTX=R_diepad(param.Tx_rd_sel);

9904

RTX=R_diepad(param.Tx_rd_sel);

9992

RRX=R_diepad(param.Rx_rd_sel);

9905

RRX=R_diepad(param.Rx_rd_sel);

9993

Z0gamma=Z0;

9906

Z0gamma=Z0;

9994

end

9907

end

9995

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

9908

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

9996

gamma_tx=0;

9909

gamma_tx=0;

9997

else

9910

else

9998

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

9911

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

9999

end

9912

end

10000

if OP.IDEAL_RX_TERM

9913

if OP.IDEAL_RX_TERM

10001

gamma_rx=0;

9914

gamma_rx=0;

10002

else

9915

else

10003

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

9916

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

10004

end

9917

end

10005

9918

10006

if OP.INC_PACKAGE==0

9919

if OP.INC_PACKAGE==0

10007

s21p= s21;

9920

s21p= s21;

10008

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

9921

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

10009

else

9922

else

10010

if OP.RX_CALIBRATION == 1 && channel_number == 2

9923

if OP.RX_CALIBRATION == 1 && channel_number == 2

10011

% for calibration do not include the transmitter package

9924

% for calibration do not include the transmitter package

10012

[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

9925

[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

10013

SCH.Frequencies=faxis;

9926

SCH.Frequencies=faxis;

10014

SCH.Parameters(1,1,:)=s11out_rx;

9927

SCH.Parameters(1,1,:)=s11out_rx;

10015

SCH.Parameters(2,2,:)=s22out_rx;

9928

SCH.Parameters(2,2,:)=s22out_rx;

10016

SCH.Parameters(1,2,:)=s12out_rx;

9929

SCH.Parameters(1,2,:)=s12out_rx;

10017

SCH.Parameters(2,1,:)=s21out_rx;

9930

SCH.Parameters(2,1,:)=s21out_rx;

10018

SCH.NumPorts=2;

9931

SCH.NumPorts=2;

10019

SCH.Impedance=100;

9932

SCH.Impedance=100;

10020

%% Equation 93A-18

9933

%% Equation 93A-18

10021

if include_die

9934

if include_die

10022

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);

9935

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);

10023

else

9936

else

10024

s21p=s21out_rx; % if no die we do not want a VTF

9937

s21p=s21out_rx; % if no die we do not want a VTF

10025

end

9938

end

10026

else

9939

else

10027

%% Equations 93A-4 to 93A-7

9940

%% Equations 93A-4 to 93A-7

10028

if ~OP.IDEAL_TX_TERM

9941

if ~OP.IDEAL_TX_TERM

10029

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

9942

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10030

end

9943

end

10031

H_t=ones(1,length(faxis)); % .3bj compatibility

9944

H_t=ones(1,length(faxis)); % .3bj compatibility

10032

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

9945

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10033

% for RITT testing with good termination as in some instruments

9946

% for RITT testing with good termination as in some instruments

10034

% and tx filter when required

9947

% and tx filter when required

10035

if OP.T_r_filter_type==0

9948

if OP.T_r_filter_type==0

10036

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

9949

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10037

else

9950

else

10038

tr=OP.transmitter_transition_time;

9951

tr=OP.transmitter_transition_time;

10039

f9=faxis/1e9;

9952

f9=faxis/1e9;

10040

if OP.T_r_meas_point == 1

9953

if OP.T_r_meas_point == 1

10041

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

9954

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10042

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);

9955

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);

10043

else

9956

else

10044

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

9957

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10045

end

9958

end

10046

9959

10047

end

9960

end

10048

end

9961

end

10049

if strcmpi(mode,'dc')

9962

if strcmpi(mode,'dc')

10050

% 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?

9963

% 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?

10051

end

9964

end

10052

if ~OP.IDEAL_RX_TERM

9965

if ~OP.IDEAL_RX_TERM

10053

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

9966

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10054

else

9967

else

10055

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

9968

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10056

end

9969

end

10057

%% 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 )

9970

%% 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 )

10058

if include_die

9971

if include_die

10059

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);

9972

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);

10060

else

9973

else

10061

s21p=s21; % if no die we do not want a VTF

9974

s21p=s21; % if no die we do not want a VTF

10062

end

9975

end

10063

end

9976

end

10064

9977

10065

if strcmpi(mode,'dc')

9978

if strcmpi(mode,'dc')

10066

% compute AC_CM_RMS at tp0

9979

% compute AC_CM_RMS at tp0

10067

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

9980

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10068

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

9981

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10069

if channel_number == 1

9982

if channel_number == 1

10070

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

9983

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10071

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

9984

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10072

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)) ;

9985

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)) ;

10073

% S=sparameters(p,faxis);

9986

% S=sparameters(p,faxis);

10074

% rfwrite(S,'temp.s4p');

9987

% rfwrite(S,'temp.s4p');

10075

end

9988

end

10076

end

9989

end

10077

9990

10078

SCH.Frequencies=faxis;

9991

SCH.Frequencies=faxis;

10079

SCH.Parameters(1,1,:)=s11;

9992

SCH.Parameters(1,1,:)=s11;

10080

SCH.Parameters(2,2,:)=s22;

9993

SCH.Parameters(2,2,:)=s22;

10081

SCH.Parameters(1,2,:)=s12;

9994

SCH.Parameters(1,2,:)=s12;

10082

SCH.Parameters(2,1,:)=s21;

9995

SCH.Parameters(2,1,:)=s21;

10083

SCH.NumPorts=2;

9996

SCH.NumPorts=2;

10084

if strcmpi(mode,'dc')

9997

if strcmpi(mode,'dc')

10085

SCH.Impedance=25;

9998

SCH.Impedance=25;

10086

else

9999

else

10087

SCH.Impedance=100;

10000

SCH.Impedance=100;

10088

end

10001

end

10089

10002

10090

end

10003

end

10091

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10004

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10092

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10005

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10093

% Creates a time-domain impulse response from frequency-domain IL data.

10006

% Creates a time-domain impulse response from frequency-domain IL data.

10094

% IL does not need to have DC but a corresponding frequency array

10007

% IL does not need to have DC but a corresponding frequency array

10095

% (freq_array) is required.

10008

% (freq_array) is required.

10096

%

10009

%

10097

% Causality is imposed using the Alternating Projections Method. See also:

10010

% Causality is imposed using the Alternating Projections Method. See also:

10098

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10011

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10099

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10012

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10100

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10013

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10101

10014

10102

ILin=IL;

10015

ILin=IL;

10103

fmax=1/time_step/2;

10016

fmax=1/time_step/2;

10104

freq_step=(freq_array(3)-freq_array(2))/1;

10017

freq_step=(freq_array(3)-freq_array(2))/1;

10105

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10018

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10106

if all(IL==0)

10019

if all(IL==0)

10107

%response with all zeros is problematic. set to all eps and avoid interp function

10020

%response with all zeros is problematic. set to all eps and avoid interp function

10108

IL=ones(1,length(fout))*eps;

10021

IL=ones(1,length(fout))*eps;

10109

else

10022

else

10110

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10023

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10111

IL_nan = find(isnan(IL));

10024

IL_nan = find(isnan(IL));

10112

for in=IL_nan

10025

for in=IL_nan

10113

IL(in)=IL(in-1);

10026

IL(in)=IL(in-1);

10114

end

10027

end

10115

end

10028

end

10116

IL = IL(:);

10029

IL = IL(:);

10117

% add padding for time steps

10030

% add padding for time steps

10118

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10031

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10119

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10032

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10120

impulse_response = real(ifft(IL_symmetric));

10033

impulse_response = real(ifft(IL_symmetric));

10121

L = length(impulse_response);

10034

L = length(impulse_response);

10122

t_base = (0:L-1)/(freq_step*L);

10035

t_base = (0:L-1)/(freq_step*L);

10123

10036

10124

original_impulse_response=impulse_response;

10037

original_impulse_response=impulse_response;

10125

% Correct non-causal effects frequently caused by extrapolation of IL

10038

% Correct non-causal effects frequently caused by extrapolation of IL

10126

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10039

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10127

abs_ir=abs(impulse_response);

10040

abs_ir=abs(impulse_response);

10128

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10041

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10129

start_ind = a(1);

10042

start_ind = a(1);

10130

10043

10131

err=inf;

10044

err=inf;

10132

while ~all(impulse_response==0)

10045

while ~all(impulse_response==0)

10133

impulse_response(1:start_ind)=0;

10046

impulse_response(1:start_ind)=0;

10134

impulse_response(floor(L/2):end)=0;

10047

impulse_response(floor(L/2):end)=0;

10135

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10048

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10136

ir_modified = real(ifft(IL_modified));

10049

ir_modified = real(ifft(IL_modified));

10137

delta = abs(impulse_response-ir_modified);

10050

delta = abs(impulse_response-ir_modified);

10138

10051

10139

err_prev = err;

10052

err_prev = err;

10140

err=max(delta)/max(impulse_response);

10053

err=max(delta)/max(impulse_response);

10141

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10054

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10142

break;

10055

break;

10143

end

10056

end

10144

10057

10145

impulse_response=ir_modified;

10058

impulse_response=ir_modified;

10146

end

10059

end

10147

10060

10148

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10061

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10149

10062

10150

if ~OP.ENFORCE_CAUSALITY

10063

if ~OP.ENFORCE_CAUSALITY

10151

impulse_response = original_impulse_response;

10064

impulse_response = original_impulse_response;

10152

end

10065

end

10153

% truncate final samples smaller than 1e-3 of the peak

10066

% truncate final samples smaller than 1e-3 of the peak

10154

ir_peak = max(abs(impulse_response));

10067

ir_peak = max(abs(impulse_response));

10155

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10068

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10156

10069

10157

voltage = impulse_response(1:ir_last);

10070

voltage = impulse_response(1:ir_last);

10158

t_base = t_base(1:ir_last);

10071

t_base = t_base(1:ir_last);

10159

10072

10160

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10073

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10161

10074

10162

function S =s_for_c2(zref,f,cpad)

10075

function S =s_for_c2(zref,f,cpad)

10163

% S is 2 port s parameters out

10076

% S is 2 port s parameters out

10164

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10077

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10165

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10078

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10166

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10079

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10167

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10080

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10168

S=sparameters(S_Parameters,f,zref);

10081

S=sparameters(S_Parameters,f,zref);

10169

10082

10170

function S =s_for_c4(zref,f,cpad)

10083

function S =s_for_c4(zref,f,cpad)

10171

10084

10172

S2 = s_for_c2(zref,f,cpad);

10085

S2 = s_for_c2(zref,f,cpad);

10173

S4P=s2_to_s4(S2.Parameters);

10086

S4P=s2_to_s4(S2.Parameters);

10174

S=sparameters(S4P,f,zref);

10087

S=sparameters(S4P,f,zref);

10175

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10088

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10176

10089

10177

10090

10178

10091

10179

10092

10180

%%

10093

%%

10181

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10094

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10182

% save commmend string

10095

% save commmend string

10183

% for saving from interactive queries

10096

% for saving from interactive queries

10184

10097

10185

10098

10186

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10099

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10187

for i=1:num_next+num_fext

10100

for i=1:num_next+num_fext

10188

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10101

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10189

end

10102

end

10190

cmd_str= [ cmd_str ')'];

10103

cmd_str= [ cmd_str ')'];

10191

10104

10192

10105

10193

%%%%% require the RF tool box

10106

%%%%% require the RF tool box

10194

%%

10107

%%

10195

function [ h ] = savefigs( param, OP )

10108

function [ h ] = savefigs( param, OP )

10196

10109

10197

%% find the figures

10110

%% find the figures

10198

hw = waitbar(0,'Saving figures...');

10111

hw = waitbar(0,'Saving figures...');

10199

h = findobj(0, 'Type', 'figure');

10112

h = findobj(0, 'Type', 'figure');

10200

for ii=1:length(h)

10113

for ii=1:length(h)

10201

10114

10202

figname= get(h(ii), 'Name'); % use the figure name as file name

10115

figname= get(h(ii), 'Name'); % use the figure name as file name

10203

if isempty(strfind(figname,param.base))

10116

if isempty(strfind(figname,param.base))

10204

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10117

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10205

end

10118

end

10206

if verLessThan('matlab', '8.4.0')

10119

if verLessThan('matlab', '8.4.0')

10207

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10120

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10208

else

10121

else

10209

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10122

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10210

end

10123

end

10211

figname = strrep(figname,':','-');

10124

figname = strrep(figname,':','-');

10212

figname = strrep(figname,' ','_');

10125

figname = strrep(figname,' ','_');

10213

if OP.SAVE_FIGURES==1

10126

if OP.SAVE_FIGURES==1

10214

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10127

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10215

end

10128

end

10216

%% get x y data

10129

%% get x y data

10217

if OP.SAVE_FIGURE_to_CSV==1

10130

if OP.SAVE_FIGURE_to_CSV==1

10218

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10131

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10219

M=[]; %ncol=1;

10132

M=[]; %ncol=1;

10220

for nk=1:length(h_L)

10133

for nk=1:length(h_L)

10221

% get x and data for a line.

10134

% get x and data for a line.

10222

x_data=get(h_L(nk),'xdata')';

10135

x_data=get(h_L(nk),'xdata')';

10223

y_data=get(h_L(nk),'ydata')';

10136

y_data=get(h_L(nk),'ydata')';

10224

% .........>> need to get data in the line structure (legend or label) for headers

10137

% .........>> need to get data in the line structure (legend or label) for headers

10225

M=[M; x_data; y_data]; %#ok<AGROW>

10138

M=[M; x_data; y_data]; %#ok<AGROW>

10226

end

10139

end

10227

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10140

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10228

% clear M y x header h_L

10141

% clear M y x header h_L

10229

end

10142

end

10230

waitbar(ii/length(h),hw)

10143

waitbar(ii/length(h),hw)

10231

10144

10232

end

10145

end

10233

10146

10234

close(hw)

10147

close(hw)

10235

10148

10236

%%

10149

%%

10237

function [ h ] = savefigs_png( param, OP )

10150

function [ h ] = savefigs_png( param, OP )

10238

10151

10239

%% find the figures

10152

%% find the figures

10240

hw = waitbar(0,'Saving figures...');

10153

hw = waitbar(0,'Saving figures...');

10241

h = findobj(0, 'Type', 'figure');

10154

h = findobj(0, 'Type', 'figure');

10242

for ii=1:length(h)

10155

for ii=1:length(h)

10243

10156

10244

figname= get(h(ii), 'Name'); % use the figure name as file name

10157

figname= get(h(ii), 'Name'); % use the figure name as file name

10245

if isempty(strfind(figname,param.base))

10158

if isempty(strfind(figname,param.base))

10246

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10159

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10247

end

10160

end

10248

if verLessThan('matlab', '8.4.0')

10161

if verLessThan('matlab', '8.4.0')

10249

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10162

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10250

else

10163

else

10251

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10164

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10252

end

10165

end

10253

figname = strrep(figname,':','-');

10166

figname = strrep(figname,':','-');

10254

figname = strrep(figname,' ','_');

10167

figname = strrep(figname,' ','_');

10255

if OP.SAVE_FIGURES==1

10168

if OP.SAVE_FIGURES==1

10256

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10169

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10257

end

10170

end

10258

%% get x y data

10171

%% get x y data

10259

if OP.SAVE_FIGURE_to_CSV==1

10172

if OP.SAVE_FIGURE_to_CSV==1

10260

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10173

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10261

M=[]; %ncol=1;

10174

M=[]; %ncol=1;

10262

for nk=1:length(h_L)

10175

for nk=1:length(h_L)

10263

% get x and data for a line.

10176

% get x and data for a line.

10264

x_data=get(h_L(nk),'xdata')';

10177

x_data=get(h_L(nk),'xdata')';

10265

y_data=get(h_L(nk),'ydata')';

10178

y_data=get(h_L(nk),'ydata')';

10266

% .........>> need to get data in the line structure (legend or label) for headers

10179

% .........>> need to get data in the line structure (legend or label) for headers

10267

M=[M; x_data; y_data]; %#ok<AGROW>

10180

M=[M; x_data; y_data]; %#ok<AGROW>

10268

end

10181

end

10269

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10182

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10270

% clear M y x header h_L

10183

% clear M y x header h_L

10271

end

10184

end

10272

waitbar(ii/length(h),hw)

10185

waitbar(ii/length(h),hw)

10273

10186

10274

end

10187

end

10275

10188

10276

close(hw)

10189

close(hw)

10277

10190

10278

%%

10191

%%

10279

function [pdf_out, cdf_out, scale_factor] = scaleCDF(pdf,delta_com,DER0,A_s)

10192

function [pdf_out, cdf_out, scale_factor] = scaleCDF(pdf,delta_com,DER0,A_s)

10280

% scale CDF at DER0 to delta_com

10193

% scale CDF at DER0 to delta_com

10281

pdf_out=pdf;

10194

pdf_out=pdf;

10282

P=cumsum(pdf.y);

10195

P=cumsum(pdf.y);

10283

ider0=find(P>=DER0,1,'first');

10196

ider0=find(P>=DER0,1,'first');

10284

anias=pdf.x(ider0)/A_s; % ani/as

10197

anias=pdf.x(ider0)/A_s; % ani/as

10285

new_db = 20*log10(-1/anias)-delta_com;

10198

new_db = 20*log10(-1/anias)-delta_com;

10286

new_value = -1*1/10^(new_db/20);

10199

new_value = -1*1/10^(new_db/20);

10287

scale_factor=1/10^(-delta_com/20);

10200

scale_factor=1/10^(-delta_com/20);

10288

pdf_out=scalePDF(pdf,scale_factor);

10201

pdf_out=scalePDF(pdf,scale_factor);

10289

cdf_out=cumsum(pdf_out.y);

10202

cdf_out=cumsum(pdf_out.y);

10290

function pdf_out = scalePDF(pdf,scale_factor)

10203

function pdf_out = scalePDF(pdf,scale_factor)

10291

pdf_out=pdf;

10204

pdf_out=pdf;

10292

pdf_out.Min=floor(pdf.Min*scale_factor);

10205

pdf_out.Min=floor(pdf.Min*scale_factor);

10293

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10206

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10294

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10207

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10295

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10208

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10296

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10209

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10297

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10210

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10298

function t_params = stot(s_params)

10211

function t_params = stot(s_params)

10299

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10212

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10300

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10213

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10301

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10214

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10302

delta = (s11.*s22-s12.*s21);

10215

delta = (s11.*s22-s12.*s21);

10303

s21(s21==0)=eps;

10216

s21(s21==0)=eps;

10304

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10217

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10305

10218

10306

function csv_string = str2csv(c)

10219

function csv_string = str2csv(c)

10307

% convert a cell array of strings to a csv string

10220

% convert a cell array of strings to a csv string

10308

cell_tmp = cell(2, length(c));

10221

cell_tmp = cell(2, length(c));

10309

cell_tmp(1,:)=c;

10222

cell_tmp(1,:)=c;

10310

cell_tmp(2,:) = {','};

10223

cell_tmp(2,:) = {','};

10311

cell_tmp{2,end} = '';

10224

cell_tmp{2,end} = '';

10312

csv_string=strcat(cell_tmp{:});

10225

csv_string=strcat(cell_tmp{:});

10313

10226

10314

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10227

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10315

f_GHz=f/1e9;

10228

f_GHz=f/1e9;

10316

%% Equation 93A-10 %%

10229

%% Equation 93A-10 %%

10317

gamma_1 = gamma_coeff(2)*(1+1i);

10230

gamma_1 = gamma_coeff(2)*(1+1i);

10318

%% Equation 93A-11 %%

10231

%% Equation 93A-11 %%

10319

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10232

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10320

%% Equation 93A-9 %%

10233

%% Equation 93A-9 %%

10321

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10234

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10322

gamma(f_GHz==0) = gamma_coeff(1);

10235

gamma(f_GHz==0) = gamma_coeff(1);

10323

10236

10324

%% Equation 93A-12 %%

10237

%% Equation 93A-12 %%

10325

if d==0

10238

if d==0

10326

%force matched impedance if length is 0

10239

%force matched impedance if length is 0

10327

%otherwise divide by zero can occur if Z_c=0

10240

%otherwise divide by zero can occur if Z_c=0

10328

rho_rl=0;

10241

rho_rl=0;

10329

else

10242

else

10330

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10243

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10331

end

10244

end

10332

10245

10333

exp_gamma_d = exp(-d*gamma);

10246

exp_gamma_d = exp(-d*gamma);

10334

%% Equations 93A-13 and 93A-14 %%

10247

%% Equations 93A-13 and 93A-14 %%

10335

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10248

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10336

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10249

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10337

s12 = s21;

10250

s12 = s21;

10338

s22 = s11;

10251

s22 = s11;

10339

10252

10340

function s_params = ttos(t_params)

10253

function s_params = ttos(t_params)

10341

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10254

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10342

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10255

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10343

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10256

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10344

delta = t11.*t22-t21.*t12;

10257

delta = t11.*t22-t21.*t12;

10345

t11(t11==0)=eps;

10258

t11(t11==0)=eps;

10346

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10259

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10347

10260

10348

function [out_var,varg_out]=varargin_extractor(varargin)

10261

function [out_var,varg_out]=varargin_extractor(varargin)

10349

10262

10350

if isempty(varargin)

10263

if isempty(varargin)

10351

out_var=[];

10264

out_var=[];

10352

varg_out={};

10265

varg_out={};

10353

else

10266

else

10354

out_var=varargin{1};

10267

out_var=varargin{1};

10355

varg_out=varargin;

10268

varg_out=varargin;

10356

varg_out(1)=[];

10269

varg_out(1)=[];

10357

end

10270

end

10358

10271

10359

10272

10360

function results= vma(PR, M)

10273

function results= vma(PR, M)

10361

% PR=sbr.Data;

10274

% PR=sbr.Data;

10362

% M=32;

10275

% M=32;

10363

% PR is the pulse response

10276

% PR is the pulse response

10364

% M is samples per UI

10277

% M is samples per UI

10365

[ seq, syms, syms_nrz ] = PRBS13Q( );

10278

[ seq, syms, syms_nrz ] = PRBS13Q( );

10366

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10279

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10367

symbols=seq;

10280

symbols=seq;

10368

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10281

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10369

% start end symbols index for 7 3's and 6 0's

10282

% start end symbols index for 7 3's and 6 0's

10370

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10283

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10371

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10284

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10372

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10285

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10373

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10286

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10374

% superposition code

10287

% superposition code

10375

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10288

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10376

Bit_stream_response=filter(PR,1, shifting_vector);

10289

Bit_stream_response=filter(PR,1, shifting_vector);

10377

% find center of 3's and 0's

10290

% find center of 3's and 0's

10378

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10291

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10379

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10292

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10380

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10293

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10381

% hold on

10294

% hold on

10382

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10295

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10383

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10296

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10384

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10297

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10385

VMA= P_3 - P_0;

10298

VMA= P_3 - P_0;

10386

results.P_3=P_3;

10299

results.P_3=P_3;

10387

results.P_0=P_0;

10300

results.P_0=P_0;

10388

results.VMA=VMA;

10301

results.VMA=VMA;

10389

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10302

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10390

10303

10391

%slope of the 2 sample points around vref crossing

10304

%slope of the 2 sample points around vref crossing

10392

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10305

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10393

%x-intercept for the line

10306

%x-intercept for the line

10394

b1=eye_contour(x_in,1)-m1*x_in;

10307

b1=eye_contour(x_in,1)-m1*x_in;

10395

% drawing a horizontal line through vref so slope = 0

10308

% drawing a horizontal line through vref so slope = 0

10396

m2=0;

10309

m2=0;

10397

%special case for horizontal line, b=y

10310

%special case for horizontal line, b=y

10398

b2=vref;

10311

b2=vref;

10399

%the x-value of line intersection = (b2-b1)/(m1-m2)

10312

%the x-value of line intersection = (b2-b1)/(m1-m2)

10400

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10313

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10401

%And usually vref is 0, so it further reduces to -b1/m1

10314

%And usually vref is 0, so it further reduces to -b1/m1

10402

line_intersection=(b2-b1)/(m1-m2);

10315

line_intersection=(b2-b1)/(m1-m2);

10403

10316

10404

10317

10405

10318

10406

10319

10407

10320

10408

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10321

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10409

% helper function to read parameter values from XLS file. Uses names to find values.

10322

% helper function to read parameter values from XLS file. Uses names to find values.

10410

if nargin<3, eval_if_string=0; end

10323

if nargin<3, eval_if_string=0; end

10411

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10324

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10412

if numel(row)*numel(col)==0

10325

if numel(row)*numel(col)==0

10413

if nargin<4

10326

if nargin<4

10414

missingParameter(param_name);

10327

missingParameter(param_name);

10415

else

10328

else

10416

p = default_value;

10329

p = default_value;

10417

end

10330

end

10418

elseif numel(row)*numel(col)>1

10331

elseif numel(row)*numel(col)>1

10419

% if there are several occurrences, use the first, but warn

10332

% if there are several occurrences, use the first, but warn

10420

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10333

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10421

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10334

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10422

error('COM:XLS_parameter:MultipleOccurrence', ...

10335

error('COM:XLS_parameter:MultipleOccurrence', ...

10423

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10336

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10424

p=param_sheet{row(1), col(1)+1};

10337

p=param_sheet{row(1), col(1)+1};

10425

else

10338

else

10426

p=param_sheet{row, col+1};

10339

p=param_sheet{row, col+1};

10427

end

10340

end

10428

if ischar(p) && eval_if_string

10341

if ischar(p) && eval_if_string

10429

p=eval(p);

10342

p=eval(p);

10430

end

10343

end

10431

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10344

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10432

if OP.SAVE_KEYWORD_FILE

10345

if OP.SAVE_KEYWORD_FILE

10433

10346

10434

if nargin<3 || ~exist('default_value','var')

10347

if nargin<3 || ~exist('default_value','var')

10435

default_value=p;

10348

default_value=p;

10436

end

10349

end

10437

if isempty(default_value)

10350

if isempty(default_value)

10438

default_value='-';

10351

default_value='-';

10439

end

10352

end

10440

%%

10353

%%

10441

% Get call-stack info:

10354

% Get call-stack info:

10442

stDebug = dbstack;

10355

stDebug = dbstack;

10443

callerFileName = stDebug(2).file;

10356

callerFileName = stDebug(2).file;

10444

callerLineNumber = stDebug(2).line;

10357

callerLineNumber = stDebug(2).line;

10445

% Open caller file:

10358

% Open caller file:

10446

fCaller = fopen(callerFileName);

10359

fCaller = fopen(callerFileName);

10447

% Iterate through lines to get to desired line number:

10360

% Iterate through lines to get to desired line number:

10448

for iLine = 1 : callerLineNumber

10361

for iLine = 1 : callerLineNumber

10449

% Read current line of text:

10362

% Read current line of text:

10450

currLine = fgetl(fCaller);

10363

currLine = fgetl(fCaller);

10451

end

10364

end

10452

% (currLine) now reflects calling desired code: display this code:

10365

% (currLine) now reflects calling desired code: display this code:

10453

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10366

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10454

% Close caller file:

10367

% Close caller file:

10455

left_side=currLine(1:strfind(currLine,'=')-1);

10368

left_side=currLine(1:strfind(currLine,'=')-1);

10456

cmt_side=currLine(strfind(currLine,'%')+1:end);

10369

cmt_side=currLine(strfind(currLine,'%')+1:end);

10457

if isempty(cmt_side), cmt_side=' ';end

10370

if isempty(cmt_side), cmt_side=' ';end

10458

fclose(fCaller);

10371

fclose(fCaller);

10459

10372

10460

if ~ischar(default_value)

10373

if ~ischar(default_value)

10461

default_str=sprintf('%g ',default_value);

10374

default_str=sprintf('%g ',default_value);

10462

else

10375

else

10463

default_str=default_value;

10376

default_str=default_value;

10464

end

10377

end

10465

if ~isfile('keyworklog.mat')

10378

if ~isfile('keyworklog.mat')

10466

save_p=param_name;

10379

save_p=param_name;

10467

save_d=default_str;

10380

save_d=default_str;

10468

save_r=left_side;

10381

save_r=left_side;

10469

save_c=cmt_side;

10382

save_c=cmt_side;

10470

param_name = {'keyword'};

10383

param_name = {'keyword'};

10471

default_str = {'default'};

10384

default_str = {'default'};

10472

left_side={'matlab variable'};

10385

left_side={'matlab variable'};

10473

cmt_side={'info'};

10386

cmt_side={'info'};

10474

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10387

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10475

param_name=save_p;

10388

param_name=save_p;

10476

default_str=save_d;

10389

default_str=save_d;

10477

left_side=save_r;

10390

left_side=save_r;

10478

cmt_side=save_c;

10391

cmt_side=save_c;

10479

data=load('keyworklog.mat');

10392

data=load('keyworklog.mat');

10480

else

10393

else

10481

load('keyworklog.mat');

10394

load('keyworklog.mat');

10482

end

10395

end

10483

data.left_side = [ data.left_side; left_side];

10396

data.left_side = [ data.left_side; left_side];

10484

data.param_name = [data.param_name; param_name];

10397

data.param_name = [data.param_name; param_name];

10485

data.default_str = [data.default_str; default_str ];

10398

data.default_str = [data.default_str; default_str ];

10486

data.cmt_side = [ data.cmt_side; cmt_side];

10399

data.cmt_side = [ data.cmt_side; cmt_side];

10487

if length(data.default_str)~=length(data.default_str)

10400

if length(data.default_str)~=length(data.default_str)

10488

a=1;

10401

a=1;

10489

end

10402

end

10490

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10403

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10491

save('keyworklog.mat','data');

10404

save('keyworklog.mat','data');

10492

writetable(T,[ 'keywords_' date '.csv' ]);

10405

writetable(T,[ 'keywords_' date '.csv' ]);

10493

end

10406

end

10494

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10407

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10495

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10408

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10496

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10409

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10497

10410

10498

found=1;

10411

found=1;

10499

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10412

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10500

if numel(row)*numel(col)==0

10413

if numel(row)*numel(col)==0

10501

p = 0;

10414

p = 0;

10502

found=0;

10415

found=0;

10503

elseif numel(row)*numel(col)>1

10416

elseif numel(row)*numel(col)>1

10504

% if there are several occurrences, use the first, but warn

10417

% if there are several occurrences, use the first, but warn

10505

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10418

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10506

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10419

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10507

error('COM:XLS_parameter:MultipleOccurrence', ...

10420

error('COM:XLS_parameter:MultipleOccurrence', ...

10508

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10421

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10509

p=param_sheet{row(1), col(1)+1};

10422

p=param_sheet{row(1), col(1)+1};

10510

else

10423

else

10511

p=param_sheet{row, col+1};

10424

p=param_sheet{row, col+1};

10512

end

10425

end

10513

if ischar(p)

10426

if ischar(p)

10514

p=eval(p);

10427

p=eval(p);

10515

end

10428

end

10516

function zzz_list_of_changes

10429

function zzz_list_of_changes

10517

% structures:

10430

% structures:

10518

% chdata(i)

10431

% chdata(i)

10519

% i= 1 --> THRU index

10432

% i= 1 --> THRU index

10520

% i= 2, num_fext+1 --> FEXT channel index

10433

% i= 2, num_fext+1 --> FEXT channel index

10521

% i= num_fext+2, num_next+num_fext+1

10434

% i= num_fext+2, num_next+num_fext+1

10522

% base: name of THRU file

10435

% base: name of THRU file

10523

% A: amplitude

10436

% A: amplitude

10524

% type: 'THRU', 'NEXT', or 'FEXT'

10437

% type: 'THRU', 'NEXT', or 'FEXT'

10525

% ftr: Rise time frequency

10438

% ftr: Rise time frequency

10526

% fmaxi: max number of frequency points

10439

% fmaxi: max number of frequency points

10527

% faxis: frequency array [Hz]

10440

% faxis: frequency array [Hz]

10528

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10441

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10529

% sdd22: differential RL

10442

% sdd22: differential RL

10530

% sdd11: differential RL

10443

% sdd11: differential RL

10531

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10444

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10532

% sdd21f: raw differential IL not filtered use for FD plots

10445

% sdd21f: raw differential IL not filtered use for FD plots

10533

% added output_args.peak_uneq_pulse_mV

10446

% added output_args.peak_uneq_pulse_mV

10534

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10447

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10535

% added: tap c(-2) c(2) and c(3)

10448

% added: tap c(-2) c(2) and c(3)

10536

% added: g_DC_HP and f_HP_PZ

10449

% added: g_DC_HP and f_HP_PZ

10537

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10450

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10538

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10451

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10539

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10452

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10540

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10453

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10541

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10454

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10542

% fixed INCLUDE_CTLE=0 to really remove from computation

10455

% fixed INCLUDE_CTLE=0 to really remove from computation

10543

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10456

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10544

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10457

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10545

% r162 tx and rx package impedance {Zc)

10458

% r162 tx and rx package impedance {Zc)

10546

% r162a Gaussian equation corrected

10459

% r162a Gaussian equation corrected

10547

% r163 cast snr_tx with package test case

10460

% r163 cast snr_tx with package test case

10548

% r164 fix pdf for very low noise and lo pass filter enhancements

10461

% r164 fix pdf for very low noise and lo pass filter enhancements

10549

% r164 add zero gain at nqyist CTLE as in CL12e

10462

% r164 add zero gain at nqyist CTLE as in CL12e

10550

% r165 add simpler congfig command called FORCE_TR (force risetime)

10463

% r165 add simpler congfig command called FORCE_TR (force risetime)

10551

% r200 cm3 and cm4 added cp3 removed

10464

% r200 cm3 and cm4 added cp3 removed

10552

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10465

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10553

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10466

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10554

% r200 improved phase interpolation for return loss time conversion

10467

% r200 improved phase interpolation for return loss time conversion

10555

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10468

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10556

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10469

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10557

% r200c missed on fix for interpolation

10470

% r200c missed on fix for interpolation

10558

% r210 new ERL with time gating function

10471

% r210 new ERL with time gating function

10559

% r224 update ERL with from D3.1

10472

% r224 update ERL with from D3.1

10560

% r226 fix s2p reading problem

10473

% r226 fix s2p reading problem

10561

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10474

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10562

% Fix Rx calibration issue

10475

% Fix Rx calibration issue

10563

% added ERL limit and Nd

10476

% added ERL limit and Nd

10564

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10477

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10565

% INC_PACKAGE=0 not fully supported message

10478

% INC_PACKAGE=0 not fully supported message

10566

% if N=0 use TDR_duration

10479

% if N=0 use TDR_duration

10567

% red display text for fail ERL and COM

10480

% red display text for fail ERL and COM

10568

% r228 fixed ERL pass fail report, default Grr_limit to 1

10481

% r228 fixed ERL pass fail report, default Grr_limit to 1

10569

% r230 add rx ffe

10482

% r230 add rx ffe

10570

% r231 change crosstalk noise to icn like to speed things up

10483

% r231 change crosstalk noise to icn like to speed things up

10571

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10484

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10572

% 1e-5mof-

10485

% 1e-5mof-

10573

% r232 fix default for Rx eq so old spead sheets work

10486

% r232 fix default for Rx eq so old spead sheets work

10574

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10487

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10575

% r235 adding dfe quantization changed to normalized DFE taps reported

10488

% r235 adding dfe quantization changed to normalized DFE taps reported

10576

% r236 adding ffe gain loop and resample after RxFFE

10489

% r236 adding ffe gain loop and resample after RxFFE

10577

% r240 added output for C2M and setting defaults for some FFE eq

10490

% r240 added output for C2M and setting defaults for some FFE eq

10578

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10491

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10579

% r250 adding more complex package

10492

% r250 adding more complex package

10580

% r251 post cursor fix for DFE in force() and ffe backoff

10493

% r251 post cursor fix for DFE in force() and ffe backoff

10581

% r251 remove TDR threshold noise filter

10494

% r251 remove TDR threshold noise filter

10582

% r252 add rx FFE filter to receiver noise filter

10495

% r252 add rx FFE filter to receiver noise filter

10583

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10496

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10584

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10497

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10585

% r254 precursor check fix in optimize_fom % mod fix in force

10498

% r254 precursor check fix in optimize_fom % mod fix in force

10586

% r254 help to align columns in csv file

10499

% r254 help to align columns in csv file

10587

% r254 accept syntax for 2 tline flex package model

10500

% r254 accept syntax for 2 tline flex package model

10588

% r256 speed up optimize FOM

10501

% r256 speed up optimize FOM

10589

% r256 fix problem reading in config file from q/a

10502

% r256 fix problem reading in config file from q/a

10590

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10503

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10591

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10504

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10592

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10505

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10593

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10506

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10594

% r258 CDR switch 'MM' or 'mod-MM'

10507

% r258 CDR switch 'MM' or 'mod-MM'

10595

% r258 correction for asymentirc tx/Rx packages

10508

% r258 correction for asymentirc tx/Rx packages

10596

% r258 revamped display results display window

10509

% r258 revamped display results display window

10597

% r259 fix problem if Min_VEO is set in spreadsheet.

10510

% r259 fix problem if Min_VEO is set in spreadsheet.

10598

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10511

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10599

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10512

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10600

% r259 putting COM_db and IL last in output to terminal

10513

% r259 putting COM_db and IL last in output to terminal

10601

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10514

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10602

% r259 use N_bx for ERL rather than Nb (ndfe))

10515

% r259 use N_bx for ERL rather than Nb (ndfe))

10603

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10516

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10604

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10517

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10605

% r260 used eta_0 PSD equation for sigma_n

10518

% r260 used eta_0 PSD equation for sigma_n

10606

% r260 fix IL graph legend to w/pkg and Tr

10519

% r260 fix IL graph legend to w/pkg and Tr

10607

% r260 define tfx for each port

10520

% r260 define tfx for each port

10608

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10521

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10609

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10522

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10610

% r262 reset on exit default text interpreter to tex

10523

% r262 reset on exit default text interpreter to tex

10611

% r262 localize run timer (John Buck 1/17/19)

10524

% r262 localize run timer (John Buck 1/17/19)

10612

% r262 set db as internal function in force to avoid tool box

10525

% r262 set db as internal function in force to avoid tool box

10613

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10526

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10614

% r263 added to output_args RL structure and report "struct" in csv file

10527

% r263 added to output_args RL structure and report "struct" in csv file

10615

% r264 added EW estimate

10528

% r264 added EW estimate

10616

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10529

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10617

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10530

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10618

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10531

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10619

% r269 changed param.N_bmax to param.N_f

10532

% r269 changed param.N_bmax to param.N_f

10620

% r270 implement JingBo Li's and Howard Heck's floating tap method

10533

% r270 implement JingBo Li's and Howard Heck's floating tap method

10621

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10534

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10622

% r270 added c_0 and c_1 for CA in add_brd

10535

% r270 added c_0 and c_1 for CA in add_brd

10623

% r272 fixed version syntax problem in output_args RL report

10536

% r272 fixed version syntax problem in output_args RL report

10624

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10537

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10625

% r272 removed eye width report if doing a Rx calibration

10538

% r272 removed eye width report if doing a Rx calibration

10626

% r273 better alignment and control for ICN reporting

10539

% r273 better alignment and control for ICN reporting

10627

% r273 fixed PSXTK graph

10540

% r273 fixed PSXTK graph

10628

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10541

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10629

% 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)

10542

% 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)

10630

% 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

10543

% 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

10631

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10544

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10632

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10545

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10633

% r276 C_1 was instantiated as C_0. This was fixed

10546

% r276 C_1 was instantiated as C_0. This was fixed

10634

% r276 fixed rounding problem in reporting of loss at f_nq

10547

% r276 fixed rounding problem in reporting of loss at f_nq

10635

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10548

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10636

% r277 added nv for deterining steady state voltage for fitting compatibility

10549

% r277 added nv for deterining steady state voltage for fitting compatibility

10637

% r278 added b_min to support asymmetric bmax

10550

% r278 added b_min to support asymmetric bmax

10638

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10551

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10639

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10552

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10640

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10553

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10641

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10554

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10642

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10555

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10643

% 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

10556

% 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

10644

% r292 H_t implemented in s21_pkg

10557

% r292 H_t implemented in s21_pkg

10645

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10558

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10646

% r292 add GDC_MIN to optimize_FOM

10559

% r292 add GDC_MIN to optimize_FOM

10647

% r293 fix if ndfe-0 and ERL only and s2p issue

10560

% r293 fix if ndfe-0 and ERL only and s2p issue

10648

% r293a investigate the Tukey filtering

10561

% r293a investigate the Tukey filtering

10649

% r293a if fix if bmin is missing

10562

% r293a if fix if bmin is missing

10650

% r294 fix problems reading s2p files for ERL computation

10563

% r294 fix problems reading s2p files for ERL computation

10651

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10564

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10652

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10565

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10653

% r294 add gdc and gdc2 range limitations

10566

% r294 add gdc and gdc2 range limitations

10654

% r295 add VEC Pass threshold

10567

% r295 add VEC Pass threshold

10655

% r295 removed close force all. Tagged all figures with "COM"

10568

% r295 removed close force all. Tagged all figures with "COM"

10656

% r295 consolidated print in new function "end_display_control"

10569

% r295 consolidated print in new function "end_display_control"

10657

% r295 report pre/pmax for Txffe

10570

% r295 report pre/pmax for Txffe

10658

% r295 speed up test cases by not re-reading in s4p files

10571

% r295 speed up test cases by not re-reading in s4p files

10659

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10572

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10660

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10573

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10661

% r310 refine VEC and EH for C2M from Adam Gregory in

10574

% r310 refine VEC and EH for C2M from Adam Gregory in

10662

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10575

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10663

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10576

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10664

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10577

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10665

% r311 added RILN

10578

% r311 added RILN

10666

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10579

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10667

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10580

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10668

% r316 remove DC computation for RX Calibration loops

10581

% r316 remove DC computation for RX Calibration loops

10669

% r317 for SAVE_TD to include EQ and unEQ FIR

10582

% r317 for SAVE_TD to include EQ and unEQ FIR

10670

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10583

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10671

% 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

10584

% 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

10672

% r320 fixed RX_CALIBRATION which was broken in r310

10585

% r320 fixed RX_CALIBRATION which was broken in r310

10673

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10586

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10674

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10587

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10675

% r320 removed external feature and replace with TDMODE

10588

% r320 removed external feature and replace with TDMODE

10676

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10589

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10677

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10590

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10678

% r335 fixed typo in when processing the bessel thompson filter option

10591

% r335 fixed typo in when processing the bessel thompson filter option

10679

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10592

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10680

% r335 compute and report CD_CM_RMS

10593

% r335 compute and report CD_CM_RMS

10681

% r335 fixed where output_arg is save i.e. move to end

10594

% r335 fixed where output_arg is save i.e. move to end

10682

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10595

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10683

% r335 change raw IL plot to not include boards

10596

% r335 change raw IL plot to not include boards

10684

% r335 set T_0 to zero if not C2M

10597

% r335 set T_0 to zero if not C2M

10685

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10598

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10686

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10599

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10687

% r335 TD_RILN changes from Hansel Dsilva

10600

% r335 TD_RILN changes from Hansel Dsilva

10688

% r335 Fixed sigma_N for RxFFE

10601

% r335 Fixed sigma_N for RxFFE

10689

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10602

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10690

% r335 added c(2) and C(3) back to read_ParamConfigFile

10603

% r335 added c(2) and C(3) back to read_ParamConfigFile

10691

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10604

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10692

% r335 corrected GDC_MIN per 0.3ck D2.3

10605

% r335 corrected GDC_MIN per 0.3ck D2.3

10693

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10606

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10694

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10607

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10695

% r370 speed up

10608

% r370 speed up

10696

% r370 fix for floating tap missing locations

10609

% r370 fix for floating tap missing locations

10697

% r370 variable Tx FFE taps

10610

% r370 variable Tx FFE taps

10698

% r370 package die load with ladder circuit

10611

% r370 package die load with ladder circuit

10699

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10612

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10700

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10613

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10701

% r380 added capabablity to enable a raised cosine Rx filter0

10614

% r380 added capabablity to enable a raised cosine Rx filter0

10702

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10615

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10703

% r380 added plot for VTF

10616

% r380 added plot for VTF

10704

% r385 added capability for additional Tx FFE per package

10617

% r385 added capability for additional Tx FFE per package

10705

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10618

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10706

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10619

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10707

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10620

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10708

% r389 Improvement by A. Ran for reporting loss at Nq

10621

% r389 Improvement by A. Ran for reporting loss at Nq

10709

% r389 Fixed typo: changed VIM to VMP

10622

% r389 Fixed typo: changed VIM to VMP

10710

% r400 fixed PR with zero pad extension

10623

% r400 fixed PR with zero pad extension

10711

% r400 keyword MLSE and SNRADJ_EQUA for future work

10624

% r400 keyword MLSE and SNRADJ_EQUA for future work

10712

% r400 replaced function db with instances of 20*log10(abs(...))

10625

% r400 replaced function db with instances of 20*log10(abs(...))

10713

% r410 widen voltage distriution for normal_dist doubled max Q

10626

% r410 widen voltage distriution for normal_dist doubled max Q

10714

% r410 improve reading in of config files

10627

% r410 improve reading in of config files

10715

% r410 renormalize s-parameter if not 50 ohm ref

10628

% r410 renormalize s-parameter if not 50 ohm ref

10716

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10629

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10717

% r410 remove RL from output_args bc not need and too much storage allocation

10630

% r410 remove RL from output_args bc not need and too much storage allocation

10718

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10631

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10719

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10632

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10720

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10633

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10721

% r420 updade force to account for pulse responces with short delays in force

10634

% r420 updade force to account for pulse responces with short delays in force

10722

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10635

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10723

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10636

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10724

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10637

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10725

% r420 Wiener-Kofp MMSE optimization for RxFFE

10638

% r420 Wiener-Kofp MMSE optimization for RxFFE

10726

% r430 first pass at healey_3dj_01_2401

10639

% r430 first pass at healey_3dj_01_2401

10727

% r430 RxFFE fixed taps

10640

% r430 RxFFE fixed taps

10728

% r440 RxffE fixed tap index corrections and floating taps

10641

% r440 RxffE fixed tap index corrections and floating taps

10729

% r440 first pass implemenation of MLSE U3

10642

% r440 first pass implemenation of MLSE U3

10730

% r450 fix MLSE_FOM typos, sigma_e,and FOM.

10643

% r450 fix MLSE_FOM typos, sigma_e,and FOM.

10731

% r450 incude Hisi in PSD in get_PSDs

10644

% r450 incude Hisi in PSD in get_PSDs

10732

% r460 is working out reporting bug from RxFFE and package A,B invocations

10645

% r460 is working out reporting bug from RxFFE and package A,B invocations

10733

% r460 align package config Tx and Rx cases with selected casting 4p5_3

10646

% r460 align package config Tx and Rx cases with selected casting 4p5_3

10734

% r460 fix RxFFE floating taps display (indexing error) 4p5_4

10647

% r460 fix RxFFE floating taps display (indexing error) 4p5_4

10735

% r470 beta1 added MLSE truncation inclusion using N_tc

10648

% r470 beta1 added MLSE truncation inclusion using N_tc

10736

% r470 beta1 add MLSE Q_budget_adj

10649

% r470 beta1 add MLSE Q_budget_adj

10737

% r470 added parameter defaults to support multiple packages

10650

% r470 added parameter defaults to support multiple packages

10738

% r470 beta2 added MLSD proposal from healey_3dj_01_2409

10651

% r470 beta2 added MLSD proposal from healey_3dj_01_2409

10739

% r470 remOved support for MLSE_Q

10740

% r480 beta1 added new keyword ENOB for quantization. if 0 or missing ignored

10741

% r480 beta1 added function adjust_Rx_noise_for_quantization

10742

% r480 beta2 fixed typo's and updated from shakiba_3dj_COM_02_241001 to shakiba_3dj_COM_01_241029

10743

10652