File Comparison Report

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

richardm

02-May-2024

Files

Left FileRight File
File namecom_ieee8023_93a_450com_ieee8023_93a_440
File pathC:\Users\richardm\OneDrive - Samtec\COM\COM\srcC:\Users\richardm\OneDrive - Samtec\COM\COM\src
Last modified02-May-2024 14:31:3326-Mar-2024 14:35:57

Environment

MATLAB9.14 (R2023a)

Comparison Results

+

Insertion

Deletion

Modification
1

function results=com_ieee8023_93a(varargin)

1

function results=com_ieee8023_93a(varargin)

2

% This is NOT an official IEEE document.

2

% This is NOT an official IEEE document.op.mlse

3

%% Implementation example of annex 93A IEEE Std 802.3

3

%% Implementation example of annex 93A IEEE Std 802.3

4

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

4

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

5

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

5

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

6

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

6

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

7

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

7

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

8

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

8

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

9

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

9

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

10

% will ask for each of the files interactively.opupu

10

% will ask for each of the files interactively.opupu

11

%

11

%

12

% This program is intended for the development of standard specifications

12

% This program is intended for the development of standard specifications

13

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

13

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

14

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

14

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

15

% original proposal for COM may be found at

15

% original proposal for COM may be found at

16

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

16

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

17

% from the following authors and affiliations in 2012.

17

% from the following authors and affiliations in 2012.

18

% Richard Mellitz, Intel Corporation

18

% Richard Mellitz, Intel Corporation

19

% Charles Moore, Avago Technologies

19

% Charles Moore, Avago Technologies

20

% Mike Dudek, QLogic Corporation

20

% Mike Dudek, QLogic Corporation

21

% Mike Peng Li, Altera Corporation

21

% Mike Peng Li, Altera Corporation

22

% Adee Ran, Intel Corporation

22

% Adee Ran, Intel Corporation

23

%

23

%

24

% Some of the authors and Contributors:

24

% Some of the authors and Contributors:

25

% Adee Ran

25

% Adee Ran

26

% Richard Mellitz

26

% Richard Mellitz

27

% Yasuo Hidaka

27

% Yasuo Hidaka

28

% John Ewen

28

% John Ewen

29

% Bill Kirkland

29

% Bill Kirkland

30

% Adam Gregory

30

% Adam Gregory

31

% Howard Heck

31

% Howard Heck

32

% Jingbo Li

32

% Jingbo Li

33

% Adam Healey

33

% Adam Healey

34

% Matt Brown

34

% Matt Brown

35

% Sameh Elnagar

35

% Sameh Elnagar

36

% Hossein Shakiba

36

% Hossein Shakiba

37

zzz_list_of_changes()

37

zzz_list_of_changes()

38

38

39

%% Opening Preface

39

%% Opening Preface

40

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

40

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

41

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

41

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

42

try % version number at end of call string

42

try % version number at end of call string

43

cmdfile=mfilename;

43

cmdfile=mfilename;

44

hindx=strfind(mfilename,'_');

44

hindx=strfind(mfilename,'_');

45

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

45

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

46

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

46

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

47

catch

47

catch

48

output_args.code_revision ='';

48

output_args.code_revision ='';

49

end

49

end

50

teststr='';

50

teststr='';

51

OP.TESTING=0;

51

OP.TESTING=0;

52

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

52

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

53

teststr='testing';

53

teststr='testing';

54

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

54

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

55

htest = msgbox(testmsg);

55

htest = msgbox(testmsg);

56

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

56

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

57

end

57

end

58

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

58

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

59

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

59

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

60

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

60

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

61

t0=tic;

61

t0=tic;

62

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

62

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

63

% reset to tex on exit

63

% reset to tex on exit

64

%% file_setup

64

%% file_setup

65

%%

65

%%

66

% need to see what happens for version 8

66

% need to see what happens for version 8

67

if verLessThan('matlab', '7.4.1')

67

if verLessThan('matlab', '7.4.1')

68

error('Matlab version 7.4 or higher required')

68

error('Matlab version 7.4 or higher required')

69

end

69

end

70

70

71

results=[];

71

results=[];

72

72

73

%% New Command Line parser

73

%% New Command Line parser

74

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

74

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

75

75

76

76

77

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

77

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

78

if isempty(config_file)

78

if isempty(config_file)

79

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

79

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

80

if isempty(config_file)

80

if isempty(config_file)

81

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

81

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

82

else

82

else

83

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

83

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

84

config_file=[cname cext];

84

config_file=[cname cext];

85

end

85

end

86

if config_file==0

86

if config_file==0

87

% cancel - exit gracefully

87

% cancel - exit gracefully

88

return;

88

return;

89

end

89

end

90

config_file = fullfile(config_file_path, config_file);

90

config_file = fullfile(config_file_path, config_file);

91

end

91

end

92

output_args.config_file = config_file;

92

output_args.config_file = config_file;

93

OP.SAVE_KEYWORD_FILE=0;

93

OP.SAVE_KEYWORD_FILE=0;

94

if OP.SAVE_KEYWORD_FILE

94

if OP.SAVE_KEYWORD_FILE

95

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

95

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

96

delete('keyworklog.mat');

96

delete('keyworklog.mat');

97

end

97

end

98

end

98

end

99

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

99

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

100

if OP.CONFIG2MAT_ONLY

100

if OP.CONFIG2MAT_ONLY

101

return;

101

return;

102

end

102

end

103

if isempty(num_fext)

103

if isempty(num_fext)

104

if OP.RX_CALIBRATION

104

if OP.RX_CALIBRATION

105

num_fext=1;

105

num_fext=1;

106

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

106

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

107

else

107

else

108

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

108

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

109

num_fext=1;

109

num_fext=1;

110

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

110

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

111

elseif ~OP.ERL_ONLY

111

elseif ~OP.ERL_ONLY

112

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

112

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

113

else

113

else

114

num_fext=0;

114

num_fext=0;

115

end

115

end

116

end

116

end

117

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

117

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

118

end

118

end

119

if isempty(num_next)

119

if isempty(num_next)

120

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

120

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

121

num_next=0;

121

num_next=0;

122

else

122

else

123

if OP.RX_CALIBRATION

123

if OP.RX_CALIBRATION

124

num_next=0;

124

num_next=0;

125

elseif ~OP.ERL_ONLY

125

elseif ~OP.ERL_ONLY

126

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

126

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

127

else

127

else

128

num_next=0;

128

num_next=0;

129

end

129

end

130

end

130

end

131

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

131

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

132

end

132

end

133

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

133

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

134

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

134

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

135

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

135

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

136

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

136

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

137

param.num_next=num_next;

137

param.num_next=num_next;

138

param.num_fext=num_fext;

138

param.num_fext=num_fext;

139

param.num_s4p_files=num_fext+num_next+1;

139

param.num_s4p_files=num_fext+num_next+1;

140

% checking for data when running for rx compliance BBN calibration

140

% checking for data when running for rx compliance BBN calibration

141

if OP.RX_CALIBRATION == 1

141

if OP.RX_CALIBRATION == 1

142

if num_fext ~=1

142

if num_fext ~=1

143

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

143

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

144

movegui(h,'northwest')

144

movegui(h,'northwest')

145

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

145

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

146

if OP.DEBUG ~= 1

146

if OP.DEBUG ~= 1

147

return

147

return

148

end

148

end

149

end

149

end

150

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

150

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

151

movegui(h,'southeast')

151

movegui(h,'southeast')

152

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

152

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

153

end

153

end

154

154

155

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

155

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

156

if num_fext ~=1

156

if num_fext ~=1

157

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

157

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

158

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

158

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

159

movegui(h,'northwest')

159

movegui(h,'northwest')

160

if OP.DEBUG ~= 1

160

if OP.DEBUG ~= 1

161

return

161

return

162

end

162

end

163

end

163

end

164

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

164

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

165

movegui(h,'southeast')

165

movegui(h,'southeast')

166

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

166

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

167

end

167

end

168

168

169

169

170

% create result directory if needed

170

% create result directory if needed

171

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

171

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

172

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

172

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

173

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

173

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

174

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

174

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

175

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

175

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

176

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

176

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

177

%OP.EXTERNAL = true;

177

%OP.EXTERNAL = true;

178

%OP.GET_FD = 0;

178

%OP.GET_FD = 0;

179

%ir1a= varargin(2);

179

%ir1a= varargin(2);

180

%ex_var = varargin(3);

180

%ex_var = varargin(3);

181

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

181

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

182

else

182

else

183

if OP.TDMODE

183

if OP.TDMODE

184

OP.GET_FD=false;

184

OP.GET_FD=false;

185

end

185

end

186

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

186

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

187

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

187

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

188

end

188

end

189

%% eveluate any extra arguments as possible modifications of parameters

189

%% eveluate any extra arguments as possible modifications of parameters

190

extra_args = varargin(xtk+2:end);

190

extra_args = varargin(xtk+2:end);

191

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

191

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

192

try

192

try

193

orig_value_is_str = 1;

193

orig_value_is_str = 1;

194

orig_value=eval(extra_args{k});

194

orig_value=eval(extra_args{k});

195

if ~ischar(orig_value)

195

if ~ischar(orig_value)

196

orig_value_is_str = 0;

196

orig_value_is_str = 0;

197

orig_value=mat2str(orig_value);

197

orig_value=mat2str(orig_value);

198

end

198

end

199

catch eval_err

199

catch eval_err

200

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

200

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

201

% trying to modify a nonexistent parameter - probably a

201

% trying to modify a nonexistent parameter - probably a

202

% typo. save the user from his error.

202

% typo. save the user from his error.

203

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

203

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

204

else

204

else

205

% unexpected condition

205

% unexpected condition

206

rethrow(eval_err);

206

rethrow(eval_err);

207

end

207

end

208

end

208

end

209

try

209

try

210

if orig_value_is_str

210

if orig_value_is_str

211

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

211

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

212

else

212

else

213

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

213

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

214

end

214

end

215

eval(mod_string);

215

eval(mod_string);

216

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

216

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

217

% begin yasuo patch 2/11/2018

217

% begin yasuo patch 2/11/2018

218

% output_args.(fname)=mod_string;

218

% output_args.(fname)=mod_string;

219

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

219

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

220

220

221

% re-patch yasuo 3/18/2019

221

% re-patch yasuo 3/18/2019

222

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

222

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

223

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

223

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

224

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

224

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

225

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

225

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

226

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

226

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

227

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

227

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

228

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

228

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

229

else

229

else

230

output_args.(fname)=mod_string;

230

output_args.(fname)=mod_string;

231

end

231

end

232

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

232

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

233

catch eval_err

233

catch eval_err

234

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

234

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

235

end

235

end

236

end

236

end

237

end

237

end

238

end

238

end

239

%% Parameters computationally defined by values from the settings files

239

%% Parameters computationally defined by values from the settings files

240

param.ui=1/param.fb;

240

param.ui=1/param.fb;

241

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

241

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

242

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

242

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

243

factor_3db=0.473037;

243

factor_3db=0.473037;

244

param.fb_BT_cutoff=factor_3db*param.f_r;

244

param.fb_BT_cutoff=factor_3db*param.f_r;

245

param.fb_BW_cutoff=param.f_r;

245

param.fb_BW_cutoff=param.f_r;

246

param.Tx_rd_sel=1;

246

param.Tx_rd_sel=1;

247

param.Rx_rd_sel=2;

247

param.Rx_rd_sel=2;

248

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

248

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

249

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

249

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

250

end

250

end

251

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

251

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

252

param=parameter_size_adjustment(param,OP);

252

param=parameter_size_adjustment(param,OP);

253

253

254

%% get input models

254

%% get input models

255

param.FLAG.S2P=0;

255

param.FLAG.S2P=0;

256

if OP.TDMODE

256

if OP.TDMODE

257

OP.FIXTURE_CALIBRATION= 0;

257

OP.FIXTURE_CALIBRATION= 0;

258

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

258

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

259

else

259

else

260

OP.FIXTURE_CALIBRATION= 0;

260

OP.FIXTURE_CALIBRATION= 0;

261

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

261

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

262

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

262

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

263

param.FLAG.S2P=1;

263

param.FLAG.S2P=1;

264

end

264

end

265

end

265

end

266

266

267

OP.SAVE_CMD_STR=1;

267

OP.SAVE_CMD_STR=1;

268

if OP.SAVE_CMD_STR

268

if OP.SAVE_CMD_STR

269

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

269

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

270

setappdata(0,'cmd_str',cmd_str);

270

setappdata(0,'cmd_str',cmd_str);

271

end

271

end

272

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

272

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

273

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

273

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

274

COM = inf;

274

COM = inf;

275

min_COM=inf; % reset COM prior to calibration

275

min_COM=inf; % reset COM prior to calibration

276

% min_VEO = inf;

276

% min_VEO = inf;

277

min_VEO_mV = inf;

277

min_VEO_mV = inf;

278

max_VEC_dB = -inf;

278

max_VEC_dB = -inf;

279

threshold_DER=inf;

279

threshold_DER=inf;

280

% begin yasuo patch 3/18/2019

280

% begin yasuo patch 3/18/2019

281

threshold_DER_max = 0; % reset worst DER

281

threshold_DER_max = 0; % reset worst DER

282

% end yasuo patch

282

% end yasuo patch

283

sigma_bn=0;

283

sigma_bn=0;

284

DO_ONCE=true;

284

DO_ONCE=true;

285

low_COM_found = 0;

285

low_COM_found = 0;

286

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

286

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

287

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

287

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

288

if ~DO_ONCE

288

if ~DO_ONCE

289

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

289

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

290

break;

290

break;

291

elseif min_COM > param.pass_threshold

291

elseif min_COM > param.pass_threshold

292

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

292

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

293

if low_COM_found

293

if low_COM_found

294

if OP.sigma_bn_STEP>0 % previous increase too small

294

if OP.sigma_bn_STEP>0 % previous increase too small

295

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

295

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

296

else % previously decrease too large

296

else % previously decrease too large

297

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

297

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

298

end

298

end

299

end

299

end

300

else % binary searchparam.Pkg_len_TX

300

else % binary searchparam.Pkg_len_TX

301

low_COM_found=1;

301

low_COM_found=1;

302

if OP.sigma_bn_STEP>0 % previous increase too large

302

if OP.sigma_bn_STEP>0 % previous increase too large

303

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

303

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

304

else % previously decrease too small

304

else % previously decrease too small

305

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

305

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

306

end

306

end

307

end

307

end

308

min_COM = inf; % ignore previous iterations

308

min_COM = inf; % ignore previous iterations

309

min_VEO_mV = inf;

309

min_VEO_mV = inf;

310

max_VEC_dB = -inf;

310

max_VEC_dB = -inf;

311

sigma_bn = sigma_bn + OP.sigma_bn_STEP;

311

sigma_bn = sigma_bn + OP.sigma_bn_STEP;

312

end

312

end

313

msgctr=1;

313

msgctr=1;

314

for package_testcase_i = 1:length(OP.pkg_len_select)

314

for package_testcase_i = 1:length(OP.pkg_len_select)

315

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

315

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

316

package_testcase=OP.pkg_len_select(package_testcase_i);

316

package_testcase=OP.pkg_len_select(package_testcase_i);

317

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

317

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

318

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

318

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

319

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

319

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

320

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

320

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

321

param.AC_CM_RMS_TX= param.AC_CM_RMS(package_testcase);

321

param.AC_CM_RMS_TX= param.AC_CM_RMS(package_testcase);

322

if param.PKG_Tx_FFE_preset ~=0

322

if param.PKG_Tx_FFE_preset ~=0

323

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

323

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

324

else

324

else

325

param.Pkg_TXFFE_preset=0;

325

param.Pkg_TXFFE_preset=0;

326

end

326

end

327

% ki=package_testcase;

327

% ki=package_testcase;

328

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

328

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

329

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

329

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

330

param.Pkg_Zc= param.pkg_Z_c;

330

param.Pkg_Zc= param.pkg_Z_c;

331

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

331

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

332

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

332

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

333

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

333

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

334

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

334

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

335

end

335

end

336

param.package_testcase_i = package_testcase_i;

336

param.package_testcase_i = package_testcase_i;

337

337

338

%% Fill in chdata

338

%% Fill in chdata

339

if OP.TDMODE

339

if OP.TDMODE

340

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

340

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

341

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

341

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

342

else

342

else

343

%fill in chada with s-parameters

343

%fill in chada with s-parameters

344

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

344

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

345

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

345

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

346

end

346

end

347

if OP.BREAD_CRUMBS

347

if OP.BREAD_CRUMBS

348

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

348

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

349

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

349

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

350

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

350

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

351

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

351

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

352

end

352

end

353

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

353

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

354

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

354

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

355

end

355

end

356

end

356

end

357

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

357

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

358

358

359

%% Process TDR & ERL

359

%% Process TDR & ERL

360

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

360

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

361

if OP.ERL_ONLY

361

if OP.ERL_ONLY

362

results = cell(1);

362

results = cell(1);

363

results{1} = output_args;

363

results{1} = output_args;

364

rt=toc(t0);

364

rt=toc(t0);

365

output_args.rtmin=rt/60;

365

output_args.rtmin=rt/60;

366

if 1

366

if 1

367

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

367

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

368

end

368

end

369

if OP.CSV_REPORT ==1

369

if OP.CSV_REPORT ==1

370

Write_CSV(output_args,CSV_FILE);

370

Write_CSV(output_args,CSV_FILE);

371

end

371

end

372

break;

372

break;

373

end

373

end

374

374

375

%% FD processing s-parameter

375

%% FD processing s-parameter

376

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

376

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

377

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

377

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

378

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

378

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

379

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

379

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

380

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

380

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

381

%most operations now wrapped into FD_Processing function

381

%most operations now wrapped into FD_Processing function

382

param.number_of_s4p_files=length(chdata);

382

param.number_of_s4p_files=length(chdata);

383

%ICN=0;

383

%ICN=0;

384

output_args.ICN_mV=0;

384

output_args.ICN_mV=0;

385

output_args.MDNEXT_ICN_92_46_mV=0;

385

output_args.MDNEXT_ICN_92_46_mV=0;

386

output_args.MDFEXT_ICN_92_47_mV=0;

386

output_args.MDFEXT_ICN_92_47_mV=0;

387

if OP.WC_PORTZ

387

if OP.WC_PORTZ

388

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

388

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

389

else

389

else

390

param.SNR_TX=param.SNDR(package_testcase);

390

param.SNR_TX=param.SNDR(package_testcase);

391

end

391

end

392

392

393

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

393

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

394

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

394

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

395

395

396

%% Convert from Frequency Domain to Time Domain

396

%% Convert from Frequency Domain to Time Domain

397

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

397

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

398

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

398

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

399

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

399

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

400

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

400

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

401

if DO_ONCE

401

if DO_ONCE

402

if ~OP.TDMODE

402

if ~OP.TDMODE

403

chdata=COM_FD_to_TD(chdata,param,OP);

403

chdata=COM_FD_to_TD(chdata,param,OP);

404

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

404

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

405

output_args.SCMR_dB=chdata(1).SCMR;

405

output_args.SCMR_dB=chdata(1).SCMR;

406

end

406

end

407

end

407

end

408

408

409

%% Determine equalization settings

409

%% Determine equalization settings

410

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

410

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

411

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

411

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

412

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

412

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

413

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

413

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

414

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

414

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

415

do_C2M=0;

415

do_C2M=0;

416

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

416

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

417

do_C2M=1;

417

do_C2M=1;

418

end

418

end

419

OP.COMPUTE_COM=false;

420

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

419

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

421

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

420

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

422

OP.COMPUTE_COM=true;

421

423

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

422

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

424

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

423

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

425

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

424

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

426

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

425

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

427

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

426

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

428

429

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

427

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

430

param.use_bmax=fom_result.best_bmax.';

428

param.use_bmax=fom_result.best_bmax.';

431

%AJG021820

429

%AJG021820

432

param.use_bmin=fom_result.best_bmin.';

430

param.use_bmin=fom_result.best_bmin.';

433

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

431

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

434

param.current_ffegain=fom_result.best_current_ffegain;

432

param.current_ffegain=fom_result.best_current_ffegain;

435

if OP.force_pdf_bin_size

433

if OP.force_pdf_bin_size

436

param.delta_y = OP.BinSize;

434

param.delta_y = OP.BinSize;

437

else

435

else

438

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

436

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

439

end

437

end

440

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

438

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

441

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

439

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

442

440

443

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

441

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

+442

444

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

443

PSD_results=[];

445

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

444

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

446

OP.WO_TXFFE=1;

445

OP.WO_TXFFE=1;

447

PSD_results.w=fom_result.RxFFE;

448

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

446

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

449

% well as CTLE (CTF) and tx FFE

450

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

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

447

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

452

OP.WO_TXFFE=0;

448

OP.WO_TXFFE=0;

453

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

454

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

455

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

456

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

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

449

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

458

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

450

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

459

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

460

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

451

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

461

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

452

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

462

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

453

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

463

end

454

end

464

%% Create ISI PDF & Individual Crosstalk PDFs

455

%% Create ISI PDF & Individual Crosstalk PDFs

465

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

456

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

466

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

457

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

467

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

458

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

468

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

459

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

469

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

460

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

470

for i=1:param.number_of_s4p_files

461

for i=1:param.number_of_s4p_files

471

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

462

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

472

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

463

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

473

464

474

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

465

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

475

else

466

else

476

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

467

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

477

end

468

end

478

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

469

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

479

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

470

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

480

subplot(2,1,2);

471

subplot(2,1,2);

481

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

472

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

482

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

473

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

483

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

474

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

484

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

475

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

485

hold on; title('PDF')

476

hold on; title('PDF')

486

recolor_plots(gca);

477

recolor_plots(gca);

487

end

478

end

488

479

489

chdata(i).pdfr=pdf;

480

chdata(i).pdfr=pdf;

490

% reporting

481

% reporting

491

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

482

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

492

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

483

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

493

484

494

end

485

end

495

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

486

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

496

487

497

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

488

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

498

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

489

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

499

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

490

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

500

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

491

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

501

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

492

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

502

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

493

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

503

combined_interference_and_noise_pdf=PDF;

494

combined_interference_and_noise_pdf=PDF;

504

combined_interference_and_noise_cdf=CDF;

495

combined_interference_and_noise_cdf=CDF;

505

496

506

497

507

%% Calculate COM and other associated outputs

498

%% Calculate COM and other associated outputs

508

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

499

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

509

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

500

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

510

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

501

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

511

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

502

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

512

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

503

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

513

% that satisfies the relationship P(y0) = DER_0

504

% that satisfies the relationship P(y0) = DER_0

514

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

505

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

515

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

506

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

516

507

517

% begin yasuo patch 3/18/2019

508

% begin yasuo patch 3/18/2019

518

% estimate DER at threshold COM

509

% estimate DER at threshold COM

519

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

510

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

520

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

511

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

521

threshold_DER_max = max(threshold_DER_max, threshold_DER);

512

threshold_DER_max = max(threshold_DER_max, threshold_DER);

522

% end yasuo patch

513

% end yasuo patch

523

514

524

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

515

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

525

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

516

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

526

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

517

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

527

if OP.DISPLAY_WINDOW && OP.DEBUG

518

if OP.DISPLAY_WINDOW && OP.DEBUG

528

figure_name = 'Eye at DER0 estimate';

519

figure_name = 'Eye at DER0 estimate';

529

fig=findobj('Name', figure_name);

520

fig=findobj('Name', figure_name);

530

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

521

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

531

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

522

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

532

movegui(fig,'southwest')

523

movegui(fig,'southwest')

533

plot(eye_contour)

524

plot(eye_contour)

534

xlabel('UI %')

525

xlabel('UI %')

535

ylabel('V')

526

ylabel('V')

536

end

527

end

537

528

538

else

529

else

539

EW_UI=0;

530

EW_UI=0;

540

eye_contour=[];

531

eye_contour=[];

541

end

532

end

542

if OP.MLSE==0

533

if OP.MLSE==0

543

if param.T_O ~=0

534

if param.T_O ~=0

544

eye_opening=EH_T_C2M-EH_B_C2M;

535

eye_opening=EH_T_C2M-EH_B_C2M;

545

A_ni=2*A_s-eye_opening;

536

A_ni=2*A_s-eye_opening;

546

%eq 124E-4

537

%eq 124E-4

547

vec_arg=2*A_s/eye_opening;

538

vec_arg=2*A_s/eye_opening;

548

if vec_arg<eps

539

if vec_arg<eps

549

vec_arg=eps;

540

vec_arg=eps;

550

end

541

end

551

VEC_dB = 20*log10(vec_arg);

542

VEC_dB = 20*log10(vec_arg);

552

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

543

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

553

VEO_mV=eye_opening*1000;

544

VEO_mV=eye_opening*1000;

554

min_COM = min(min_COM, COM);

545

min_COM = min(min_COM, COM);

555

min_VEO_mV = min(min_VEO_mV,VEO_mV);

546

min_VEO_mV = min(min_VEO_mV,VEO_mV);

556

max_VEC_dB = max(max_VEC_dB, VEC_dB);

547

max_VEC_dB = max(max_VEC_dB, VEC_dB);

557

else

548

else

558

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

549

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

559

vec_arg=(A_s-A_ni)/A_s;

550

vec_arg=(A_s-A_ni)/A_s;

560

if vec_arg<eps

551

if vec_arg<eps

561

vec_arg=eps;

552

vec_arg=eps;

562

end

553

end

563

VEC_dB = -20*log10(vec_arg);

554

VEC_dB = -20*log10(vec_arg);

564

COM=20*log10(A_s/A_ni);

555

COM=20*log10(A_s/A_ni);

565

min_COM = min(min_COM, COM);

556

min_COM = min(min_COM, COM);

566

min_VEO_mV = min(min_VEO_mV,VEO_mV);

557

min_VEO_mV = min(min_VEO_mV,VEO_mV);

567

max_VEC_dB = max(max_VEC_dB, VEC_dB);

558

max_VEC_dB = max(max_VEC_dB, VEC_dB);

568

end

559

end

569

MLSE_results=struct;

560

MLSE_results=struct;

570

else % MLSE case added U3 option

561

else % MLSE case added U3 option

571

if OP.MLSE==1

562

if OP.MLSE==1

572

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

563

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

573

elseif OP.MLSE==2

564

elseif OP.MLSE==2

574

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

565

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

575

elseif OP.MLSE==3

566

elseif OP.MLSE==3

576

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

567

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

577

else

568

else

578

warning('unsuported MLSE option')

569

warning('unsuported MLSE option')

579

end

570

end

580

if param.T_O ~=0

571

if param.T_O ~=0

581

eye_opening=EH_T_C2M-EH_B_C2M;

572

eye_opening=EH_T_C2M-EH_B_C2M;

582

A_ni=2*A_s-eye_opening;

573

A_ni=2*A_s-eye_opening;

583

%eq 124E-4

574

%eq 124E-4

584

vec_arg=2*A_s/eye_opening;

575

vec_arg=2*A_s/eye_opening;

585

if vec_arg<eps

576

if vec_arg<eps

586

vec_arg=eps;

577

vec_arg=eps;

587

end

578

end

588

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

579

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

589

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

580

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

590

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

581

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

591

COM=MLSE_results.COM_CDF;

582

COM=MLSE_results.COM_CDF;

592

VEO_mV=eye_opening*1000;

583

VEO_mV=eye_opening*1000;

593

min_COM = min(min_COM, COM);

584

min_COM = min(min_COM, COM);

594

min_VEO_mV = min(min_VEO_mV,VEO_mV);

585

min_VEO_mV = min(min_VEO_mV,VEO_mV);

595

max_VEC_dB = max(max_VEC_dB, VEC_dB);

586

max_VEC_dB = max(max_VEC_dB, VEC_dB);

596

output_args.delta_COM=MLSE_results.delta_com_CDF;

587

output_args.delta_COM=MLSE_results.delta_com_CDF;

597

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

588

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

598

else

589

else

599

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

590

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

600

vec_arg=(A_s-A_ni)/A_s;

591

vec_arg=(A_s-A_ni)/A_s;

601

if vec_arg<eps

592

if vec_arg<eps

602

vec_arg=eps;

593

vec_arg=eps;

603

end

594

end

604

VEC_dB_orig = -20*log10(vec_arg);

595

VEC_dB_orig = -20*log10(vec_arg);

605

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

596

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

606

COM_orig=20*log10(A_s/A_ni);

597

COM_orig=20*log10(A_s/A_ni);

607

COM=MLSE_results.COM_CDF;

598

COM=MLSE_results.COM_CDF;

608

min_COM = min(min_COM, COM);

599

min_COM = min(min_COM, COM);

609

min_VEO_mV = min(min_VEO_mV,VEO_mV);

600

min_VEO_mV = min(min_VEO_mV,VEO_mV);

610

max_VEC_dB = max(max_VEC_dB, VEC_dB);

601

max_VEC_dB = max(max_VEC_dB, VEC_dB);

611

output_args.delta_COM=MLSE_results.delta_com_CDF;

602

output_args.delta_COM=MLSE_results.delta_com_CDF;

612

end

603

end

613

end

604

end

614

605

615

%% Create COM_SNR_Struct to hold the main COM outputs

606

%% Create COM_SNR_Struct to hold the main COM outputs

616

COM_SNR_Struct.A_s=A_s;

607

COM_SNR_Struct.A_s=A_s;

617

COM_SNR_Struct.A_ni=A_ni;

608

COM_SNR_Struct.A_ni=A_ni;

618

COM_SNR_Struct.threshold_DER=threshold_DER;

609

COM_SNR_Struct.threshold_DER=threshold_DER;

619

COM_SNR_Struct.EW_UI=EW_UI;

610

COM_SNR_Struct.EW_UI=EW_UI;

620

COM_SNR_Struct.COM=COM;

611

COM_SNR_Struct.COM=COM;

621

COM_SNR_Struct.VEC_dB=VEC_dB;

612

COM_SNR_Struct.VEC_dB=VEC_dB;

622

if OP.MLSE == 0

613

if OP.MLSE == 0

623

COM_SNR_Struct.COM_orig=[];

614

COM_SNR_Struct.COM_orig=[];

624

COM_SNR_Struct.VEC_dB_orig=[];

615

COM_SNR_Struct.VEC_dB_orig=[];

625

else

616

else

626

COM_SNR_Struct.COM_orig=COM_orig;

617

COM_SNR_Struct.COM_orig=COM_orig;

627

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

618

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

628

end

619

end

629

COM_SNR_Struct.VEO_mV=VEO_mV;

620

COM_SNR_Struct.VEO_mV=VEO_mV;

630

COM_SNR_Struct.combined_interference_and_noise_pdf=combined_interference_and_noise_pdf;

621

COM_SNR_Struct.combined_interference_and_noise_pdf=combined_interference_and_noise_pdf;

631

COM_SNR_Struct.combined_interference_and_noise_cdf=combined_interference_and_noise_cdf;

622

COM_SNR_Struct.combined_interference_and_noise_cdf=combined_interference_and_noise_cdf;

632

COM_SNR_Struct.eye_contour=eye_contour;

623

COM_SNR_Struct.eye_contour=eye_contour;

633

624

634

625

635

%% Save TD

626

%% Save TD

636

if OP.SAVE_TD

627

if OP.SAVE_TD

637

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

628

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

638

if ~OP.TDMODE

629

if ~OP.TDMODE

639

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

630

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

640

end

631

end

641

for i=1:param.number_of_s4p_files

632

for i=1:param.number_of_s4p_files

642

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

633

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

643

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

634

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

644

if ~OP.TDMODE

635

if ~OP.TDMODE

645

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

636

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

646

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

637

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

647

end

638

end

648

end

639

end

649

if OP.TDMODE

640

if OP.TDMODE

650

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

641

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

651

else

642

else

652

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

643

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

653

end

644

end

654

end

645

end

655

646

656

%% Bathtub/Contribution Plot

647

%% Bathtub/Contribution Plot

657

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

648

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

658

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

649

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

659

end

650

end

660

651

661

%% Msg management

652

%% Msg management

662

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

653

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

663

msg=[];

654

msg=[];

664

end

655

end

665

if OP.DEBUG

656

if OP.DEBUG

666

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

657

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

667

switch param.flex

658

switch param.flex

668

case 4

659

case 4

669

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

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

670

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

661

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

671

);

662

);

672

case 2

663

case 2

673

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

664

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

674

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

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

675

);

666

);

676

otherwise

667

otherwise

677

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

668

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

678

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

669

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

679

);

670

);

680

671

681

end

672

end

682

else

673

else

683

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

674

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

684

end

675

end

685

676

686

if OP.TDMODE

677

if OP.TDMODE

687

min_ERL=inf;

678

min_ERL=inf;

688

ERL=[inf inf];

679

ERL=[inf inf];

689

end

680

end

690

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

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

691

682

692

683

693

%% Output Args

684

%% Output Args

694

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

685

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

695

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

686

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

696

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

687

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

697

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

688

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

698

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

689

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

699

rt=toc(t0);

690

rt=toc(t0);

700

output_args.rtmin=rt/60;

691

output_args.rtmin=rt/60;

701

692

702

if OP.BREAD_CRUMBS

693

if OP.BREAD_CRUMBS

703

output_args.OP=OP;

694

output_args.OP=OP;

704

output_args.param=param;

695

output_args.param=param;

705

output_args.chdata=chdata;

696

output_args.chdata=chdata;

706

output_args.fom_result = fom_result;

697

output_args.fom_result = fom_result;

707

output_args.PDF=PDF; % for exploration

698

output_args.PDF=PDF; % for exploration

708

output_args.CDF=CDF; % for exploration

699

output_args.CDF=CDF; % for exploration

709

output_args.MLSE_results=MLSE_results;

700

output_args.MLSE_results=MLSE_results;

710

output_args.PSD_results=PSD_results;

701

output_args.PSD_results=PSD_results;

711

end

702

end

712

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

703

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

713

704

714

%% making csv file

705

%% making csv file

715

if OP.CSV_REPORT ==1

706

if OP.CSV_REPORT ==1

716

Write_CSV(output_args,CSV_FILE);

707

Write_CSV(output_args,CSV_FILE);

717

end

708

end

718

%% making mat file

709

%% making mat file

719

if(OP.DEBUG)

710

if(OP.DEBUG)

720

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

711

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

721

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

712

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

722

end

713

end

723

if 1

714

if 1

724

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

715

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

725

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

716

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

726

end

717

end

727

718

728

if nargout==0

719

if nargout==0

729

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

720

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

730

disp(output_args)

721

disp(output_args)

731

end

722

end

732

723

733

if OP.BREAD_CRUMBS

724

if OP.BREAD_CRUMBS

734

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

725

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

735

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

726

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

736

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

727

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

737

try

728

try

738

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

729

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

739

catch

730

catch

740

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

731

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

741

end

732

end

742

end

733

end

743

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

734

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

744

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

735

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

745

end

736

end

746

737

747

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

738

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

748

end

739

end

749

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

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

750

%%

741

%%

751

742

752

if OP.RX_CALIBRATION ==1

743

if OP.RX_CALIBRATION ==1

753

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

744

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

754

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

745

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

755

end

746

end

756

DO_ONCE=false;

747

DO_ONCE=false;

757

end

748

end

758

749

759

%% Final cleanup

750

%% Final cleanup

760

if OP.DISPLAY_WINDOW

751

if OP.DISPLAY_WINDOW

761

savefigs(param, OP);

752

savefigs(param, OP);

762

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

753

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

763

end

754

end

764

755

765

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

756

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

766

if ~param.f_hp==0

757

if ~param.f_hp==0

767

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

758

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

768

if OP.DISPLAY_WINDOW

759

if OP.DISPLAY_WINDOW

769

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

760

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

770

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

761

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

771

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

762

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

772

end

763

end

773

else

764

else

774

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

765

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

775

if OP.DISPLAY_WINDOW

766

if OP.DISPLAY_WINDOW

776

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

767

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

777

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

768

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

778

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

769

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

779

end

770

end

780

end

771

end

781

end

772

end

782

773

783

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

774

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

784

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

775

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

785

disp(redo_cmd_str);

776

disp(redo_cmd_str);

786

if isdeployed

777

if isdeployed

787

if OP.exit_if_deployed

778

if OP.exit_if_deployed

788

quit

779

quit

789

end

780

end

790

end

781

end

791

%%

782

%%

792

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

783

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

793

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

784

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

794

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

785

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

795

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

786

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

796

787

797

FB=param.fb;

788

FB=param.fb;

798

FZ=param.CTLE_fz(fom_result.ctle);

789

FZ=param.CTLE_fz(fom_result.ctle);

799

FP1=param.CTLE_fp1(fom_result.ctle);

790

FP1=param.CTLE_fp1(fom_result.ctle);

800

FP2=param.CTLE_fp2(fom_result.ctle);

791

FP2=param.CTLE_fp2(fom_result.ctle);

801

GDC=param.ctle_gdc_values(fom_result.ctle);

792

GDC=param.ctle_gdc_values(fom_result.ctle);

802

if ~isempty(param.f_HP)

793

if ~isempty(param.f_HP)

803

FHP=param.f_HP(fom_result.best_G_high_pass);

794

FHP=param.f_HP(fom_result.best_G_high_pass);

804

end

795

end

805

if ~isempty(param.g_DC_HP_values)

796

if ~isempty(param.g_DC_HP_values)

806

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

797

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

807

end

798

end

808

if ~isempty(param.f_HP_Z)

799

if ~isempty(param.f_HP_Z)

809

FHPZ=param.f_HP_Z(fom_result.ctle);

800

FHPZ=param.f_HP_Z(fom_result.ctle);

810

end

801

end

811

if ~isempty(param.f_HP_P)

802

if ~isempty(param.f_HP_P)

812

FHPP=param.f_HP_P(fom_result.ctle);

803

FHPP=param.f_HP_P(fom_result.ctle);

813

end

804

end

814

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

805

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

815

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

806

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

816

%length

807

%length

817

SBR_Len=length(fom_result.sbr);

808

SBR_Len=length(fom_result.sbr);

818

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

809

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

819

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

810

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

820

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

811

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

821

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

812

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

822

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

813

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

823

end

814

end

824

for i=1:param.number_of_s4p_files

815

for i=1:param.number_of_s4p_files

825

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

816

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

826

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

817

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

827

if OP.INCLUDE_CTLE==1

818

if OP.INCLUDE_CTLE==1

828

switch param.CTLE_type

819

switch param.CTLE_type

829

case 'CL93'

820

case 'CL93'

830

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

821

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

831

case 'CL120d'

822

case 'CL120d'

832

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

823

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

833

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

824

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

834

case 'CL120e' % z has been adjusted for gain

825

case 'CL120e' % z has been adjusted for gain

835

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

826

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

836

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

827

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

837

end

828

end

838

else

829

else

839

eq_ir=uneq_ir;

830

eq_ir=uneq_ir;

840

end

831

end

841

chdata(i).eq_imp_response=eq_ir;

832

chdata(i).eq_imp_response=eq_ir;

842

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

833

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

843

834

844

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

835

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

845

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

836

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

846

end

837

end

847

% chdata(i).ctle_imp_response

838

% chdata(i).ctle_imp_response

848

if OP.RxFFE

839

if OP.RxFFE

849

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

840

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

850

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

841

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

851

end

842

end

852

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

843

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

853

end

844

end

854

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

845

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

855

end

846

end

856

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

847

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

857

848

858

% display bathtub curves in one axis per test case.

849

% display bathtub curves in one axis per test case.

859

case_number=param.package_testcase_i;

850

case_number=param.package_testcase_i;

860

if ~OP.COM_CONTRIBUTION_CURVES

851

if ~OP.COM_CONTRIBUTION_CURVES

861

figure_name = 'Voltage bathtub curves';

852

figure_name = 'Voltage bathtub curves';

862

fig=findobj('Name', figure_name);

853

fig=findobj('Name', figure_name);

863

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

854

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

864

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

855

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

865

movegui(fig,'south')

856

movegui(fig,'south')

866

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

857

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

867

plot_bathtub_curves( hax ...

858

plot_bathtub_curves( hax ...

868

, COM_SNR_Struct.A_s ...

859

, COM_SNR_Struct.A_s ...

869

, Noise_Struct.sci_pdf ...

860

, Noise_Struct.sci_pdf ...

870

, Noise_Struct.cci_pdf ...

861

, Noise_Struct.cci_pdf ...

871

, Noise_Struct.isi_and_xtalk_pdf ...

862

, Noise_Struct.isi_and_xtalk_pdf ...

872

, Noise_Struct.noise_pdf ...

863

, Noise_Struct.noise_pdf ...

873

, Noise_Struct.jitt_pdf ...

864

, Noise_Struct.jitt_pdf ...

874

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

865

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

875

, param.delta_y ...

866

, param.delta_y ...

876

);

867

);

877

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

868

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

878

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

869

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

879

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

870

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

880

% show BER target line

871

% show BER target line

881

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

872

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

882

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

873

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

883

else

874

else

884

figure_name = 'COM Contributions (Rough Allocations)';

875

figure_name = 'COM Contributions (Rough Allocations)';

885

fig=findobj('Name', figure_name);

876

fig=findobj('Name', figure_name);

886

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

877

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

887

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

878

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

888

movegui(fig,'south')

879

movegui(fig,'south')

889

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

880

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

890

881

891

plot_pie_com( hax ...

882

plot_pie_com( hax ...

892

, COM_SNR_Struct.A_s ...

883

, COM_SNR_Struct.A_s ...

893

, Noise_Struct.sci_pdf ...

884

, Noise_Struct.sci_pdf ...

894

, Noise_Struct.cci_pdf ...

885

, Noise_Struct.cci_pdf ...

895

, Noise_Struct.isi_and_xtalk_pdf ...

886

, Noise_Struct.isi_and_xtalk_pdf ...

896

, Noise_Struct.noise_pdf ...

887

, Noise_Struct.noise_pdf ...

897

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

888

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

898

, param.delta_y, param...

889

, param.delta_y, param...

899

);

890

);

900

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

891

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

901

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

892

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

902

end

893

end

903

894

904

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

895

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

905

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

896

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

906

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

897

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

907

end

898

end

908

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

899

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

909

900

910

if use_BT

901

if use_BT

911

a = bessel( param.BTorder );

902

a = bessel( param.BTorder );

912

acoef=fliplr( a );

903

acoef=fliplr( a );

913

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

904

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

914

else

905

else

915

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

906

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

916

end

907

end

917

908

918

909

919

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

910

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

920

911

921

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

912

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

922

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

913

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

923

%All subsequent lines are field names in chdata

914

%All subsequent lines are field names in chdata

924

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

915

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

925

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

916

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

926

%

917

%

927

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

918

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

928

%#reduce

919

%#reduce

929

%sdd12_raw

920

%sdd12_raw

930

%sdd21_raw

921

%sdd21_raw

931

%sdd22_raw

922

%sdd22_raw

932

%sdd11_raw

923

%sdd11_raw

933

%

924

%

934

925

935

fid=fopen(fields_file,'r');

926

fid=fopen(fields_file,'r');

936

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

927

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

937

928

938

file_data=file_data{1};

929

file_data=file_data{1};

939

fclose(fid);

930

fclose(fid);

940

931

941

%remove blank lines

932

%remove blank lines

942

L=cellfun('length',file_data);

933

L=cellfun('length',file_data);

943

file_data=file_data(L~=0);

934

file_data=file_data(L~=0);

944

935

945

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

936

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

946

type=file_data{1};

937

type=file_data{1};

947

field_names=file_data(2:end);

938

field_names=file_data(2:end);

948

switch lower(type)

939

switch lower(type)

949

case '#reduce'

940

case '#reduce'

950

remove_fields=field_names;

941

remove_fields=field_names;

951

case '#include'

942

case '#include'

952

all_fields=fieldnames(chdata);

943

all_fields=fieldnames(chdata);

953

remove_fields=setdiff(all_fields,field_names);

944

remove_fields=setdiff(all_fields,field_names);

954

otherwise

945

otherwise

955

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

946

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

956

end

947

end

957

948

958

%remove the "remove_fields" from chdata

949

%remove the "remove_fields" from chdata

959

for j=1:length(remove_fields)

950

for j=1:length(remove_fields)

960

this_field=remove_fields{j};

951

this_field=remove_fields{j};

961

if isfield(chdata,this_field)

952

if isfield(chdata,this_field)

962

chdata=rmfield(chdata,this_field);

953

chdata=rmfield(chdata,this_field);

963

end

954

end

964

end

955

end

965

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

956

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

966

957

967

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

958

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

968

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

959

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

969

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

960

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

970

961

971

A_s=COM_SNR_Struct.A_s;

962

A_s=COM_SNR_Struct.A_s;

972

% initialize loop with uncorrelated noise and BER

963

% initialize loop with uncorrelated noise and BER

973

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

964

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

974

965

975

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

966

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

976

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

967

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

977

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

968

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

978

% below target BER).

969

% below target BER).

979

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

970

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

980

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

971

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

981

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

972

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

982

if isempty(x_error_propagation)

973

if isempty(x_error_propagation)

983

p_error_propagation(1) = 1e-20;

974

p_error_propagation(1) = 1e-20;

984

else

975

else

985

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

976

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

986

end

977

end

987

978

988

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

979

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

989

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

980

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

990

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

981

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

991

if OP.use_simple_EP_model

982

if OP.use_simple_EP_model

992

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

983

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

993

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

984

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

994

else

985

else

995

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

986

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

996

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

987

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

997

end

988

end

998

989

999

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

990

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

1000

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

991

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

1001

if isempty(x_error_propagation)

992

if isempty(x_error_propagation)

1002

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

993

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

1003

else

994

else

1004

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

995

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

1005

end

996

end

1006

end

997

end

1007

998

1008

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

999

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

1009

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

1000

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

1010

% of this event by partial sum of the PDF.

1001

% of this event by partial sum of the PDF.

1011

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

1002

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

1012

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

1003

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

1013

1004

1014

% probability of bursts of different lengths

1005

% probability of bursts of different lengths

1015

p_burst = cumprod(p_error_propagation);

1006

p_burst = cumprod(p_error_propagation);

1016

function H_bw=Butterworth_Filter(param,f,use_BW)

1007

function H_bw=Butterworth_Filter(param,f,use_BW)

1017

1008

1018

if use_BW

1009

if use_BW

1019

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

1010

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

1020

else

1011

else

1021

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

1012

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

1022

end

1013

end

1023

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

1014

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

1024

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

1015

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

1025

CDF_ev=CDF(index);

1016

CDF_ev=CDF(index);

1026

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

1017

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

1027

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

1018

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

1028

if isempty(index)

1019

if isempty(index)

1029

CDF_inv_ev=PDF.x(end);

1020

CDF_inv_ev=PDF.x(end);

1030

else

1021

else

1031

CDF_inv_ev=PDF.x(index);

1022

CDF_inv_ev=PDF.x(index);

1032

end

1023

end

1033

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

1024

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

1034

1025

1035

1026

1036

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

1027

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

1037

Remember_keyword='Legacy';

1028

Remember_keyword='Legacy';

1038

OP.TDMODE=false;

1029

OP.TDMODE=false;

1039

OP.GET_FD=true;

1030

OP.GET_FD=true;

1040

OP.CONFIG2MAT_ONLY=false;

1031

OP.CONFIG2MAT_ONLY=false;

1041

config_file='';

1032

config_file='';

1042

num_fext=[];

1033

num_fext=[];

1043

num_next=[];

1034

num_next=[];

1044

if ~isempty(varargin)

1035

if ~isempty(varargin)

1045

if ~ischar(varargin{1})

1036

if ~ischar(varargin{1})

1046

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

1037

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

1047

end

1038

end

1048

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

1039

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

1049

if isempty(keyword_idx)

1040

if isempty(keyword_idx)

1050

%Legacy Mode

1041

%Legacy Mode

1051

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

1042

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

1052

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

1043

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

1053

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

1044

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

1054

else

1045

else

1055

%Keyword Mode

1046

%Keyword Mode

1056

my_keyword=varargin{1};

1047

my_keyword=varargin{1};

1057

Remember_keyword=my_keyword;

1048

Remember_keyword=my_keyword;

1058

varargin(1)=[];

1049

varargin(1)=[];

1059

switch my_keyword

1050

switch my_keyword

1060

1051

1061

case 'Legacy'

1052

case 'Legacy'

1062

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

1053

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

1063

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

1054

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

1064

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

1055

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

1065

case 'TD'

1056

case 'TD'

1066

OP.TDMODE=true;

1057

OP.TDMODE=true;

1067

OP.GET_FD=false;

1058

OP.GET_FD=false;

1068

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

1059

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

1069

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

1060

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

1070

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

1061

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

1071

case 'Config2Mat'

1062

case 'Config2Mat'

1072

OP.CONFIG2MAT_ONLY=true;

1063

OP.CONFIG2MAT_ONLY=true;

1073

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

1064

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

1074

end

1065

end

1075

end

1066

end

1076

end

1067

end

1077

function chdata=COM_FD_to_TD(chdata,param,OP)

1068

function chdata=COM_FD_to_TD(chdata,param,OP)

1078

1069

1079

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

1070

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

1080

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

1071

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

1081

case_number=param.package_testcase_i;

1072

case_number=param.package_testcase_i;

1082

for i=1:param.number_of_s4p_files

1073

for i=1:param.number_of_s4p_files

1083

% RIM 2-01-2023 moved to FD_Processing

1074

% RIM 2-01-2023 moved to FD_Processing

1084

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1075

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1085

% % Equation 93A-20 %%

1076

% % Equation 93A-20 %%

1086

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

1077

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

1087

% f=chdata(i).faxis;

1078

% f=chdata(i).faxis;

1088

% %

1079

% %

1089

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

1080

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

1090

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

1081

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

1091

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

1082

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

1092

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

1083

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

1093

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

1084

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

1094

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

1085

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

1095

% if OP.DISPLAY_WINDOW

1086

% if OP.DISPLAY_WINDOW

1096

% if i==1

1087

% if i==1

1097

% figure(300+param.package_testcase_i);

1088

% figure(300+param.package_testcase_i);

1098

% subplot(3,1,1)

1089

% subplot(3,1,1)

1099

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

1090

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

1100

% try

1091

% try

1101

% legend('NumColumns',2)

1092

% legend('NumColumns',2)

1102

% legend('location','south')

1093

% legend('location','south')

1103

% catch

1094

% catch

1104

% end

1095

% end

1105

% end

1096

% end

1106

% end

1097

% end

1107

% end

1098

% end

1108

[chdata(i).uneq_imp_response, ...

1099

[chdata(i).uneq_imp_response, ...

1109

chdata(i).t, ...

1100

chdata(i).t, ...

1110

chdata(i).causality_correction_dB, ...

1101

chdata(i).causality_correction_dB, ...

1111

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

1102

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

1112

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

1103

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

1113

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

1104

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

1114

[chdata(i).uneq_CD_imp_response, ...

1105

[chdata(i).uneq_CD_imp_response, ...

1115

chdata(i).t_DC, ...

1106

chdata(i).t_DC, ...

1116

chdata(i).causality_correction_DC_dB, ...

1107

chdata(i).causality_correction_DC_dB, ...

1117

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

1108

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

1118

end

1109

end

1119

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

1110

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

1120

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

1111

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

1121

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

1112

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

1122

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

1113

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

1123

1114

1124

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

1115

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

1125

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

1116

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

1126

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

1117

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

1127

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

1118

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

1128

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

1119

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

1129

rss=-inf;

1120

rss=-inf;

1130

for im=1:param.samples_per_ui

1121

for im=1:param.samples_per_ui

1131

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

1122

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

1132

end

1123

end

1133

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

1124

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

1134

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

1125

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

1135

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

1126

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

1136

end

1127

end

1137

if OP.DEBUG && OP.DISPLAY_WINDOW

1128

if OP.DEBUG && OP.DISPLAY_WINDOW

1138

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1129

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1139

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

1130

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

1140

screen_size=get(0,'ScreenSize');

1131

screen_size=get(0,'ScreenSize');

1141

pos = get(gcf, 'OuterPosition');

1132

pos = get(gcf, 'OuterPosition');

1142

set(gcf, 'OuterPosition', ...

1133

set(gcf, 'OuterPosition', ...

1143

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

1134

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

1144

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

1135

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

1145

%movegui(gcf,'northeast')

1136

%movegui(gcf,'northeast')

1146

1137

1147

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

1138

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

1148

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

1139

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

1149

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

1140

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

1150

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

1141

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

1151

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

1142

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

1152

end

1143

end

1153

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

1144

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

1154

% scale. thru is shown in another plot.

1145

% scale. thru is shown in another plot.

1155

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

1146

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

1156

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

1147

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

1157

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

1148

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

1158

end

1149

end

1159

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

1150

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

1160

ylabel('Volts')

1151

ylabel('Volts')

1161

xlabel('seconds')

1152

xlabel('seconds')

1162

1153

1163

recolor_plots(gca);

1154

recolor_plots(gca);

1164

else

1155

else

1165

if param.ndfe~=0

1156

if param.ndfe~=0

1166

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

1157

fprintf('%s\tUnequalized pulse peak = %.1f mV\n', chdata(i).base, 1000*max(abs(chdata(i).uneq_pulse_response)));

1167

end

1158

end

1168

end

1159

end

1169

1160

1170

fprintf('%s\tCausality correction = %.1f dB', chdata(i).base, chdata(i).causality_correction_dB);

1161

fprintf('%s\tCausality correction = %.1f dB', chdata(i).base, chdata(i).causality_correction_dB);

1171

if OP.ENFORCE_CAUSALITY

1162

if OP.ENFORCE_CAUSALITY

1172

fprintf('\n');

1163

fprintf('\n');

1173

else

1164

else

1174

fprintf(' (not applied)\n');

1165

fprintf(' (not applied)\n');

1175

end

1166

end

1176

fprintf('%s\tTruncation ratio = %.1f dB\n', chdata(i).base, chdata(i).truncation_dB);

1167

fprintf('%s\tTruncation ratio = %.1f dB\n', chdata(i).base, chdata(i).truncation_dB);

1177

1168

1178

end

1169

end

1179

function [Left_EW,Right_EW,eye_contour,out_VT,out_VB]=COM_eye_width(chdata,delta_y,fom_result,param,OP,Struct_Noise,pdf_range_flag)

1170

function [Left_EW,Right_EW,eye_contour,out_VT,out_VB]=COM_eye_width(chdata,delta_y,fom_result,param,OP,Struct_Noise,pdf_range_flag)

1180

1171

1181

1172

1182

debug_plot=0;

1173

debug_plot=0;

1183

1174

1184

1175

1185

samp_UI=param.samples_for_C2M;

1176

samp_UI=param.samples_for_C2M;

1186

half_UI=get_center_of_UI(samp_UI);

1177

half_UI=get_center_of_UI(samp_UI);

1187

T_O=floor((param.T_O/1000)*param.samples_for_C2M);

1178

T_O=floor((param.T_O/1000)*param.samples_for_C2M);

1188

start_sample=half_UI-T_O;

1179

start_sample=half_UI-T_O;

1189

end_sample=half_UI+T_O;

1180

end_sample=half_UI+T_O;

1190

1181

1191

1182

1192

%pdf_range is a placeholder to allow fractional UI calculation for optimize

1183

%pdf_range is a placeholder to allow fractional UI calculation for optimize

1193

%C2M speedup. For regular COM_eye_width calls, pdf_range will be empty

1184

%C2M speedup. For regular COM_eye_width calls, pdf_range will be empty

1194

%which will force pdf_range=1:samp_UI for stanard full UI calculation.

1185

%which will force pdf_range=1:samp_UI for stanard full UI calculation.

1195

if pdf_range_flag

1186

if pdf_range_flag

1196

pdf_range=[start_sample end_sample];

1187

pdf_range=[start_sample end_sample];

1197

else

1188

else

1198

pdf_range=[];

1189

pdf_range=[];

1199

end

1190

end

1200

1191

1201

%pdf_full is self ISI pdf for each sample point

1192

%pdf_full is self ISI pdf for each sample point

1202

%h_j_full is the v/t calculation for each sample point

1193

%h_j_full is the v/t calculation for each sample point

1203

%the center vector for each should be identical to the standard COM variables

1194

%the center vector for each should be identical to the standard COM variables

1204

[pdf_full_1,h_j_full,A_s_vec] = get_pdf_full(chdata(1), delta_y, fom_result.t_s, param, OP,pdf_range) ;

1195

[pdf_full_1,h_j_full,A_s_vec] = get_pdf_full(chdata(1), delta_y, fom_result.t_s, param, OP,pdf_range) ;

1205

1196

1206

1197

1207

1198

1208

if isempty(pdf_range)

1199

if isempty(pdf_range)

1209

pdf_range=1:samp_UI;

1200

pdf_range=1:samp_UI;

1210

else

1201

else

1211

pdf_range=min(pdf_range):max(pdf_range);

1202

pdf_range=min(pdf_range):max(pdf_range);

1212

end

1203

end

1213

1204

1214

%Test doing Level PDFs

1205

%Test doing Level PDFs

1215

Levels = 2*(0:param.levels-1)/(param.levels-1)-1;

1206

Levels = 2*(0:param.levels-1)/(param.levels-1)-1;

1216

%A_s_vec=A_s_vec*(param.levels-1)/param.R_LM;

1207

%A_s_vec=A_s_vec*(param.levels-1)/param.R_LM;

1217

A_s_vec=A_s_vec*(param.levels-1);

1208

A_s_vec=A_s_vec*(param.levels-1);

1218

1209

1219

%add signal vector into pdf

1210

%add signal vector into pdf

1220

for n=1:param.levels

1211

for n=1:param.levels

1221

pdf_full{n}=pdf_full_1;

1212

pdf_full{n}=pdf_full_1;

1222

for j=pdf_range

1213

for j=pdf_range

1223

pdf_full{n}(j).x=pdf_full{n}(j).x+A_s_vec(j)*Levels(n);

1214

pdf_full{n}(j).x=pdf_full{n}(j).x+A_s_vec(j)*Levels(n);

1224

pdf_full{n}(j).Min=pdf_full{n}(j).x(1)/pdf_full{n}(j).BinSize;

1215

pdf_full{n}(j).Min=pdf_full{n}(j).x(1)/pdf_full{n}(j).BinSize;

1225

end

1216

end

1226

end

1217

end

1227

1218

1228

1219

1229

% figure;

1220

% figure;

1230

% hold on;

1221

% hold on;

1231

%This loop builds the same PDF/CDF structures from regular COM, but it is

1222

%This loop builds the same PDF/CDF structures from regular COM, but it is

1232

%computed for every sample point

1223

%computed for every sample point

1233

for n=1:param.levels

1224

for n=1:param.levels

1234

for j=pdf_range

1225

for j=pdf_range

1235

sigma_G_full(j) = norm([param.sigma_RJ*param.sigma_X*norm(h_j_full(:,j)), Struct_Noise.sigma_N, Struct_Noise.sigma_TX]);

1226

sigma_G_full(j) = norm([param.sigma_RJ*param.sigma_X*norm(h_j_full(:,j)), Struct_Noise.sigma_N, Struct_Noise.sigma_TX]);

1236

gaussian_noise_pdf_full(j) = normal_dist(sigma_G_full(j), Struct_Noise.ber_q, delta_y);

1227

gaussian_noise_pdf_full(j) = normal_dist(sigma_G_full(j), Struct_Noise.ber_q, delta_y);

1237

gaussian_noise_pdf_full(j) = conv_fct(gaussian_noise_pdf_full(j), Struct_Noise.ne_noise_pdf);

1228

gaussian_noise_pdf_full(j) = conv_fct(gaussian_noise_pdf_full(j), Struct_Noise.ne_noise_pdf);

1238

p_DD_full(j) = get_pdf_from_sampled_signal(param.A_DD*h_j_full(:,j), param.levels, delta_y);

1229

p_DD_full(j) = get_pdf_from_sampled_signal(param.A_DD*h_j_full(:,j), param.levels, delta_y);

1239

noise_pdf_full(j)=conv_fct(gaussian_noise_pdf_full(j), p_DD_full(j));

1230

noise_pdf_full(j)=conv_fct(gaussian_noise_pdf_full(j), p_DD_full(j));

1240

isi_and_xtalk_pdf_full(j) = conv_fct_MeanNotZero(pdf_full{n}(j), Struct_Noise.cci_pdf);

1231

isi_and_xtalk_pdf_full(j) = conv_fct_MeanNotZero(pdf_full{n}(j), Struct_Noise.cci_pdf);

1241

% change from adam gregory to include crosstalk

1232

% change from adam gregory to include crosstalk

1242

% combined_interference_and_noise_pdf_full = conv_fct(pdf_full(j), noise_pdf_full(j));

1233

% combined_interference_and_noise_pdf_full = conv_fct(pdf_full(j), noise_pdf_full(j));

1243

combined_interference_and_noise_pdf_full{n}(j) = conv_fct_MeanNotZero(isi_and_xtalk_pdf_full(j), noise_pdf_full(j));

1234

combined_interference_and_noise_pdf_full{n}(j) = conv_fct_MeanNotZero(isi_and_xtalk_pdf_full(j), noise_pdf_full(j));

1244

1235

1245

%PDF to CDF

1236

%PDF to CDF

1246

combined_interference_and_noise_cdf_full{n}(j)=pdf_to_cdf(combined_interference_and_noise_pdf_full{n}(j));

1237

combined_interference_and_noise_cdf_full{n}(j)=pdf_to_cdf(combined_interference_and_noise_pdf_full{n}(j));

1247

1238

1248

end

1239

end

1249

end

1240

end

1250

%hold off;

1241

%hold off;

1251

1242

1252

1243

1253

%For the given BER, find the top & bottom voltage level in the CDF

1244

%For the given BER, find the top & bottom voltage level in the CDF

1254

for n=1:param.levels

1245

for n=1:param.levels

1255

A_ni_bottom{n}=zeros(1,samp_UI);

1246

A_ni_bottom{n}=zeros(1,samp_UI);

1256

A_ni_top{n}=zeros(1,samp_UI);

1247

A_ni_top{n}=zeros(1,samp_UI);

1257

for j=pdf_range

1248

for j=pdf_range

1258

[A_ni_top{n}(j),A_ni_bottom{n}(j)]=cdf_to_ber_contour(combined_interference_and_noise_cdf_full{n}(j),param.specBER);

1249

[A_ni_top{n}(j),A_ni_bottom{n}(j)]=cdf_to_ber_contour(combined_interference_and_noise_cdf_full{n}(j),param.specBER);

1259

end

1250

end

1260

end

1251

end

1261

%plot(1:samp_UI,cursor_vector-A_ni_top,1:samp_UI,-cursor_vector+A_ni_bottom)

1252

%plot(1:samp_UI,cursor_vector-A_ni_top,1:samp_UI,-cursor_vector+A_ni_bottom)

1262

1253

1263

for n=1:param.levels-1

1254

for n=1:param.levels-1

1264

eye_contour{n}(:,1)=A_ni_top{n+1};

1255

eye_contour{n}(:,1)=A_ni_top{n+1};

1265

eye_contour{n}(:,2)=A_ni_bottom{n};

1256

eye_contour{n}(:,2)=A_ni_bottom{n};

1266

end

1257

end

1267

1258

1268

1259

1269

for n=1:param.levels-1

1260

for n=1:param.levels-1

1270

%eye_contour holds the top eye in the 1st column & bottom eye in the 2nd column

1261

%eye_contour holds the top eye in the 1st column & bottom eye in the 2nd column

1271

%define vref as middle of top eye height and bottom eye height. Now

1262

%define vref as middle of top eye height and bottom eye height. Now

1272

%that all eyes are created, vref is non-zero except for middle eye

1263

%that all eyes are created, vref is non-zero except for middle eye

1273

EH_top=eye_contour{n}(half_UI,1);

1264

EH_top=eye_contour{n}(half_UI,1);

1274

EH_bot=eye_contour{n}(half_UI,2);

1265

EH_bot=eye_contour{n}(half_UI,2);

1275

EH=EH_top-EH_bot;

1266

EH=EH_top-EH_bot;

1276

vref=EH_top/2+EH_bot/2;

1267

vref=EH_top/2+EH_bot/2;

1277

%This function finds left/right eye width by finding the vref crossings of

1268

%This function finds left/right eye width by finding the vref crossings of

1278

%the top and bottom eye contours

1269

%the top and bottom eye contours

1279

[Left_EW(n),Right_EW(n)]=find_eye_width(eye_contour{n},half_UI,samp_UI,vref);

1270

[Left_EW(n),Right_EW(n)]=find_eye_width(eye_contour{n},half_UI,samp_UI,vref);

1280

end

1271

end

1281

1272

1282

%For reporting to .csv, need eye contour to be a matrix instead of cell

1273

%For reporting to .csv, need eye contour to be a matrix instead of cell

1283

eye_contour_tmp=eye_contour;

1274

eye_contour_tmp=eye_contour;

1284

eye_contour=[];

1275

eye_contour=[];

1285

for n=1:param.levels-1

1276

for n=1:param.levels-1

1286

eye_contour(:,(n-1)*2+1:n*2)=eye_contour_tmp{n};

1277

eye_contour(:,(n-1)*2+1:n*2)=eye_contour_tmp{n};

1287

end

1278

end

1288

1279

1289

1280

1290

%Find VEC eye height

1281

%Find VEC eye height

1291

out_VT=[];

1282

out_VT=[];

1292

out_VB=[];

1283

out_VB=[];

1293

if param.T_O ~=0

1284

if param.T_O ~=0

1294

1285

1295

switch lower(OP.Histogram_Window_Weight)

1286

switch lower(OP.Histogram_Window_Weight)

1296

case {'gaussian' 'norm' 'normal' 'guassian'}

1287

case {'gaussian' 'norm' 'normal' 'guassian'}

1297

%build a gaussian window of weights that are multiplied by each pdf in the T_O range

1288

%build a gaussian window of weights that are multiplied by each pdf in the T_O range

1298

%Sigma = T_O/QL. Default QL=2.5. This gives a nice descent to near 0 at the edge of the window

1289

%Sigma = T_O/QL. Default QL=2.5. This gives a nice descent to near 0 at the edge of the window

1299

QL_sigma=T_O/param.QL;

1290

QL_sigma=T_O/param.QL;

1300

weights=exp(-1/2 * ([-T_O:T_O]/QL_sigma).^2);

1291

weights=exp(-1/2 * ([-T_O:T_O]/QL_sigma).^2);

1301

case 'triangle'

1292

case 'triangle'

1302

%triangle window. linear slope from 0 to 1 and back down to 0

1293

%triangle window. linear slope from 0 to 1 and back down to 0

1303

%for the weights

1294

%for the weights

1304

t_slope=1/(T_O);

1295

t_slope=1/(T_O);

1305

weights=[0:t_slope:1 1-t_slope:-t_slope:0];

1296

weights=[0:t_slope:1 1-t_slope:-t_slope:0];

1306

case 'rectangle'

1297

case 'rectangle'

1307

%default = rectangle. all weights = 1

1298

%default = rectangle. all weights = 1

1308

weights(1:2*T_O+1)=1;

1299

weights(1:2*T_O+1)=1;

1309

case 'dual_rayleigh'

1300

case 'dual_rayleigh'

1310

QL_sigma=T_O/param.QL;

1301

QL_sigma=T_O/param.QL;

1311

X=-T_O:T_O;

1302

X=-T_O:T_O;

1312

weights=(X+T_O)/QL_sigma^2.*exp(-1/2 * ((X+T_O)/QL_sigma).^2)...

1303

weights=(X+T_O)/QL_sigma^2.*exp(-1/2 * ((X+T_O)/QL_sigma).^2)...

1313

-(X-T_O)/QL_sigma^2.*exp(-1/2 * ((X-T_O)/QL_sigma).^2);

1304

-(X-T_O)/QL_sigma^2.*exp(-1/2 * ((X-T_O)/QL_sigma).^2);

1314

weights=weights/max(weights);

1305

weights=weights/max(weights);

1315

otherwise

1306

otherwise

1316

error('%s not recognized for Histogram_Window_Weight',OP.Histogram_Window_Weight)

1307

error('%s not recognized for Histogram_Window_Weight',OP.Histogram_Window_Weight)

1317

end

1308

end

1318

1309

1319

for n=1:param.levels

1310

for n=1:param.levels

1320

out_pdf{n}=[];

1311

out_pdf{n}=[];

1321

for j=start_sample:end_sample

1312

for j=start_sample:end_sample

1322

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1313

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1323

target_pdf.y=target_pdf.y*weights(j-start_sample+1);

1314

target_pdf.y=target_pdf.y*weights(j-start_sample+1);

1324

if isempty(out_pdf{n})

1315

if isempty(out_pdf{n})

1325

out_pdf{n}=target_pdf;

1316

out_pdf{n}=target_pdf;

1326

else

1317

else

1327

out_pdf{n} = combine_pdf_same_voltage_axis(out_pdf{n}, target_pdf);

1318

out_pdf{n} = combine_pdf_same_voltage_axis(out_pdf{n}, target_pdf);

1328

end

1319

end

1329

end

1320

end

1330

out_pdf{n}.y=out_pdf{n}.y/sum(out_pdf{n}.y);

1321

out_pdf{n}.y=out_pdf{n}.y/sum(out_pdf{n}.y);

1331

end

1322

end

1332

1323

1333

for n=1:param.levels

1324

for n=1:param.levels

1334

out_cdf{n}=pdf_to_cdf(out_pdf{n});

1325

out_cdf{n}=pdf_to_cdf(out_pdf{n});

1335

end

1326

end

1336

1327

1337

for n=1:param.levels

1328

for n=1:param.levels

1338

[A_ni_top_O(n),A_ni_bottom_O(n)]=cdf_to_ber_contour(out_cdf{n},param.specBER);

1329

[A_ni_top_O(n),A_ni_bottom_O(n)]=cdf_to_ber_contour(out_cdf{n},param.specBER);

1339

end

1330

end

1340

1331

1341

for n=1:param.levels-1

1332

for n=1:param.levels-1

1342

OUT_VT_L(n,1)=A_ni_top_O(n+1);

1333

OUT_VT_L(n,1)=A_ni_top_O(n+1);

1343

OUT_VT_L(n,2)=A_ni_bottom_O(n);

1334

OUT_VT_L(n,2)=A_ni_bottom_O(n);

1344

end

1335

end

1345

1336

1346

%Report the top/bottom eye height of the worst eye

1337

%Report the top/bottom eye height of the worst eye

1347

EH_VT=OUT_VT_L(:,1)-OUT_VT_L(:,2);

1338

EH_VT=OUT_VT_L(:,1)-OUT_VT_L(:,2);

1348

[mineh,min_idx]=min(EH_VT);

1339

[mineh,min_idx]=min(EH_VT);

1349

out_VT=OUT_VT_L(min_idx,1);

1340

out_VT=OUT_VT_L(min_idx,1);

1350

out_VB=OUT_VT_L(min_idx,2);

1341

out_VB=OUT_VT_L(min_idx,2);

1351

1342

1352

% CDF_Mean=mean(A_s_vec(start_sample:end_sample));

1343

% CDF_Mean=mean(A_s_vec(start_sample:end_sample));

1353

% out_VT=2*CDF_Mean-A_ni_top_O;

1344

% out_VT=2*CDF_Mean-A_ni_top_O;

1354

% out_VB=-1*A_ni_bottom_O;

1345

% out_VB=-1*A_ni_bottom_O;

1355

1346

1356

if debug_plot

1347

if debug_plot

1357

figure;

1348

figure;

1358

hold on;

1349

hold on;

1359

for j=start_sample:end_sample

1350

for j=start_sample:end_sample

1360

plot(combined_interference_and_noise_pdf_full(j).x,combined_interference_and_noise_pdf_full(j).y);

1351

plot(combined_interference_and_noise_pdf_full(j).x,combined_interference_and_noise_pdf_full(j).y);

1361

end

1352

end

1362

plot(out_pdf.x,out_pdf.y,'color','k','LineWidth',2);

1353

plot(out_pdf.x,out_pdf.y,'color','k','LineWidth',2);

1363

hold off;

1354

hold off;

1364

end

1355

end

1365

end

1356

end

1366

1357

1367

1358

1368

1359

1369

1360

1370

function [PDF,CDF,NS]=Create_Noise_PDF(A_s,param,fom_result,chdata,OP,sigma_bn,PSD_results)

1361

function [PDF,CDF,NS]=Create_Noise_PDF(A_s,param,fom_result,chdata,OP,sigma_bn,PSD_results)

1371

1362

1372

%This block was originally in main COM function but was moved here for

1363

%This block was originally in main COM function but was moved here for

1373

%cleanup. It returns the combined interference and noise PDF & CDF as well

1364

%cleanup. It returns the combined interference and noise PDF & CDF as well

1374

%as a structure "NS" that contains all the noise parameters that are used

1365

%as a structure "NS" that contains all the noise parameters that are used

1375

%in other places in COM

1366

%in other places in COM

1376

1367

1377

if OP.RX_CALIBRATION

1368

if OP.RX_CALIBRATION

1378

ctle_gain2 = (10.^(param.ctle_gdc_values(fom_result.ctle)/20) + 1i*chdata(2).faxis/param.CTLE_fz(fom_result.ctle)) ./ ...

1369

ctle_gain2 = (10.^(param.ctle_gdc_values(fom_result.ctle)/20) + 1i*chdata(2).faxis/param.CTLE_fz(fom_result.ctle)) ./ ...

1379

((1+1i*chdata(2).faxis/param.CTLE_fp1(fom_result.ctle)).*(1+1i*chdata(2).faxis/param.CTLE_fp2(fom_result.ctle)));

1370

((1+1i*chdata(2).faxis/param.CTLE_fp1(fom_result.ctle)).*(1+1i*chdata(2).faxis/param.CTLE_fp2(fom_result.ctle)));

1380

switch param.CTLE_type

1371

switch param.CTLE_type

1381

case 'CL93'

1372

case 'CL93'

1382

H_low2=1;

1373

H_low2=1;

1383

case 'CL120d' % this clause uses two gain indexes

1374

case 'CL120d' % this clause uses two gain indexes

1384

H_low2=(10.^(param.g_DC_HP_values(fom_result.best_G_high_pass)/20) + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass))./(1 + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass));

1375

H_low2=(10.^(param.g_DC_HP_values(fom_result.best_G_high_pass)/20) + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass))./(1 + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass));

1385

case 'CL120e' % Z1 has been adjusted

1376

case 'CL120e' % Z1 has been adjusted

1386

H_low2=(1 + 1i*chdata(2).faxis/f_HP_P(fom_result.ctle))./(1 + 1i*chdata(2).faxis/f_HP_Z(fom_result.ctle));

1377

H_low2=(1 + 1i*chdata(2).faxis/f_HP_P(fom_result.ctle))./(1 + 1i*chdata(2).faxis/f_HP_Z(fom_result.ctle));

1387

end

1378

end

1388

H_ctf2=H_low2.*ctle_gain2;

1379

H_ctf2=H_low2.*ctle_gain2;

1389

[ sigma_ne, NS.sigma_hp] = get_sigma_noise( H_ctf2, param, chdata, sigma_bn );

1380

[ sigma_ne, NS.sigma_hp] = get_sigma_noise( H_ctf2, param, chdata, sigma_bn );

1390

else

1381

else

1391

sigma_ne=0;

1382

sigma_ne=0;

1392

end

1383

end

1393

1384

1394

NS.sigma_N = fom_result.sigma_N; % eta zero noise

1385

NS.sigma_N = fom_result.sigma_N; % eta zero noise

1395

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

1386

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

1396

if ~OP.SNR_TXwC0

1387

if ~OP.SNR_TXwC0

1397

% Equation 93A-30 %% h0(ts0)= A_s*R_lm/(L-1)

1388

% Equation 93A-30 %% h0(ts0)= A_s*R_lm/(L-1)

1398

NS.sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx and RLM

1389

NS.sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx and RLM

1399

else

1390

else

1400

NS.sigma_TX = (param.levels-1)*A_s/fom_result.txffe(fom_result.cur) /param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx from Adee

1391

NS.sigma_TX = (param.levels-1)*A_s/fom_result.txffe(fom_result.cur) /param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx from Adee

1401

end

1392

end

1402

NS.sigma_G = norm([param.sigma_RJ*param.sigma_X*norm(fom_result.h_J), NS.sigma_N, NS.sigma_TX]);

1403

NS.sigma_rjit= param.sigma_RJ*param.sigma_X*norm(fom_result.h_J);

1404

else

1393

else

1405

NS.sigma_TX =PSD_results.S_tn_rms;

1394

NS.sigma_TX =PSD_results.tn_rms;

1406

NS.sigma_G = PSD_results.S_G_rms;

1407

NS.sigma_rjit=PSD_results.S_rj_rms ;

1408

NS.sigma_N=PSD_results.S_rn_rms ; % Commit request 4p4_8, healey_3dj_COM_01_240416

1409

end

1395

end

1410

% Equation 93A-41 %%

1396

% Equation 93A-41 %%

1411

+1397

NS.sigma_G = norm([param.sigma_RJ*param.sigma_X*norm(fom_result.h_J), NS.sigma_N, NS.sigma_TX]);

1398

NS.sigma_rjit= param.sigma_RJ*param.sigma_X*norm(fom_result.h_J);

1412

1399

1413

% Equation 93A-42 %%

1400

% Equation 93A-42 %%

1414

% number of sigmas needed depends on the required BER.

1401

% number of sigmas needed depends on the required BER.

1415

if param.Noise_Crest_Factor == 0

1402

if param.Noise_Crest_Factor == 0

1416

NS.ber_q = sqrt(2)*erfcinv(2*param.specBER);

1403

NS.ber_q = sqrt(2)*erfcinv(2*param.specBER);

1417

else

1404

else

1418

NS.ber_q=param.Noise_Crest_Factor;

1405

NS.ber_q=param.Noise_Crest_Factor;

1419

end

1406

end

1420

NS.gaussian_noise_pdf = normal_dist(NS.sigma_G, NS.ber_q, param.delta_y);

1407

NS.gaussian_noise_pdf = normal_dist(NS.sigma_G, NS.ber_q, param.delta_y);

1421

% enable overriding the Q factor of the BBN instrument.

1408

% enable overriding the Q factor of the BBN instrument.

1422

if OP.force_BBN_Q_factor

1409

if OP.force_BBN_Q_factor

1423

NS.ne_noise_pdf = normal_dist(sigma_ne, OP.BBN_Q_factor, param.delta_y);

1410

NS.ne_noise_pdf = normal_dist(sigma_ne, OP.BBN_Q_factor, param.delta_y);

1424

else

1411

else

1425

NS.ne_noise_pdf = normal_dist(sigma_ne, NS.ber_q, param.delta_y);

1412

NS.ne_noise_pdf = normal_dist(sigma_ne, NS.ber_q, param.delta_y);

1426

end

1413

end

1427

NS.gaussian_noise_pdf = conv_fct(NS.gaussian_noise_pdf, NS.ne_noise_pdf);

1414

NS.gaussian_noise_pdf = conv_fct(NS.gaussian_noise_pdf, NS.ne_noise_pdf);

1428

1415

1429

% p_DD is computed using the procedure defined in 93A.1.7.1 with h(n)=A_DD*h_J(n)

1416

% p_DD is computed using the procedure defined in 93A.1.7.1 with h(n)=A_DD*h_J(n)

1430

NS.p_DD = get_pdf_from_sampled_signal(param.A_DD*fom_result.h_J, param.levels, param.delta_y);

1417

NS.p_DD = get_pdf_from_sampled_signal(param.A_DD*fom_result.h_J, param.levels, param.delta_y);

1431

1418

1432

% Equation 93A-43 % only used for reporting bathtub curves

1419

% Equation 93A-43

1433

NS.noise_pdf=conv_fct(NS.gaussian_noise_pdf, NS.p_DD);

1420

NS.noise_pdf=conv_fct(NS.gaussian_noise_pdf, NS.p_DD);

+1421

1434

gaussian_rjitt_pdf = normal_dist(NS.sigma_rjit, NS.ber_q, param.delta_y);

1422

gaussian_rjitt_pdf = normal_dist(NS.sigma_rjit, NS.ber_q, param.delta_y);

1435

NS.jitt_pdf=conv_fct(gaussian_rjitt_pdf, NS.p_DD);

1423

NS.jitt_pdf=conv_fct(gaussian_rjitt_pdf, NS.p_DD);

1436

1424

1437

% Implementation of 93A.1.7.3 combination procedure

1425

% Implementation of 93A.1.7.3 combination procedure

1438

% (effectively Equation 93A-44) %%

1426

% (effectively Equation 93A-44) %%

1439

1427

1440

% Self-Channel Interference is thru residual result

1428

% Self-Channel Interference is thru residual result

1441

NS.sci_pdf = chdata(1).pdfr;

1429

NS.sci_pdf = chdata(1).pdfr;

1442

sci_mxi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1430

sci_mxi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1443

NS.thru_peak_interference_at_BER=abs(NS.sci_pdf.x(sci_mxi));

1431

NS.thru_peak_interference_at_BER=abs(NS.sci_pdf.x(sci_mxi));

1444

sci_msi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1432

sci_msi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1445

NS.sci_sigma=abs(NS.sci_pdf.x(sci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1433

NS.sci_sigma=abs(NS.sci_pdf.x(sci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1446

if OP.RX_CALIBRATION ==0

1434

if OP.RX_CALIBRATION ==0

1447

% Co-Channel Interference PDFs (for information only):

1435

% Co-Channel Interference PDFs (for information only):

1448

% initialize to deltas

1436

% initialize to deltas

1449

MDNEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1437

MDNEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1450

MDFEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1438

MDFEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1451

% serially convolve FEXT/NEXT PDFs

1439

% serially convolve FEXT/NEXT PDFs

1452

for k=2:param.number_of_s4p_files

1440

for k=2:param.number_of_s4p_files

1453

if isequal(chdata(k).type, 'NEXT')

1441

if isequal(chdata(k).type, 'NEXT')

1454

MDNEXT_cci_pdf = conv_fct(MDNEXT_cci_pdf, chdata(k).pdfr);

1442

MDNEXT_cci_pdf = conv_fct(MDNEXT_cci_pdf, chdata(k).pdfr);

1455

else % ... must be FEXT

1443

else % ... must be FEXT

1456

MDFEXT_cci_pdf = conv_fct(MDFEXT_cci_pdf, chdata(k).pdfr);

1444

MDFEXT_cci_pdf = conv_fct(MDFEXT_cci_pdf, chdata(k).pdfr);

1457

end

1445

end

1458

end

1446

end

1459

1447

1460

% find "peaks" of MDNEXT/MDFEXT for reporting

1448

% find "peaks" of MDNEXT/MDFEXT for reporting

1461

mdnxi=find(cumsum(MDNEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1449

mdnxi=find(cumsum(MDNEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1462

NS.MDNEXT_peak_interference=abs(MDNEXT_cci_pdf.x(mdnxi));

1450

NS.MDNEXT_peak_interference=abs(MDNEXT_cci_pdf.x(mdnxi));

1463

mdfxi=find(cumsum(MDFEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1451

mdfxi=find(cumsum(MDFEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1464

NS.MDFEXT_peak_interference=abs(MDFEXT_cci_pdf.x(mdfxi));

1452

NS.MDFEXT_peak_interference=abs(MDFEXT_cci_pdf.x(mdfxi));

1465

1453

1466

% Combined crosstalk effect

1454

% Combined crosstalk effect

1467

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1455

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1468

cci_mxi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1456

cci_mxi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1469

cci_msi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1457

cci_msi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1470

NS.cci_sigma=abs(NS.cci_pdf.x(cci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1458

NS.cci_sigma=abs(NS.cci_pdf.x(cci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1471

NS.crosstalk_peak_interference_at_BER=abs(NS.cci_pdf.x(cci_mxi));

1459

NS.crosstalk_peak_interference_at_BER=abs(NS.cci_pdf.x(cci_mxi));

1472

% combine cci and sci

1460

% combine cci and sci

1473

NS.isi_and_xtalk_pdf = conv_fct(NS.sci_pdf, NS.cci_pdf);

1461

NS.isi_and_xtalk_pdf = conv_fct(NS.sci_pdf, NS.cci_pdf);

1474

else

1462

else

1475

% for calibration there is no cci

1463

% for calibration there is no cci

1476

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1464

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1477

end

1465

end

1478

1466

1479

mxi=find(cumsum(NS.isi_and_xtalk_pdf.y)>=param.specBER, 1, 'first');

1467

mxi=find(cumsum(NS.isi_and_xtalk_pdf.y)>=param.specBER, 1, 'first');

1480

NS.peak_interference_at_BER=abs(NS.isi_and_xtalk_pdf.x(mxi));

1468

NS.peak_interference_at_BER=abs(NS.isi_and_xtalk_pdf.x(mxi));

1481

1469

1482

1470

1483

% Equation 93A-45

1471

% Equation 93A-45

1484

combined_interference_and_noise_pdf = conv_fct(NS.isi_and_xtalk_pdf, NS.noise_pdf);

1472

combined_interference_and_noise_pdf = conv_fct(NS.isi_and_xtalk_pdf, NS.noise_pdf);

1485

PDF=combined_interference_and_noise_pdf;

1473

PDF=combined_interference_and_noise_pdf;

1486

1474

1487

% Equation 93A-37

1475

% Equation 93A-37

1488

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1476

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1489

CDF=combined_interference_and_noise_cdf;

1477

CDF=combined_interference_and_noise_cdf;

1490

function [hctf] = FD_CTLE(freq, fb, f_z, f_p1, f_p2, kacdc_dB)

1478

function [hctf] = FD_CTLE(freq, fb, f_z, f_p1, f_p2, kacdc_dB)

1491

hctf = ( 10.^(kacdc_dB/20) + 1i*freq/f_z ) ./ ( (1+1i*freq/f_p1) .* (1+1i*freq/f_p2)) ;

1479

hctf = ( 10.^(kacdc_dB/20) + 1i*freq/f_z ) ./ ( (1+1i*freq/f_p1) .* (1+1i*freq/f_p2)) ;

1492

1480

1493

function [chdata,output_args]=FD_Processing(chdata,output_args,param,OP,SDDp2p,DO_ONCE)

1481

function [chdata,output_args]=FD_Processing(chdata,output_args,param,OP,SDDp2p,DO_ONCE)

1494

%This function calculates various frequency domain metrics

1482

%This function calculates various frequency domain metrics

1495

%Mainly IL_fit, FOM_ILD, ICN, ICN_Fext, and ICN_Next

1483

%Mainly IL_fit, FOM_ILD, ICN, ICN_Fext, and ICN_Next

1496

db = @(x) 20*log10(abs(x));

1484

db = @(x) 20*log10(abs(x));

1497

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1485

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1498

if OP.WC_PORTZ

1486

if OP.WC_PORTZ

1499

A_thru = param.a_thru(param.Tx_rd_sel);

1487

A_thru = param.a_thru(param.Tx_rd_sel);

1500

A_fext = param.a_fext(param.Tx_rd_sel);

1488

A_fext = param.a_fext(param.Tx_rd_sel);

1501

A_next = param.a_next(param.Tx_rd_sel);

1489

A_next = param.a_next(param.Tx_rd_sel);

1502

else

1490

else

1503

A_thru = param.a_thru(package_testcase);

1491

A_thru = param.a_thru(package_testcase);

1504

A_fext = param.a_fext(package_testcase);

1492

A_fext = param.a_fext(package_testcase);

1505

A_next = param.a_next(package_testcase);

1493

A_next = param.a_next(package_testcase);

1506

end

1494

end

1507

for i=1:param.number_of_s4p_files

1495

for i=1:param.number_of_s4p_files

1508

if isequal(chdata(i).type, 'THRU')

1496

if isequal(chdata(i).type, 'THRU')

1509

chdata(i).A=A_thru;

1497

chdata(i).A=A_thru;

1510

chdata(i).Aicn=A_thru;

1498

chdata(i).Aicn=A_thru;

1511

elseif isequal(chdata(i).type, 'FEXT')

1499

elseif isequal(chdata(i).type, 'FEXT')

1512

chdata(i).A=A_fext;

1500

chdata(i).A=A_fext;

1513

chdata(i).Aicn=param.a_icn_fext;

1501

chdata(i).Aicn=param.a_icn_fext;

1514

elseif isequal(chdata(i).type, 'NEXT')

1502

elseif isequal(chdata(i).type, 'NEXT')

1515

chdata(i).A=A_next;

1503

chdata(i).A=A_next;

1516

chdata(i).Aicn=param.a_icn_next;

1504

chdata(i).Aicn=param.a_icn_next;

1517

end

1505

end

1518

end

1506

end

1519

if OP.TDMODE

1507

if OP.TDMODE

1520

for i=1:param.number_of_s4p_files % freq delta for integration

1508

for i=1:param.number_of_s4p_files % freq delta for integration

1521

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1509

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1522

end

1510

end

1523

end

1511

end

1524

if ~DO_ONCE

1512

if ~DO_ONCE

1525

return;

1513

return;

1526

end

1514

end

1527

%Any new output_args fields set in this function should be initialized here as empty

1515

%Any new output_args fields set in this function should be initialized here as empty

1528

output_args.fitted_IL_dB_at_Fnq = [];

1516

output_args.fitted_IL_dB_at_Fnq = [];

1529

output_args.cable__assembley_loss=[];

1517

output_args.cable__assembley_loss=[];

1530

output_args.loss_with_PCB=[];

1518

output_args.loss_with_PCB=[];

1531

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1519

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1532

output_args.IL_dB_channel_only_at_Fnq=[];

1520

output_args.IL_dB_channel_only_at_Fnq=[];

1533

output_args.VTF_loss_dB_at_Fnq=[];

1521

output_args.VTF_loss_dB_at_Fnq=[];

1534

output_args.IL_db_die_to_die_at_Fnq=[];

1522

output_args.IL_db_die_to_die_at_Fnq=[];

1535

output_args.FOM_TDILN=[];

1523

output_args.FOM_TDILN=[];

1536

output_args.TD_ILN=[];

1524

output_args.TD_ILN=[];

1537

output_args.FOM_RILN=[];

1525

output_args.FOM_RILN=[];

1538

output_args.FOM_ILD=[];

1526

output_args.FOM_ILD=[];

1539

%TD_Mode is just a pass through to set the empty values and return

1527

%TD_Mode is just a pass through to set the empty values and return

1540

if ~OP.GET_FD

1528

if ~OP.GET_FD

1541

return;

1529

return;

1542

end

1530

end

1543

case_number=param.package_testcase_i;

1531

case_number=param.package_testcase_i;

1544

f2=param.f2;

1532

f2=param.f2;

1545

f1=param.f1;

1533

f1=param.f1;

1546

MDFEXT_ICN=0; MDNEXT_ICN=0;

1534

MDFEXT_ICN=0; MDNEXT_ICN=0;

1547

for i=1:param.number_of_s4p_files

1535

for i=1:param.number_of_s4p_files

1548

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1536

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1549

% Equation 93A-20 %%

1537

% Equation 93A-20 %%

1550

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(i).faxis./(param.f_r*param.fb));

1538

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(i).faxis./(param.f_r*param.fb));

1551

f=chdata(i).faxis;

1539

f=chdata(i).faxis;

1552

%

1540

%

1553

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

1541

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

1554

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

1542

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

1555

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine); % conditionally include the RCos filter for all IR conversion using COM_FD_to_TD

1543

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine); % conditionally include the RCos filter for all IR conversion using COM_FD_to_TD

1556

H_txffe= Tx_FFE_Filter(param,f,param.Pkg_TXFFE_preset); % RIM 08-18-2022 to add forced TX ffe per package case

1544

H_txffe= Tx_FFE_Filter(param,f,param.Pkg_TXFFE_preset); % RIM 08-18-2022 to add forced TX ffe per package case

1557

H_r=H_bw.*H_bt.*H_RCos.*H_txffe; % RIM 08-18-2022 to add forced TX ffe per package case

1545

H_r=H_bw.*H_bt.*H_RCos.*H_txffe; % RIM 08-18-2022 to add forced TX ffe per package case

1558

chdata(i).sdd21=chdata(i).sdd21.*H_r;

1546

chdata(i).sdd21=chdata(i).sdd21.*H_r;

1559

if OP.DISPLAY_WINDOW

1547

if OP.DISPLAY_WINDOW

1560

if i==1

1548

if i==1

1561

figure(300+param.package_testcase_i);

1549

figure(300+param.package_testcase_i);

1562

subplot(3,1,1)

1550

subplot(3,1,1)

1563

hold on

1551

hold on

1564

plot(chdata(i).faxis/1e9, 20*log10(abs(squeeze(chdata(i).sdd21))), 'k-','linewidth',2, 'Disp',sprintf('VTF (no Tx/Rx eq)')')

1552

plot(chdata(i).faxis/1e9, 20*log10(abs(squeeze(chdata(i).sdd21))), 'k-','linewidth',2, 'Disp',sprintf('VTF (no Tx/Rx eq)')')

1565

try

1553

try

1566

legend('NumColumns',2)

1554

legend('NumColumns',2)

1567

legend('location','south')

1555

legend('location','south')

1568

catch

1556

catch

1569

end

1557

end

1570

end

1558

end

1571

end

1559

end

1572

end

1560

end

1573

end

1561

end

1574

for i=1:param.number_of_s4p_files

1562

for i=1:param.number_of_s4p_files

1575

if i == 2

1563

if i == 2

1576

PSXT(1:length(chdata(i).sdd21f))=0;

1564

PSXT(1:length(chdata(i).sdd21f))=0;

1577

MDFEXT(1:length(chdata(i).sdd21f))=0;

1565

MDFEXT(1:length(chdata(i).sdd21f))=0;

1578

MDNEXT(1:length(chdata(i).sdd21f))=0;

1566

MDNEXT(1:length(chdata(i).sdd21f))=0;

1579

end

1567

end

1580

a=find(chdata(i).faxis(:)>=f2,1,'first');% RIM 01-12-21

1568

a=find(chdata(i).faxis(:)>=f2,1,'first');% RIM 01-12-21

1581

if isempty(a)

1569

if isempty(a)

1582

f2=chdata(i).faxis(end);

1570

f2=chdata(i).faxis(end);

1583

index_f2=length(chdata(i).faxis);

1571

index_f2=length(chdata(i).faxis);

1584

else

1572

else

1585

index_f2=a(1);

1573

index_f2=a(1);

1586

end

1574

end

1587

b=find(chdata(i).faxis(:)<=f1,1,'last');% RIM 01-12-21

1575

b=find(chdata(i).faxis(:)<=f1,1,'last');% RIM 01-12-21

1588

if isempty(b)

1576

if isempty(b)

1589

f1=chdata(i).faxis(1);

1577

f1=chdata(i).faxis(1);

1590

index_f1=1;

1578

index_f1=1;

1591

else

1579

else

1592

index_f1=b(1);

1580

index_f1=b(1);

1593

end

1581

end

1594

% R is the frequency dependent parameter for the sinc function use in the

1582

% R is the frequency dependent parameter for the sinc function use in the

1595

% PWF for ICN

1583

% PWF for ICN

1596

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(i).faxis;

1584

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(i).faxis;

1597

if(chdata(i).faxis(1)==0)

1585

if(chdata(i).faxis(1)==0)

1598

temp_angle(1)=1e-20;% we don't want to divide by zero

1586

temp_angle(1)=1e-20;% we don't want to divide by zero

1599

end

1587

end

1600

SINC = sin(temp_angle)./temp_angle;

1588

SINC = sin(temp_angle)./temp_angle;

1601

PWF_data=SINC.^2;

1589

PWF_data=SINC.^2;

1602

PWF_trf=(1+(chdata(i).faxis/chdata(i).ftr).^4).^-1;

1590

PWF_trf=(1+(chdata(i).faxis/chdata(i).ftr).^4).^-1;

1603

%// bw1=2.613126; bw2=3.4142136; bw3=2.613126;

1591

%// bw1=2.613126; bw2=3.4142136; bw3=2.613126;

1604

fr=param.f_r*param.fb;

1592

fr=param.f_r*param.fb;

1605

PWF_rx=(1+(chdata(i).faxis/fr).^8).^-1;

1593

PWF_rx=(1+(chdata(i).faxis/fr).^8).^-1;

1606

PWF_highpass=1;

1594

PWF_highpass=1;

1607

% Equation 93A-57 %

1595

% Equation 93A-57 %

1608

PWF=PWF_data.*PWF_trf.*PWF_rx.*PWF_highpass; % power weight function

1596

PWF=PWF_data.*PWF_trf.*PWF_rx.*PWF_highpass; % power weight function

1609

% freq delta for integration

1597

% freq delta for integration

1610

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1598

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1611

% from ba spec, this is basically ICN

1599

% from ba spec, this is basically ICN

1612

faxis_GHz = chdata(i).faxis/1e9;

1600

faxis_GHz = chdata(i).faxis/1e9;

1613

if isequal(chdata(i).type, 'THRU')

1601

if isequal(chdata(i).type, 'THRU')

1614

[ILD_magft chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2));

1602

[ILD_magft chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2));

1615

% find fitted loss values by interpolation using full data, no indexing - Adee 2022-08-28

1603

% find fitted loss values by interpolation using full data, no indexing - Adee 2022-08-28

1616

[~, chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f, chdata(i).faxis);

1604

[~, chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f, chdata(i).faxis);

1617

fit_loss = interp1(chdata(i).faxis, -chdata(i).fit_orig, 1/param.ui/2);

1605

fit_loss = interp1(chdata(i).faxis, -chdata(i).fit_orig, 1/param.ui/2);

1618

chdata(i).fit_ILatNq = fit_loss;

1606

chdata(i).fit_ILatNq = fit_loss;

1619

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1607

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1620

IL_interp = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21f)), 1/param.ui/2);

1608

IL_interp = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21f)), 1/param.ui/2);

1621

chdata(i).ILatNq = IL_interp;

1609

chdata(i).ILatNq = IL_interp;

1622

if OP.include_pcb

1610

if OP.include_pcb

1623

cable_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_orig)), 1/param.ui/2);

1611

cable_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_orig)), 1/param.ui/2);

1624

loss_with_PCB = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_raw)), 1/param.ui/2);

1612

loss_with_PCB = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_raw)), 1/param.ui/2);

1625

output_args.cable__assembley_loss=cable_loss;

1613

output_args.cable__assembley_loss=cable_loss;

1626

output_args.loss_with_PCB=loss_with_PCB;

1614

output_args.loss_with_PCB=loss_with_PCB;

1627

end

1615

end

1628

Nq_loss=chdata(i).ILatNq;

1616

Nq_loss=chdata(i).ILatNq;

1629

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1617

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1630

% time domain ref RR = complex fit pulse

1618

% time domain ref RR = complex fit pulse

1631

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1619

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1632

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1620

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1633

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1621

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1634

FOM_ILN_complex= TD_ILN.FOM;

1622

FOM_ILN_complex= TD_ILN.FOM;

1635

end

1623

end

1636

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1624

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1637

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1625

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1638

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1626

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1639

FOM_ILN_complex= TD_ILN.FOM;

1627

FOM_ILN_complex= TD_ILN.FOM;

1640

end

1628

end

1641

if OP.COMPUTE_TDILN

1629

if OP.COMPUTE_TDILN

1642

output_args.FOM_TDILN=FOM_TDILN;

1630

output_args.FOM_TDILN=FOM_TDILN;

1643

output_args.TD_ILN=TD_ILN; % struct

1631

output_args.TD_ILN=TD_ILN; % struct

1644

end

1632

end

1645

if OP.COMPUTE_RILN

1633

if OP.COMPUTE_RILN

1646

% Get RIL, RILN, and TD_RILN

1634

% Get RIL, RILN, and TD_RILN

1647

[RIL_struct]= capture_RIL_RILN(chdata);

1635

[RIL_struct]= capture_RIL_RILN(chdata);

1648

FOM_RILN=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2-1).*RIL_struct.RILN_dB(index_f1:index_f2-1)'.^2));

1636

FOM_RILN=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2-1).*RIL_struct.RILN_dB(index_f1:index_f2-1)'.^2));

1649

output_args.FOM_RILN=FOM_RILN;

1637

output_args.FOM_RILN=FOM_RILN;

1650

%---start. plotting ILN based on ILD and RILN % Hansel 10/18/2021

1638

%---start. plotting ILN based on ILD and RILN % Hansel 10/18/2021

1651

plot_tdomain_debug= 0; % must have OP.COMPUTE_TDILN = 1 to use

1639

plot_tdomain_debug= 0; % must have OP.COMPUTE_TDILN = 1 to use

1652

if plot_tdomain_debug== 1

1640

if plot_tdomain_debug== 1

1653

figure(988); set(gcf,'Tag','COM')

1641

figure(988); set(gcf,'Tag','COM')

1654

ax_1= subplot(3,1,1);

1642

ax_1= subplot(3,1,1);

1655

plot(TD_ILN.REF.t*1e9, TD_ILN.REF.PR*1e3,'disp','ref');

1643

plot(TD_ILN.REF.t*1e9, TD_ILN.REF.PR*1e3,'disp','ref');

1656

hold on;

1644

hold on;

1657

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1645

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1658

hold on;

1646

hold on;

1659

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k','disp','ref - fit (IL noise)');

1647

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k','disp','ref - fit (IL noise)');

1660

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1648

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1661

grid on;

1649

grid on;

1662

box on;

1650

box on;

1663

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1651

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1664

xlabel('Time [nsec]');

1652

xlabel('Time [nsec]');

1665

ylabel('Pulse Response [mV]');

1653

ylabel('Pulse Response [mV]');

1666

1654

1667

ax_2= subplot(3,1,2);

1655

ax_2= subplot(3,1,2);

1668

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1656

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1669

hold on;

1657

hold on;

1670

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1658

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1671

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1659

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1672

grid on;

1660

grid on;

1673

box on;

1661

box on;

1674

legend('REF', 'TD\_RILN');

1662

legend('REF', 'TD\_RILN');

1675

xlabel('Time [nsec]');

1663

xlabel('Time [nsec]');

1676

ylabel('Pulse Response [mV]');

1664

ylabel('Pulse Response [mV]');

1677

ax_3= subplot(3,1,3);

1665

ax_3= subplot(3,1,3);

1678

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1666

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1679

hold on;

1667

hold on;

1680

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1668

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1681

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1669

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1682

grid on;

1670

grid on;

1683

box on;

1671

box on;

1684

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1672

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1685

xlabel('Time [nsec]');

1673

xlabel('Time [nsec]');

1686

ylabel('Pulse Response [mV]');

1674

ylabel('Pulse Response [mV]');

1687

1675

1688

linkaxes([ax_1, ax_2, ax_3], 'x');

1676

linkaxes([ax_1, ax_2, ax_3], 'x');

1689

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1677

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1690

end

1678

end

1691

%---end. plotting ILN based on ILD and RILN

1679

%---end. plotting ILN based on ILD and RILN

1692

end

1680

end

1693

% Equation 93A-56 %

1681

% Equation 93A-56 %

1694

FOM_ILD=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1682

FOM_ILD=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1695

output_args.FOM_ILD=FOM_ILD;

1683

output_args.FOM_ILD=FOM_ILD;

1696

if OP.DEBUG

1684

if OP.DEBUG

1697

if OP.DISPLAY_WINDOW

1685

if OP.DISPLAY_WINDOW

1698

figure(300+case_number);

1686

figure(300+case_number);

1699

set(gcf,'Tag','COM')

1687

set(gcf,'Tag','COM')

1700

screen_size=get(0,'ScreenSize');

1688

screen_size=get(0,'ScreenSize');

1701

pos = get(gcf, 'OuterPosition');

1689

pos = get(gcf, 'OuterPosition');

1702

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1690

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1703

screen_size([3 4 3 4]).*[0 1 0 0] + pos([3 4 3 4]).*[0 -2 1 2] ...IL fit

1691

screen_size([3 4 3 4]).*[0 1 0 0] + pos([3 4 3 4]).*[0 -2 1 2] ...IL fit

1704

- (case_number-1)*[0 20 0 0]);

1692

- (case_number-1)*[0 20 0 0]);

1705

subplot(3,1,1)

1693

subplot(3,1,1)

1706

title('Losses')

1694

title('Losses')

1707

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1695

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1708

hold on

1696

hold on

1709

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1697

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1710

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1698

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1711

ylim(get(gca, 'ylim'));

1699

ylim(get(gca, 'ylim'));

1712

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1700

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1713

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1701

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1714

subplot(3,1,3)

1702

subplot(3,1,3)

1715

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1703

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1716

if OP.PLOT_CM

1704

if OP.PLOT_CM

1717

if case_number ==1

1705

if case_number ==1

1718

h350=figure(350);set(gcf,'Tag','COM')

1706

h350=figure(350);set(gcf,'Tag','COM')

1719

screen_size=get(0,'ScreenSize');

1707

screen_size=get(0,'ScreenSize');

1720

pos = get(gcf, 'OuterPosition');

1708

pos = get(gcf, 'OuterPosition');

1721

set(gcf, 'OuterPosition',screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-2 -2 2 1])

1709

set(gcf, 'OuterPosition',screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-2 -2 2 1])

1722

movegui(gcf,'center');

1710

movegui(gcf,'center');

1723

htabgroup350 = uitabgroup(h350);

1711

htabgroup350 = uitabgroup(h350);

1724

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1712

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1725

hax1 = axes('Parent', htab1);

1713

hax1 = axes('Parent', htab1);

1726

set(h350,'CurrentAxes',hax1)

1714

set(h350,'CurrentAxes',hax1)

1727

hold on

1715

hold on

1728

set(gcf,'Tag','COM')

1716

set(gcf,'Tag','COM')

1729

screen_size=get(0,'ScreenSize');

1717

screen_size=get(0,'ScreenSize');

1730

pos = get(gcf, 'OuterPosition');

1718

pos = get(gcf, 'OuterPosition');

1731

title('IL & CM Losses')

1719

title('IL & CM Losses')

1732

base=strrep(chdata(i).base,'_',' ');

1720

base=strrep(chdata(i).base,'_',' ');

1733

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp', [ 'sdd21(IL) TP0-TP5 ' base])

1721

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp', [ 'sdd21(IL) TP0-TP5 ' base])

1734

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1722

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1735

ylabel('dB')

1723

ylabel('dB')

1736

xlabel('GHz')

1724

xlabel('GHz')

1737

legend show

1725

legend show

1738

legend('Location','eastoutside')

1726

legend('Location','eastoutside')

1739

hold on

1727

hold on

1740

grid on

1728

grid on

1741

if param.number_of_s4p_files > 1

1729

if param.number_of_s4p_files > 1

1742

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1730

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1743

hax2 = axes('Parent', htab2);

1731

hax2 = axes('Parent', htab2);

1744

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1732

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1745

hax3 = axes('Parent', htab3);

1733

hax3 = axes('Parent', htab3);

1746

end

1734

end

1747

1735

1748

end

1736

end

1749

end

1737

end

1750

else

1738

else

1751

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1739

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1752

end

1740

end

1753

end

1741

end

1754

else % NEXT or FEXT

1742

else % NEXT or FEXT

1755

if isequal(chdata(i).type, 'FEXT')

1743

if isequal(chdata(i).type, 'FEXT')

1756

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1744

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1757

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46

1745

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46

1758

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1746

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1759

elseif isequal(chdata(i).type, 'NEXT')

1747

elseif isequal(chdata(i).type, 'NEXT')

1760

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1748

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1761

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47

1749

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47

1762

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1750

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1763

end

1751

end

1764

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1752

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1765

ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));

1753

ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));

1766

output_args.ICN_mV=ICN*1000;

1754

output_args.ICN_mV=ICN*1000;

1767

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1755

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1768

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1756

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1769

if case_number ==1

1757

if case_number ==1

1770

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1758

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1771

% hax2 = axes('Parent', htab2);

1759

% hax2 = axes('Parent', htab2);

1772

set(h350,'CurrentAxes',hax2)

1760

set(h350,'CurrentAxes',hax2)

1773

hold on

1761

hold on

1774

title('CM Losses')

1762

title('CM Losses')

1775

base=strrep(chdata(i).base,'_',' ');

1763

base=strrep(chdata(i).base,'_',' ');

1776

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1764

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1777

legend('Location','eastoutside')

1765

legend('Location','eastoutside')

1778

hold on

1766

hold on

1779

grid on

1767

grid on

1780

set(h350,'CurrentAxes',hax3)

1768

set(h350,'CurrentAxes',hax3)

1781

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1769

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1782

legend('Location','eastoutside')

1770

legend('Location','eastoutside')

1783

hold on

1771

hold on

1784

grid on

1772

grid on

1785

end

1773

end

1786

end

1774

end

1787

end

1775

end

1788

end % for loop

1776

end % for loop

1789

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1777

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1790

if OP.DEBUG && OP.DISPLAY_WINDOW

1778

if OP.DEBUG && OP.DISPLAY_WINDOW

1791

figure(300+case_number);set(gcf,'Tag','COM');

1779

figure(300+case_number);set(gcf,'Tag','COM');

1792

if param.number_of_s4p_files > 1

1780

if param.number_of_s4p_files > 1

1793

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1781

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1794

subplot(3,1,1)

1782

subplot(3,1,1)

1795

hold on

1783

hold on

1796

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1784

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1797

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1785

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1798

subplot(3,1,2)

1786

subplot(3,1,2)

1799

grid on

1787

grid on

1800

ILtemp=20*log10(abs(chdata(1).sdd21f));

1788

ILtemp=20*log10(abs(chdata(1).sdd21f));

1801

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1789

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1802

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1790

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1803

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1791

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1804

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1792

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1805

hold on

1793

hold on

1806

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1794

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1807

end

1795

end

1808

subplot(3,1,1)

1796

subplot(3,1,1)

1809

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1797

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1810

grid on; legend show

1798

grid on; legend show

1811

subplot(3,1,2)

1799

subplot(3,1,2)

1812

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1800

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1813

ylim([0 80])

1801

ylim([0 80])

1814

xlim([.1 100])

1802

xlim([.1 100])

1815

grid on; %legend show

1803

grid on; %legend show

1816

subplot(3,1,3)

1804

subplot(3,1,3)

1817

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1805

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1818

ylim([-3 3])

1806

ylim([-3 3])

1819

grid on; legend show

1807

grid on; legend show

1820

end

1808

end

1821

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1809

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1822

total_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21)), 1/param.ui/2);

1810

total_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21)), 1/param.ui/2);

1823

d2d_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p_nodie)), 1/param.ui/2);

1811

d2d_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p_nodie)), 1/param.ui/2);

1824

VIP_VMP_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p)), 1/param.ui/2);

1812

VIP_VMP_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p)), 1/param.ui/2);

1825

output_args.VTF_loss_dB_at_Fnq=total_loss;

1813

output_args.VTF_loss_dB_at_Fnq=total_loss;

1826

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1814

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1827

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1815

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1828

function [ V0 ] = FFE( C , cmx,spui, V )

1816

function [ V0 ] = FFE( C , cmx,spui, V )

1829

% C FFE taps

1817

% C FFE taps

1830

% cmx number of precursors taps

1818

% cmx number of precursors taps

1831

% spui samples per ui

1819

% spui samples per ui

1832

% V input signal

1820

% V input signal

1833

%speed ups implemented:

1821

%speed ups implemented:

1834

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1822

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1835

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1823

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1836

1824

1837

V0=0;

1825

V0=0;

1838

if iscolumn(V); V=V.';end

1826

if iscolumn(V); V=V.';end

1839

for i=1:length(C)

1827

for i=1:length(C)

1840

if C(i)~=0

1828

if C(i)~=0

1841

ishift=(i-1-cmx)*spui;

1829

ishift=(i-1-cmx)*spui;

1842

V0=circshift(V',[ishift,0])*C(i)+V0;

1830

V0=circshift(V',[ishift,0])*C(i)+V0;

1843

end

1831

end

1844

end

1832

end

1845

%V0=circshift(V0,[(-cmx)*spui,0]);

1833

%V0=circshift(V0,[(-cmx)*spui,0]);

1846

% disp(max(V0));

1834

% disp(max(V0));

1847

1835

1848

1836

1849

% begin yasuo patch 12/11/2018

1837

% begin yasuo patch 12/11/2018

1850

% calculate sigma (standard deviation) value of PDF

1838

% calculate sigma (standard deviation) value of PDF

1851

function [ V0 ] = FFE_Fast( C,V_shift )

1839

function [ V0 ] = FFE_Fast( C,V_shift )

1852

% C FFE taps

1840

% C FFE taps

1853

% V input signal separated into length(C) columns with circshift already performed

1841

% V input signal separated into length(C) columns with circshift already performed

1854

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1842

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1855

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1843

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1856

% saved by pre-shifting it and remembering it across loops

1844

% saved by pre-shifting it and remembering it across loops

1857

% Another speed up: only multiply by indices of C that are not 0

1845

% Another speed up: only multiply by indices of C that are not 0

1858

1846

1859

V0=0;

1847

V0=0;

1860

for i=1:length(C)

1848

for i=1:length(C)

1861

if C(i)~=0

1849

if C(i)~=0

1862

V0=V_shift(:,i)*C(i)+V0;

1850

V0=V_shift(:,i)*C(i)+V0;

1863

end

1851

end

1864

end

1852

end

1865

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1853

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1866

1854

1867

hisi=h(isi_start:isi_end);

1855

hisi=h(isi_start:isi_end);

1868

hisi=hisi(param.N_tail_start:param.N_bmax);

1856

hisi=hisi(param.N_tail_start:param.N_bmax);

1869

bank_size = param.N_bf;

1857

bank_size = param.N_bf;

1870

num_groups = param.N_bg;

1858

num_groups = param.N_bg;

1871

1859

1872

1860

1873

%start with one by one Floating Tap

1861

%start with one by one Floating Tap

1874

num_isi=length(hisi);

1862

num_isi=length(hisi);

1875

max_isi=num_isi-bank_size+1;

1863

max_isi=num_isi-bank_size+1;

1876

valid_tap_locations=1:max_isi;

1864

valid_tap_locations=1:max_isi;

1877

all_idx=[];

1865

all_idx=[];

1878

for j=1:num_groups

1866

for j=1:num_groups

1879

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1867

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1880

for k=1:length(valid_tap_locations)

1868

for k=1:length(valid_tap_locations)

1881

this_location=valid_tap_locations(k);

1869

this_location=valid_tap_locations(k);

1882

new_idx = [all_idx this_location:this_location+bank_size-1];

1870

new_idx = [all_idx this_location:this_location+bank_size-1];

1883

new_idx=sort(new_idx);

1871

new_idx=sort(new_idx);

1884

new_idx = new_idx+param.N_tail_start-1;

1872

new_idx = new_idx+param.N_tail_start-1;

1885

%calculate FOM for each one

1873

%calculate FOM for each one

1886

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1874

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1887

end

1875

end

1888

%choose the location with best FOM

1876

%choose the location with best FOM

1889

%add it to the "all_idx" list and remove it from valid locations

1877

%add it to the "all_idx" list and remove it from valid locations

1890

[~,best_FOM_idx]=max(best_FOM);

1878

[~,best_FOM_idx]=max(best_FOM);

1891

start_tap = valid_tap_locations(best_FOM_idx);

1879

start_tap = valid_tap_locations(best_FOM_idx);

1892

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1880

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1893

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1881

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1894

remove_range(remove_range>length(valid_tap_locations))=[];

1882

remove_range(remove_range>length(valid_tap_locations))=[];

1895

valid_tap_locations(remove_range)=[];

1883

valid_tap_locations(remove_range)=[];

1896

1884

1897

%Also remove illegal taps from valid locations

1885

%Also remove illegal taps from valid locations

1898

%illegal taps are ones that would overlap with the chosen bank

1886

%illegal taps are ones that would overlap with the chosen bank

1899

bad_tap=start_tap-bank_size+1:start_tap-1;

1887

bad_tap=start_tap-bank_size+1:start_tap-1;

1900

bad_tap(bad_tap<1)=[];

1888

bad_tap(bad_tap<1)=[];

1901

for n=1:length(bad_tap)

1889

for n=1:length(bad_tap)

1902

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1890

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1903

if ~isempty(bad_tap_idx)

1891

if ~isempty(bad_tap_idx)

1904

valid_tap_locations(bad_tap_idx)=[];

1892

valid_tap_locations(bad_tap_idx)=[];

1905

end

1893

end

1906

end

1894

end

1907

end

1895

end

1908

1896

1909

%put idx back in the right location (adding N_tail_start)

1897

%put idx back in the right location (adding N_tail_start)

1910

idx = all_idx+param.N_tail_start-1;

1898

idx = all_idx+param.N_tail_start-1;

1911

idx = sort(idx);

1899

idx = sort(idx);

1912

function [ V0 ] = Fract_T_FFE( V , skew_step)

1900

function [ V0 ] = Fract_T_FFE( V , skew_step)

1913

% skew_step sub UI skew assuming param.samples_per_ui

1901

% skew_step sub UI skew assuming param.samples_per_ui

1914

% V input signal

1902

% V input signal

1915

% V0 output signal

1903

% V0 output signal

1916

% Richard Mellitz 8/17/2021

1904

% Richard Mellitz 8/17/2021

1917

V0=0;

1905

V0=0;

1918

if iscolumn(V); V=V.';end

1906

if iscolumn(V); V=V.';end

1919

ishift=skew_step;

1907

ishift=skew_step;

1920

V0=circshift(V',[ishift,0])'+V;

1908

V0=circshift(V',[ishift,0])'+V;

1921

V0=V0/2;

1909

V0=V0/2;

1922

function out=Full_Grid_Matrix(in)

1910

function out=Full_Grid_Matrix(in)

1923

1911

1924

%create a full grid matrix of input variables

1912

%create a full grid matrix of input variables

1925

%used to create the full grid of all txffe cases

1913

%used to create the full grid of all txffe cases

1926

%example:

1914

%example:

1927

%Full_Grid_Matrix({ [1 2] [100 200] })

1915

%Full_Grid_Matrix({ [1 2] [100 200] })

1928

%out =

1916

%out =

1929

% 1 100

1917

% 1 100

1930

% 1 200

1918

% 1 200

1931

% 2 100

1919

% 2 100

1932

% 2 200

1920

% 2 200

1933

%

1921

%

1934

%input can also be mixed between numeric and cell of char

1922

%input can also be mixed between numeric and cell of char

1935

%example:

1923

%example:

1936

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1924

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1937

%out =

1925

%out =

1938

% {[1]} {'A'}

1926

% {[1]} {'A'}

1939

% {[1]} {'B'}

1927

% {[1]} {'B'}

1940

% {[2]} {'A'}

1928

% {[2]} {'A'}

1941

% {[2]} {'B'}

1929

% {[2]} {'B'}

1942

1930

1943

if ~iscell(in)

1931

if ~iscell(in)

1944

error('input must be cell array of individual sweep variables');

1932

error('input must be cell array of individual sweep variables');

1945

end

1933

end

1946

1934

1947

num_columns=length(in);

1935

num_columns=length(in);

1948

num_cases=prod(cellfun('length',in));

1936

num_cases=prod(cellfun('length',in));

1949

1937

1950

cell_output=0;

1938

cell_output=0;

1951

cell_indices=cellfun(@(x) iscell(x),in);

1939

cell_indices=cellfun(@(x) iscell(x),in);

1952

if any(cell_indices)

1940

if any(cell_indices)

1953

cell_output=1;

1941

cell_output=1;

1954

end

1942

end

1955

if cell_output

1943

if cell_output

1956

for k=find(~cell_indices)

1944

for k=find(~cell_indices)

1957

in{k}=num2cell(in{k});

1945

in{k}=num2cell(in{k});

1958

end

1946

end

1959

end

1947

end

1960

1948

1961

if cell_output

1949

if cell_output

1962

out=cell(num_cases,num_columns);

1950

out=cell(num_cases,num_columns);

1963

else

1951

else

1964

out=zeros(num_cases,num_columns);

1952

out=zeros(num_cases,num_columns);

1965

end

1953

end

1966

1954

1967

%num_repetitions controls how many times each element of the column

1955

%num_repetitions controls how many times each element of the column

1968

%repeats. The first column is always just a copy of itself since every

1956

%repeats. The first column is always just a copy of itself since every

1969

%case will vary.

1957

%case will vary.

1970

num_repetitions=1;

1958

num_repetitions=1;

1971

for k=num_columns:-1:1

1959

for k=num_columns:-1:1

1972

this_column=in{k}(:);

1960

this_column=in{k}(:);

1973

%copy the column into a matrix to create the repetitions needed

1961

%copy the column into a matrix to create the repetitions needed

1974

B=repmat(this_column,[1 num_repetitions]);

1962

B=repmat(this_column,[1 num_repetitions]);

1975

%reshape into single column (actual repetitions)

1963

%reshape into single column (actual repetitions)

1976

C=reshape(B',[numel(B) 1]);

1964

C=reshape(B',[numel(B) 1]);

1977

%repeat the single column to build the entire length required

1965

%repeat the single column to build the entire length required

1978

num_repeats=num_cases/length(C);

1966

num_repeats=num_cases/length(C);

1979

D=repmat(C,[num_repeats 1]);

1967

D=repmat(C,[num_repeats 1]);

1980

out(:,k)=D;

1968

out(:,k)=D;

1981

%determine how many repetitions the next column needs

1969

%determine how many repetitions the next column needs

1982

num_repetitions=num_repetitions*length(this_column);

1970

num_repetitions=num_repetitions*length(this_column);

1983

end

1971

end

1984

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1972

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1985

% p=cpdf(type, ...)

1973

% p=cpdf(type, ...)

1986

%

1974

%

1987

% CPDF is a probability mass function for discrete distributions or an

1975

% CPDF is a probability mass function for discrete distributions or an

1988

% approxmation of a PDF for continuous distributions.

1976

% approxmation of a PDF for continuous distributions.

1989

%

1977

%

1990

% cpdf is internally normalized so that the sum of probabilities is 1

1978

% cpdf is internally normalized so that the sum of probabilities is 1

1991

% (regardless of bin size).

1979

% (regardless of bin size).

1992

1980

1993

% Internal fields:

1981

% Internal fields:

1994

% Min: *bin number* of minimum value.

1982

% Min: *bin number* of minimum value.

1995

% BinSize: size of PDF bins. Bin center is the representative value.

1983

% BinSize: size of PDF bins. Bin center is the representative value.

1996

% Vec: vector of probabilities per bin.

1984

% Vec: vector of probabilities per bin.

1997

1985

1998

pdf=EmptyPDF;

1986

pdf=EmptyPDF;

1999

1987

2000

rounded_values_div_binsize=round(values/pdf.BinSize);

1988

rounded_values_div_binsize=round(values/pdf.BinSize);

2001

%values=pdf.BinSize*rounded_values_div_binsize;

1989

%values=pdf.BinSize*rounded_values_div_binsize;

2002

1990

2003

% %speed up for small values round to 0 (because they are all much smaller than binsize)

1991

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2004

% if all(values==0)

1992

% if all(values==0)

2005

% return;

1993

% return;

2006

% end

1994

% end

2007

%

1995

%

2008

% %speed up for all values rounded to the same bin

1996

% %speed up for all values rounded to the same bin

2009

% %The output pdf is the same as the

1997

% %The output pdf is the same as the

2010

% %empty pdf, but the x value is non-zero (but still scalar)

1998

% %empty pdf, but the x value is non-zero (but still scalar)

2011

% if all(values==values(1))

1999

% if all(values==values(1))

2012

% pdf.Min=rounded_values_div_binsize(1);

2000

% pdf.Min=rounded_values_div_binsize(1);

2013

% pdf.x=values(1);

2001

% pdf.x=values(1);

2014

% return;

2002

% return;

2015

% end

2003

% end

2016

%

2004

%

2017

% %The code below requires that values is

2005

% %The code below requires that values is

2018

% %sorted. Generally this should be true, but check to be sure

2006

% %sorted. Generally this should be true, but check to be sure

2019

% if ~issorted(values)

2007

% if ~issorted(values)

2020

% [values,si]=sort(values);

2008

% [values,si]=sort(values);

2021

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2009

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2022

% probs=probs(si);

2010

% probs=probs(si);

2023

% end

2011

% end

2024

2012

2025

2013

2026

%pdf.x=values(1):pdf.BinSize:values(end);

2014

%pdf.x=values(1):pdf.BinSize:values(end);

2027

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2015

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2028

pdf.Min=rounded_values_div_binsize(1);

2016

pdf.Min=rounded_values_div_binsize(1);

2029

2017

2030

pdf.y=zeros(size(pdf.x));

2018

pdf.y=zeros(size(pdf.x));

2031

%The rounded values divided by binsize will reveal the bin number if

2019

%The rounded values divided by binsize will reveal the bin number if

2032

%pdf.Min is subtracted from it

2020

%pdf.Min is subtracted from it

2033

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2021

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2034

%Can avoid one addition by inserting the first probability

2022

%Can avoid one addition by inserting the first probability

2035

%actually helps when calling this 2 million times

2023

%actually helps when calling this 2 million times

2036

pdf.y(bin_placement(1))=probs(1);

2024

pdf.y(bin_placement(1))=probs(1);

2037

for k=2:length(values)

2025

for k=2:length(values)

2038

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2026

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2039

end

2027

end

2040

2028

2041

2029

2042

%Have already ensured that sum(pdf.y)=1

2030

%Have already ensured that sum(pdf.y)=1

2043

%pdf.y=pdf.y/sum(pdf.y);

2031

%pdf.y=pdf.y/sum(pdf.y);

2044

2032

2045

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2033

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2046

% error('PDF must be real and nonnegative');

2034

% error('PDF must be real and nonnegative');

2047

% end

2035

% end

2048

2036

2049

% pMax=pdf.Min+length(pdf.y)-1;

2037

% pMax=pdf.Min+length(pdf.y)-1;

2050

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2038

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2051

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2039

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2052

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2040

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2053

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2041

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2054

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2042

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2055

2043

2056

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2044

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2057

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2045

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2058

2046

2059

%% step 0

2047

%% step 0

2060

COM_from_matlab=20*log10(A_s/A_ni);

2048

COM_from_matlab=20*log10(A_s/A_ni);

2061

L=param.levels;

2049

L=param.levels;

2062

DER0=param.specBER;

2050

DER0=param.specBER;

2063

%% step 1 from slide 6/5

2051

%% step 1 from slide 6/5

2064

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2052

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2065

main=A_peak;

2053

main=A_peak;

2066

k_DER=qfuncinv(param.specBER);

2054

k_DER=qfuncinv(param.specBER);

2067

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2055

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2068

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2056

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2069

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2057

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2070

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2058

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2071

if A_s >= A_ni

2059

if A_s >= A_ni

2072

%% step 2 slide 10/8

2060

%% step 2 slide 10/8

2073

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2061

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2074

%% step 2 slide 10/8

2062

%% step 2 slide 10/8

2075

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2063

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2076

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2064

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2077

%% step 3 side 11/9

2065

%% step 3 side 11/9

2078

j=1:200;

2066

j=1:200;

2079

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2067

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2080

DER_MLSE_CDF=0; jj=1;

2068

DER_MLSE_CDF=0; jj=1;

2081

DER_delta = inf;

2069

DER_delta = inf;

2082

while DER_delta > .001

2070

while DER_delta > .001

2083

last_DER_MLSE_CDF=DER_MLSE_CDF;

2071

last_DER_MLSE_CDF=DER_MLSE_CDF;

2084

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2072

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2085

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2073

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2086

jj=jj+1;

2074

jj=jj+1;

2087

end

2075

end

2088

%% step 4 slide 12/10

2076

%% step 4 slide 12/10

2089

SNR_DFE_eqivalent=SNR_DFE*(...

2077

SNR_DFE_eqivalent=SNR_DFE*(...

2090

(L-1)*sigma_noise/main * qfuncinv(...

2078

(L-1)*sigma_noise/main * qfuncinv(...

2091

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2079

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2092

) ...

2080

) ...

2093

)^2;

2081

)^2;

2094

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2082

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2095

(L-1)/main * CDF_inv_ev(...

2083

(L-1)/main * CDF_inv_ev(...

2096

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2084

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2097

,PDF, CDF ) ...

2085

,PDF, CDF ) ...

2098

)^2;

2086

)^2;

2099

2087

2100

%% step 5 slide 13/11

2088

%% step 5 slide 13/11

2101

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2089

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2102

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2090

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2103

new_com_CDF=COM_from_matlab+delta_com_CDF;

2091

new_com_CDF=COM_from_matlab+delta_com_CDF;

2104

else

2092

else

2105

warning('MLSE not applied because there is more noise than signal')

2093

warning('MLSE not applied because there is more noise than signal')

2106

DER_MLSE=[];

2094

DER_MLSE=[];

2107

DER_MLSE_CDF=[];

2095

DER_MLSE_CDF=[];

2108

SNR_DFE_eqivalent=[];

2096

SNR_DFE_eqivalent=[];

2109

SNR_DFE_eqivalent_CDF=[];

2097

SNR_DFE_eqivalent_CDF=[];

2110

new_com_CDF=COM_from_matlab;

2098

new_com_CDF=COM_from_matlab;

2111

delta_com_CDF=0;

2099

delta_com_CDF=0;

2112

delta_com=0;

2100

delta_com=0;

2113

SNR_DFE=[];

2101

SNR_DFE=[];

2114

end

2102

end

2115

2116

%%

2117

MLSE_results.COM_from_matlab=COM_from_matlab;

2118

MLSE_results.SNR_DFE=SNR_DFE;

2119

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2120

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2121

MLSE_results.sigma_noise=sigma_noise;

2122

MLSE_results.SNR_dB=SNR_dB ;

2123

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2124

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2125

MLSE_results.COM_Gaussian=new_com_CDF;

2126

MLSE_results.COM_CDF=new_com_CDF;

2127

MLSE_results.k_DER=k_DER;

2128

MLSE_results.delta_com_CDF=delta_com_CDF;

2129

MLSE_results.delta_com_Gaussian=delta_com;

2130

2103

2131

2132

2133

function [MLSE_results] = MLSE_U1_c(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2134

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2135

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2136

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2137

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2138

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2139

%% step 0

2140

COM_from_matlab=20*log10(A_s/A_ni);

2141

L=param.levels;

2142

DER0=param.specBER;

2143

%% step 1 from slide 6 shakiba_3dj_01_230116

2144

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2145

main=A_peak;

2146

k_DER=qfuncinv(param.specBER);

2147

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2148

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2149

% if A_s >= A_ni

2150

if 1

2151

%% step 2 slide 10 shakiba_3dj_01_230116

2152

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2153

%% step 2 slide 10 not used

2154

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2155

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2156

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2157

S_n=PSD_results.Sn_rho; % total agregate noise PSD

2158

Rn=ifft(S_n)*param.fb;

2159

Rho_row=Rn/Rn(1);

2160

Rn_len=length(Rn);

2161

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2162

for j=1:Rn_len

2163

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2164

end

2165

rho_noiseEE_row=Rho_row.*alphas_row;

2166

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2167

for j=1:Rn_len

2168

rho_noiseEE(j,j)=(1-alpha)^2;

2169

end

2170

rho_noiseEE(1,1)=1;

2171

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2172

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2173

% determine complete matrix

2174

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2175

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2176

%% shakiba_3dj_elec_01a_230504 slide 17

2177

j=1:Rn_len;

2178

DER_MLSE=[];

2179

DER_MLSE_CDF=0; jj=1;

2180

DER_MLSE_CDFold=0;

2181

DER_delta = inf;

2182

% slight modified for PAM4 DER vs SER

2183

while DER_delta > .0001 && jj<=Rn_len || jj==1

2184

last_DER_MLSE_CDF=DER_MLSE_CDF;

2185

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2186

DER_MLSE_CDF= ...

2187

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2188

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2189

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2190

jj=jj+1;

2191

end

2192

%% shakiba_3dj_elec_01a_230504 slide 19

2193

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2194

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2195

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2196

(L-1)/main * CDF_inv_ev(...

2197

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2198

,PDF, CDF ) ...

2199

)^2;

2200

%% step 5 shakiba_3dj_01_230116 slide 13

2201

delta_com=[];

2202

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2203

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2204

new_com_CDF=COM_from_matlab+delta_com_CDF;

2205

else

2206

warning('MLSE not applied because there is more noise than signal')

2207

DER_MLSE=[];

2208

DER_MLSE_CDF=[];

2209

SNR_DFE_eqivalent=[];

2210

SNR_DFE_eqivalent_CDF=[];

2211

new_com_CDF=COM_from_matlab;

2212

delta_com_CDF=0;

2213

delta_com=0;

2214

SNR_DFE=[];

2215

end

2216

SNR_DFE_eqivalent=[];

2217

%%

2104

%%

2218

MLSE_results.COM_from_matlab=COM_from_matlab;

2105

MLSE_results.COM_from_matlab=COM_from_matlab;

2219

MLSE_results.SNR_DFE=SNR_DFE;

2106

MLSE_results.SNR_DFE=SNR_DFE;

2220

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2107

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2221

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2108

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2222

MLSE_results.sigma_noise=sigma_noise;

2109

MLSE_results.sigma_noise=sigma_noise;

2223

MLSE_results.SNR_dB=SNR_dB ;

2110

MLSE_results.SNR_dB=SNR_dB ;

2224

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2111

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2225

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2112

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2226

MLSE_results.COM_Gaussian=new_com_CDF;

2113

MLSE_results.COM_Gaussian=new_com_CDF;

2227

MLSE_results.COM_CDF=new_com_CDF;

2114

MLSE_results.COM_CDF=new_com_CDF;

2228

MLSE_results.k_DER=k_DER;

2115

MLSE_results.k_DER=k_DER;

2229

MLSE_results.delta_com_CDF=delta_com_CDF;

2116

MLSE_results.delta_com_CDF=delta_com_CDF;

2230

MLSE_results.delta_com_Gaussian=delta_com;

2117

MLSE_results.delta_com_Gaussian=delta_com;

2231

2118

2232

2119

2233

2120

2234

function [MLSE_results] = MLSE_U3(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2121

function [MLSE_results] = MLSE_U3(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2235

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2122

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2236

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2123

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2237

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2124

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2238

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2125

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2239

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2126

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2240

%% step 0

2127

%% step 0

2241

COM_from_matlab=20*log10(A_s/A_ni);

2128

COM_from_matlab=20*log10(A_s/A_ni);

2242

L=param.levels;

2129

L=param.levels;

2243

DER0=param.specBER;

2130

DER0=param.specBER;

2244

%% step 1 from slide 6 shakiba_3dj_01_230116

2131

%% step 1 from slide 6 shakiba_3dj_01_230116

2245

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2132

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2246

main=A_peak;

2133

main=A_peak;

2247

k_DER=qfuncinv(param.specBER);

2134

k_DER=qfuncinv(param.specBER);

2248

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2135

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2249

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2136

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2250

% if A_s >= A_ni

2137

% if A_s >= A_ni

2251

if 1

2138

if 1

2252

%% step 2 slide 10 shakiba_3dj_01_230116

2139

%% step 2 slide 10 shakiba_3dj_01_230116

2253

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2140

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2254

%% step 2 slide 10 not used

2141

%% step 2 slide 10 not used

2255

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2142

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2256

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2143

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2257

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2144

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2258

S_n=PSD_results.S_n; % total agregate noise PSD

2145

S_n=PSD_results.S_n; % total agregate noise PSD

2259

Rn=ifft(S_n)*param.fb;

2146

Rn=ifft(S_n)*param.fb;

2260

Rho_row=Rn/Rn(1);

2147

Rho_row=Rn/Rn(1);

2261

Rn_len=length(Rn);

2148

Rn_len=length(Rn);

2262

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2149

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2263

for j=1:Rn_len

2150

for j=1:Rn_len

2264

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2151

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2265

end

2152

end

2266

rho_noiseEE_row=Rho_row.*alphas_row;

2153

rho_noiseEE_row=Rho_row.*alphas_row;

2267

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2154

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2268

for j=1:Rn_len

2155

for j=1:Rn_len

2269

rho_noiseEE(j,j)=(1-alpha)^2;

2156

rho_noiseEE(j,j)=(1-alpha)^2;

2270

end

2157

end

2271

rho_noiseEE(1,1)=1;

2158

rho_noiseEE(1,1)=1;

2272

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2159

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2273

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2160

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2274

% determine complete matrix

2161

% determine complete matrix

2275

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2162

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2276

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2163

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2277

%% shakiba_3dj_elec_01a_230504 slide 17

2164

%% shakiba_3dj_elec_01a_230504 slide 17

2278

j=1:Rn_len;

2165

j=1:Rn_len;

2279

DER_MLSE=[];

2166

DER_MLSE=[];

2280

DER_MLSE_CDF=0; jj=1;

2167

DER_MLSE_CDF=0; jj=1;

2281

DER_MLSE_CDFold=0;

2168

DER_MLSE_CDFold=0;

2282

DER_delta = inf;

2169

DER_delta = inf;

2283

% slight modified for PAM4 DER vs SER

2170

% slight modified for PAM4 DER vs SER

2284

while DER_delta > .0001 && jj<=Rn_len || jj==1

2171

while DER_delta > .0001 && jj<=Rn_len || jj==1

2285

last_DER_MLSE_CDF=DER_MLSE_CDF;

2172

last_DER_MLSE_CDF=DER_MLSE_CDF;

2286

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2173

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2287

DER_MLSE_CDF= ...

2174

DER_MLSE_CDF= ...

2288

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2175

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2289

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2176

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2290

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2177

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2291

jj=jj+1;

2178

jj=jj+1;

2292

end

2179

end

2293

%% shakiba_3dj_elec_01a_230504 slide 19

2180

%% shakiba_3dj_elec_01a_230504 slide 19

2294

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2181

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2295

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2182

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2296

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2183

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2297

(L-1)/main * CDF_inv_ev(...

2184

(L-1)/main * CDF_inv_ev(...

2298

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2185

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2299

,PDF, CDF ) ...

2186

,PDF, CDF ) ...

2300

)^2;

2187

)^2;

2301

%% step 5 shakiba_3dj_01_230116 slide 13

2188

%% step 5 shakiba_3dj_01_230116 slide 13

2302

delta_com=[];

2189

delta_com=[];

2303

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2190

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2304

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2191

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2305

new_com_CDF=COM_from_matlab+delta_com_CDF;

2192

new_com_CDF=COM_from_matlab+delta_com_CDF;

2306

else

2193

else

2307

warning('MLSE not applied because there is more noise than signal')

2194

warning('MLSE not applied because there is more noise than signal')

2308

DER_MLSE=[];

2195

DER_MLSE=[];

2309

DER_MLSE_CDF=[];

2196

DER_MLSE_CDF=[];

2310

SNR_DFE_eqivalent=[];

2197

SNR_DFE_eqivalent=[];

2311

SNR_DFE_eqivalent_CDF=[];

2198

SNR_DFE_eqivalent_CDF=[];

2312

new_com_CDF=COM_from_matlab;

2199

new_com_CDF=COM_from_matlab;

2313

delta_com_CDF=0;

2200

delta_com_CDF=0;

2314

delta_com=0;

2201

delta_com=0;

2315

SNR_DFE=[];

2202

SNR_DFE=[];

2316

end

2203

end

2317

SNR_DFE_eqivalent=[];

2204

SNR_DFE_eqivalent=[];

2318

%%

2205

%%

2319

MLSE_results.COM_from_matlab=COM_from_matlab;

2206

MLSE_results.COM_from_matlab=COM_from_matlab;

2320

MLSE_results.SNR_DFE=SNR_DFE;

2207

MLSE_results.SNR_DFE=SNR_DFE;

2321

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2208

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2322

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2209

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2323

MLSE_results.sigma_noise=sigma_noise;

2210

MLSE_results.sigma_noise=sigma_noise;

2324

MLSE_results.SNR_dB=SNR_dB ;

2211

MLSE_results.SNR_dB=SNR_dB ;

2325

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2212

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2326

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2213

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2327

MLSE_results.COM_Gaussian=new_com_CDF;

2214

MLSE_results.COM_Gaussian=new_com_CDF;

2328

MLSE_results.COM_CDF=new_com_CDF;

2215

MLSE_results.COM_CDF=new_com_CDF;

2329

MLSE_results.k_DER=k_DER;

2216

MLSE_results.k_DER=k_DER;

2330

MLSE_results.delta_com_CDF=delta_com_CDF;

2217

MLSE_results.delta_com_CDF=delta_com_CDF;

2331

MLSE_results.delta_com_Gaussian=delta_com;

2218

MLSE_results.delta_com_Gaussian=delta_com;

2332

2219

2333

2220

2334

2221

2335

function [MLSE_results] = MLSE_instu(param,alpha,A_s,A_ni,PDF,CDF)

2222

function [MLSE_results] = MLSE_instu(param,alpha,A_s,A_ni,PDF,CDF)

2336

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2223

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2337

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2224

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2338

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2225

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2339

2226

2340

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2227

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2341

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2228

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2342

2229

2343

%% step 0

2230

%% step 0

2344

COM_from_matlab=20*log10(A_s/A_ni);

2231

COM_from_matlab=20*log10(A_s/A_ni);

2345

L=param.levels;

2232

L=param.levels;

2346

DER0=param.specBER;

2233

DER0=param.specBER;

2347

%% step 1 from slide 6/5

2234

%% step 1 from slide 6/5

2348

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2235

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2349

main=A_peak;

2236

main=A_peak;

2350

k_DER=qfuncinv(param.specBER);

2237

k_DER=qfuncinv(param.specBER);

2351

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2238

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2352

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2239

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2353

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2240

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2354

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2241

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2355

if A_s >= A_ni

2242

if A_s >= A_ni

2356

%% step 2 slide 10/8

2243

%% step 2 slide 10/8

2357

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2244

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2358

%% step 2 slide 10/8

2245

%% step 2 slide 10/8

2359

snr_dfe = @(der,PDF,CDF) -10*log10((A_s./CDF_inv_ev(der,PDF,CDF)).^2)+10*log10((L^2-1)/3*qfuncinv(der).^2) ;

2246

snr_dfe = @(der,PDF,CDF) -10*log10((A_s./CDF_inv_ev(der,PDF,CDF)).^2)+10*log10((L^2-1)/3*qfuncinv(der).^2) ;

2360

2247

2361

%% step 3 side 11/9

2248

%% step 3 side 11/9

2362

j=1:200;

2249

j=1:200;

2363

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2250

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2364

DER_MLSE_CDF=0; jj=1;

2251

DER_MLSE_CDF=0; jj=1;

2365

DER_delta = inf;

2252

DER_delta = inf;

2366

while DER_delta > .001

2253

while DER_delta > .001

2367

last_DER_MLSE_CDF=DER_MLSE_CDF;

2254

last_DER_MLSE_CDF=DER_MLSE_CDF;

2368

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2255

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2369

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2256

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2370

jj=jj+1;

2257

jj=jj+1;

2371

end

2258

end

2372

%%

2259

%%

2373

dscale=.05;

2260

dscale=.05;

2374

scale=1;

2261

scale=1;

2375

last_scale_tune=inf;

2262

last_scale_tune=inf;

2376

scale_tune=inf;

2263

scale_tune=inf;

2377

while abs(scale_tune) >= .1

2264

while abs(scale_tune) >= .1

2378

istart=-PDF.Min+1;

2265

istart=-PDF.Min+1;

2379

scale=scale-dscale;

2266

scale=scale-dscale;

2380

PDF_SCALED = scalePDF(PDF,scale);

2267

PDF_SCALED = scalePDF(PDF,scale);

2381

cdf_scaled=pdf_to_cdf(PDF_SCALED);

2268

cdf_scaled=pdf_to_cdf(PDF_SCALED);

2382

test_snr=snr_dfe(DER_MLSE_CDF,PDF_SCALED,cdf_scaled.y);

2269

test_snr=snr_dfe(DER_MLSE_CDF,PDF_SCALED,cdf_scaled.y);

2383

test_DER=2*(L-1)/L* (CDF_ev(main/(L-1),PDF_SCALED,cdf_scaled.y) );

2270

test_DER=2*(L-1)/L* (CDF_ev(main/(L-1),PDF_SCALED,cdf_scaled.y) );

2384

scale_tune=(test_DER-DER_MLSE_CDF)/DER_MLSE_CDF;

2271

scale_tune=(test_DER-DER_MLSE_CDF)/DER_MLSE_CDF;

2385

if sign(scale_tune) ~= sign(last_scale_tune)

2272

if sign(scale_tune) ~= sign(last_scale_tune)

2386

% scale=scale+dscale % back up

2273

% scale=scale+dscale % back up

2387

dscale=-dscale/2;

2274

dscale=-dscale/2;

2388

end

2275

end

2389

last_scale_tune=scale_tune;

2276

last_scale_tune=scale_tune;

2390

end

2277

end

2391

new_com_CDF=10*log10((A_s./CDF_inv_ev(DER0,PDF_SCALED,cdf_scaled.y)).^2);

2278

new_com_CDF=10*log10((A_s./CDF_inv_ev(DER0,PDF_SCALED,cdf_scaled.y)).^2);

2392

delta_com=new_com_CDF-10*log10((A_s./CDF_inv_ev(DER0,PDF,CDF)).^2);

2279

delta_com=new_com_CDF-10*log10((A_s./CDF_inv_ev(DER0,PDF,CDF)).^2);

2393

else

2280

else

2394

warning('MLSE not applied because there is more noise than signal')

2281

warning('MLSE not applied because there is more noise than signal')

2395

DER_MLSE=[];

2282

DER_MLSE=[];

2396

DER_MLSE_CDF=[];

2283

DER_MLSE_CDF=[];

2397

SNR_DFE_eqivalent=[];

2284

SNR_DFE_eqivalent=[];

2398

SNR_DFE_eqivalent_CDF=[];

2285

SNR_DFE_eqivalent_CDF=[];

2399

new_com_CDF=COM_from_matlab;

2286

new_com_CDF=COM_from_matlab;

2400

delta_com_CDF=0;

2287

delta_com_CDF=0;

2401

delta_com=0;

2288

delta_com=0;

2402

SNR_DFE=[];

2289

SNR_DFE=[];

2403

PDF_SCALED=[];

2290

PDF_SCALED=[];

2404

cdf_scaled=[];

2291

cdf_scaled=[];

2405

end

2292

end

2406

2293

2407

%%

2294

%%

2408

MLSE_results.COM_from_matlab=COM_from_matlab;

2295

MLSE_results.COM_from_matlab=COM_from_matlab;

2409

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2296

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2410

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2297

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2411

MLSE_results.sigma_noise=sigma_noise;

2298

MLSE_results.sigma_noise=sigma_noise;

2412

MLSE_results.k_DER=k_DER;

2299

MLSE_results.k_DER=k_DER;

2413

MLSE_results.COM_CDF=new_com_CDF;

2300

MLSE_results.COM_CDF=new_com_CDF;

2414

MLSE_results.delta_com_CDF=delta_com;

2301

MLSE_results.delta_com_CDF=delta_com;

2415

MLSE_results.delta_com_Gaussian=delta_com;

2302

MLSE_results.delta_com_Gaussian=delta_com;

2416

MLSE_results.PDF=PDF_SCALED;

2303

MLSE_results.PDF=PDF_SCALED;

2417

MLSE_results.CDF=cdf_scaled.y;

2304

MLSE_results.CDF=cdf_scaled.y;

2418

MLSE_results.PDF_scale=scale;

2305

MLSE_results.PDF_scale=scale;

2419

2306

2420

2307

2421

2308

2422

2309

2423

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2310

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2424

if 1

2311

if 1

2425

num_ui=param.num_ui_RXFF_noise;

2312

num_ui=param.num_ui_RXFF_noise;

2426

M=param.samples_per_ui;

2313

M=param.samples_per_ui;

2427

L=param.levels;

2314

L=param.levels;

2428

sigma_X2=(L^2-1)/(3*(L-1)^2);

2315

sigma_X2=(L^2-1)/(3*(L-1)^2);

2429

fb=param.fb;

2316

fb=param.fb;

2430

R_LM=param.R_LM;

2317

R_LM=param.R_LM;

2431

end

2318

end

2432

h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2319

h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2433

h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2320

h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2434

h=reshape(h,1,[]); % make row vectors

2321

h=reshape(h,1,[]); % make row vectors

2435

h=[ h(1:floor(length(h)/M)*M) ];

2322

h=[ h(1:floor(length(h)/M)*M) ];

2436

h= [h zeros(1,num_ui*M-length(h)) ];

2323

h= [h zeros(1,num_ui*M-length(h)) ];

2437

h=h(1:M:end);% resample

2324

h=h(1:M:end);% resample

2438

N=length(h);

2325

N=length(h);

2439

dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2326

dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2440

dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2327

dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2441

if param.N_bg == 0

2328

if param.N_bg == 0

2442

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2329

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2443

bmax=param.bmax;

2330

bmax=param.bmax;

2444

bmin=param.bmin ;

2331

bmin=param.bmin ;

2445

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2332

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2446

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2333

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2447

idx=[];

2334

idx=[];

2448

else

2335

else

2449

Nfloating_taps=param.N_bf*param.N_bg;

2336

Nfloating_taps=param.N_bf*param.N_bg;

2450

Nmax=param.N_bmax;

2337

Nmax=param.N_bmax;

2451

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2338

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2452

Ng=param.N_bg;

2339

Ng=param.N_bg;

2453

Nf=param.N_bf;

2340

Nf=param.N_bf;

2454

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2341

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2455

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2342

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2456

% hisi=h(dh+2:((dh-dw)+Nw));

2343

% hisi=h(dh+2:((dh-dw)+Nw));

2457

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2344

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2458

% idx=sort(idx);

2345

% idx=sort(idx);

2459

bmax=param.bmax;

2346

bmax=param.bmax;

2460

bmin=param.bmin ;

2347

bmin=param.bmin ;

2461

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ones(1,Nfloating_taps)*param.bmaxg ];

2348

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ones(1,Nfloating_taps)*param.bmaxg ];

2462

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max -ones(1,Nfloating_taps)*param.bmaxg ];

2349

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max -ones(1,Nfloating_taps)*param.bmaxg ];

2463

end

2350

end

2464

Nb=param.ndfe; % DFE taps

2351

Nb=param.ndfe; % DFE taps

2465

d=dw+dh; % used for index in algorithms

2352

d=dw+dh; % used for index in algorithms

2466

indx(1:N)=(1:N)-dh-1;

2353

indx(1:N)=(1:N)-dh-1;

2467

S_n=PSD_results.S_n; % total agregate noise PSD

2354

S_n=PSD_results.S_n; % total agregate noise PSD

2468

Rn=ifft(S_n)*fb;

2355

Rn=ifft(S_n)*fb;

2469

%% HH and R

2356

%% HH and R

2470

2357

2471

%Test routine finding rxffe floating taps using best FOM for each bank

2358

%Test routine finding rxffe floating taps using best FOM for each bank

2472

isi_start = dh+2;

2359

isi_start = dh+2;

2473

isi_end = (dh-dw)+Nw;

2360

isi_end = (dh-dw)+Nw;

2474

hc1=[ h zeros(1,Nw-1) ];

2361

hc1=[ h zeros(1,Nw-1) ];

2475

hr1=[ h(1) zeros(1,Nw-1)];

2362

hr1=[ h(1) zeros(1,Nw-1)];

2476

H=toeplitz(hc1,hr1);

2363

H=toeplitz(hc1,hr1);

2477

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2364

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2478

if param.N_bg ~= 0

2365

if param.N_bg ~= 0

2479

switch lower(OP.RXFFE_FLOAT_CTL)

2366

switch lower(OP.RXFFE_FLOAT_CTL)

2480

case 'isi'

2367

case 'isi'

2481

hisi=h(dh+2:((dh-dw)+Nw));

2368

hisi=h(dh+2:((dh-dw)+Nw));

2482

[idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2369

[idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2483

idx=sort(idx);

2370

idx=sort(idx);

2484

otherwise

2371

otherwise

2485

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2372

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2486

idx=sort(idx);

2373

idx=sort(idx);

2487

end

2374

end

2488

end

2375

end

2489

[sigma_e,FOM,w,idx] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx);

2376

[sigma_e,FOM,w,idx] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx);

2490

MMSE_results.sigma_e=sigma_e; %

2377

MMSE_results.sigma_e=sigma_e; %

2491

MMSE_results.FOM=FOM;

2378

MMSE_results.FOM=FOM;

2492

Craw=w/w(dw+1); % returned Rx FFE taps

2379

Craw=w/w(dw+1); % returned Rx FFE taps

2493

% re-align Cmod to floating tap locations

2380

% re-align Cmod to floating tap locations

2494

if param.N_bg ~= 0

2381

if param.N_bg ~= 0

2495

C=Craw;

2382

C=Craw;

2496

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2383

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2497

C(idx-param.N_tail_start+1+Nfix)=Craw(Nfix+(1:Nfloating_taps));

2384

C(idx-param.N_tail_start+1+Nfix)=Craw(Nfix+(1:Nfloating_taps));

2498

else

2385

else

2499

C=Craw;

2386

C=Craw;

2500

end

2387

end

2501

MMSE_results.floating_tap_locations=idx;

2388

MMSE_results.floating_tap_locations=idx;

2502

MMSE_results.C=C;

2389

MMSE_results.C=C;

2503

2390

2504

2391

2505

2392

2506

2393

2507

function [sigma_e,FOM,w,idx,Nw] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2394

function [sigma_e,FOM,w,idx,Nw] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2508

if isempty(idx)

2395

if isempty(idx)

2509

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2396

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2510

bmax=param.bmax;

2397

bmax=param.bmax;

2511

bmin=param.bmin ;

2398

bmin=param.bmin ;

2512

else

2399

else

2513

Nfloating_taps=param.N_bf*param.N_bg;

2400

Nfloating_taps=param.N_bf*param.N_bg;

2514

%If using the routine that finds RXFFE floating taps bank-by-bank, the number of total floating taps can be less than the final amount

2401

%If using the routine that finds RXFFE floating taps bank-by-bank, the number of total floating taps can be less than the final amount

2515

Nfloating_taps = length(idx);

2402

Nfloating_taps = length(idx);

2516

Nmax=param.N_bmax;

2403

Nmax=param.N_bmax;

2517

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2404

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2518

Ng=param.N_bg;

2405

Ng=param.N_bg;

2519

Nf=param.N_bf;

2406

Nf=param.N_bf;

2520

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2407

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2521

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2408

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2522

end

2409

end

2523

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2410

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2524

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2411

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2525

% hc1=[ h zeros(1,Nw-1) ];

2412

% hc1=[ h zeros(1,Nw-1) ];

2526

% hr1=[ h(1) zeros(1,Nw-1)];

2413

% hr1=[ h(1) zeros(1,Nw-1)];

2527

% H=toeplitz(hc1,hr1);

2414

% H=toeplitz(hc1,hr1);

2528

2415

2529

if param.N_bg ~= 0

2416

if param.N_bg ~= 0

2530

H=H( :,[1:Nfix idx-param.N_tail_start+1+Nfix]); % from Tobey (Pei-Rong Li 02/28/2024)

2417

H=H( :,[1:Nfix idx-param.N_tail_start+1+Nfix]); % from Tobey (Pei-Rong Li 02/28/2024)

2531

end

2418

end

2532

%% HH and R

2419

%% HH and R

2533

HH= H'*H;

2420

HH= H'*H;

2534

if param.N_bg ~= 0

2421

if param.N_bg ~= 0

2535

Rnn=Rnn( [1:Nfix idx-param.N_tail_start+1+Nfix],[1:Nfix idx-param.N_tail_start+1+Nfix]);

2422

Rnn=Rnn( [1:Nfix idx-param.N_tail_start+1+Nfix],[1:Nfix idx-param.N_tail_start+1+Nfix]);

2536

end

2423

end

2537

R=HH+Rnn/sigma_X2;

2424

R=HH+Rnn/sigma_X2;

2538

%% hb and h0

2425

%% hb and h0

2539

Hb= H(d+2:d+Nb+1,:);

2426

Hb= H(d+2:d+Nb+1,:);

2540

h0=H(d+1,:);

2427

h0=H(d+1,:);

2541

% display(floor(h0));

2428

% display(floor(h0));

2542

2429

2543

%% Ib and zb (slide 10)

2430

%% Ib and zb (slide 10)

2544

ib=eye(Nb);

2431

ib=eye(Nb);

2545

zb=zeros(1,Nb);

2432

zb=zeros(1,Nb);

2546

wbl= [ R -Hb' -h0';...

2433

wbl= [ R -Hb' -h0';...

2547

-Hb ib zb'; ...

2434

-Hb ib zb'; ...

2548

h0 zb 0]\[h0'; zb' ;1];

2435

h0 zb 0]\[h0'; zb' ;1];

2549

2436

2550

%% re-adjust Nw to number of used taps

2437

%% re-adjust Nw to number of used taps

2551

if param.N_bg ~= 0

2438

if param.N_bg ~= 0

2552

Nw=Nwft;

2439

Nw=Nwft;

2553

end

2440

end

2554

%% check equalized pulse

2441

%% check equalized pulse

2555

w=wbl(1:Nw);

2442

w=wbl(1:Nw);

2556

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2443

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2557

2444

2558

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2445

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2559

blim = min(bmax(:), max(bmin(:), b));

2446

blim = min(bmax(:), max(bmin(:), b));

2560

if (Nb > 0) && ~isequal(b, blim)

2447

if (Nb > 0) && ~isequal(b, blim)

2561

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2448

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2562

w = wl(1:Nw);

2449

w = wl(1:Nw);

2563

end

2450

end

2564

2451

2565

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2452

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2566

%so need to chop off the extra indices on wmax and wmin

2453

%so need to chop off the extra indices on wmax and wmin

2567

if length(w)<length(wmax)

2454

if length(w)<length(wmax)

2568

wmax=wmax(1:length(w));

2455

wmax=wmax(1:length(w));

2569

wmin=wmin(1:length(w));

2456

wmin=wmin(1:length(w));

2570

end

2457

end

2571

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2458

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2572

if ~isequal(w, wlim)

2459

if ~isequal(w, wlim)

2573

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2460

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2574

if Nb > 0

2461

if Nb > 0

2575

b = Hb*wlim; % Update the feedback coefficients.

2462

b = Hb*wlim; % Update the feedback coefficients.

2576

blim = min(bmax(:), max(bmin(:), b));

2463

blim = min(bmax(:), max(bmin(:), b));

2577

end

2464

end

2578

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2465

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2579

% wl = wl(1:Nw);

2466

wl = wl(1:Nw);

2580

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2467

w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2581

end

2468

end

2582

% w=w(1:Nw) ;

2469

w=w(1:Nw) ;

2583

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2470

sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2584

w=wlim;

2585

b=blim;

2586

sigma_e=sqrt(sigma_X2*(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b)); % Commit request 4p4_5 from healey_3dj_COM_01_240416

2587

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2471

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2588

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2472

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2589

2473

2590

%not all output_args are filled here but most are

2474

%not all output_args are filled here but most are

2591

2475

2592

switch lower(OP.TDECQ)

2476

switch lower(OP.TDECQ)

2593

case { false 'none' } % should be the default

2477

case { false 'none' } % should be the default

2594

output_args.VMA=[];

2478

output_args.VMA=[];

2595

case 'vma'

2479

case 'vma'

2596

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2480

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2597

output_args.VMA=est_vma.VMA;

2481

output_args.VMA=est_vma.VMA;

2598

otherwise

2482

otherwise

2599

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2483

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2600

end

2484

end

2601

2485

2602

fileset_str=str2csv({chdata.base});

2486

fileset_str=str2csv({chdata.base});

2603

output_args.file_names=sprintf('"%s"', fileset_str);

2487

output_args.file_names=sprintf('"%s"', fileset_str);

2604

% [ahealey] Echo the termination parameters in the output arguments..

2488

% [ahealey] Echo the termination parameters in the output arguments..

2605

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2489

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2606

output_args.(odt_param{:}) = param.(odt_param{:});

2490

output_args.(odt_param{:}) = param.(odt_param{:});

2607

end

2491

end

2608

% [ahealey] End of modifications.

2492

% [ahealey] End of modifications.

2609

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2493

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2610

output_args.(pkg_params{:})= param.(pkg_params{:});

2494

output_args.(pkg_params{:})= param.(pkg_params{:});

2611

end

2495

end

2612

output_args.baud_rate_GHz=param.fb/1e9;

2496

output_args.baud_rate_GHz=param.fb/1e9;

2613

output_args.f_Nyquist_GHz = param.fb/2e9;

2497

output_args.f_Nyquist_GHz = param.fb/2e9;

2614

output_args.BER=param.specBER;

2498

output_args.BER=param.specBER;

2615

output_args.FOM = fom_result.FOM;

2499

output_args.FOM = fom_result.FOM;

2616

output_args.sigma_N=Noise_Struct.sigma_N;

2500

output_args.sigma_N=Noise_Struct.sigma_N;

2617

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2501

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2618

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2502

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2619

output_args.tail_RSS=fom_result.tail_RSS;

2503

output_args.tail_RSS=fom_result.tail_RSS;

2620

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2504

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2621

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2505

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2622

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2506

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2623

try

2507

try

2624

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2508

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2625

catch

2509

catch

2626

output_args.uneq_FIR_peak_time=[];

2510

output_args.uneq_FIR_peak_time=[];

2627

end

2511

end

2628

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2512

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2629

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2513

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2630

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2514

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2631

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2515

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2632

2516

2633

if OP.RX_CALIBRATION== 1

2517

if OP.RX_CALIBRATION== 1

2634

output_args.sigma_bn=sigma_bn;

2518

output_args.sigma_bn=sigma_bn;

2635

else

2519

else

2636

output_args.sigma_bn=[];

2520

output_args.sigma_bn=[];

2637

end

2521

end

2638

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2522

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2639

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2523

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2640

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2524

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2641

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2525

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2642

2526

2643

if OP.RX_CALIBRATION == 0

2527

if OP.RX_CALIBRATION == 0

2644

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2528

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2645

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2529

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2646

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2530

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2647

else

2531

else

2648

output_args.peak_MDXTK_interference_at_BER_mV=[];

2532

output_args.peak_MDXTK_interference_at_BER_mV=[];

2649

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2533

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2650

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2534

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2651

end

2535

end

2652

%output_args.ICN_mV=ICN*1000;

2536

%output_args.ICN_mV=ICN*1000;

2653

% output_args.ICN_test_mV=ICN_test*1000;

2537

% output_args.ICN_test_mV=ICN_test*1000;

2654

xtk=param.num_next+param.num_fext;

2538

xtk=param.num_next+param.num_fext;

2655

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2539

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2656

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2540

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2657

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2541

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2658

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2542

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2659

else

2543

else

2660

output_args.MDNEXT_ICN_92_46_mV=0;

2544

output_args.MDNEXT_ICN_92_46_mV=0;

2661

output_args.MDFEXT_ICN_92_47_mV=0;

2545

output_args.MDFEXT_ICN_92_47_mV=0;

2662

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2546

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2663

end

2547

end

2664

%output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(A_s/(peak_interference_at_BER/qfuncinv(param.specBER))); modified by Yasuo Hidaka, 8/7/17

2548

%output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(A_s/(peak_interference_at_BER/qfuncinv(param.specBER))); modified by Yasuo Hidaka, 8/7/17

2665

if 1

2549

if 1

2666

output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(COM_SNR_Struct.A_s/(Noise_Struct.peak_interference_at_BER/sqrt(2)/erfcinv(2*param.specBER)));

2550

output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(COM_SNR_Struct.A_s/(Noise_Struct.peak_interference_at_BER/sqrt(2)/erfcinv(2*param.specBER)));

2667

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2551

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2668

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2552

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2669

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2553

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2670

end

2554

end

2671

2555

2672

2556

2673

switch param.CTLE_type

2557

switch param.CTLE_type

2674

case 'CL93'

2558

case 'CL93'

2675

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2559

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2676

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2560

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2677

output_args.g_DC_HP=[];

2561

output_args.g_DC_HP=[];

2678

output_args.HP_poles_zero=[];

2562

output_args.HP_poles_zero=[];

2679

case 'CL120d'

2563

case 'CL120d'

2680

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2564

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2681

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2565

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2682

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2566

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2683

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2567

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2684

case 'CL120e'

2568

case 'CL120e'

2685

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.f_HP_Z(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle) param.f_HP_P(fom_result.ctle)];

2569

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.f_HP_Z(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle) param.f_HP_P(fom_result.ctle)];

2686

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2570

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2687

output_args.g_DC_HP=[];

2571

output_args.g_DC_HP=[];

2688

output_args.HP_poles_zero=[];

2572

output_args.HP_poles_zero=[];

2689

end

2573

end

2690

output_args.TXLE_taps=fom_result.txffe;

2574

output_args.TXLE_taps=fom_result.txffe;

2691

if length(output_args.TXLE_taps) >= 3

2575

if length(output_args.TXLE_taps) >= 3

2692

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2576

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2693

else

2577

else

2694

output_args.Pre2Pmax=[];

2578

output_args.Pre2Pmax=[];

2695

end

2579

end

2696

output_args.DFE_taps=fom_result.DFE_taps;

2580

output_args.DFE_taps=fom_result.DFE_taps;

2697

if param.Floating_DFE || param.Floating_RXFFE

2581

if param.Floating_DFE || param.Floating_RXFFE

2698

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2582

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2699

else

2583

else

2700

output_args.floating_tap_locations=[];

2584

output_args.floating_tap_locations=[];

2701

end

2585

end

2702

2586

2703

if OP.RxFFE

2587

if OP.RxFFE

2704

output_args.RxFFE=fom_result.RxFFE;

2588

output_args.RxFFE=fom_result.RxFFE;

2705

output_args.RxFFEgain=param.current_ffegain;

2589

output_args.RxFFEgain=param.current_ffegain;

2706

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2590

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2707

output_args.RxFFE=[];

2591

output_args.RxFFE=[];

2708

output_args.RxFFEgain=[];

2592

output_args.RxFFEgain=[];

2709

end

2593

end

2710

2594

2711

output_args.itick=fom_result.itick;

2595

output_args.itick=fom_result.itick;

2712

2596

2713

% Calculation of error propagation and burst probability

2597

% Calculation of error propagation and burst probability

2714

if OP.nburst>0

2598

if OP.nburst>0

2715

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2599

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2716

output_args.error_propagation_probability = p_error_propagation;

2600

output_args.error_propagation_probability = p_error_propagation;

2717

output_args.burst_probabilities = p_burst;

2601

output_args.burst_probabilities = p_burst;

2718

else

2602

else

2719

output_args.error_propagation_probability = [];

2603

output_args.error_propagation_probability = [];

2720

output_args.burst_probabilities = [];

2604

output_args.burst_probabilities = [];

2721

end

2605

end

2722

2606

2723

2607

2724

%begin yasuo patch 12/11/2018

2608

%begin yasuo patch 12/11/2018

2725

% collect sigma values to report

2609

% collect sigma values to report

2726

% pdf2sgm() is a function to calculate sigma value from PDF

2610

% pdf2sgm() is a function to calculate sigma value from PDF

2727

% It is added at the end of this file code.

2611

% It is added at the end of this file code.

2728

% I am not sure if an equivalent function already exists.

2612

% I am not sure if an equivalent function already exists.

2729

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2613

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2730

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2614

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2731

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2615

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2732

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2616

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2733

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2617

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2734

output_args.sgm_G = Noise_Struct.sigma_G;

2618

output_args.sgm_G = Noise_Struct.sigma_G;

2735

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2619

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2736

output_args.sgm_N = Noise_Struct.sigma_N;

2620

output_args.sgm_N = Noise_Struct.sigma_N;

2737

output_args.sgm_TX = Noise_Struct.sigma_TX;

2621

output_args.sgm_TX = Noise_Struct.sigma_TX;

2738

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2622

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2739

if OP.RX_CALIBRATION == 0

2623

if OP.RX_CALIBRATION == 0

2740

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2624

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2741

else

2625

else

2742

output_args.sgm_xt=[];

2626

output_args.sgm_xt=[];

2743

end

2627

end

2744

% end yasuo patch

2628

% end yasuo patch

2745

2629

2746

% r259 putting COM, VEO and loss last in report

2630

% r259 putting COM, VEO and loss last in report

2747

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2631

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2748

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2632

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2749

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2633

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2750

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2634

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2751

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2635

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2752

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2636

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2753

output_args.VEO_window_mUI= param.T_O;

2637

output_args.VEO_window_mUI= param.T_O;

2754

else

2638

else

2755

output_args.EW_UI_est=[];

2639

output_args.EW_UI_est=[];

2756

output_args.eye_contour=[];

2640

output_args.eye_contour=[];

2757

output_args.VEO_window_mUI= [];

2641

output_args.VEO_window_mUI= [];

2758

end

2642

end

2759

2643

2760

if sum(param.AC_CM_RMS) ~= 0

2644

if sum(param.AC_CM_RMS) ~= 0

2761

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2645

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2762

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2646

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2763

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2647

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2764

else

2648

else

2765

output_args.sigma_ACCM_at_tp0_mV=[];

2649

output_args.sigma_ACCM_at_tp0_mV=[];

2766

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2650

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2767

end

2651

end

2768

if OP.MLSE

2652

if OP.MLSE

2769

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2653

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2770

output_args.VEC_dB_orig=COM_SNR_Struct.VEC_dB_orig;

2654

output_args.VEC_dB_orig=COM_SNR_Struct.VEC_dB_orig;

2771

end

2655

end

2772

%

2656

%

2773

output_args.COM_dB=COM_SNR_Struct.COM;

2657

output_args.COM_dB=COM_SNR_Struct.COM;

2774

% end yasuo patch

2658

% end yasuo patch

2775

% begin yasuo patch 3/18/2019

2659

% begin yasuo patch 3/18/2019

2776

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2660

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2777

% end yasuo patch

2661

% end yasuo patch

2778

function [ seq syms syms_nrz ] = PRBS13Q( )

2662

function [ seq syms syms_nrz ] = PRBS13Q( )

2779

%UNTITLED Summary of this function goes here

2663

%UNTITLED Summary of this function goes here

2780

% Detailed explanation goes here

2664

% Detailed explanation goes here

2781

2665

2782

2666

2783

taps = ([13 12 2 1]);

2667

taps = ([13 12 2 1]);

2784

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2668

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2785

[seq_nrz c] =LFSR(seed,taps);

2669

[seq_nrz c] =LFSR(seed,taps);

2786

seq_nrz=2*(seq_nrz-0.5);

2670

seq_nrz=2*(seq_nrz-0.5);

2787

seq=pam(seq_nrz);

2671

seq=pam(seq_nrz);

2788

% syms=round(2*(seq+1));

2672

% syms=round(2*(seq+1));

2789

syms((round(2*(seq+1))/2==2))=3;

2673

syms((round(2*(seq+1))/2==2))=3;

2790

syms((round(2*(seq+1))/2==1.5))=2;

2674

syms((round(2*(seq+1))/2==1.5))=2;

2791

syms((round(2*(seq+1))/2==.5))=1;

2675

syms((round(2*(seq+1))/2==.5))=1;

2792

syms((round(2*(seq+1))/2==0))=0;

2676

syms((round(2*(seq+1))/2==0))=0;

2793

2677

2794

% syms_nrz=((seq_nrz+1)/2);

2678

% syms_nrz=((seq_nrz+1)/2);

2795

2679

2796

syms_nrz=seq_nrz;

2680

syms_nrz=seq_nrz;

2797

2681

2798

2682

2799

function[seq c]=LFSR(s,t)

2683

function[seq c]=LFSR(s,t)

2800

%s=initial state of LFSR, you can choose any lenght of LFSR

2684

%s=initial state of LFSR, you can choose any lenght of LFSR

2801

%Instruction:==========

2685

%Instruction:==========

2802

%Save LFSR.m in your current directory and type following

2686

%Save LFSR.m in your current directory and type following

2803

%on Command window for simulating 5 bit LFSR with tap [5 2]

2687

%on Command window for simulating 5 bit LFSR with tap [5 2]

2804

%---------------------

2688

%---------------------

2805

%>>s=[1 1 0 0 1]

2689

%>>s=[1 1 0 0 1]

2806

%>>t=[5 2]

2690

%>>t=[5 2]

2807

%>>[seq c] =LFSR(s,t)

2691

%>>[seq c] =LFSR(s,t)

2808

%---------------------------

2692

%---------------------------

2809

%seq = generated sequence

2693

%seq = generated sequence

2810

%c will be matrix containing the states of LFSR raw wise

2694

%c will be matrix containing the states of LFSR raw wise

2811

%

2695

%

2812

%-----------------------------------------------------------

2696

%-----------------------------------------------------------

2813

%If any doubt, confusion or feedback please contact me

2697

%If any doubt, confusion or feedback please contact me

2814

% NIKESH BAJAJ

2698

% NIKESH BAJAJ

2815

% bajaj.nikkey@gmail.com (+91-9915522564)

2699

% bajaj.nikkey@gmail.com (+91-9915522564)

2816

% Asst. Professor at Lovely Profesional University

2700

% Asst. Professor at Lovely Profesional University

2817

% Masters from Aligarh Muslim University,INDIA

2701

% Masters from Aligarh Muslim University,INDIA

2818

%--------------------------------------------------

2702

%--------------------------------------------------

2819

n=length(s);

2703

n=length(s);

2820

c(1,:)=s;

2704

c(1,:)=s;

2821

m=length(t);

2705

m=length(t);

2822

for k=1:2^n-2;

2706

for k=1:2^n-2;

2823

b(1)=xor(s(t(1)), s(t(2)));

2707

b(1)=xor(s(t(1)), s(t(2)));

2824

if m>2;

2708

if m>2;

2825

for i=1:m-2;

2709

for i=1:m-2;

2826

b(i+1)=xor(s(t(i+2)), b(i));

2710

b(i+1)=xor(s(t(i+2)), b(i));

2827

end

2711

end

2828

end

2712

end

2829

j=1:n-1;

2713

j=1:n-1;

2830

s(n+1-j)=s(n-j);

2714

s(n+1-j)=s(n-j);

2831

s(1)=b(m-1);

2715

s(1)=b(m-1);

2832

c(k+1,:)=s;

2716

c(k+1,:)=s;

2833

end

2717

end

2834

seq=c(:,n)';

2718

seq=c(:,n)';

2835

2719

2836

function [ dataout ] = pam( data )

2720

function [ dataout ] = pam( data )

2837

% mapping data usng Grey Coding

2721

% mapping data usng Grey Coding

2838

for i=1:2:floor(length(data)/2)*2

2722

for i=1:2:floor(length(data)/2)*2

2839

if data(i:i+1)==[ -1 -1 ]

2723

if data(i:i+1)==[ -1 -1 ]

2840

dataout(ceil(i/2)) = -1;

2724

dataout(ceil(i/2)) = -1;

2841

elseif data(i:i+1)==[ -1 1 ]

2725

elseif data(i:i+1)==[ -1 1 ]

2842

dataout(ceil(i/2)) = -1/3;

2726

dataout(ceil(i/2)) = -1/3;

2843

elseif data(i:i+1)==[ 1 1 ]

2727

elseif data(i:i+1)==[ 1 1 ]

2844

dataout(ceil(i/2)) = 1/3;

2728

dataout(ceil(i/2)) = 1/3;

2845

elseif data(i:i+1)==[ 1 -1 ]

2729

elseif data(i:i+1)==[ 1 -1 ]

2846

dataout(ceil(i/2)) = 1;

2730

dataout(ceil(i/2)) = 1;

2847

end

2731

end

2848

end

2732

end

2849

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2733

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2850

db = @(x) 20*log10(abs(x));

2734

db = @(x) 20*log10(abs(x));

2851

disp('computing TD_RILN...')

2735

disp('computing TD_RILN...')

2852

sdd21=squeeze(sdd21);

2736

sdd21=squeeze(sdd21);

2853

if iscolumn(sdd21)

2737

if iscolumn(sdd21)

2854

sdd21=sdd21.';

2738

sdd21=sdd21.';

2855

end

2739

end

2856

RIL=squeeze(RIL);

2740

RIL=squeeze(RIL);

2857

if iscolumn(RIL)

2741

if iscolumn(RIL)

2858

RIL=RIL.';

2742

RIL=RIL.';

2859

end

2743

end

2860

print_for_codereview=1;

2744

print_for_codereview=1;

2861

if exist('OP','var')

2745

if exist('OP','var')

2862

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2746

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2863

2747

2864

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2748

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2865

H_bw=Butterworth_Filter(param,faxis_f2,1);

2749

H_bw=Butterworth_Filter(param,faxis_f2,1);

2866

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2750

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2867

H_tw=Tukey_Window(faxis_f2,param);

2751

H_tw=Tukey_Window(faxis_f2,param);

2868

H_tw=ones(1,length(faxis_f2) );

2752

H_tw=ones(1,length(faxis_f2) );

2869

[RILN_TD_struct.REF.FIR, ...

2753

[RILN_TD_struct.REF.FIR, ...

2870

RILN_TD_struct.REF.t, ...

2754

RILN_TD_struct.REF.t, ...

2871

RILN_TD_struct.REF.causality_correction_dB, ...

2755

RILN_TD_struct.REF.causality_correction_dB, ...

2872

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2756

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2873

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2757

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2874

[RILN_TD_struct.FIT.FIR, ...

2758

[RILN_TD_struct.FIT.FIR, ...

2875

RILN_TD_struct.FIT.t, ...

2759

RILN_TD_struct.FIT.t, ...

2876

RILN_TD_struct.FIT.causality_correction_dB, ...

2760

RILN_TD_struct.FIT.causality_correction_dB, ...

2877

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2761

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2878

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2762

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2879

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2763

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2880

NrangeUI=1000;

2764

NrangeUI=1000;

2881

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2765

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2882

range=ipeak:range_end;

2766

range=ipeak:range_end;

2883

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2767

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2884

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2768

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2885

RILN_TD_struct.FOM=-inf;

2769

RILN_TD_struct.FOM=-inf;

2886

RILN_TD_struct.FOM_PDF=-inf;

2770

RILN_TD_struct.FOM_PDF=-inf;

2887

rms_fom=-inf;

2771

rms_fom=-inf;

2888

for im=1:param.samples_per_ui

2772

for im=1:param.samples_per_ui

2889

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2773

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2890

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2774

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2891

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2775

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2892

cdf=pdf; cdf.y=cumsum(pdf.y);

2776

cdf=pdf; cdf.y=cumsum(pdf.y);

2893

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2777

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2894

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2778

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2895

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2779

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2896

if print_for_codereview % remove once all checked out

2780

if print_for_codereview % remove once all checked out

2897

h=figure(191);set(gcf,'Tag','COM');

2781

h=figure(191);set(gcf,'Tag','COM');

2898

semilogy(-cdf.x,cdf.y);

2782

semilogy(-cdf.x,cdf.y);

2899

% xlim ([0,-cdf.x(1)])

2783

% xlim ([0,-cdf.x(1)])

2900

ylim([param.specBER 1]);title ('CDF of RILN')

2784

ylim([param.specBER 1]);title ('CDF of RILN')

2901

hold on

2785

hold on

2902

end

2786

end

2903

if rms>rms_fom

2787

if rms>rms_fom

2904

rms_fom=rms;

2788

rms_fom=rms;

2905

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2789

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2906

RILN_TD_struct.PDF=pdf;

2790

RILN_TD_struct.PDF=pdf;

2907

end

2791

end

2908

end

2792

end

2909

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2793

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2910

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2794

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2911

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2795

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2912

if print_for_codereview % remove once all checked out

2796

if print_for_codereview % remove once all checked out

2913

figure(9003);set(gcf,'Tag','COM');

2797

figure(9003);set(gcf,'Tag','COM');

2914

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2798

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2915

hold on

2799

hold on

2916

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2800

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2917

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2801

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2918

hold off

2802

hold off

2919

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

2803

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

2920

figure(9004);set(gcf,'Tag','COM');

2804

figure(9004);set(gcf,'Tag','COM');

2921

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2805

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2922

hold on

2806

hold on

2923

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2807

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2924

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2808

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2925

grid on

2809

grid on

2926

legend('show')

2810

legend('show')

2927

end

2811

end

2928

end

2812

end

2929

function is_illegal=RXFFE_Illegal(C,param,last_index)

2813

function is_illegal=RXFFE_Illegal(C,param,last_index)

2930

2814

2931

%check if RXFFE taps are illegal

2815

%check if RXFFE taps are illegal

2932

%C = RXFFE taps

2816

%C = RXFFE taps

2933

%param = COM param struct

2817

%param = COM param struct

2934

%last_index is used when computing illegality prior to Backoff. It will be set so taps

2818

%last_index is used when computing illegality prior to Backoff. It will be set so taps

2935

% in the Backoff region are not considered in the legality check.

2819

% in the Backoff region are not considered in the legality check.

2936

2820

2937

%If last index is omitted, set it to length(C)

2821

%If last index is omitted, set it to length(C)

2938

if nargin<3

2822

if nargin<3

2939

last_index=length(C);

2823

last_index=length(C);

2940

end

2824

end

2941

2825

2942

is_illegal=0;

2826

is_illegal=0;

2943

2827

2944

%Check cursor tap

2828

%Check cursor tap

2945

Ccur_i=param.RxFFE_cmx+1;

2829

Ccur_i=param.RxFFE_cmx+1;

2946

if C(Ccur_i) < param.ffe_main_cursor_min

2830

if C(Ccur_i) < param.ffe_main_cursor_min

2947

is_illegal=1;

2831

is_illegal=1;

2948

return;

2832

return;

2949

end

2833

end

2950

2834

2951

%Check postcursors

2835

%Check postcursors

2952

if param.ffe_post_tap_len ~=0

2836

if param.ffe_post_tap_len ~=0

2953

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

2837

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

2954

is_illegal=1;

2838

is_illegal=1;

2955

return;

2839

return;

2956

end

2840

end

2957

if (param.ffe_post_tap_len > 1)

2841

if (param.ffe_post_tap_len > 1)

2958

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

2842

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

2959

is_illegal=1;

2843

is_illegal=1;

2960

return;

2844

return;

2961

end

2845

end

2962

end

2846

end

2963

end

2847

end

2964

2848

2965

%Check precursors

2849

%Check precursors

2966

if param.ffe_pre_tap_len ~=0

2850

if param.ffe_pre_tap_len ~=0

2967

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

2851

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

2968

is_illegal=1;

2852

is_illegal=1;

2969

return;

2853

return;

2970

end

2854

end

2971

if (param.ffe_pre_tap_len > 1)

2855

if (param.ffe_pre_tap_len > 1)

2972

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

2856

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

2973

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

2857

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

2974

is_illegal=1;

2858

is_illegal=1;

2975

return;

2859

return;

2976

end % 11.22.2018 Yasou Hadaka

2860

end % 11.22.2018 Yasou Hadaka

2977

end

2861

end

2978

end

2862

end

2979

function S =R_series2(zref,f,R)

2863

function S =R_series2(zref,f,R)

2980

r=ones(1,length(f))*R;

2864

r=ones(1,length(f))*R;

2981

S.Parameters(1,1,:) = r./(r + 2*zref);

2865

S.Parameters(1,1,:) = r./(r + 2*zref);

2982

S.Parameters(2,2,:) = r./(r + 2*zref);

2866

S.Parameters(2,2,:) = r./(r + 2*zref);

2983

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

2867

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

2984

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

2868

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

2985

% Sm=sparameters(S.Parameters,f,zref);

2869

% Sm=sparameters(S.Parameters,f,zref);

2986

2870

2987

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

2871

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

2988

2872

2989

if use_RC

2873

if use_RC

2990

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

2874

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

2991

else

2875

else

2992

H_tw=ones(1,length(f));

2876

H_tw=ones(1,length(f));

2993

end

2877

end

2994

function SLD=SL(S,f,R)

2878

function SLD=SL(S,f,R)

2995

% source load impact return loss add to S21

2879

% source load impact return loss add to S21

2996

% S and SLD are the same structure

2880

% S and SLD are the same structure

2997

% S.Parameters

2881

% S.Parameters

2998

% S.Impedance

2882

% S.Impedance

2999

% S.NumPorts

2883

% S.NumPorts

3000

% S.Frequencies

2884

% S.Frequencies

3001

SLD=S; % assign the fields

2885

SLD=S; % assign the fields

3002

zref=100;

2886

zref=100;

3003

if R==0

2887

if R==0

3004

warndlg('Termination should not be set to zero');

2888

warndlg('Termination should not be set to zero');

3005

SLD=S;

2889

SLD=S;

3006

return

2890

return

3007

end

2891

end

3008

2892

3009

if R > zref

2893

if R > zref

3010

spr =R_series2(zref,f,(R-zref)); % make series sparameter

2894

spr =R_series2(zref,f,(R-zref)); % make series sparameter

3011

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

2895

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

3012

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2896

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3013

combines4p( ...

2897

combines4p( ...

3014

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2898

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3015

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2899

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3016

);

2900

);

3017

elseif R < zref

2901

elseif R < zref

3018

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

2902

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

3019

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

2903

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

3020

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2904

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3021

combines4p( ...

2905

combines4p( ...

3022

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2906

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3023

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2907

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3024

);

2908

);

3025

else

2909

else

3026

SLD=S;

2910

SLD=S;

3027

end

2911

end

3028

2912

3029

%%

2913

%%

3030

2914

3031

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

2915

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

3032

p1=param.CTLE_fp1(1);

2916

p1=param.CTLE_fp1(1);

3033

z1=param.CTLE_fz(1);

2917

z1=param.CTLE_fz(1);

3034

p2=param.CTLE_fp2(1);

2918

p2=param.CTLE_fp2(1);

3035

zlf=param.f_HP(1);

2919

zlf=param.f_HP(1);

3036

plf=param.f_HP(1);

2920

plf=param.f_HP(1);

3037

f_b=param.fb;

2921

f_b=param.fb;

3038

f_r=param.f_r;

2922

f_r=param.f_r;

3039

eta_0=param.eta_0;

2923

eta_0=param.eta_0;

3040

H_CTF = ( 10^(G_DC/20)+ 1i*f/z1 ) .*( 10^(G_DC2/20) + 1i*f/zlf )./ ( ( 1+1i*f/p1) .* ( 1+1i*f/p2) .* ( 1+1i*f/plf));

2924

H_CTF = ( 10^(G_DC/20)+ 1i*f/z1 ) .*( 10^(G_DC2/20) + 1i*f/zlf )./ ( ( 1+1i*f/p1) .* ( 1+1i*f/p2) .* ( 1+1i*f/plf));

3041

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

2925

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

3042

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

2926

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

3043

if 0

2927

if 0

3044

figure

2928

figure

3045

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

2929

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

3046

% see if it looks correct

2930

% see if it looks correct

3047

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

2931

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

3048

ylabel('dB');

2932

ylabel('dB');

3049

xlabel('GHz');

2933

xlabel('GHz');

3050

title( 'H_ctf with H_r')

2934

title( 'H_ctf with H_r')

3051

grid on

2935

grid on

3052

ylim([-30 0])

2936

ylim([-30 0])

3053

end

2937

end

3054

2938

3055

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

2939

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

3056

2940

3057

%Fill TDR data

2941

%Fill TDR data

3058

if package_testcase_i == 1

2942

if package_testcase_i == 1

3059

if OP.TDR

2943

if OP.TDR

3060

output_args.Z11est=chdata(1).TDR11.avgZport;

2944

output_args.Z11est=chdata(1).TDR11.avgZport;

3061

if ~param.FLAG.S2P

2945

if ~param.FLAG.S2P

3062

output_args.Z22est=chdata(1).TDR22.avgZport;

2946

output_args.Z22est=chdata(1).TDR22.avgZport;

3063

else

2947

else

3064

output_args.Z22est=[];

2948

output_args.Z22est=[];

3065

end

2949

end

3066

if OP.AUTO_TFX

2950

if OP.AUTO_TFX

3067

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

2951

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

3068

else

2952

else

3069

output_args.tfx_estimate=[];

2953

output_args.tfx_estimate=[];

3070

end

2954

end

3071

else

2955

else

3072

output_args.Z11est=[];

2956

output_args.Z11est=[];

3073

output_args.Z22est=[];

2957

output_args.Z22est=[];

3074

output_args.tfx_estimate=[];

2958

output_args.tfx_estimate=[];

3075

end

2959

end

3076

end

2960

end

3077

2961

3078

% Process ERL

2962

% Process ERL

3079

if package_testcase_i == 1

2963

if package_testcase_i == 1

3080

if OP.ERL

2964

if OP.ERL

3081

output_args.ERL11=chdata(1).TDR11.ERL;

2965

output_args.ERL11=chdata(1).TDR11.ERL;

3082

if ~param.FLAG.S2P

2966

if ~param.FLAG.S2P

3083

output_args.ERL22=chdata(1).TDR22.ERL;

2967

output_args.ERL22=chdata(1).TDR22.ERL;

3084

else

2968

else

3085

output_args.ERL22=[];

2969

output_args.ERL22=[];

3086

end

2970

end

3087

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

2971

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

3088

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

2972

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

3089

else

2973

else

3090

output_args.ERL11=[];

2974

output_args.ERL11=[];

3091

output_args.ERL22=[];

2975

output_args.ERL22=[];

3092

end

2976

end

3093

end

2977

end

3094

if OP.ERL

2978

if OP.ERL

3095

if OP.TDR_W_TXPKG

2979

if OP.TDR_W_TXPKG

3096

min_ERL=output_args.ERL22;

2980

min_ERL=output_args.ERL22;

3097

ERL= [ nan output_args.ERL22 ];

2981

ERL= [ nan output_args.ERL22 ];

3098

else

2982

else

3099

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

2983

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

3100

min_ERL=output_args.ERL11;

2984

min_ERL=output_args.ERL11;

3101

ERL= [ output_args.ERL11 nan ];

2985

ERL= [ output_args.ERL11 nan ];

3102

else

2986

else

3103

min_ERL=min(output_args.ERL11,output_args.ERL22);

2987

min_ERL=min(output_args.ERL11,output_args.ERL22);

3104

ERL= [ output_args.ERL11 output_args.ERL22 ];

2988

ERL= [ output_args.ERL11 output_args.ERL22 ];

3105

end

2989

end

3106

end

2990

end

3107

output_args.ERL=min_ERL;

2991

output_args.ERL=min_ERL;

3108

else

2992

else

3109

min_ERL=[];

2993

min_ERL=[];

3110

ERL= [];

2994

ERL= [];

3111

output_args.ERL=[];

2995

output_args.ERL=[];

3112

end

2996

end

3113

if OP.ERL_ONLY

2997

if OP.ERL_ONLY

3114

if OP.BREAD_CRUMBS

2998

if OP.BREAD_CRUMBS

3115

output_args.OP=OP;

2999

output_args.OP=OP;

3116

output_args.param=param;

3000

output_args.param=param;

3117

output_args.chdata=chdata;

3001

output_args.chdata=chdata;

3118

%This seems to be the intent of setting fom_result.ran=0. Add it

3002

%This seems to be the intent of setting fom_result.ran=0. Add it

3119

%to output_args so there is a fom_result field.

3003

%to output_args so there is a fom_result field.

3120

fom_result.ran=0;

3004

fom_result.ran=0;

3121

output_args.fom_result=fom_result;

3005

output_args.fom_result=fom_result;

3122

end

3006

end

3123

output_args.Z_t=param.Z_t;

3007

output_args.Z_t=param.Z_t;

3124

fileset_str=str2csv({chdata(1).base});

3008

fileset_str=str2csv({chdata(1).base});

3125

output_args.file_names=sprintf('"%s"', fileset_str);

3009

output_args.file_names=sprintf('"%s"', fileset_str);

3126

if OP.DISPLAY_WINDOW

3010

if OP.DISPLAY_WINDOW

3127

savefigs(param, OP);

3011

savefigs(param, OP);

3128

end

3012

end

3129

end

3013

end

3130

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3014

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3131

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3015

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3132

p1_ctle = -2*pi*f_p1;

3016

p1_ctle = -2*pi*f_p1;

3133

p2_ctle = -2*pi*f_p2;

3017

p2_ctle = -2*pi*f_p2;

3134

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3018

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3135

k_ctle = -p2_ctle;

3019

k_ctle = -p2_ctle;

3136

bilinear_fs = 2*fb*oversampling;

3020

bilinear_fs = 2*fb*oversampling;

3137

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3021

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3138

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3022

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3139

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3023

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3140

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3024

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3141

% allow for different pole zeros RIM 9-29-2015

3025

% allow for different pole zeros RIM 9-29-2015

3142

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3026

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3143

B_filt =k_ctle*kd*poly([zd, -1]);

3027

B_filt =k_ctle*kd*poly([zd, -1]);

3144

A_filt=poly([p1d, p2d]);

3028

A_filt=poly([p1d, p2d]);

3145

impulse_response=filter(B_filt,A_filt,ir_in);

3029

impulse_response=filter(B_filt,A_filt,ir_in);

3146

3030

3147

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3031

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3148

Over_sample=2;

3032

Over_sample=2;

3149

num_files=length(chdata);

3033

num_files=length(chdata);

3150

for i=1:num_files

3034

for i=1:num_files

3151

V=chdata(i).uneq_pulse_response;

3035

V=chdata(i).uneq_pulse_response;

3152

T=chdata(i).t;

3036

T=chdata(i).t;

3153

dt=T(2)-T(1);

3037

dt=T(2)-T(1);

3154

f=0:1/max(T):1/dt;

3038

f=0:1/max(T):1/dt;

3155

chdata(i).faxis=f;

3039

chdata(i).faxis=f;

3156

f75=find(f >= param.fb*.75,1,'first');

3040

f75=find(f >= param.fb*.75,1,'first');

3157

fnq=find(f >= param.fb*.5,1,'first');

3041

fnq=find(f >= param.fb*.5,1,'first');

3158

chdata(i).fmaxi = length(f);

3042

chdata(i).fmaxi = length(f);

3159

chdata(i).faxis = f;

3043

chdata(i).faxis = f;

3160

UI=param.ui; % unit interval

3044

UI=param.ui; % unit interval

3161

M=param.samples_per_ui; % sample per UI

3045

M=param.samples_per_ui; % sample per UI

3162

N_v=param.N_v; % number of UI for Vf determination

3046

N_v=param.N_v; % number of UI for Vf determination

3163

3047

3164

% filters

3048

% filters

3165

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3049

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3166

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3050

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3167

H_ftr=H_bw.*H_bt;

3051

H_ftr=H_bw.*H_bt;

3168

H_ftr=H_ftr(:);

3052

H_ftr=H_ftr(:);

3169

% fd of PR

3053

% fd of PR

3170

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3054

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3171

prr = prr(:);

3055

prr = prr(:);

3172

if f(1)==0, prr(1)=1; end %remove NaN

3056

if f(1)==0, prr(1)=1; end %remove NaN

3173

fd=fft(V);

3057

fd=fft(V);

3174

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3058

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3175

3059

3176

%% get Vf

3060

%% get Vf

3177

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3061

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3178

step_response=filter(V,1, shifting_vector);

3062

step_response=filter(V,1, shifting_vector);

3179

Vf=step_response(end);

3063

Vf=step_response(end);

3180

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3064

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3181

%%

3065

%%

3182

% ILest=20.*log10(abs(fd(1:f75)/Vf/M/Over_sample)) - 20.*log10(abs(prr(1:f75))) - 20*log10(abs(squeeze(H_ftr(1:f75)))) ; %removing db function to avoid using sig proc toolbox

3066

% ILest=20.*log10(abs(fd(1:f75)/Vf/M/Over_sample)) - 20.*log10(abs(prr(1:f75))) - 20*log10(abs(squeeze(H_ftr(1:f75)))) ; %removing db function to avoid using sig proc toolbox

3183

% figure

3067

% figure

3184

% plot(f(1:f75),ILest)

3068

% plot(f(1:f75),ILest)

3185

3069

3186

IL_conv=fd(1:f75)/Vf/M/Over_sample ./ prr(1:f75) ./ H_ftr(1:f75) ; %removing db function to avoid using sig proc toolbox

3070

IL_conv=fd(1:f75)/Vf/M/Over_sample ./ prr(1:f75) ./ H_ftr(1:f75) ; %removing db function to avoid using sig proc toolbox

3187

% set same variables as get_s4p_files

3071

% set same variables as get_s4p_files

3188

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3072

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3189

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3073

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3190

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3074

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3191

zero_vector=zeros(length(IL_conv),1);

3075

zero_vector=zeros(length(IL_conv),1);

3192

for j=1:length(IL_fields)

3076

for j=1:length(IL_fields)

3193

chdata(i).(IL_fields{j})=IL_conv;

3077

chdata(i).(IL_fields{j})=IL_conv;

3194

end

3078

end

3195

for j=1:length(Zero_fields)

3079

for j=1:length(Zero_fields)

3196

chdata(i).(Zero_fields{j})=zero_vector;

3080

chdata(i).(Zero_fields{j})=zero_vector;

3197

end

3081

end

3198

3082

3199

if i==1

3083

if i==1

3200

SDDch(:,1,2)=chdata.sdd12_raw;

3084

SDDch(:,1,2)=chdata.sdd12_raw;

3201

SDDch(:,2,1)=chdata.sdd21_raw;

3085

SDDch(:,2,1)=chdata.sdd21_raw;

3202

SDDch(:,1,1)=chdata.sdd11_raw;

3086

SDDch(:,1,1)=chdata.sdd11_raw;

3203

SDDch(:,2,2)=chdata.sdd22_raw;

3087

SDDch(:,2,2)=chdata.sdd22_raw;

3204

SDDp2p= zeros(length(IL_conv),1);

3088

SDDp2p= zeros(length(IL_conv),1);

3205

end

3089

end

3206

chdata(i).TX_RL=[];

3090

chdata(i).TX_RL=[];

3207

chdata(i).TDR11=[];

3091

chdata(i).TDR11=[];

3208

chdata(i).PDTR11=[];

3092

chdata(i).PDTR11=[];

3209

chdata(i).TDR22=[];

3093

chdata(i).TDR22=[];

3210

chdata(i).PDTR22=[];

3094

chdata(i).PDTR22=[];

3211

end

3095

end

3212

3096

3213

3097

3214

function H_tw=Tukey_Window(f,param,fr,fb)

3098

function H_tw=Tukey_Window(f,param,fr,fb)

3215

% RIM 05/26/2022 added optional fr and fb

3099

% RIM 05/26/2022 added optional fr and fb

3216

% fr is the start of the raised cosine window

3100

% fr is the start of the raised cosine window

3217

% fb is the end of the raised cosine window

3101

% fb is the end of the raised cosine window

3218

if ~exist('fr','var') && ~exist('fb','var')

3102

if ~exist('fr','var') && ~exist('fb','var')

3219

fb=param.fb;

3103

fb=param.fb;

3220

fr=param.f_r*param.fb;

3104

fr=param.f_r*param.fb;

3221

end

3105

end

3222

fperiod=2*(fb-fr);

3106

fperiod=2*(fb-fr);

3223

H_tw = [ ones(1,length(f(f<fr))) ...

3107

H_tw = [ ones(1,length(f(f<fr))) ...

3224

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3108

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3225

zeros(1,length(f(f>fb)) )];

3109

zeros(1,length(f(f>fb)) )];

3226

H_tw=H_tw(1:length(f));

3110

H_tw=H_tw(1:length(f));

3227

if 0

3111

if 0

3228

plot(f/1e9,H_tw)

3112

plot(f/1e9,H_tw)

3229

end

3113

end

3230

3114

3231

3115

3232

3116

3233

%% moved output control to functions

3117

%% moved output control to functions

3234

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3118

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3235

% Author: Richard Mellitz

3119

% Author: Richard Mellitz

3236

% Date: 7/29/2022

3120

% Date: 7/29/2022

3237

% generate FD tx ffe system function

3121

% generate FD tx ffe system function

3238

% varagins...

3122

% varagins...

3239

% param - stucture

3123

% param - stucture

3240

% param.fb baud rate

3124

% param.fb baud rate

3241

% param.Tx_FFE Tx FFE coef

3125

% param.Tx_FFE Tx FFE coef

3242

% f - freq array

3126

% f - freq array

3243

% Use_Tx_FFE = flag to use or not

3127

% Use_Tx_FFE = flag to use or not

3244

% H_TxFFE is system function for Tx_FFE

3128

% H_TxFFE is system function for Tx_FFE

3245

db = @(x) 20*log10(abs(x));

3129

db = @(x) 20*log10(abs(x));

3246

[param,varargin]=varargin_extractor(varargin{:});

3130

[param,varargin]=varargin_extractor(varargin{:});

3247

[f,varargin]=varargin_extractor(varargin{:});

3131

[f,varargin]=varargin_extractor(varargin{:});

3248

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3132

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3249

if isempty(Use_Tx_FFE)

3133

if isempty(Use_Tx_FFE)

3250

Use_Tx_FFE=0;

3134

Use_Tx_FFE=0;

3251

end

3135

end

3252

if isempty(param)

3136

if isempty(param)

3253

param.fb=106.25e9;

3137

param.fb=106.25e9;

3254

Tx_FFE=[1 ];

3138

Tx_FFE=[1 ];

3255

else

3139

else

3256

if ~isfield(param, 'Pkg_TXFFE_preset')

3140

if ~isfield(param, 'Pkg_TXFFE_preset')

3257

Tx_FFE=[ 1 ];

3141

Tx_FFE=[ 1 ];

3258

else

3142

else

3259

Tx_FFE=param.Pkg_TXFFE_preset;

3143

Tx_FFE=param.Pkg_TXFFE_preset;

3260

end

3144

end

3261

end

3145

end

3262

if isempty(f)

3146

if isempty(f)

3263

f=0:10e6:param.fb;

3147

f=0:10e6:param.fb;

3264

end

3148

end

3265

3149

3266

3150

3267

if Use_Tx_FFE ~=0

3151

if Use_Tx_FFE ~=0

3268

[mcur,icur] = max(Tx_FFE);

3152

[mcur,icur] = max(Tx_FFE);

3269

H_TxFFE=zeros(1,length(f));

3153

H_TxFFE=zeros(1,length(f));

3270

for ii=1:length(Tx_FFE)

3154

for ii=1:length(Tx_FFE)

3271

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3155

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3272

end

3156

end

3273

else

3157

else

3274

H_TxFFE=ones(1,length(f));

3158

H_TxFFE=ones(1,length(f));

3275

end

3159

end

3276

% figure (1102320)

3160

% figure (1102320)

3277

% plot(f/1e9,db(H_TxFFE))

3161

% plot(f/1e9,db(H_TxFFE))

3278

% hold on

3162

% hold on

3279

function C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs)

3163

function C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs)

3280

cmx=param.RxFFE_cmx;

3164

cmx=param.RxFFE_cmx;

3281

cpx=param.RxFFE_cpx;

3165

cpx=param.RxFFE_cpx;

3282

% do this early on so we can reuse the old code

3166

% do this early on so we can reuse the old code

3283

% to be replaced with MMSE function from healey...

3167

% to be replaced with MMSE function from healey...

3284

if param.N_bg ~=0 % must be floating taps

3168

if param.N_bg ~=0 % must be floating taps

3285

cpx=param.N_bmax; % N_f in spreadsheet

3169

cpx=param.N_bmax; % N_f in spreadsheet

3286

end

3170

end

3287

num_taps=cmx+cpx+1;

3171

num_taps=cmx+cpx+1;

3288

ndfe=param.ndfe;

3172

ndfe=param.ndfe;

3289

spui=param.samples_per_ui;

3173

spui=param.samples_per_ui;

3290

%% Start of WIENER-HOPF MMSE EQ code

3174

%% Start of WIENER-HOPF MMSE EQ code

3291

R_n = zeros(num_taps,num_taps);

3175

R_n = zeros(num_taps,num_taps);

3292

R_xt = zeros(num_taps,num_taps);

3176

R_xt = zeros(num_taps,num_taps);

3293

3177

3294

if OP.Do_Colored_Noise

3178

if OP.Do_Colored_Noise

3295

% Form Noise Autocorrelation matrix

3179

% Form Noise Autocorrelation matrix

3296

Noise_XC = reshape (Noise_XC,1,[]);

3180

Noise_XC = reshape (Noise_XC,1,[]);

3297

len = length(Noise_XC);

3181

len = length(Noise_XC);

3298

if len < num_taps, Noise_XC = [Noise_XC,zeros(1,num_taps-len)]; end

3182

if len < num_taps, Noise_XC = [Noise_XC,zeros(1,num_taps-len)]; end

3299

Noise_XC = Noise_XC(1:num_taps);

3183

Noise_XC = Noise_XC(1:num_taps);

3300

R_n = toeplitz (Noise_XC,Noise_XC);

3184

R_n = toeplitz (Noise_XC,Noise_XC);

3301

end

3185

end

3302

%% Calculate Cross Talk Correlation matrix at T intervals.

3186

%% Calculate Cross Talk Correlation matrix at T intervals.

3303

if OP.Do_XT_Noise

3187

if OP.Do_XT_Noise

3304

% Calculate variance of Tx signal based on +/-1 outer limits

3188

% Calculate variance of Tx signal based on +/-1 outer limits

3305

Tx_sigma = sqrt( (param.levels^2-1)/(3*(param.levels-1)^2) );

3189

Tx_sigma = sqrt( (param.levels^2-1)/(3*(param.levels-1)^2) );

3306

for jj = 2:length(chdata)

3190

for jj = 2:length(chdata)

3307

if isequal(chdata(jj).type, 'FEXT') || isequal(chdata(jj).type, 'NEXT')

3191

if isequal(chdata(jj).type, 'FEXT') || isequal(chdata(jj).type, 'NEXT')

3308

if isequal(chdata(jj).type, 'FEXT')

3192

if isequal(chdata(jj).type, 'FEXT')

3309

% len = length(chdata(jj).ctle_imp_response);

3193

% len = length(chdata(jj).ctle_imp_response);

3310

% ch_imp = ifft( fft(reshape(chdata(jj).ctle_imp_response,1,[])) .* fft(reshape(upsample(txffe, param.samples_per_ui),1,[]),len) );

3194

% ch_imp = ifft( fft(reshape(chdata(jj).ctle_imp_response,1,[])) .* fft(reshape(upsample(txffe, param.samples_per_ui),1,[]),len) );

3311

ch_imp= FFE( txffe , cmx,param.samples_per_ui, chdata(jj).ctle_imp_response).';

3195

ch_imp= FFE( txffe , cmx,param.samples_per_ui, chdata(jj).ctle_imp_response).';

3312

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3196

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3313

elseif isequal(chdata(jj).type, 'NEXT')

3197

elseif isequal(chdata(jj).type, 'NEXT')

3314

ch_imp = chdata(jj).ctle_imp_response;

3198

ch_imp = chdata(jj).ctle_imp_response;

3315

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3199

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3316

end

3200

end

3317

norms = zeros(1,spui);

3201

norms = zeros(1,spui);

3318

for ii = 1:spui

3202

for ii = 1:spui

3319

norms(ii) = norm(ch_imp(ii:spui:end));

3203

norms(ii) = norm(ch_imp(ii:spui:end));

3320

end

3204

end

3321

% Pick out sampling phase with largest noise contribution

3205

% Pick out sampling phase with largest noise contribution

3322

[~,cursor] = max(norms);

3206

[~,cursor] = max(norms);

3323

sub_sample_ch = ch_imp(cursor:spui:end);

3207

sub_sample_ch = ch_imp(cursor:spui:end);

3324

xc = xcorr(sub_sample_ch,num_taps)* Tx_sigma^2;

3208

xc = xcorr(sub_sample_ch,num_taps)* Tx_sigma^2;

3325

xc = xc(num_taps+1:end);

3209

xc = xc(num_taps+1:end);

3326

xc = xc(1:num_taps);

3210

xc = xc(1:num_taps);

3327

R = toeplitz (xc,xc);

3211

R = toeplitz (xc,xc);

3328

R_xt = R_xt + R;

3212

R_xt = R_xt + R;

3329

end

3213

end

3330

end

3214

end

3331

end

3215

end

3332

%% Noise + Cross Talk contribution to R matrix

3216

%% Noise + Cross Talk contribution to R matrix

3333

R_n_xc = zeros(num_taps+ndfe);

3217

R_n_xc = zeros(num_taps+ndfe);

3334

R_n_xc(1:num_taps,1:num_taps) = R_n + R_xt ;

3218

R_n_xc(1:num_taps,1:num_taps) = R_n + R_xt ;

3335

%% For least means squares, we want to solve

3219

%% For least means squares, we want to solve

3336

%

3220

%

3337

% ro = |Ryy Ryx| * w

3221

% ro = |Ryy Ryx| * w

3338

% |Rxy Rxx|

3222

% |Rxy Rxx|

3339

% see Cioffi chapter 3, 3.7.3

3223

% see Cioffi chapter 3, 3.7.3

3340

3224

3341

himp = vsampled;

3225

himp = vsampled;

3342

RefTap = cmx+1;

3226

RefTap = cmx+1;

3343

Signal_Variance = mean ( [-1, -1/3, 1/3, 1].^2 );

3227

Signal_Variance = mean ( [-1, -1/3, 1/3, 1].^2 );

3344

Ryy.r = [1:num_taps];

3228

Ryy.r = [1:num_taps];

3345

Ryy.c = [1:num_taps];

3229

Ryy.c = [1:num_taps];

3346

Ryx.r = 1:num_taps;

3230

Ryx.r = 1:num_taps;

3347

Ryx.c = num_taps + (1:ndfe);

3231

Ryx.c = num_taps + (1:ndfe);

3348

Rxy.r = num_taps + (1:ndfe);

3232

Rxy.r = num_taps + (1:ndfe);

3349

Rxy.c = 1:num_taps;

3233

Rxy.c = 1:num_taps;

3350

Rxx.r = num_taps+(1:ndfe);

3234

Rxx.r = num_taps+(1:ndfe);

3351

Rxx.c = num_taps+(1:ndfe);

3235

Rxx.c = num_taps+(1:ndfe);

3352

himp = reshape (himp,1,[]);

3236

himp = reshape (himp,1,[]);

3353

%% ro is simply the channel response reversed in time

3237

%% ro is simply the channel response reversed in time

3354

himp_lr = fliplr(himp); % make sure himp has enough pre/post cursors, e.g. numtaps+ndfe

3238

himp_lr = fliplr(himp); % make sure himp has enough pre/post cursors, e.g. numtaps+ndfe

3355

himp_lr = [zeros(1,num_taps+ndfe), himp_lr, zeros(1,num_taps+ndfe)];

3239

himp_lr = [zeros(1,num_taps+ndfe), himp_lr, zeros(1,num_taps+ndfe)];

3356

[~,pk] = max(himp_lr);

3240

[~,pk] = max(himp_lr);

3357

r_indx = (1:num_taps) - RefTap;

3241

r_indx = (1:num_taps) - RefTap;

3358

ro = [himp_lr(pk+r_indx), zeros(1,ndfe)].';

3242

ro = [himp_lr(pk+r_indx), zeros(1,ndfe)].';

3359

ro = ro*Signal_Variance;

3243

ro = ro*Signal_Variance;

3360

%% Setup up the covariance matrix

3244

%% Setup up the covariance matrix

3361

R = zeros(num_taps+ndfe);

3245

R = zeros(num_taps+ndfe);

3362

% Form Ryy

3246

% Form Ryy

3363

% Note: important to use whole impulse response

3247

% Note: important to use whole impulse response

3364

% not just the part that spans the FFE.

3248

% not just the part that spans the FFE.

3365

[ryy,lags] = xcorr(himp,himp, num_taps-1);

3249

[ryy,lags] = xcorr(himp,himp, num_taps-1);

3366

R(Ryy.r,Ryy.c) = toeplitz (ryy(num_taps:end));

3250

R(Ryy.r,Ryy.c) = toeplitz (ryy(num_taps:end));

3367

3251

3368

% Form Rxx

3252

% Form Rxx

3369

R(Rxx.r,Rxx.c) = diag(ones(1,ndfe));

3253

R(Rxx.r,Rxx.c) = diag(ones(1,ndfe));

3370

3254

3371

% Form Ryx columns

3255

% Form Ryx columns

3372

Ryx_indxs = (1:num_taps)-1;

3256

Ryx_indxs = (1:num_taps)-1;

3373

for jj = 0:ndfe-1

3257

for jj = 0:ndfe-1

3374

% R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk+1 + Ryx_indxs -jj ).';

3258

% R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk+1 + Ryx_indxs -jj ).';

3375

R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk-cmx-1 + Ryx_indxs -jj ).';

3259

R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk-cmx-1 + Ryx_indxs -jj ).';

3376

end

3260

end

3377

% Form Rxy rows

3261

% Form Rxy rows

3378

R(Rxy.r,Rxy.c ) = R(Ryx.r,Ryx.c )';

3262

R(Rxy.r,Rxy.c ) = R(Ryx.r,Ryx.c )';

3379

3263

3380

% add in Signal Variance

3264

% add in Signal Variance

3381

R = R*Signal_Variance;

3265

R = R*Signal_Variance;

3382

Rtmp = R;

3266

Rtmp = R;

3383

% Add in Xt and colored noise terms

3267

% Add in Xt and colored noise terms

3384

R = R + R_n_xc;

3268

R = R + R_n_xc;

3385

3269

3386

% SNR = 25 dB

3270

% SNR = 25 dB

3387

SNR = OP.FFE_SNR;

3271

SNR = OP.FFE_SNR;

3388

Noise_var = max(vsampled)^2*Signal_Variance/10^(SNR/10);

3272

Noise_var = max(vsampled)^2*Signal_Variance/10^(SNR/10);

3389

R_noise = diag(ones(1,num_taps))*Noise_var;

3273

R_noise = diag(ones(1,num_taps))*Noise_var;

3390

if ~OP.Do_Colored_Noise && ~OP.Do_XT_Noise

3274

if ~OP.Do_Colored_Noise && ~OP.Do_XT_Noise

3391

R(Ryy.r,Ryy.c) = R(Ryy.r,Ryy.c) + R_noise;

3275

R(Ryy.r,Ryy.c) = R(Ryy.r,Ryy.c) + R_noise;

3392

end

3276

end

3393

3277

3394

3278

3395

%% Solve for equalizer weights

3279

%% Solve for equalizer weights

3396

w = inv(R)*ro;

3280

w = inv(R)*ro;

3397

C = w;

3281

C = w;

3398

%% Deal with 1st post Cursor DFE weight saturation

3282

%% Deal with 1st post Cursor DFE weight saturation

3399

% ro = Rw by moving "saturated" weights over to the LHS

3283

% ro = Rw by moving "saturated" weights over to the LHS

3400

DFE_h1_indx = num_taps+1;

3284

DFE_h1_indx = num_taps+1;

3401

Indx_full = 1:length(C);

3285

Indx_full = 1:length(C);

3402

ws = C;

3286

ws = C;

3403

if ndfe>0 && abs(C(DFE_h1_indx)) > param.bmax(1)

3287

if ndfe>0 && abs(C(DFE_h1_indx)) > param.bmax(1)

3404

rtmp = reshape (ro,[],1);

3288

rtmp = reshape (ro,[],1);

3405

Rtmp = R;

3289

Rtmp = R;

3406

% Move saturated DFE weights over to left hand side of equation

3290

% Move saturated DFE weights over to left hand side of equation

3407

ws = zeros (size(C));

3291

ws = zeros (size(C));

3408

ws (DFE_h1_indx) = sign(C(DFE_h1_indx))*param.bmax(1);

3292

ws (DFE_h1_indx) = sign(C(DFE_h1_indx))*param.bmax(1);

3409

rtmp = rtmp - Rtmp*ws;

3293

rtmp = rtmp - Rtmp*ws;

3410

3294

3411

% and remove the corresponding column from R

3295

% and remove the corresponding column from R

3412

Rtmp(:,DFE_h1_indx) = [];

3296

Rtmp(:,DFE_h1_indx) = [];

3413

Indx_full (DFE_h1_indx) = [];

3297

Indx_full (DFE_h1_indx) = [];

3414

% now Rtmp isn't square so have to use the R'R trick

3298

% now Rtmp isn't square so have to use the R'R trick

3415

% Probably a little dicey "theoretically" because

3299

% Probably a little dicey "theoretically" because

3416

% w = inv(R)*ro is already the mmse solution

3300

% w = inv(R)*ro is already the mmse solution

3417

% now we at doing a R'R operation, but hey

3301

% now we at doing a R'R operation, but hey

3418

% seems to work

3302

% seems to work

3419

% Alternative, since R is now over specified, more rows than

3303

% Alternative, since R is now over specified, more rows than

3420

% columns, one could try removing one of the DFE rows from the

3304

% columns, one could try removing one of the DFE rows from the

3421

% Rxy Rxx portion of the R matrix.

3305

% Rxy Rxx portion of the R matrix.

3422

3306

3423

w_partial = inv(Rtmp'*Rtmp)*(Rtmp'*rtmp);

3307

w_partial = inv(Rtmp'*Rtmp)*(Rtmp'*rtmp);

3424

ws (Indx_full,:) = w_partial;

3308

ws (Indx_full,:) = w_partial;

3425

C = ws;

3309

C = ws;

3426

end

3310

end

3427

% From Cioffi, Chapter 3

3311

% From Cioffi, Chapter 3

3428

var_ffe_dfe = Signal_Variance-ws.'*ro;

3312

var_ffe_dfe = Signal_Variance-ws.'*ro;

3429

SNR_Eq = 10*log10(Signal_Variance/var_ffe_dfe-1);

3313

SNR_Eq = 10*log10(Signal_Variance/var_ffe_dfe-1);

3430

3314

3431

%% Scale FFE gain to target output voltage

3315

%% Scale FFE gain to target output voltage

3432

Target_ouput = vsampled(ivs)*10^(param.current_ffegain/20);

3316

Target_ouput = vsampled(ivs)*10^(param.current_ffegain/20);

3433

C = C*Target_ouput;

3317

C = C*Target_ouput;

3434

C = C(1:num_taps);

3318

C = C(1:num_taps);

3435

%% End MMSE dfe code

3319

%% End MMSE dfe code

3436

function Write_CSV(output_args,csv_file)

3320

function Write_CSV(output_args,csv_file)

3437

3321

3438

items = fieldnames(output_args);

3322

items = fieldnames(output_args);

3439

item_value_strings = cell(size(items));

3323

item_value_strings = cell(size(items));

3440

for field_id=1:length(items)

3324

for field_id=1:length(items)

3441

field_name=items{field_id};

3325

field_name=items{field_id};

3442

field_value=output_args.(field_name);

3326

field_value=output_args.(field_name);

3443

if isstruct(output_args.(field_name))

3327

if isstruct(output_args.(field_name))

3444

field_value='struct';

3328

field_value='struct';

3445

end

3329

end

3446

if ischar(field_value)

3330

if ischar(field_value)

3447

item_value_strings{field_id}=field_value;

3331

item_value_strings{field_id}=field_value;

3448

elseif isempty(field_value)

3332

elseif isempty(field_value)

3449

item_value_strings{field_id}='';

3333

item_value_strings{field_id}='';

3450

elseif numel(field_value)==1

3334

elseif numel(field_value)==1

3451

item_value_strings{field_id}=num2str(field_value);

3335

item_value_strings{field_id}=num2str(field_value);

3452

else

3336

else

3453

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3337

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3454

end

3338

end

3455

end

3339

end

3456

3340

3457

header_string = str2csv(items);

3341

header_string = str2csv(items);

3458

data_string = str2csv(item_value_strings);

3342

data_string = str2csv(item_value_strings);

3459

fid = fopen(csv_file,'w');

3343

fid = fopen(csv_file,'w');

3460

fprintf(fid,'%s\n', header_string);

3344

fprintf(fid,'%s\n', header_string);

3461

fprintf(fid,'%s\n', data_string);

3345

fprintf(fid,'%s\n', data_string);

3462

fclose(fid);

3346

fclose(fid);

3463

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3347

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3464

%% Used in Clause 92 for adding board trace between TP0 and TP2

3348

%% Used in Clause 92 for adding board trace between TP0 and TP2

3465

3349

3466

switch chdata.type

3350

switch chdata.type

3467

case 'THRU'

3351

case 'THRU'

3468

z_bp_tx = param.z_bp_tx;

3352

z_bp_tx = param.z_bp_tx;

3469

z_bp_rx = param.z_bp_rx;

3353

z_bp_rx = param.z_bp_rx;

3470

case 'NEXT'

3354

case 'NEXT'

3471

z_bp_tx = param.z_bp_rx;

3355

z_bp_tx = param.z_bp_rx;

3472

z_bp_rx = param.z_bp_next;

3356

z_bp_rx = param.z_bp_next;

3473

case 'FEXT'

3357

case 'FEXT'

3474

z_bp_tx = param.z_bp_fext;

3358

z_bp_tx = param.z_bp_fext;

3475

z_bp_rx = param.z_bp_rx;

3359

z_bp_rx = param.z_bp_rx;

3476

end

3360

end

3477

% Same cap on each tx and rx three is a data stratue for bifrucation but

3361

% Same cap on each tx and rx three is a data stratue for bifrucation but

3478

% logic no implemented here RIM 06/28/2019

3362

% logic no implemented here RIM 06/28/2019

3479

zref=param.Z0;

3363

zref=param.Z0;

3480

c1=param.C_0;

3364

c1=param.C_0;

3481

c2=param.C_1;

3365

c2=param.C_1;

3482

f=chdata.faxis;

3366

f=chdata.faxis;

3483

f(f<eps)=eps;

3367

f(f<eps)=eps;

3484

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3368

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3485

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3369

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3486

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3370

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3487

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3371

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3488

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3372

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3489

% add Tx caps

3373

% add Tx caps

3490

[s11tx, s12tx, s21tx, s22tx ]= ...

3374

[s11tx, s12tx, s21tx, s22tx ]= ...

3491

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3375

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3492

[s11tx, s12tx, s21tx, s22tx ]= ...

3376

[s11tx, s12tx, s21tx, s22tx ]= ...

3493

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3377

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3494

3378

3495

3379

3496

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3380

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3497

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3381

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3498

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3382

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3499

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3383

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3500

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_rx);

3384

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_rx);

3501

% add Rx caps

3385

% add Rx caps

3502

[s11rx, s12rx, s21rx, s22rx ]= ...

3386

[s11rx, s12rx, s21rx, s22rx ]= ...

3503

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3387

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3504

[s11rx, s12rx, s21rx, s22rx ]= ...

3388

[s11rx, s12rx, s21rx, s22rx ]= ...

3505

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3389

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3506

3390

3507

3391

3508

switch OP.include_pcb

3392

switch OP.include_pcb

3509

case 1

3393

case 1

3510

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3394

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3511

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3395

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3512

case 2

3396

case 2

3513

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3397

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3514

end

3398

end

3515

3399

3516

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3400

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3517

% Used in Clause 92 for adding board trace between TP0 and TP2

3401

% Used in Clause 92 for adding board trace between TP0 and TP2

3518

switch chdata.type

3402

switch chdata.type

3519

case 'THRU'

3403

case 'THRU'

3520

z_bp_tx = param.z_bp_tx;

3404

z_bp_tx = param.z_bp_tx;

3521

case 'NEXT'

3405

case 'NEXT'

3522

z_bp_tx = param.z_bp_next;

3406

z_bp_tx = param.z_bp_next;

3523

case 'FEXT'

3407

case 'FEXT'

3524

z_bp_tx = param.z_bp_fext;

3408

z_bp_tx = param.z_bp_fext;

3525

end

3409

end

3526

3410

3527

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3411

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3528

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, param.z_bp_rx);

3412

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, param.z_bp_rx);

3529

3413

3530

switch OP.include_pcb

3414

switch OP.include_pcb

3531

case 1

3415

case 1

3532

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3416

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3533

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3417

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3534

case 2

3418

case 2

3535

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3419

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3536

end

3420

end

3537

3421

3538

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3422

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3539

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3423

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3540

% applying a bank of DFE at desired location

3424

% applying a bank of DFE at desired location

3541

% hisi: waveform with cursor values;

3425

% hisi: waveform with cursor values;

3542

% idx: starting index of the bank;

3426

% idx: starting index of the bank;

3543

% tap_bk: number of taps in bank;

3427

% tap_bk: number of taps in bank;

3544

% bmaxg: maxmum coefficient in bank;

3428

% bmaxg: maxmum coefficient in bank;

3545

3429

3546

if nargin<6

3430

if nargin<6

3547

dfe_delta=0;

3431

dfe_delta=0;

3548

end

3432

end

3549

3433

3550

rng=idx:idx+tap_bk-1;

3434

rng=idx:idx+tap_bk-1;

3551

flt_curval=hisi(rng);

3435

flt_curval=hisi(rng);

3552

3436

3553

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3437

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3554

3438

3555

if dfe_delta~=0

3439

if dfe_delta~=0

3556

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3440

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3557

dfe_delta.*sign(flt_curval)*curval;

3441

dfe_delta.*sign(flt_curval)*curval;

3558

else

3442

else

3559

flt_curval_q=hisi(rng);

3443

flt_curval_q=hisi(rng);

3560

end

3444

end

3561

3445

3562

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3446

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3563

hisi(rng)= hisi(rng) - curval*tap_coef;

3447

hisi(rng)= hisi(rng) - curval*tap_coef;

3564

hisi_ref(rng)=0;

3448

hisi_ref(rng)=0;

3565

3449

3566

%AJG021820

3450

%AJG021820

3567

function [ a] = bessel( n )

3451

function [ a] = bessel( n )

3568

% bessel polynomial

3452

% bessel polynomial

3569

for ii= 0:n

3453

for ii= 0:n

3570

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3454

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3571

end

3455

end

3572

3456

3573

3457

3574

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3458

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3575

% History:

3459

% History:

3576

% 1. 14th October, 2021 (Intial release)

3460

% 1. 14th October, 2021 (Intial release)

3577

3461

3578

% Definition:

3462

% Definition:

3579

% This function captures the channel delay through the time domain using causality enforcement.

3463

% This function captures the channel delay through the time domain using causality enforcement.

3580

% Following are the steps being followed.

3464

% Following are the steps being followed.

3581

% Step 1. Cascade negative frequencies

3465

% Step 1. Cascade negative frequencies

3582

% Step 2. Extract magnitude

3466

% Step 2. Extract magnitude

3583

% Step 3. IFFT of the magnitude

3467

% Step 3. IFFT of the magnitude

3584

% Step 4. Multiply by the sign(t)

3468

% Step 4. Multiply by the sign(t)

3585

% Step 5. Calculate the phase of the 1j*causal_phase

3469

% Step 5. Calculate the phase of the 1j*causal_phase

3586

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3470

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3587

% Step 7. f-domain to t-domain pulse response

3471

% Step 7. f-domain to t-domain pulse response

3588

% Step 8. Calculate the delay

3472

% Step 8. Calculate the delay

3589

3473

3590

% Author:

3474

% Author:

3591

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3475

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3592

3476

3593

% Reference:

3477

% Reference:

3594

% 1] "IEEE Standard for Electrical Characterization of Printed Circuit Board and Related Interconnects at Frequencies up to 50 GHz," in IEEE Std 370-2020 , vol., no., pp.1-147, 8 Jan. 2021, doi: 10.1109/IEEESTD.2021.9316329.

3478

% 1] "IEEE Standard for Electrical Characterization of Printed Circuit Board and Related Interconnects at Frequencies up to 50 GHz," in IEEE Std 370-2020 , vol., no., pp.1-147, 8 Jan. 2021, doi: 10.1109/IEEESTD.2021.9316329.

3595

3479

3596

% Input:

3480

% Input:

3597

% freq %frequency in hertz (odd number points)

3481

% freq %frequency in hertz (odd number points)

3598

% sdd21 %insertion loss in complex (odd number points)

3482

% sdd21 %insertion loss in complex (odd number points)

3599

% param %COM native structure passed

3483

% param %COM native structure passed

3600

% OP %COM native structure passed

3484

% OP %COM native structure passed

3601

3485

3602

% Output:

3486

% Output:

3603

% delay_sec %channel delay in seconds

3487

% delay_sec %channel delay in seconds

3604

% delay_idx %channel delay index

3488

% delay_idx %channel delay index

3605

3489

3606

if iscolumn(sdd21)

3490

if iscolumn(sdd21)

3607

sdd21= sdd21.';

3491

sdd21= sdd21.';

3608

end

3492

end

3609

if iscolumn(freq)

3493

if iscolumn(freq)

3610

freq= freq.';

3494

freq= freq.';

3611

end

3495

end

3612

3496

3613

%---start. Step 1. Cascade negative frequencies

3497

%---start. Step 1. Cascade negative frequencies

3614

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3498

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3615

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3499

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3616

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3500

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3617

%---end. Step 1. Cascade negative frequencies

3501

%---end. Step 1. Cascade negative frequencies

3618

3502

3619

%---start. Step 2. Extract magnitude

3503

%---start. Step 2. Extract magnitude

3620

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3504

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3621

%---end. Step 2. Extract magnitude

3505

%---end. Step 2. Extract magnitude

3622

3506

3623

%---start. Step 3. IFFT of the magnitude

3507

%---start. Step 3. IFFT of the magnitude

3624

sdd21_mag_time = ifft(sdd21_mag_conj);

3508

sdd21_mag_time = ifft(sdd21_mag_conj);

3625

%---end. Step 3. IFFT of the magnitude

3509

%---end. Step 3. IFFT of the magnitude

3626

3510

3627

%---start. Step 4. Multiply by the sign(t)

3511

%---start. Step 4. Multiply by the sign(t)

3628

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3512

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3629

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3513

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3630

%---end. Step 4. Multiply by the sign(t)

3514

%---end. Step 4. Multiply by the sign(t)

3631

3515

3632

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3516

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3633

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3517

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3634

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3518

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3635

3519

3636

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3520

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3637

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3521

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3638

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3522

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3639

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3523

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3640

3524

3641

%---start. Step 7. f-domain to t-domain pulse response

3525

%---start. Step 7. f-domain to t-domain pulse response

3642

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3526

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3643

%--------- Extrapolation has been already done by the COM tool

3527

%--------- Extrapolation has been already done by the COM tool

3644

freq_array= freq;

3528

freq_array= freq;

3645

time_step= param.sample_dt;

3529

time_step= param.sample_dt;

3646

fmax=1/time_step/2;

3530

fmax=1/time_step/2;

3647

freq_step=(freq_array(3)-freq_array(2))/1;

3531

freq_step=(freq_array(3)-freq_array(2))/1;

3648

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3532

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3649

3533

3650

ILin=sdd21;

3534

ILin=sdd21;

3651

IL=interp_Sparam(ILin,freq_array,fout, ...

3535

IL=interp_Sparam(ILin,freq_array,fout, ...

3652

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3536

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3653

IL_nan = find(isnan(IL));

3537

IL_nan = find(isnan(IL));

3654

for in=IL_nan

3538

for in=IL_nan

3655

IL(in)=IL(in-1);

3539

IL(in)=IL(in-1);

3656

end

3540

end

3657

IL = IL(:);

3541

IL = IL(:);

3658

% add padding for time steps

3542

% add padding for time steps

3659

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3543

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3660

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3544

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3661

clear IL IL_nan IL_symmetric

3545

clear IL IL_nan IL_symmetric

3662

3546

3663

ILin=sdd21_causality_enforced;

3547

ILin=sdd21_causality_enforced;

3664

IL=interp_Sparam(ILin,freq_array,fout, ...

3548

IL=interp_Sparam(ILin,freq_array,fout, ...

3665

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3549

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3666

IL_nan = find(isnan(IL));

3550

IL_nan = find(isnan(IL));

3667

for in=IL_nan

3551

for in=IL_nan

3668

IL(in)=IL(in-1);

3552

IL(in)=IL(in-1);

3669

end

3553

end

3670

IL = IL(:);

3554

IL = IL(:);

3671

% add padding for time steps

3555

% add padding for time steps

3672

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3556

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3673

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3557

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3674

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3558

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3675

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3559

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3676

clear IL IL_nan IL_symmetric

3560

clear IL IL_nan IL_symmetric

3677

3561

3678

clear time_step fmax freq_step freq_array

3562

clear time_step fmax freq_step freq_array

3679

3563

3680

freq_step=(fout(3)-fout(2))/1;

3564

freq_step=(fout(3)-fout(2))/1;

3681

L= length(sdd21_PR);

3565

L= length(sdd21_PR);

3682

t_base = (0:L-1)/(freq_step*L);

3566

t_base = (0:L-1)/(freq_step*L);

3683

clear fout freq_step L

3567

clear fout freq_step L

3684

%---end. Step 7. f-domain to t-domain pulse response

3568

%---end. Step 7. f-domain to t-domain pulse response

3685

3569

3686

%---start. Step 8. Calculate the delay

3570

%---start. Step 8. Calculate the delay

3687

%------start. Remove the last 5% of the waveform for noise due to IFFT

3571

%------start. Remove the last 5% of the waveform for noise due to IFFT

3688

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3572

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3689

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3573

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3690

%------end. Remove the last 5% of the waveform for noise due to IFFT

3574

%------end. Remove the last 5% of the waveform for noise due to IFFT

3691

3575

3692

%---start. calculate the difference in index between the peaks

3576

%---start. calculate the difference in index between the peaks

3693

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3577

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3694

[~, peak_y_idx] = max(sdd21_PR_reduced);

3578

[~, peak_y_idx] = max(sdd21_PR_reduced);

3695

peak_idx_difference = peak_x_idx - peak_y_idx;

3579

peak_idx_difference = peak_x_idx - peak_y_idx;

3696

%---end. calculate the difference in index between the peaks

3580

%---end. calculate the difference in index between the peaks

3697

3581

3698

if peak_idx_difference~=0

3582

if peak_idx_difference~=0

3699

search_bounds = min(peak_x_idx, peak_y_idx);%<----one may fix it to 1e3; using minimum of the peaks in assuming the other signal has zero delay

3583

search_bounds = min(peak_x_idx, peak_y_idx);%<----one may fix it to 1e3; using minimum of the peaks in assuming the other signal has zero delay

3700

error_value = length(sdd21_causality_enforced_PR_reduced);

3584

error_value = length(sdd21_causality_enforced_PR_reduced);

3701

error_idx = 0;

3585

error_idx = 0;

3702

% i= 1;

3586

% i= 1;

3703

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3587

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3704

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3588

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3705

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3589

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3706

if (error_value > current_error)

3590

if (error_value > current_error)

3707

error_idx = shift_value;

3591

error_idx = shift_value;

3708

error_value = current_error;

3592

error_value = current_error;

3709

end

3593

end

3710

% error_idx_H(i)= error_idx;

3594

% error_idx_H(i)= error_idx;

3711

% i= i+ 1;

3595

% i= i+ 1;

3712

end

3596

end

3713

%plot(error_idx_H);

3597

%plot(error_idx_H);

3714

3598

3715

if error_idx==0

3599

if error_idx==0

3716

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3600

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3717

end

3601

end

3718

3602

3719

delay_idx = error_idx;

3603

delay_idx = error_idx;

3720

else

3604

else

3721

delay_idx= 1;

3605

delay_idx= 1;

3722

end

3606

end

3723

3607

3724

delay_sec= t_base(abs(delay_idx));

3608

delay_sec= t_base(abs(delay_idx));

3725

3609

3726

3610

3727

function [return_struct]= capture_RIL_RILN(chdata)

3611

function [return_struct]= capture_RIL_RILN(chdata)

3728

% History:

3612

% History:

3729

% 1. 12th April, 2019 (Intial release)

3613

% 1. 12th April, 2019 (Intial release)

3730

%

3614

%

3731

% 2. 11th October, 2021

3615

% 2. 11th October, 2021

3732

% - Details:

3616

% - Details:

3733

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3617

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3734

% 2] Revised the selection criteria for the solution of the quadratic

3618

% 2] Revised the selection criteria for the solution of the quadratic

3735

% equation in finding the reflection coefficient (rho).

3619

% equation in finding the reflection coefficient (rho).

3736

% - Impact:

3620

% - Impact:

3737

% => Zero impact in |RIL|, while impact on angle(RIL).

3621

% => Zero impact in |RIL|, while impact on angle(RIL).

3738

% - Previous:

3622

% - Previous:

3739

% %---start. For passive networks the reflection coefficient should be less than one

3623

% %---start. For passive networks the reflection coefficient should be less than one

3740

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3624

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3741

% rho_port2= solution_1;

3625

% rho_port2= solution_1;

3742

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3626

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3743

% rho_port2= solution_2;

3627

% rho_port2= solution_2;

3744

% else

3628

% else

3745

% rho_port2= solution_1;

3629

% rho_port2= solution_1;

3746

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3630

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3747

% end

3631

% end

3748

% %---end. For passive networks the reflection coefficient should be less than one

3632

% %---end. For passive networks the reflection coefficient should be less than one

3749

%

3633

%

3750

% RIL= conj((1- rho_port1).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- rho_port2).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3634

% RIL= conj((1- rho_port1).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- rho_port2).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3751

% - Change:

3635

% - Change:

3752

% %---start. Given the real part of the impedance is to be positive

3636

% %---start. Given the real part of the impedance is to be positive

3753

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3637

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3754

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3638

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3755

%

3639

%

3756

% rho_port2= zeros(length(solution_1), 1);

3640

% rho_port2= zeros(length(solution_1), 1);

3757

% for solution_idx= 1:length(solution_1)

3641

% for solution_idx= 1:length(solution_1)

3758

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3642

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3759

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3643

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3760

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3644

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3761

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3645

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3762

% else

3646

% else

3763

% error('An odd case has occured. Please contact the tool developer.');

3647

% error('An odd case has occured. Please contact the tool developer.');

3764

% end

3648

% end

3765

% end

3649

% end

3766

% %---end. Given the real part of the impedance is to be positive

3650

% %---end. Given the real part of the impedance is to be positive

3767

% RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3651

% RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3768

3652

3769

% Definition:

3653

% Definition:

3770

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3654

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3771

3655

3772

% Author:

3656

% Author:

3773

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3657

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3774

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3658

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3775

3659

3776

% This function has been shared by Hansel for others to evaluate for reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter.

3660

% This function has been shared by Hansel for others to evaluate for reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter.

3777

3661

3778

% Reference:

3662

% Reference:

3779

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3663

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3780

% 2] H. Dsilva, A. Jain, J. Sasikala and A. Kumar, "Novel Signal Integrity Application of Power Wave Scattering Matrix theory," 2019 IEEE MTT-S International Microwave and RF Conference (IMARC), 2019, pp. 1-7, doi: 10.1109/IMaRC45935.2019.9118701.

3664

% 2] H. Dsilva, A. Jain, J. Sasikala and A. Kumar, "Novel Signal Integrity Application of Power Wave Scattering Matrix theory," 2019 IEEE MTT-S International Microwave and RF Conference (IMARC), 2019, pp. 1-7, doi: 10.1109/IMaRC45935.2019.9118701.

3781

3665

3782

% Input:

3666

% Input:

3783

% 1] SCH: S-matrix structure

3667

% 1] SCH: S-matrix structure

3784

% SCH.Frequencies= faxis;

3668

% SCH.Frequencies= faxis;

3785

% SCH.Parameters(1,1,:)= sdd11;

3669

% SCH.Parameters(1,1,:)= sdd11;

3786

% SCH.Parameters(2,2,:)= sdd22;

3670

% SCH.Parameters(2,2,:)= sdd22;

3787

% SCH.Parameters(1,2,:)= sdd12;

3671

% SCH.Parameters(1,2,:)= sdd12;

3788

% SCH.Parameters(2,1,:)= sdd21;

3672

% SCH.Parameters(2,1,:)= sdd21;

3789

% SCH.NumPorts= 2;

3673

% SCH.NumPorts= 2;

3790

% SCH.Impedance= 100;

3674

% SCH.Impedance= 100;

3791

3675

3792

% Output: Struct returned has the following,

3676

% Output: Struct returned has the following,

3793

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3677

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3794

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3678

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3795

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3679

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3796

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3680

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3797

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3681

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3798

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3682

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3799

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3683

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3800

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3684

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3801

% return_struct.freq %Frequency axis

3685

% return_struct.freq %Frequency axis

3802

3686

3803

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3687

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3804

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3688

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3805

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3689

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3806

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3690

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3807

SCH.Frequencies=chdata(1).faxis;

3691

SCH.Frequencies=chdata(1).faxis;

3808

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3692

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3809

SCH.NumPorts= 2;

3693

SCH.NumPorts= 2;

3810

3694

3811

%---start. allowed is only a 2-port network having a transmitter and receiver

3695

%---start. allowed is only a 2-port network having a transmitter and receiver

3812

if size(SCH.Parameters, 1)~=2

3696

if size(SCH.Parameters, 1)~=2

3813

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3697

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3814

error('Allowed is only a 2-port network having a transmitter and receiver.');

3698

error('Allowed is only a 2-port network having a transmitter and receiver.');

3815

end

3699

end

3816

%---end. allowed is only a 2-port network having a transmitter and receiver

3700

%---end. allowed is only a 2-port network having a transmitter and receiver

3817

3701

3818

%---start. do not include the DC point given sinusoidals at DC are not

3702

%---start. do not include the DC point given sinusoidals at DC are not

3819

%defined

3703

%defined

3820

if SCH.Frequencies(1)==0

3704

if SCH.Frequencies(1)==0

3821

idx_start= 2;

3705

idx_start= 2;

3822

else

3706

else

3823

idx_start= 1;

3707

idx_start= 1;

3824

end

3708

end

3825

%---end. do not include the DC point given sinusoidals at DC are not

3709

%---end. do not include the DC point given sinusoidals at DC are not

3826

%defined

3710

%defined

3827

3711

3828

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3712

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3829

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3713

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3830

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3714

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3831

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3715

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3832

3716

3833

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3717

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3834

b= 1+ Sdd22.*conj(Sdd22)+...

3718

b= 1+ Sdd22.*conj(Sdd22)+...

3835

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3719

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3836

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3720

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3837

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3721

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3838

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3722

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3839

Sdd11.*conj(Sdd11);

3723

Sdd11.*conj(Sdd11);

3840

c= -conj(Sdd22)-...

3724

c= -conj(Sdd22)-...

3841

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3725

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3842

Sdd11.*conj(Sdd11).*conj(Sdd22);

3726

Sdd11.*conj(Sdd11).*conj(Sdd22);

3843

3727

3844

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3728

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3845

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3729

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3846

3730

3847

clear a b c

3731

clear a b c

3848

3732

3849

%---start. Given the real part of the impedance is to be positive

3733

%---start. Given the real part of the impedance is to be positive

3850

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3734

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3851

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3735

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3852

3736

3853

rho_port2= zeros(length(solution_1), 1);

3737

rho_port2= zeros(length(solution_1), 1);

3854

for solution_idx= 1:length(solution_1)

3738

for solution_idx= 1:length(solution_1)

3855

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3739

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3856

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3740

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3857

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3741

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3858

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3742

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3859

else

3743

else

3860

error('An odd case has occured. Please contact the tool developer.');

3744

error('An odd case has occured. Please contact the tool developer.');

3861

end

3745

end

3862

end

3746

end

3863

%---end. Given the real part of the impedance is to be positive

3747

%---end. Given the real part of the impedance is to be positive

3864

3748

3865

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3749

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3866

3750

3867

%---start. calculate the equivalent port impedance

3751

%---start. calculate the equivalent port impedance

3868

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3752

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3869

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3753

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3870

%---end. calculate the equivalent port impedance

3754

%---end. calculate the equivalent port impedance

3871

3755

3872

3756

3873

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3757

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3874

% %to zero reflections.

3758

% %to zero reflections.

3875

RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3759

RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3876

%---end. The reflectionless insertion loss is the insertion loss corresponding

3760

%---end. The reflectionless insertion loss is the insertion loss corresponding

3877

%to zero reflections.

3761

%to zero reflections.

3878

3762

3879

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3763

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3880

RILN= RIL- Sdd21;

3764

RILN= RIL- Sdd21;

3881

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3765

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3882

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3766

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3883

3767

3884

%---start. preparing returns struct

3768

%---start. preparing returns struct

3885

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3769

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3886

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3770

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3887

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3771

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3888

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3772

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3889

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3773

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3890

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3774

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3891

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3775

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3892

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3776

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3893

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3777

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3894

%---end. preparing returns struct

3778

%---end. preparing returns struct

3895

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3779

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3896

3780

3897

3781

3898

%For the given BER, find the top & bottom voltage level in the CDF

3782

%For the given BER, find the top & bottom voltage level in the CDF

3899

3783

3900

%for the top, just find the first index at the spec BER

3784

%for the top, just find the first index at the spec BER

3901

nidx=find(cdf.y>specBER, 1, 'first');

3785

nidx=find(cdf.y>specBER, 1, 'first');

3902

noise_bottom = cdf.x(nidx);

3786

noise_bottom = cdf.x(nidx);

3903

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3787

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3904

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3788

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3905

%the true index without flipping

3789

%the true index without flipping

3906

nidx=length(cdf.y)-nidx+1;

3790

nidx=length(cdf.y)-nidx+1;

3907

noise_top = cdf.x(nidx);

3791

noise_top = cdf.x(nidx);

3908

function p=comb_fct(p1, p2)

3792

function p=comb_fct(p1, p2)

3909

if p1.BinSize ~= p2.BinSize

3793

if p1.BinSize ~= p2.BinSize

3910

error('bin size must be equal')

3794

error('bin size must be equal')

3911

end

3795

end

3912

3796

3913

p=p1;

3797

p=p1;

3914

p.BinSize=p1.BinSize;

3798

p.BinSize=p1.BinSize;

3915

%p.Min=p1.Min+p2.Min;

3799

%p.Min=p1.Min+p2.Min;

3916

p.Min=min(p1.Min,p2.Min);

3800

p.Min=min(p1.Min,p2.Min);

3917

difsz=abs(p1.Min-p2.Min);

3801

difsz=abs(p1.Min-p2.Min);

3918

lp1=length(p1.y);

3802

lp1=length(p1.y);

3919

lp2=length(p2.y);

3803

lp2=length(p2.y);

3920

if p1.Min == p.Min

3804

if p1.Min == p.Min

3921

p2.y(difsz+1:lp2+difsz)=p2.y;

3805

p2.y(difsz+1:lp2+difsz)=p2.y;

3922

p2.y(1:difsz)=0;

3806

p2.y(1:difsz)=0;

3923

p2.y(lp2+difsz+1:lp1)=0;

3807

p2.y(lp2+difsz+1:lp1)=0;

3924

elseif p2.Min == p.Min

3808

elseif p2.Min == p.Min

3925

p1.y(difsz+1:lp1+difsz)=p1.y;

3809

p1.y(difsz+1:lp1+difsz)=p1.y;

3926

p1.y(1:difsz)=0;

3810

p1.y(1:difsz)=0;

3927

p1.y(lp1+difsz+1:lp2)=0;

3811

p1.y(lp1+difsz+1:lp2)=0;

3928

end

3812

end

3929

% p.y=conv(p1.y, p2.y);

3813

% p.y=conv(p1.y, p2.y);

3930

p.y=(p1.y+p2.y);

3814

p.y=(p1.y+p2.y);

3931

% p.y=p.y/sum(p.y);

3815

% p.y=p.y/sum(p.y);

3932

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3816

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3933

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3817

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3934

3818

3935

3819

3936

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

3820

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

3937

3821

3938

if pdf1.BinSize ~= pdf2.BinSize

3822

if pdf1.BinSize ~= pdf2.BinSize

3939

error('bin size must be equal')

3823

error('bin size must be equal')

3940

end

3824

end

3941

3825

3942

x1=pdf1.x;

3826

x1=pdf1.x;

3943

y1=pdf1.y;

3827

y1=pdf1.y;

3944

x2=pdf2.x;

3828

x2=pdf2.x;

3945

y2=pdf2.y;

3829

y2=pdf2.y;

3946

%find the pdf with a larger min, force it to have the same min, and insert

3830

%find the pdf with a larger min, force it to have the same min, and insert

3947

%probability = 0

3831

%probability = 0

3948

min1=pdf1.x(1);

3832

min1=pdf1.x(1);

3949

min2=pdf2.x(1);

3833

min2=pdf2.x(1);

3950

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

3834

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

3951

if min1<min2

3835

if min1<min2

3952

x2=[pdf1.x(1:shift_amount) pdf2.x];

3836

x2=[pdf1.x(1:shift_amount) pdf2.x];

3953

y2=[zeros(1,shift_amount) pdf2.y];

3837

y2=[zeros(1,shift_amount) pdf2.y];

3954

else

3838

else

3955

x1=[pdf2.x(1:shift_amount) pdf1.x];

3839

x1=[pdf2.x(1:shift_amount) pdf1.x];

3956

y1=[zeros(1,shift_amount) pdf1.y];

3840

y1=[zeros(1,shift_amount) pdf1.y];

3957

end

3841

end

3958

%find the pdf with smaller max, force it to have the same max, and insert

3842

%find the pdf with smaller max, force it to have the same max, and insert

3959

%probability=0

3843

%probability=0

3960

L1=length(x1);

3844

L1=length(x1);

3961

L2=length(x2);

3845

L2=length(x2);

3962

Ldiff=abs(L1-L2);

3846

Ldiff=abs(L1-L2);

3963

if L1>L2

3847

if L1>L2

3964

out_x=x1;

3848

out_x=x1;

3965

y2=[y2 zeros(1,Ldiff)];

3849

y2=[y2 zeros(1,Ldiff)];

3966

else

3850

else

3967

out_x=x2;

3851

out_x=x2;

3968

y1=[y1 zeros(1,Ldiff)];

3852

y1=[y1 zeros(1,Ldiff)];

3969

end

3853

end

3970

%now the 2 pdfs have the same voltage axis, add probabilities together

3854

%now the 2 pdfs have the same voltage axis, add probabilities together

3971

%renormalization is not handled here, so the output pdf will not have sum=1

3855

%renormalization is not handled here, so the output pdf will not have sum=1

3972

%It is the responsibility of the calling function to handle renormalization

3856

%It is the responsibility of the calling function to handle renormalization

3973

%if needed

3857

%if needed

3974

out_y=y1+y2;

3858

out_y=y1+y2;

3975

out_pdf.x=out_x;

3859

out_pdf.x=out_x;

3976

out_pdf.y=out_y;

3860

out_pdf.y=out_y;

3977

out_pdf.BinSize=pdf1.BinSize;

3861

out_pdf.BinSize=pdf1.BinSize;

3978

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

3862

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

3979

3863

3980

%original method:

3864

%original method:

3981

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

3865

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

3982

% for i=1:length(s11in1)

3866

% for i=1:length(s11in1)

3983

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

3867

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

3984

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

3868

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

3985

% end

3869

% end

3986

% t1=stot(s1);

3870

% t1=stot(s1);

3987

% t2=stot(s2);

3871

% t2=stot(s2);

3988

% for i=1:length(s11in1)

3872

% for i=1:length(s11in1)

3989

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

3873

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

3990

% end

3874

% end

3991

% s3=ttos(t3);

3875

% s3=ttos(t3);

3992

% s11out=s3(1,1,:);

3876

% s11out=s3(1,1,:);

3993

% s11out=transpose(s11out(:));

3877

% s11out=transpose(s11out(:));

3994

% s12out=s3(1,2,:);

3878

% s12out=s3(1,2,:);

3995

% s12out=transpose(s12out(:));

3879

% s12out=transpose(s12out(:));

3996

% s21out=s3(2,1,:);

3880

% s21out=s3(2,1,:);

3997

% s21out=transpose(s21out(:));

3881

% s21out=transpose(s21out(:));

3998

% s22out=s3(2,2,:);

3882

% s22out=s3(2,2,:);

3999

% s22out=transpose(s22out(:));

3883

% s22out=transpose(s22out(:));

4000

3884

4001

3885

4002

%vectorized method:

3886

%vectorized method:

4003

s1(1,1,:)=s11in1;

3887

s1(1,1,:)=s11in1;

4004

s1(1,2,:)=s12in1;

3888

s1(1,2,:)=s12in1;

4005

s1(2,1,:)=s21in1;

3889

s1(2,1,:)=s21in1;

4006

s1(2,2,:)=s22in1;

3890

s1(2,2,:)=s22in1;

4007

s2(1,1,:)=s11in2;

3891

s2(1,1,:)=s11in2;

4008

s2(1,2,:)=s12in2;

3892

s2(1,2,:)=s12in2;

4009

s2(2,1,:)=s21in2;

3893

s2(2,1,:)=s21in2;

4010

s2(2,2,:)=s22in2;

3894

s2(2,2,:)=s22in2;

4011

3895

4012

3896

4013

N = (1-s1(2,2,:).*s2(1,1,:)) ;

3897

N = (1-s1(2,2,:).*s2(1,1,:)) ;

4014

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

3898

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

4015

s12out = s1(1,2,:).*s2(1,2,:)./N ;

3899

s12out = s1(1,2,:).*s2(1,2,:)./N ;

4016

s21out = s2(2,1,:).*s1(2,1,:)./N;

3900

s21out = s2(2,1,:).*s1(2,1,:)./N;

4017

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

3901

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

4018

3902

4019

s11out=transpose(squeeze(s11out));

3903

s11out=transpose(squeeze(s11out));

4020

s12out=transpose(squeeze(s12out));

3904

s12out=transpose(squeeze(s12out));

4021

s21out=transpose(squeeze(s21out));

3905

s21out=transpose(squeeze(s21out));

4022

s22out=transpose(squeeze(s22out));

3906

s22out=transpose(squeeze(s22out));

4023

function p=conv_fct(p1, p2)

3907

function p=conv_fct(p1, p2)

4024

if p1.BinSize ~= p2.BinSize

3908

if p1.BinSize ~= p2.BinSize

4025

error('bin size must be equal')

3909

error('bin size must be equal')

4026

end

3910

end

4027

3911

4028

p=p1;

3912

p=p1;

4029

%p.BinSize=p1.BinSize;

3913

%p.BinSize=p1.BinSize;

4030

%p.Min=p1.Min+p2.Min;

3914

%p.Min=p1.Min+p2.Min;

4031

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3915

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4032

p.y=conv2(p1.y, p2.y);

3916

p.y=conv2(p1.y, p2.y);

4033

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3917

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

4034

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3918

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

4035

pMax=p.Min+length(p.y)-1;

3919

pMax=p.Min+length(p.y)-1;

4036

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3920

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4037

3921

4038

3922

4039

3923

4040

3924

4041

function p=conv_fct_MeanNotZero(p1, p2)

3925

function p=conv_fct_MeanNotZero(p1, p2)

4042

3926

4043

if p1.BinSize ~= p2.BinSize

3927

if p1.BinSize ~= p2.BinSize

4044

error('bin size must be equal')

3928

error('bin size must be equal')

4045

end

3929

end

4046

3930

4047

p=p1;

3931

p=p1;

4048

%p.BinSize=p1.BinSize;

3932

%p.BinSize=p1.BinSize;

4049

%p.Min=p1.Min+p2.Min;

3933

%p.Min=p1.Min+p2.Min;

4050

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3934

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4051

p.y=conv2(p1.y, p2.y);

3935

p.y=conv2(p1.y, p2.y);

4052

3936

4053

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

3937

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

4054

%But it is faster to pre-multiply BinSize instead of multiplying the entire

3938

%But it is faster to pre-multiply BinSize instead of multiplying the entire

4055

%vector by BinSize

3939

%vector by BinSize

4056

pMax=p.Min+length(p.y)-1;

3940

pMax=p.Min+length(p.y)-1;

4057

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3941

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4058

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

3942

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

4059

3943

4060

%IN:

3944

%IN:

4061

%sbr = pulse response

3945

%sbr = pulse response

4062

%param = COM "param" struct

3946

%param = COM "param" struct

4063

%OP = COM "OP" struct

3947

%OP = COM "OP" struct

4064

%peak_search_range= a limited range to search for the peak (for speed up)

3948

%peak_search_range= a limited range to search for the peak (for speed up)

4065

% it is usually +/- 20 UI

3949

% it is usually +/- 20 UI

4066

%

3950

%

4067

%OUT:

3951

%OUT:

4068

%cursor_i = sampling location

3952

%cursor_i = sampling location

4069

%no_zero_crossing = flag that reveals if sampling is not possible.

3953

%no_zero_crossing = flag that reveals if sampling is not possible.

4070

% When this function is called in optimize_fom, it signals to quit the current case

3954

% When this function is called in optimize_fom, it signals to quit the current case

4071

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

3955

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

4072

% time consuming, so saving the peak in one spot is advantageous

3956

% time consuming, so saving the peak in one spot is advantageous

4073

%zxi = zero crossing index (returned because RXFFE uses it)

3957

%zxi = zero crossing index (returned because RXFFE uses it)

4074

3958

4075

no_zero_crossing=0;

3959

no_zero_crossing=0;

4076

%need to set cursor_i to empty in case no_zero_crossing flag is set

3960

%need to set cursor_i to empty in case no_zero_crossing flag is set

4077

cursor_i=[];

3961

cursor_i=[];

4078

3962

4079

%get peak of pulse and peak index

3963

%get peak of pulse and peak index

4080

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

3964

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

4081

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

3965

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

4082

3966

4083

3967

4084

% initial guess at cursor location (t_s) - based on approximate zero crossing

3968

% initial guess at cursor location (t_s) - based on approximate zero crossing

4085

%limit search space for speed up

3969

%limit search space for speed up

4086

search_start=sbr_peak_i-4*param.samples_per_ui;

3970

search_start=sbr_peak_i-4*param.samples_per_ui;

4087

if search_start<1

3971

if search_start<1

4088

search_start=1;

3972

search_start=1;

4089

end

3973

end

4090

%Find zero crossings

3974

%Find zero crossings

4091

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

3975

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

4092

3976

4093

%Note: the original implementation of zxi:

3977

%Note: the original implementation of zxi:

4094

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

3978

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

4095

% zxi = zxi(zxi<sbr_peak_i);

3979

% zxi = zxi(zxi<sbr_peak_i);

4096

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

3980

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

4097

% The changes to limit search space and remember max(sbr) give 10x speed up

3981

% The changes to limit search space and remember max(sbr) give 10x speed up

4098

% A test case of 25k runs, reduced from 1.2s to 0.1s

3982

% A test case of 25k runs, reduced from 1.2s to 0.1s

4099

3983

4100

3984

4101

if isempty(zxi)

3985

if isempty(zxi)

4102

%if no zero crossing, the calling program must respond (since sample point will be empty)

3986

%if no zero crossing, the calling program must respond (since sample point will be empty)

4103

no_zero_crossing=1;

3987

no_zero_crossing=1;

4104

return;

3988

return;

4105

elseif length(zxi)>1

3989

elseif length(zxi)>1

4106

%only need the last zero crossing

3990

%only need the last zero crossing

4107

zxi=zxi(end);

3991

zxi=zxi(end);

4108

end

3992

end

4109

if param.ndfe==0

3993

if param.ndfe==0

4110

max_dfe1=0;

3994

max_dfe1=0;

4111

else

3995

else

4112

max_dfe1=param.bmax(1);

3996

max_dfe1=param.bmax(1);

4113

end

3997

end

4114

% adjust cursor_i to Solve equation 93A-25 %%

3998

% adjust cursor_i to Solve equation 93A-25 %%

4115

% Muller-Mueller criterion with DFE

3999

% Muller-Mueller criterion with DFE

4116

mm_range = zxi+(0:2*param.samples_per_ui);

4000

mm_range = zxi+(0:2*param.samples_per_ui);

4117

switch OP.CDR

4001

switch OP.CDR

4118

case 'Mod-MM'

4002

case 'Mod-MM'

4119

mm_metric = ...

4003

mm_metric = ...

4120

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

4004

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

4121

otherwise % MM

4005

otherwise % MM

4122

%MM is generally: first precursor = 0

4006

%MM is generally: first precursor = 0

4123

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

4007

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

4124

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

4008

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

4125

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

4009

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

4126

%first precursor = first postcursor - max_dfe

4010

%first precursor = first postcursor - max_dfe

4127

mm_metric = ...

4011

mm_metric = ...

4128

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

4012

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

4129

end

4013

end

4130

[~, mm_cursor_offset] = min(mm_metric);

4014

[~, mm_cursor_offset] = min(mm_metric);

4131

4015

4132

%cursor_i = the sample location

4016

%cursor_i = the sample location

4133

cursor_i = zxi+mm_cursor_offset-1;

4017

cursor_i = zxi+mm_cursor_offset-1;

4134

function pdf=d_cpdf( binsize, values, probs)

4018

function pdf=d_cpdf( binsize, values, probs)

4135

% p=cpdf(type, ...)

4019

% p=cpdf(type, ...)

4136

%

4020

%

4137

% CPDF is a probability mass function for discrete distributions or an

4021

% CPDF is a probability mass function for discrete distributions or an

4138

% approxmation of a PDF for continuous distributions.

4022

% approxmation of a PDF for continuous distributions.

4139

%

4023

%

4140

% cpdf is internally normalized so that the sum of probabilities is 1

4024

% cpdf is internally normalized so that the sum of probabilities is 1

4141

% (regardless of bin size).

4025

% (regardless of bin size).

4142

4026

4143

% Internal fields:

4027

% Internal fields:

4144

% Min: *bin number* of minimum value.

4028

% Min: *bin number* of minimum value.

4145

% BinSize: size of PDF bins. Bin center is the representative value.

4029

% BinSize: size of PDF bins. Bin center is the representative value.

4146

% Vec: vector of probabilities per bin.

4030

% Vec: vector of probabilities per bin.

4147

4031

4148

%speed up for initializing empty pdf

4032

%speed up for initializing empty pdf

4149

if all(values==0)

4033

if all(values==0)

4150

pdf.BinSize=binsize;

4034

pdf.BinSize=binsize;

4151

pdf.Min=0;

4035

pdf.Min=0;

4152

pdf.y=1;

4036

pdf.y=1;

4153

pdf.x=0;

4037

pdf.x=0;

4154

return;

4038

return;

4155

end

4039

end

4156

4040

4157

if ~issorted(values)

4041

if ~issorted(values)

4158

[values,si]=sort(values);

4042

[values,si]=sort(values);

4159

probs=probs(si);

4043

probs=probs(si);

4160

end

4044

end

4161

values=binsize*round(values/binsize);

4045

values=binsize*round(values/binsize);

4162

t=(values(1):binsize:values(end));

4046

t=(values(1):binsize:values(end));

4163

pdf.Min=values(1)/binsize;

4047

pdf.Min=values(1)/binsize;

4164

pdf.y=zeros(size(t));

4048

pdf.y=zeros(size(t));

4165

for k=1:length(values)

4049

for k=1:length(values)

4166

if k==1

4050

if k==1

4167

bin=1;

4051

bin=1;

4168

elseif k==length(values)

4052

elseif k==length(values)

4169

bin=length(t);

4053

bin=length(t);

4170

else

4054

else

4171

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

4055

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

4172

end

4056

end

4173

pdf.y(bin) = pdf.y(bin)+probs(k);

4057

pdf.y(bin) = pdf.y(bin)+probs(k);

4174

end

4058

end

4175

4059

4176

pdf.BinSize=binsize;

4060

pdf.BinSize=binsize;

4177

pdf.y=pdf.y/sum(pdf.y);

4061

pdf.y=pdf.y/sum(pdf.y);

4178

if any(~isreal(pdf.y)) || any(pdf.y<0)

4062

if any(~isreal(pdf.y)) || any(pdf.y<0)

4179

error('PDF must be real and nonnegative');

4063

error('PDF must be real and nonnegative');

4180

end

4064

end

4181

support=find(pdf.y);

4065

support=find(pdf.y);

4182

pdf.y=pdf.y(support(1):support(end));

4066

pdf.y=pdf.y(support(1):support(end));

4183

pdf.Min=pdf.Min+(support(1)-1);

4067

pdf.Min=pdf.Min+(support(1)-1);

4184

pdf.x=(pdf.Min:-pdf.Min)*binsize;

4068

pdf.x=(pdf.Min:-pdf.Min)*binsize;

4185

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

4069

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

4186

4070

4187

if isrow(input)

4071

if isrow(input)

4188

max_threshold=max_threshold(:).';

4072

max_threshold=max_threshold(:).';

4189

min_threshold=min_threshold(:).';

4073

min_threshold=min_threshold(:).';

4190

else

4074

else

4191

max_threshold=max_threshold(:);

4075

max_threshold=max_threshold(:);

4192

min_threshold=min_threshold(:);

4076

min_threshold=min_threshold(:);

4193

end

4077

end

4194

4078

4195

clip_output=input;

4079

clip_output=input;

4196

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

4080

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

4197

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

4081

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

4198

4082

4199

4083

4200

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

4084

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

4201

[ncases, mele]=size(param.z_p_tx_cases);

4085

[ncases, mele]=size(param.z_p_tx_cases);

4202

if mele ==2

4086

if mele ==2

4203

param.flex=2;

4087

param.flex=2;

4204

elseif mele==4

4088

elseif mele==4

4205

param.flex=4;

4089

param.flex=4;

4206

elseif mele==1

4090

elseif mele==1

4207

param.flex=1;

4091

param.flex=1;

4208

else

4092

else

4209

error(springf('config file syntax error'))

4093

error(springf('config file syntax error'))

4210

end

4094

end

4211

4095

4212

4096

4213

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

4097

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

4214

% display bathtub curves in one axis per test case.

4098

% display bathtub curves in one axis per test case.

4215

% h=findall(0, 'Name', 'COM results');

4099

% h=findall(0, 'Name', 'COM results');

4216

if ~exist('h','var')

4100

if ~exist('h','var')

4217

msgtext = cell(1, length(OP.pkg_len_select));

4101

msgtext = cell(1, length(OP.pkg_len_select));

4218

msgcolor = 'g';

4102

msgcolor = 'g';

4219

else

4103

else

4220

msgtext=get(findobj(h, 'type', 'text'), 'string');

4104

msgtext=get(findobj(h, 'type', 'text'), 'string');

4221

msgcolor = get(h, 'color');

4105

msgcolor = get(h, 'color');

4222

close(h); % will be recreated

4106

close(h); % will be recreated

4223

end

4107

end

4224

msgctr=size(msgtext,1)+1;

4108

msgctr=size(msgtext,1)+1;

4225

if ~OP.ERL_ONLY

4109

if ~OP.ERL_ONLY

4226

switch OP.PHY

4110

switch OP.PHY

4227

case 'C2M'

4111

case 'C2M'

4228

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4112

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4229

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4113

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4230

msg, VEO_mV);

4114

msg, VEO_mV);

4231

else

4115

else

4232

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4116

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4233

msg, VEO_mV);

4117

msg, VEO_mV);

4234

msgcolor = 'r';

4118

msgcolor = 'r';

4235

end

4119

end

4236

4120

4237

if VEC_dB <= param.VEC_pass_threshold

4121

if VEC_dB <= param.VEC_pass_threshold

4238

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4122

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4239

(msg), VEC_dB);

4123

(msg), VEC_dB);

4240

else

4124

else

4241

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4125

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4242

(msg), VEC_dB);

4126

(msg), VEC_dB);

4243

msgcolor = 'r';

4127

msgcolor = 'r';

4244

end

4128

end

4245

case 'C2C'

4129

case 'C2C'

4246

if COM >= param.pass_threshold

4130

if COM >= param.pass_threshold

4247

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4131

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4248

% msg, COM);

4132

% msg, COM);

4249

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4133

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4250

msg, COM);

4134

msg, COM);

4251

else

4135

else

4252

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4136

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4253

% msg, COM);

4137

% msg, COM);

4254

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4138

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4255

msg, COM);

4139

msg, COM);

4256

msgcolor = 'r';

4140

msgcolor = 'r';

4257

end

4141

end

4258

% begin yasuo patch 3/18/2019

4142

% begin yasuo patch 3/18/2019

4259

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4143

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4260

% end yasuo patch

4144

% end yasuo patch

4261

case 'C2Mcom'

4145

case 'C2Mcom'

4262

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4146

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4263

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4147

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4264

msg, VEO_mV);

4148

msg, VEO_mV);

4265

else

4149

else

4266

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4150

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4267

msg, VEO_mV);

4151

msg, VEO_mV);

4268

msgcolor = 'r';

4152

msgcolor = 'r';

4269

end

4153

end

4270

4154

4271

if VEC_dB <= param.VEC_pass_threshold

4155

if VEC_dB <= param.VEC_pass_threshold

4272

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4156

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4273

(msg), VEC_dB);

4157

(msg), VEC_dB);

4274

else

4158

else

4275

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4159

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4276

(msg), VEC_dB);

4160

(msg), VEC_dB);

4277

msgcolor = 'r';

4161

msgcolor = 'r';

4278

end

4162

end

4279

if COM >= param.pass_threshold

4163

if COM >= param.pass_threshold

4280

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4164

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4281

% msg, COM);

4165

% msg, COM);

4282

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4166

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4283

msg, COM);

4167

msg, COM);

4284

else

4168

else

4285

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4169

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4286

% msg, COM);

4170

% msg, COM);

4287

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4171

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4288

msg, COM);

4172

msg, COM);

4289

msgcolor = 'r';

4173

msgcolor = 'r';

4290

end

4174

end

4291

% begin yasuo patch 3/18/2019

4175

% begin yasuo patch 3/18/2019

4292

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4176

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4293

% end yasuo patch

4177

% end yasuo patch

4294

end

4178

end

4295

end

4179

end

4296

if OP.ERL

4180

if OP.ERL

4297

if ~isempty(ERL)

4181

if ~isempty(ERL)

4298

if min_ERL >= param.ERL_pass_threshold

4182

if min_ERL >= param.ERL_pass_threshold

4299

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4183

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4300

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4184

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4301

else

4185

else

4302

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4186

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4303

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4187

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4304

msgcolor = 'r';

4188

msgcolor = 'r';

4305

end

4189

end

4306

end

4190

end

4307

end

4191

end

4308

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4192

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4309

set(h, 'color', msgcolor, 'tag', 'COM');

4193

set(h, 'color', msgcolor, 'tag', 'COM');

4310

movegui(h, 'center');

4194

movegui(h, 'center');

4311

else % no windows

4195

else % no windows

4312

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4196

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4313

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4197

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4314

if ~OP.ERL_ONLY

4198

if ~OP.ERL_ONLY

4315

switch OP.PHY

4199

switch OP.PHY

4316

case 'C2C'

4200

case 'C2C'

4317

if COM >= param.pass_threshold

4201

if COM >= param.pass_threshold

4318

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4202

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4319

else

4203

else

4320

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4204

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4321

end

4205

end

4322

% begin yasuo patch 3/18/2019

4206

% begin yasuo patch 3/18/2019

4323

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4207

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4324

% end yasuo patch

4208

% end yasuo patch

4325

case 'C2Mcom'

4209

case 'C2Mcom'

4326

if VEC_dB <= param.VEC_pass_threshold

4210

if VEC_dB <= param.VEC_pass_threshold

4327

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4211

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4328

else

4212

else

4329

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4213

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4330

end

4214

end

4331

4215

4332

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4216

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4333

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4217

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4334

else

4218

else

4335

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4219

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4336

end

4220

end

4337

if COM >= param.pass_threshold

4221

if COM >= param.pass_threshold

4338

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4222

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4339

else

4223

else

4340

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4224

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4341

end

4225

end

4342

% begin yasuo patch 3/18/2019

4226

% begin yasuo patch 3/18/2019

4343

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4227

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4344

% end yasuo patch

4228

% end yasuo patch

4345

case 'C2M'

4229

case 'C2M'

4346

if VEC_dB <= param.VEC_pass_threshold

4230

if VEC_dB <= param.VEC_pass_threshold

4347

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4231

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4348

else

4232

else

4349

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4233

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4350

end

4234

end

4351

4235

4352

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4236

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4353

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4237

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4354

else

4238

else

4355

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4239

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4356

end

4240

end

4357

end

4241

end

4358

end

4242

end

4359

if OP.ERL

4243

if OP.ERL

4360

if ~isempty(ERL)

4244

if ~isempty(ERL)

4361

if min_ERL >= param.ERL_pass_threshold

4245

if min_ERL >= param.ERL_pass_threshold

4362

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4246

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4363

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4247

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4364

else

4248

else

4365

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4249

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4366

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4250

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4367

end

4251

end

4368

end

4252

end

4369

end

4253

end

4370

end

4254

end

4371

4255

4372

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4256

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4373

4257

4374

%Left eye Width (Top Eye)

4258

%Left eye Width (Top Eye)

4375

left_top=eye_contour(half_UI:-1:1,1);

4259

left_top=eye_contour(half_UI:-1:1,1);

4376

%vref_crossing is the first point less than vref (usually first point < 0)

4260

%vref_crossing is the first point less than vref (usually first point < 0)

4377

vref_crossing=find(left_top<vref,1,'first');

4261

vref_crossing=find(left_top<vref,1,'first');

4378

if isempty(vref_crossing)

4262

if isempty(vref_crossing)

4379

%this case handles completely open eye

4263

%this case handles completely open eye

4380

L1=half_UI;

4264

L1=half_UI;

4381

elseif vref_crossing==1

4265

elseif vref_crossing==1

4382

%this case handles completely closed eye

4266

%this case handles completely closed eye

4383

L1=0;

4267

L1=0;

4384

else

4268

else

4385

%this case handles the normal eye

4269

%this case handles the normal eye

4386

%INT is a linear interpolation between the 2 points on either side of

4270

%INT is a linear interpolation between the 2 points on either side of

4387

%vref to determine where the vref crossing occurred. In systems with

4271

%vref to determine where the vref crossing occurred. In systems with

4388

%a small number of samples_per_UI, interpolation improves accuracy over

4272

%a small number of samples_per_UI, interpolation improves accuracy over

4389

%just using the integer sample point

4273

%just using the integer sample point

4390

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4274

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4391

L1=half_UI-INT;

4275

L1=half_UI-INT;

4392

end

4276

end

4393

%Left eye Width (Bottom Eye)

4277

%Left eye Width (Bottom Eye)

4394

left_bot=eye_contour(half_UI:-1:1,2);

4278

left_bot=eye_contour(half_UI:-1:1,2);

4395

vref_crossing=find(left_bot>vref,1,'first');

4279

vref_crossing=find(left_bot>vref,1,'first');

4396

if isempty(vref_crossing)

4280

if isempty(vref_crossing)

4397

L0=half_UI;

4281

L0=half_UI;

4398

elseif vref_crossing==1

4282

elseif vref_crossing==1

4399

L0=0;

4283

L0=0;

4400

else

4284

else

4401

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4285

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4402

L0=half_UI-INT;

4286

L0=half_UI-INT;

4403

end

4287

end

4404

%Right eye Width (Top Eye)

4288

%Right eye Width (Top Eye)

4405

right_top=eye_contour(half_UI:end,1);

4289

right_top=eye_contour(half_UI:end,1);

4406

vref_crossing=find(right_top<vref,1,'first');

4290

vref_crossing=find(right_top<vref,1,'first');

4407

if isempty(vref_crossing)

4291

if isempty(vref_crossing)

4408

R1=samples_per_UI-half_UI;

4292

R1=samples_per_UI-half_UI;

4409

elseif vref_crossing==1

4293

elseif vref_crossing==1

4410

R1=0;

4294

R1=0;

4411

else

4295

else

4412

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4296

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4413

R1=INT-half_UI;

4297

R1=INT-half_UI;

4414

end

4298

end

4415

%Right eye Width (Bottom Eye)

4299

%Right eye Width (Bottom Eye)

4416

right_bot=eye_contour(half_UI:end,2);

4300

right_bot=eye_contour(half_UI:end,2);

4417

vref_crossing=find(right_bot>vref,1,'first');

4301

vref_crossing=find(right_bot>vref,1,'first');

4418

if isempty(vref_crossing)

4302

if isempty(vref_crossing)

4419

R0=samples_per_UI-half_UI;

4303

R0=samples_per_UI-half_UI;

4420

elseif vref_crossing==1

4304

elseif vref_crossing==1

4421

R0=0;

4305

R0=0;

4422

else

4306

else

4423

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4307

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4424

R0=INT-half_UI;

4308

R0=INT-half_UI;

4425

end

4309

end

4426

4310

4427

%L1 = top left eye width

4311

%L1 = top left eye width

4428

%L0 = bottom left eye width

4312

%L0 = bottom left eye width

4429

%Left eye width is the minimum

4313

%Left eye width is the minimum

4430

%R1 = top right eye width

4314

%R1 = top right eye width

4431

%R0 = bottom right eye width

4315

%R0 = bottom right eye width

4432

%Right eye width is the minimum

4316

%Right eye width is the minimum

4433

Left_EW=min([L1 L0]);

4317

Left_EW=min([L1 L0]);

4434

Right_EW=min([R1 R0]);

4318

Right_EW=min([R1 R0]);

4435

4319

4436

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4320

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4437

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4321

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4438

% find the location of the DFE bank

4322

% find the location of the DFE bank

4439

% hisi: waveform with cursor values;

4323

% hisi: waveform with cursor values;

4440

% idx_st: starting index;

4324

% idx_st: starting index;

4441

% idx_en: ending index ;

4325

% idx_en: ending index ;

4442

% tap_bk: number of taps per bank;

4326

% tap_bk: number of taps per bank;

4443

% bmaxg: maximum coefficient;

4327

% bmaxg: maximum coefficient;

4444

4328

4445

hisi=hisi(:);

4329

hisi=hisi(:);

4446

len=idx_en-idx_st+1;

4330

len=idx_en-idx_st+1;

4447

h0=abs(hisi(idx_st:idx_en));

4331

h0=abs(hisi(idx_st:idx_en));

4448

h1=max(0,h0-bmaxg*curval);

4332

h1=max(0,h0-bmaxg*curval);

4449

4333

4450

%if cursor value is negative, force h1 to all zeros

4334

%if cursor value is negative, force h1 to all zeros

4451

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4335

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4452

%this makes the weakest isi the most desirable to choose so everything breaks

4336

%this makes the weakest isi the most desirable to choose so everything breaks

4453

if curval<0

4337

if curval<0

4454

h1=zeros(size(h0));

4338

h1=zeros(size(h0));

4455

end

4339

end

4456

4340

4457

h0n=zeros(len-tap_bk+1,1);

4341

h0n=zeros(len-tap_bk+1,1);

4458

h1n=h0n;

4342

h1n=h0n;

4459

4343

4460

for ii=1:tap_bk

4344

for ii=1:tap_bk

4461

h0tmp=h0(ii:ii+len-tap_bk);

4345

h0tmp=h0(ii:ii+len-tap_bk);

4462

h0n=h0n+h0tmp.^2;

4346

h0n=h0n+h0tmp.^2;

4463

h1tmp=h1(ii:ii+len-tap_bk);

4347

h1tmp=h1(ii:ii+len-tap_bk);

4464

h1n=h1n+h1tmp.^2;

4348

h1n=h1n+h1tmp.^2;

4465

end

4349

end

4466

4350

4467

ndiff=h0n-h1n;

4351

ndiff=h0n-h1n;

4468

4352

4469

min_energy = -Inf;

4353

min_energy = -Inf;

4470

4354

4471

idx=zeros(1,tap_bk*N_bg);

4355

idx=zeros(1,tap_bk*N_bg);

4472

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4356

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4473

set_next_bank=0;

4357

set_next_bank=0;

4474

%Loop through each group

4358

%Loop through each group

4475

for k=1:N_bg

4359

for k=1:N_bg

4476

%Sort to choose the strongest

4360

%Sort to choose the strongest

4477

[~,val_sort]=sort(ndiff,'descend');

4361

[~,val_sort]=sort(ndiff,'descend');

4478

if k==1

4362

if k==1

4479

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4363

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4480

if isequal(sort(val_sort(ordered_set)),ordered_set)

4364

if isequal(sort(val_sort(ordered_set)),ordered_set)

4481

idx=1:N_bg*tap_bk;

4365

idx=1:N_bg*tap_bk;

4482

break;

4366

break;

4483

end

4367

end

4484

end

4368

end

4485

if set_next_bank>0

4369

if set_next_bank>0

4486

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4370

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4487

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4371

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4488

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4372

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4489

set_next_bank=0;

4373

set_next_bank=0;

4490

ndiff(new_bank)=min_energy;

4374

ndiff(new_bank)=min_energy;

4491

bad_start=new_bank(1)-tap_bk+1;

4375

bad_start=new_bank(1)-tap_bk+1;

4492

bad_end=new_bank(1)-1;

4376

bad_end=new_bank(1)-1;

4493

if bad_end<=0

4377

if bad_end<=0

4494

badV=[];

4378

badV=[];

4495

elseif bad_start>0

4379

elseif bad_start>0

4496

badV=bad_start:bad_end;

4380

badV=bad_start:bad_end;

4497

else

4381

else

4498

badV=1:bad_end;

4382

badV=1:bad_end;

4499

end

4383

end

4500

if ~isempty(badV)

4384

if ~isempty(badV)

4501

ndiff(badV)=min_energy;

4385

ndiff(badV)=min_energy;

4502

end

4386

end

4503

continue;

4387

continue;

4504

end

4388

end

4505

%potential bank = the strongest tap group

4389

%potential bank = the strongest tap group

4506

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4390

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4507

if k==N_bg

4391

if k==N_bg

4508

%Last group: just choose the strongest

4392

%Last group: just choose the strongest

4509

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4393

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4510

break;

4394

break;

4511

end

4395

end

4512

4396

4513

do_it_again=1;

4397

do_it_again=1;

4514

first_time=1;

4398

first_time=1;

4515

num_loops=0;

4399

num_loops=0;

4516

while do_it_again

4400

while do_it_again

4517

do_it_again=0;

4401

do_it_again=0;

4518

if num_loops>length(ndiff)

4402

if num_loops>length(ndiff)

4519

break;

4403

break;

4520

end

4404

end

4521

%note badV: taps smaller and less than 1 group away

4405

%note badV: taps smaller and less than 1 group away

4522

bad_start=new_bank(1)-tap_bk+1;

4406

bad_start=new_bank(1)-tap_bk+1;

4523

bad_end=new_bank(1)-1;

4407

bad_end=new_bank(1)-1;

4524

if bad_end<=0

4408

if bad_end<=0

4525

badV=[];

4409

badV=[];

4526

elseif bad_start>0

4410

elseif bad_start>0

4527

badV=bad_start:bad_end;

4411

badV=bad_start:bad_end;

4528

else

4412

else

4529

badV=1:bad_end;

4413

badV=1:bad_end;

4530

end

4414

end

4531

for j=length(badV):-1:1

4415

for j=length(badV):-1:1

4532

if any(badV(j)-idx==0)

4416

if any(badV(j)-idx==0)

4533

badV(j)=[];

4417

badV(j)=[];

4534

end

4418

end

4535

end

4419

end

4536

%note goodV: the tap exactly 1 tap_bk smaller

4420

%note goodV: the tap exactly 1 tap_bk smaller

4537

goodV=new_bank(1)-tap_bk;

4421

goodV=new_bank(1)-tap_bk;

4538

if ~isempty(badV)

4422

if ~isempty(badV)

4539

if ~first_time

4423

if ~first_time

4540

[~,val_sort]=sort(ndiff,'descend');

4424

[~,val_sort]=sort(ndiff,'descend');

4541

end

4425

end

4542

first_time=0;

4426

first_time=0;

4543

checkV=[badV new_bank];

4427

checkV=[badV new_bank];

4544

4428

4545

badV_pos=zeros(1,length(badV));

4429

badV_pos=zeros(1,length(badV));

4546

for j=1:length(badV)

4430

for j=1:length(badV)

4547

badV_pos(j)=find(badV(j)==val_sort);

4431

badV_pos(j)=find(badV(j)==val_sort);

4548

end

4432

end

4549

4433

4550

%loop through the sorted list to find the first tap outside the group and not a member of badV

4434

%loop through the sorted list to find the first tap outside the group and not a member of badV

4551

found_goodV=0;

4435

found_goodV=0;

4552

for ii=1:length(val_sort)

4436

for ii=1:length(val_sort)

4553

if val_sort(ii)==goodV

4437

if val_sort(ii)==goodV

4554

found_goodV=1;

4438

found_goodV=1;

4555

break;

4439

break;

4556

end

4440

end

4557

if all(val_sort(ii)-checkV~=0)

4441

if all(val_sort(ii)-checkV~=0)

4558

break;

4442

break;

4559

end

4443

end

4560

end

4444

end

4561

4445

4562

if ~found_goodV && min(badV_pos)<ii

4446

if ~found_goodV && min(badV_pos)<ii

4563

%if goodV wasn't found and bad taps occur before non group members are found

4447

%if goodV wasn't found and bad taps occur before non group members are found

4564

%throw out the strongest tap and take the next strongest

4448

%throw out the strongest tap and take the next strongest

4565

do_it_again=1;

4449

do_it_again=1;

4566

ndiff(new_bank(1))=min_energy;

4450

ndiff(new_bank(1))=min_energy;

4567

%speed up: new max_val is always val_sort(2)

4451

%speed up: new max_val is always val_sort(2)

4568

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4452

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4569

end

4453

end

4570

if found_goodV

4454

if found_goodV

4571

%if goodV was found, set the next bank to goodV

4455

%if goodV was found, set the next bank to goodV

4572

set_next_bank=goodV;

4456

set_next_bank=goodV;

4573

end

4457

end

4574

end

4458

end

4575

num_loops=num_loops+1;

4459

num_loops=num_loops+1;

4576

end

4460

end

4577

%at the end, the floating taps are set to idx

4461

%at the end, the floating taps are set to idx

4578

%and ndiff has illegal values set to zero

4462

%and ndiff has illegal values set to zero

4579

ndiff(new_bank)=min_energy;

4463

ndiff(new_bank)=min_energy;

4580

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4464

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4581

if ~isempty(badV)

4465

if ~isempty(badV)

4582

ndiff(badV)=min_energy;

4466

ndiff(badV)=min_energy;

4583

end

4467

end

4584

end

4468

end

4585

4469

4586

4470

4587

idx=idx+idx_st-1;

4471

idx=idx+idx_st-1;

4588

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4472

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4589

4473

4590

% hisi = postcursor isi

4474

% hisi = postcursor isi

4591

% N_b = number of fixed dfe taps (before floating taps begin)

4475

% N_b = number of fixed dfe taps (before floating taps begin)

4592

% N_bf = number of floating taps per group

4476

% N_bf = number of floating taps per group

4593

% N_bg = nubmber of groups

4477

% N_bg = nubmber of groups

4594

% N_bmax = max tap number that can be used for floating tap

4478

% N_bmax = max tap number that can be used for floating tap

4595

% bmaxg = max tap strength for floating taps

4479

% bmaxg = max tap strength for floating taps

4596

% curval = value of the cursor

4480

% curval = value of the cursor

4597

4481

4598

4482

4599

if nargin<8, dfe_delta=0;end

4483

if nargin<8, dfe_delta=0;end

4600

4484

4601

4485

4602

tap_coef=zeros(1,length(hisi));

4486

tap_coef=zeros(1,length(hisi));

4603

b=zeros(1,length(hisi));

4487

b=zeros(1,length(hisi));

4604

4488

4605

4489

4606

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4490

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4607

4491

4608

%Apply DFE to all taps

4492

%Apply DFE to all taps

4609

flt_curval=hisi(tap_loc);

4493

flt_curval=hisi(tap_loc);

4610

if dfe_delta~=0

4494

if dfe_delta~=0

4611

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4495

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4612

dfe_delta.*sign(flt_curval)*curval;

4496

dfe_delta.*sign(flt_curval)*curval;

4613

else

4497

else

4614

flt_curval_q=hisi(tap_loc);

4498

flt_curval_q=hisi(tap_loc);

4615

end

4499

end

4616

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4500

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4617

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4501

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4618

tap_coef(tap_loc)=applied_coef;

4502

tap_coef(tap_loc)=applied_coef;

4619

4503

4620

4504

4621

4505

4622

tap_loc=sort(tap_loc,'ascend');

4506

tap_loc=sort(tap_loc,'ascend');

4623

b(tap_loc)=bmaxg;

4507

b(tap_loc)=bmaxg;

4624

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4508

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4625

% Richard Mellitz: 04/23/2019

4509

% Richard Mellitz: 04/23/2019

4626

% hisi is the isi 1 ui/sample

4510

% hisi is the isi 1 ui/sample

4627

% N_b number of fixed dfe taps

4511

% N_b number of fixed dfe taps

4628

% N_bf number of floating taps per group

4512

% N_bf number of floating taps per group

4629

% N_bg number of floating tap groups. 1 2 or 3 right now

4513

% N_bg number of floating tap groups. 1 2 or 3 right now

4630

% N_bmax number of ui for the max reach of the floating taps

4514

% N_bmax number of ui for the max reach of the floating taps

4631

% bmaxg limit for the floating taps

4515

% bmaxg limit for the floating taps

4632

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4516

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4633

%

4517

%

4634

%

4518

%

4635

% function to remove isi or add noise above bmaxg

4519

% function to remove isi or add noise above bmaxg

4636

if ~exist('COOP','var'), COOP=0;end

4520

if ~exist('COOP','var'), COOP=0;end

4637

if iscolumn(hisi); hisi=hisi.';end

4521

if iscolumn(hisi); hisi=hisi.';end

4638

hsis_in=hisi;

4522

hsis_in=hisi;

4639

% find all the reduction group taken N_bf at a time

4523

% find all the reduction group taken N_bf at a time

4640

% we are looking for the group when when remove yield the miminim isi, h, power

4524

% we are looking for the group when when remove yield the miminim isi, h, power

4641

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4525

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4642

% add on switch and loop for each potential group

4526

% add on switch and loop for each potential group

4643

switch N_bg

4527

switch N_bg

4644

case 0

4528

case 0

4645

bmax=0;

4529

bmax=0;

4646

return

4530

return

4647

case 1

4531

case 1

4648

end1=N_bmax-N_bf;

4532

end1=N_bmax-N_bf;

4649

end2=N_b+1;

4533

end2=N_b+1;

4650

end3=N_b+1;

4534

end3=N_b+1;

4651

case 2

4535

case 2

4652

end1=N_bmax-N_bf;

4536

end1=N_bmax-N_bf;

4653

end2=N_bmax-N_bf;

4537

end2=N_bmax-N_bf;

4654

end3=N_b+1;

4538

end3=N_b+1;

4655

case 3

4539

case 3

4656

end1=N_bmax-N_bf;

4540

end1=N_bmax-N_bf;

4657

end2=N_bmax-N_bf;

4541

end2=N_bmax-N_bf;

4658

end3=N_bmax-N_bf;

4542

end3=N_bmax-N_bf;

4659

end

4543

end

4660

if COOP

4544

if COOP

4661

for ig1= N_b+1:end1 % now remove the 2nd group

4545

for ig1= N_b+1:end1 % now remove the 2nd group

4662

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4546

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4663

% loop for 2rd group

4547

% loop for 2rd group

4664

for ig2= N_b+1: end2

4548

for ig2= N_b+1: end2

4665

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4549

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4666

if N_bg < 2; hcap2 =hcap; end

4550

if N_bg < 2; hcap2 =hcap; end

4667

for ig3= N_b+1: end3

4551

for ig3= N_b+1: end3

4668

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4552

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4669

if N_bg < 3 ; hcap3=hcap2 ; end

4553

if N_bg < 3 ; hcap3=hcap2 ; end

4670

sigma=norm( hcap3 );

4554

sigma=norm( hcap3 );

4671

if sigma < best_sigma

4555

if sigma < best_sigma

4672

best_sigma=sigma;

4556

best_sigma=sigma;

4673

best_ig1=ig1;

4557

best_ig1=ig1;

4674

best_ig2=ig2;

4558

best_ig2=ig2;

4675

best_ig3=ig3;

4559

best_ig3=ig3;

4676

best_hcap=hcap3;

4560

best_hcap=hcap3;

4677

end

4561

end

4678

end

4562

end

4679

end

4563

end

4680

end

4564

end

4681

else % sequentail

4565

else % sequentail

4682

for ig1= N_b+1:end1 % now remove the 1st group

4566

for ig1= N_b+1:end1 % now remove the 1st group

4683

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4567

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4684

sigma=norm( hcap );

4568

sigma=norm( hcap );

4685

if sigma < best_sigma

4569

if sigma < best_sigma

4686

best_sigma=sigma;

4570

best_sigma=sigma;

4687

best_ig1=ig1;

4571

best_ig1=ig1;

4688

best_hcap=hcap;

4572

best_hcap=hcap;

4689

end

4573

end

4690

end

4574

end

4691

% loop for 2rd group

4575

% loop for 2rd group

4692

hisi=best_hcap;

4576

hisi=best_hcap;

4693

for ig2= N_b+1: end2

4577

for ig2= N_b+1: end2

4694

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4578

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4695

sigma=norm( hcap );

4579

sigma=norm( hcap );

4696

if sigma < best_sigma

4580

if sigma < best_sigma

4697

best_sigma=sigma;

4581

best_sigma=sigma;

4698

best_ig2=ig2;

4582

best_ig2=ig2;

4699

best_hcap=hcap;

4583

best_hcap=hcap;

4700

end

4584

end

4701

end

4585

end

4702

hisi=best_hcap;

4586

hisi=best_hcap;

4703

% loop for 3rd group

4587

% loop for 3rd group

4704

for ig3= N_b+1: end3

4588

for ig3= N_b+1: end3

4705

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4589

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4706

sigma=norm( hcap );

4590

sigma=norm( hcap );

4707

if sigma < best_sigma

4591

if sigma < best_sigma

4708

best_sigma=sigma;

4592

best_sigma=sigma;

4709

best_ig3=ig3;

4593

best_ig3=ig3;

4710

best_hcap=hcap;

4594

best_hcap=hcap;

4711

end

4595

end

4712

end

4596

end

4713

4597

4714

end

4598

end

4715

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4599

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4716

switch N_bg

4600

switch N_bg

4717

case 1

4601

case 1

4718

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4602

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4719

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4603

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4720

case 2

4604

case 2

4721

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4605

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4722

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4606

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4723

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4607

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4724

case 3

4608

case 3

4725

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4609

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4726

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4610

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4727

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4611

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4728

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4612

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4729

end

4613

end

4730

floating_tap_locations=sort(floating_tap_locations);

4614

floating_tap_locations=sort(floating_tap_locations);

4731

if 0 % for code debug

4615

if 0 % for code debug

4732

close force all

4616

close force all

4733

stem(best_hcap,'disp','hcap')

4617

stem(best_hcap,'disp','hcap')

4734

hold on

4618

hold on

4735

stem(bmax,'-k','disp','bmax')

4619

stem(bmax,'-k','disp','bmax')

4736

stem(hisi,'disp','hisi')

4620

stem(hisi,'disp','hisi')

4737

hold off

4621

hold off

4738

end

4622

end

4739

4623

4740

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4624

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4741

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4625

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4742

% Vfilter is vector forced filtered sbr

4626

% Vfilter is vector forced filtered sbr

4743

% Cmod is the ffe tap co-efficient vector

4627

% Cmod is the ffe tap co-efficient vector

4744

% if C is passed, just process V with C else compute C

4628

% if C is passed, just process V with C else compute C

4745

% cmx=param.rx_cmx; number of pre cursor taps

4629

% cmx=param.rx_cmx; number of pre cursor taps

4746

% cpx=param.rx_cps; number of post cursor taps

4630

% cpx=param.rx_cps; number of post cursor taps

4747

% V=sbr; pass pulse response

4631

% V=sbr; pass pulse response

4748

% ix the sample point in the passed pulse response

4632

% ix the sample point in the passed pulse response

4749

% the sample point is recomputed by optimize_fom

4633

% the sample point is recomputed by optimize_fom

4750

% idx - return floating tap location (RIM 9-19-2023)

4634

% idx - return floating tap location (RIM 9-19-2023)

4751

% OP not used for now

4635

% OP not used for now

4752

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4636

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4753

% this allows significant speed up in optimize_fom since FFE is time consuming

4637

% this allows significant speed up in optimize_fom since FFE is time consuming

4754

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4638

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4755

% Vfiltered to be calculated

4639

% Vfiltered to be calculated

4756

% test with load('SBR_FIR_resp.mydata','-mat')

4640

% test with load('SBR_FIR_resp.mydata','-mat')

4757

idx=[];

4641

idx=[];

4758

if nargin<4

4642

if nargin<4

4759

ix=find(V==max(V),1,'first');

4643

ix=find(V==max(V),1,'first');

4760

end

4644

end

4761

if nargin<5

4645

if nargin<5

4762

C=[];

4646

C=[];

4763

end

4647

end

4764

if nargin<6

4648

if nargin<6

4765

return_V=1;

4649

return_V=1;

4766

end

4650

end

4767

cmx=param.RxFFE_cmx;

4651

cmx=param.RxFFE_cmx;

4768

cpx=param.RxFFE_cpx;

4652

cpx=param.RxFFE_cpx;

4769

% do this early on so we can reuse the old code

4653

% do this early on so we can reuse the old code

4770

if param.N_bg ~=0 % must be floating taps

4654

if param.N_bg ~=0 % must be floating taps

4771

cpx=param.N_bmax; % N_f in spreadsheet

4655

cpx=param.N_bmax; % N_f in spreadsheet

4772

end

4656

end

4773

num_taps=cmx+cpx+1;

4657

num_taps=cmx+cpx+1;

4774

cstep=param.RxFFE_stepz;

4658

cstep=param.RxFFE_stepz;

4775

ndfe=param.ndfe;

4659

ndfe=param.ndfe;

4776

spui=param.samples_per_ui;

4660

spui=param.samples_per_ui;

4777

param.current_ffegain=0;

4661

param.current_ffegain=0;

4778

if return_V && ~isempty(C)

4662

if return_V && ~isempty(C)

4779

% RIM 2-3-23 when we just want to EQ not find EQ

4663

% RIM 2-3-23 when we just want to EQ not find EQ

4780

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4664

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4781

Cmod=C;

4665

Cmod=C;

4782

return

4666

return

4783

end

4667

end

4784

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4668

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4785

if ix < length(V)

4669

if ix < length(V)

4786

if isrow(V)

4670

if isrow(V)

4787

if mod(ix,spui) == 0

4671

if mod(ix,spui) == 0

4788

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4672

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4789

else

4673

else

4790

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4674

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4791

end

4675

end

4792

4676

4793

else

4677

else

4794

if mod(ix,spui) == 0

4678

if mod(ix,spui) == 0

4795

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4679

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4796

else

4680

else

4797

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4681

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4798

end

4682

end

4799

end

4683

end

4800

else

4684

else

4801

if isrow(V)

4685

if isrow(V)

4802

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4686

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4803

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4687

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4804

else

4688

else

4805

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4689

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4806

end

4690

end

4807

else

4691

else

4808

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4692

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4809

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4693

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4810

else

4694

else

4811

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4695

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4812

end

4696

end

4813

end

4697

end

4814

end

4698

end

4815

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4699

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4816

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4700

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4817

4701

4818

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4702

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4819

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4703

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4820

% Upen Kareti suggested fix for indexing 11/04/18

4704

% Upen Kareti suggested fix for indexing 11/04/18

4821

if ix < length(V)

4705

if ix < length(V)

4822

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4706

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4823

else

4707

else

4824

ivs=find(vsampled == max(vsampled),1,'first');

4708

ivs=find(vsampled == max(vsampled),1,'first');

4825

end

4709

end

4826

4710

4827

4711

4828

%% create VV matrix of shifted UI spaced sample of the pulse response

4712

%% create VV matrix of shifted UI spaced sample of the pulse response

4829

% only consider the VV matrix that correstonds to the FFE taps

4713

% only consider the VV matrix that correstonds to the FFE taps

4830

VV=zeros(num_taps,num_taps);

4714

VV=zeros(num_taps,num_taps);

4831

for i=1:num_taps

4715

for i=1:num_taps

4832

start_idx=ivs+i-1;

4716

start_idx=ivs+i-1;

4833

end_idx=start_idx-num_taps+1;

4717

end_idx=start_idx-num_taps+1;

4834

VV(:,i)=vsampled(start_idx:-1:end_idx);

4718

VV(:,i)=vsampled(start_idx:-1:end_idx);

4835

end

4719

end

4836

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4720

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4837

%% Apply RXFFE

4721

%% Apply RXFFE

4838

if isempty(C)

4722

if isempty(C)

4839

switch upper(OP.FFE_OPT_METHOD)

4723

switch upper(OP.FFE_OPT_METHOD)

4840

case 'WIENER-HOPF'

4724

case 'WIENER-HOPF'

4841

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4725

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4842

Cmod=C(1:num_taps);

4726

Cmod=C(1:num_taps);

4843

otherwise

4727

otherwise

4844

% cmx+1 is the cursor or sample point

4728

% cmx+1 is the cursor or sample point

4845

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4729

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4846

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4730

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4847

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4731

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4848

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4732

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4849

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4733

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4850

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4734

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4851

end

4735

end

4852

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4736

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4853

if diff(size(VV))==0

4737

if diff(size(VV))==0

4854

%For square matrix, can solve C using simple inv(VV')*FV'

4738

%For square matrix, can solve C using simple inv(VV')*FV'

4855

C=VV'\FV';

4739

C=VV'\FV';

4856

else

4740

else

4857

%otherwise use the general solution with psuedo inverse

4741

%otherwise use the general solution with psuedo inverse

4858

%note: this is the same as doing pinv(VV') but pinv is far slower

4742

%note: this is the same as doing pinv(VV') but pinv is far slower

4859

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4743

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4860

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4744

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4861

end

4745

end

4862

4746

4863

Cmod=C(1:num_taps);

4747

Cmod=C(1:num_taps);

4864

end

4748

end

4865

4749

4866

4750

4867

% added for 4.2 find floating taps with either ISI or taps

4751

% added for 4.2 find floating taps with either ISI or taps

4868

switch lower(OP.RXFFE_FLOAT_CTL)

4752

switch lower(OP.RXFFE_FLOAT_CTL)

4869

case 'taps'

4753

case 'taps'

4870

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4754

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4871

otherwise

4755

otherwise

4872

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4756

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4873

end

4757

end

4874

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4758

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4875

case 'unity cursor'

4759

case 'unity cursor'

4876

Cmod=Cmod/Cmod(cmx+1);

4760

Cmod=Cmod/Cmod(cmx+1);

4877

otherwise

4761

otherwise

4878

Cmod=C;

4762

Cmod=C;

4879

end

4763

end

4880

if cstep ~= 0

4764

if cstep ~= 0

4881

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4765

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4882

end

4766

end

4883

4767

4884

if ~isempty(idx)

4768

if ~isempty(idx)

4885

idx=sort(idx);

4769

idx=sort(idx);

4886

C1=Cmod;

4770

C1=Cmod;

4887

% C1(param.N_tail_start:end)=0;

4771

% C1(param.N_tail_start:end)=0;

4888

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4772

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4889

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4773

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4890

Cmod=C1;

4774

Cmod=C1;

4891

else

4775

else

4892

% Cmod=C;

4776

% Cmod=C;

4893

end

4777

end

4894

4778

4895

% now when ussing RxFFE floating taps need to tag stems correctly and

4779

% now when ussing RxFFE floating taps need to tag stems correctly and

4896

% make sure DFEfloating tap code does not get exectuted

4780

% make sure DFEfloating tap code does not get exectuted

4897

4781

4898

%

4782

%

4899

else

4783

else

4900

Cmod=C;%just us the FFE taps, C, passed for filtering

4784

Cmod=C;%just us the FFE taps, C, passed for filtering

4901

end

4785

end

4902

%%

4786

%%

4903

%% filter the pulse response with the solved FFE

4787

%% filter the pulse response with the solved FFE

4904

% (now option to avoid this and just return Cmod for speed up)

4788

% (now option to avoid this and just return Cmod for speed up)

4905

if return_V

4789

if return_V

4906

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4790

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4907

else

4791

else

4908

Vfiltered=[];

4792

Vfiltered=[];

4909

end

4793

end

4910

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4794

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4911

% used for FD IL fitting

4795

% used for FD IL fitting

4912

% sdd21 us a complex insertion loss

4796

% sdd21 us a complex insertion loss

4913

db = @(x) 20*log10(abs(x));

4797

db = @(x) 20*log10(abs(x));

4914

sdd21=squeeze(sdd21);

4798

sdd21=squeeze(sdd21);

4915

if iscolumn(sdd21)

4799

if iscolumn(sdd21)

4916

sdd21=sdd21.';

4800

sdd21=sdd21.';

4917

end

4801

end

4918

fmbg=[ones(length(faxis_f2),1).*transpose(abs(sdd21)) transpose(sqrt(faxis_f2)).*transpose(abs(sdd21)) transpose(faxis_f2).*transpose(abs(sdd21)) transpose(faxis_f2.^2).*transpose(abs(sdd21)) ];

4802

fmbg=[ones(length(faxis_f2),1).*transpose(abs(sdd21)) transpose(sqrt(faxis_f2)).*transpose(abs(sdd21)) transpose(faxis_f2).*transpose(abs(sdd21)) transpose(faxis_f2.^2).*transpose(abs(sdd21)) ];

4919

warning('off','MATLAB:nearlySingularMatrix');

4803

warning('off','MATLAB:nearlySingularMatrix');

4920

LGw=transpose(abs(sdd21).*db(sdd21));

4804

LGw=transpose(abs(sdd21).*db(sdd21));

4921

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4805

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4922

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4806

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4923

ILN = db(sdd21)-efit;

4807

ILN = db(sdd21)-efit;

4924

4808

4925

4809

4926

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4810

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4927

% Complex IL fitting

4811

% Complex IL fitting

4928

% sdd21 us a complex insertion loss

4812

% sdd21 us a complex insertion loss

4929

% efit and ILN are in db

4813

% efit and ILN are in db

4930

% faxix_f2 needs to be at least to fb

4814

% faxix_f2 needs to be at least to fb

4931

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

4815

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

4932

% still need to settle on voltage scaling.

4816

% still need to settle on voltage scaling.

4933

% maybe db(peak/Rss

4817

% maybe db(peak/Rss

4934

4818

4935

OP.interp_sparam_mag= 'trend_to_DC';

4819

OP.interp_sparam_mag= 'trend_to_DC';

4936

OP.interp_sparam_phase= 'interp_to_DC';

4820

OP.interp_sparam_phase= 'interp_to_DC';

4937

% OP.interp_sparam_mag= 'linear_trend_to_DC';

4821

% OP.interp_sparam_mag= 'linear_trend_to_DC';

4938

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

4822

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

4939

4823

4940

print_for_codereview=0;

4824

print_for_codereview=0;

4941

if ~exist('A_T','var')

4825

if ~exist('A_T','var')

4942

A_T=1;

4826

A_T=1;

4943

end

4827

end

4944

4828

4945

db = @(x) 20*log10(abs(x));

4829

db = @(x) 20*log10(abs(x));

4946

sdd21=squeeze(sdd21);

4830

sdd21=squeeze(sdd21);

4947

if iscolumn(sdd21)

4831

if iscolumn(sdd21)

4948

sdd21=sdd21.';

4832

sdd21=sdd21.';

4949

end

4833

end

4950

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

4834

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

4951

warning('off','MATLAB:nearlySingularMatrix');

4835

warning('off','MATLAB:nearlySingularMatrix');

4952

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

4836

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

4953

LGw=transpose(sdd21.*unwraplog);

4837

LGw=transpose(sdd21.*unwraplog);

4954

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4838

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4955

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4839

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4956

FIT=transpose(exp(transpose(efit_C)));

4840

FIT=transpose(exp(transpose(efit_C)));

4957

efit=db(abs(FIT));

4841

efit=db(abs(FIT));

4958

ILN = db(sdd21)-efit;

4842

ILN = db(sdd21)-efit;

4959

% time domain

4843

% time domain

4960

fprintf('computing TD_ILN (dB) ...')

4844

fprintf('computing TD_ILN (dB) ...')

4961

if exist('OP','var')

4845

if exist('OP','var')

4962

% OP.fraction_of_F_range_start_extrap_from=.95;

4846

% OP.fraction_of_F_range_start_extrap_from=.95;

4963

OP.impulse_response_truncation_threshold =1e-7;

4847

OP.impulse_response_truncation_threshold =1e-7;

4964

4848

4965

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

4849

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

4966

H_bw=Butterworth_Filter(param,faxis_f2,1);

4850

H_bw=Butterworth_Filter(param,faxis_f2,1);

4967

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

4851

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

4968

H_tw=Tukey_Window(faxis_f2,param);

4852

H_tw=Tukey_Window(faxis_f2,param);

4969

H_tw=ones(1,length(faxis_f2) );

4853

H_tw=ones(1,length(faxis_f2) );

4970

4854

4971

[TD_ILN.REF.FIR, ...

4855

[TD_ILN.REF.FIR, ...

4972

TD_ILN.REF.t, ...

4856

TD_ILN.REF.t, ...

4973

TD_ILN.REF.causality_correction_dB, ...

4857

TD_ILN.REF.causality_correction_dB, ...

4974

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4858

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4975

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

4859

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

4976

4860

4977

[TD_ILN.FIT.FIR, ...

4861

[TD_ILN.FIT.FIR, ...

4978

TD_ILN.FIT.t, ...

4862

TD_ILN.FIT.t, ...

4979

TD_ILN.FIT.causality_correction_dB, ...

4863

TD_ILN.FIT.causality_correction_dB, ...

4980

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4864

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4981

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

4865

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

4982

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

4866

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

4983

% NrangeUI=1000;

4867

% NrangeUI=1000;

4984

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(TD_ILN.FIT.PR)-param.samples_per_ui ),length(TD_ILN.REF.PR)-param.samples_per_ui);

4868

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(TD_ILN.FIT.PR)-param.samples_per_ui ),length(TD_ILN.REF.PR)-param.samples_per_ui);

4985

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

4869

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

4986

range=ipeak:range_end;

4870

range=ipeak:range_end;

4987

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

4871

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

4988

TD_ILN.t=TD_ILN.FIT.t(range);

4872

TD_ILN.t=TD_ILN.FIT.t(range);

4989

TD_ILN.FOM=-inf;

4873

TD_ILN.FOM=-inf;

4990

TD_ILN.FOM_PDF=-inf;

4874

TD_ILN.FOM_PDF=-inf;

4991

rms_fom=-inf;

4875

rms_fom=-inf;

4992

for im=1:param.samples_per_ui

4876

for im=1:param.samples_per_ui

4993

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

4877

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

4994

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

4878

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

4995

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

4879

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

4996

cdf=pdf; cdf.y=cumsum(pdf.y);

4880

cdf=pdf; cdf.y=cumsum(pdf.y);

4997

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

4881

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

4998

% signal_and_isi_pdf = conv_fct(cursors, pdf);

4882

% signal_and_isi_pdf = conv_fct(cursors, pdf);

4999

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

4883

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5000

if print_for_codereview % remove once all checked out

4884

if print_for_codereview % remove once all checked out

5001

h=figure(190);set(gcf,'Tag','COM');

4885

h=figure(190);set(gcf,'Tag','COM');

5002

semilogy(-cdf.x,cdf.y);

4886

semilogy(-cdf.x,cdf.y);

5003

% xlim ([0,-cdf.x(1)])

4887

% xlim ([0,-cdf.x(1)])

5004

ylim([param.specBER 1]);title ('CDF of ILN')

4888

ylim([param.specBER 1]);title ('CDF of ILN')

5005

hold on

4889

hold on

5006

end

4890

end

5007

if rms>rms_fom

4891

if rms>rms_fom

5008

rms_fom=rms;

4892

rms_fom=rms;

5009

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

4893

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5010

TD_ILN.PDF=pdf;

4894

TD_ILN.PDF=pdf;

5011

end

4895

end

5012

end

4896

end

5013

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

4897

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

5014

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

4898

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

5015

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

4899

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

5016

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

4900

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

5017

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

4901

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

5018

if print_for_codereview % remove once all checked out

4902

if print_for_codereview % remove once all checked out

5019

figure(9000);set(gcf,'Tag','COM');

4903

figure(9000);set(gcf,'Tag','COM');

5020

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

4904

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

5021

hold on

4905

hold on

5022

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

4906

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

5023

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

4907

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

5024

hold off

4908

hold off

5025

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',TD_ILN.SNR_ISI_FOM,TD_ILN.SNR_ISI_FOM_PDF)

4909

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',TD_ILN.SNR_ISI_FOM,TD_ILN.SNR_ISI_FOM_PDF)

5026

figure(9002);set(gcf,'Tag','COM');

4910

figure(9002);set(gcf,'Tag','COM');

5027

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

4911

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

5028

hold on

4912

hold on

5029

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

4913

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5030

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

4914

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5031

grid on

4915

grid on

5032

legend('show')

4916

legend('show')

5033

end

4917

end

5034

end

4918

end

5035

% display('got to end of get_ILN_cmp_td')

4919

% display('got to end of get_ILN_cmp_td')

5036

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

4920

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

5037

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

5038

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

5039

if 1 % force indent for doc

4921

if 1 % force indent for doc

5040

num_ui=param.num_ui_RXFF_noise;

4922

num_ui=param.num_ui_RXFF_noise;

5041

M=param.samples_per_ui;

4923

M=param.samples_per_ui;

5042

L=param.levels;

4924

L=param.levels;

+4925

sigma_X2=(L^2-1)/(3*(L-1)^2);

5043

f_b=param.fb;

4926

f_b=param.fb;

5044

SNR_TX=param.SNR_TX;

5045

dw=param.RxFFE_cmx;

5046

bmax=param.bmax;

5047

bmin=param.bmin ;

5048

Nb=param.ndfe;

5049

sigma_X2=(L^2-1)/(3*(L-1)^2);

5050

eta_0=param.eta_0; %V^2/GHz

5051

T_b=1/f_b;

4927

T_b=1/f_b;

5052

delta_f = f_b/num_ui; % Units are Hz.

4928

delta_f = f_b/num_ui; % Units are Hz.

5053

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

4929

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

5054

result.fvec=fvec;

4930

result.fvec=fvec;

5055

end

5056

if OP.COMPUTE_COM

4931

SNR_TX=param.SNR_TX;

5057

%% H_rxffe eq 178A-29 d0.2

5058

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

5059

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

5060

H_rxffe=0;

5061

for nn=1:length(result.w)

4932

eta_0=param.eta_0; %V^2/GHz

5062

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

5063

end

5064

H_rxffe_2_of_f=abs(H_rxffe).^2;

5065

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

5066

H_rxffe_2= [real( H_rxffe_2(1)), H_rxffe_2(2:end-1), real( H_rxffe_2(end)), conj( H_rxffe_2(end-1:-1:2))];

5067

else

5068

H_rxffe_2=1;

5069

end

4933

end

5070

5071

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

4934

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

5072

% --->this is the point in the code may fork where we add extra rx noise

5073

%% compute S_rn ( eq 178A-15 d0.2 )

4935

%% compute S_rn healey_3dj_01_2401 slide 5

5074

if ~OP.COMPUTE_COM

5075

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

4936

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

5076

rxn_psd=[real(S_RN_of_f(1)), S_RN_of_f(2:end-1), real(S_RN_of_f(end)), conj(S_RN_of_f(end-1:-1:2))]; % Convert single-sided frequency response to conjugate-symmetric

4937

rxn_psd=[real(S_RN_of_f(1)), S_RN_of_f(2:end-1), real(S_RN_of_f(end)), conj(S_RN_of_f(end-1:-1:2))]; % Convert single-sided frequency response to conjugate-symmetric

5077

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

4938

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

5078

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

4939

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

5079

S_rn = sum(reshape(rxn_psd, num_ui, M).');

4940

S_rn = sum(reshape(rxn_psd, num_ui, M).');

5080

S_rn=S_rn(1:num_ui/2+1);

4941

S_rn=S_rn(1:num_ui/2+1);

5081

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

4942

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

+4943

%rxn_acf_samp = ifft(S_rn)*f_b; % Autocorrelation function. Note that the first term is rxn_rms^2.

4944

if 0 % for debug

4945

figure

4946

set(gcf, 'tag', 'COM');movegui(gcf,'northeast');

4947

plot(fvec(1:num_ui)/f_b,10*log10((S_rn)*1000/100) ...

4948

,'disp','Srn')

4949

xlim([0 0.5])

4950

ylim([-200 -140])

4951

set(gcf,'defaulttextinterpreter','none')

4952

xlabel('Normalized Frequency')

4953

ylabel('PSD dBm/Hz')

4954

hold on

4955

grid on

4956

title('PSD')

4957

end

5082

result.S_rn=S_rn;

4958

result.S_rn=S_rn;

5083

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4959

result.S_rn_rms=rxn_rms;

5084

else

5085

result.S_rn=result.S_rn.*H_rxffe_2;

5086

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5087

end

5088

4960

5089

else % find noise for item that set have tx ffe for each loop

4961

else % find noise for item that set have tx ffe for each loop

5090

%% S_xn from eq 178A-16

4962

%% from healey_3dj_01_2401 slide 6

5091

%% Crosstalk power spectral density

4963

% Crosstalk power spectral density

5092

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

5093

result.S_xn=0;

4964

result.S_xn=0;

5094

if length(chdata)~=1

4965

if length(chdata)~=1;

5095

for xchan=2:length(chdata)

4966

for xchan=2:length(chdata)

5096

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

4967

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

5097

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

4968

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

5098

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

5099

% enable less UI for computation speed improvement

4969

% enable less UI for computation speed improvement

5100

%%

4970

%%

5101

if num_ui*M > length(pulse_ctle)

4971

if num_ui*M > length(pulse_ctle)

5102

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

4972

pulse_ctle= [ pulse_ctle zeros(1,num_ui*M-length(pulse_ctle)) ];

+4973

else

4974

pulse_ctle=pulse_ctle(1:num_ui*M);

4975

end

4976

cmx=find(txffe==max(txffe))-1;

4977

for i1=1:M

4978

if ~strcmp(chdata(xchan).type,'NEXT')

4979

hk(xchan).k=FFE( txffe , cmx,M, pulse_ctle )'; % need to speed up here

5103

else

4980

else

5104

hk(xchan).k=hk(xchan).k(1:num_ui*M);

4981

hk(xchan).k=pulse_ctle;

+4982

end

5105

end

4983

end

5106

for i1=1:M

4984

for i1=1:M

5107

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

4985

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

5108

end

4986

end

5109

iphase(xchan)=find(hxn==max(hxn));

4987

iphase(xchan)=find(hxn==max(hxn));

5110

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

4988

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

5111

result.hk(xchan).hrn= hk(xchan).hrn;

4989

result.hk(xchan).hrn= hk(xchan).hrn;

5112

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

4990

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

5113

result.S_xn=hk(xchan).S_xn+result.S_xn;

4991

result.S_xn=hk(xchan).S_xn+result.S_xn;

5114

end

4992

end

5115

result.S_xn=result.S_xn;

5116

result.hk=hk;

5117

result.iphase=iphase;

5118

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4993

result.xn_rms = sqrt(sum(result.S_xn)* delta_f);

5119

else % if no crosstalk, perserve structure and return 0 for S_xn

4994

else

5120

result.S_xn=0;

4995

result.xn_rms=0;

5121

result.hk=[];

5122

result.iphase=1;

5123

result.S_xn_rms = 0;

4996

iphase=0;

5124

end

4997

end

5125

else % adjust for H_rxffe when computing COM

5126

result.S_xn=result.S_xn.*H_rxffe_2;

5127

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5128

end

5129

%% S_tn from eq 178A-17

4998

%% from healey_3dj_01_2401 slide 7

5130

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

5131

%% Transmitter noise power spectral density

4999

% Transmitter noise power spectral density

5132

if ~OP.COMPUTE_COM

5133

if ~OP.TDMODE

5000

if ~OP.TDMODE

5134

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

5001

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

5135

else % only use when the input was a pulse response not s-parameters

5002

else % only use when the input was a pulse response not s-parameters

5136

if isfield(chdata(1),'ctle_pulse_response')

5003

if isfield(chdata(1),'ctle_pulse_response')

5137

htn=chdata(1).ctle_pulse_response;

5004

htn=chdata(1).ctle_pulse_response;

5138

else

5005

else

5139

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

5006

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

5140

end

5007

end

5141

end

5008

end

5142

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

5009

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

5143

htn=reshape(htn,1,[]); % make row vectors

5010

htn=reshape(htn,1,[]); % make row vectors

5144

htn=[ htn(1:floor(length(htn)/M)*M) ];

5011

htn=[ htn(1:floor(length(htn)/M)*M) ];

5145

htn= [htn zeros(1,num_ui*M-length(htn)) ];

5012

htn= [htn zeros(1,num_ui*M-length(htn)) ];

5146

htn=htn(1:M:end);% resample

5013

htn=htn(1:M:end);% resample

5147

if num_ui>length(htn)

5014

if num_ui>length(htn)

5148

hext=[htn zeros(1,num_ui-length(htn))];

5015

hext=[htn zeros(1,num_ui-length(htn))];

5149

else

5016

else

5150

hext=htn(1:num_ui);

5017

hext=htn(1:num_ui);

5151

end

5018

end

5152

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

5019

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

5153

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5020

result.tn_rms = sqrt(sum(result.S_tn)* delta_f);

5154

else

5155

result.S_tn=result.S_tn.*H_rxffe_2;

5156

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5157

end

5158

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

5021

%% from healey_3dj_01_2401 slide 8

5159

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

5160

%% Power spectral density of noise due to jitter

5022

% Power spectral density of noise due to jitter

5161

%% Eq. 93A-28 %%

5023

%% Eq. 93A-28 %%

5162

if ~OP.COMPUTE_COM

5163

sampling_offset = mod(cursor_i, M);

5024

sampling_offset = mod(cursor_i, M);

5164

%ensure we can take early sample

5025

%ensure we can take early sample

5165

if sampling_offset<=1

5026

if sampling_offset<=1

5166

sampling_offset=sampling_offset+M;

5027

sampling_offset=sampling_offset+M;

5167

end

5028

end

5168

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

5029

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

5169

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

5030

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

5170

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

5031

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

5171

else

5032

else

5172

cursors_early_sample = h(sampling_offset-1:M:end);

5033

cursors_early_sample = h(sampling_offset-1:M:end);

5173

cursors_late_sample = h(sampling_offset+1:M:end);

5034

cursors_late_sample = h(sampling_offset+1:M:end);

5174

end

5035

end

5175

% ensure lengths are equal

5036

% ensure lengths are equal

5176

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

5037

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

5177

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

5038

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

5178

h_J=reshape(h_J,1,[]); % make row vectors

5039

h_J=reshape(h_J,1,[]); % make row vectors

5179

if num_ui>length(h_J)

5040

if num_ui>length(h_J)

5180

h_J=[h_J zeros(1,num_ui-length(h_J))];

5041

h_J=[h_J zeros(1,num_ui-length(h_J))];

5181

else

5042

else

5182

h_J=h_J(1:num_ui);

5043

h_J=h_J(1:num_ui);

5183

end

5044

end

+5045

result.iphase=iphase;

5184

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5046

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5185

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5047

result.jn_rms = sqrt(sum(result.S_jn)* delta_f);

5186

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5187

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5188

else

5189

result.S_jn=result.S_jn.*H_rxffe_2;

5190

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5191

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

5192

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5193

end

5194

% result.S_jn

5195

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn;

5048

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn;

5196

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

5197

5198

%%

5199

%% Hisi to be included in MLSE rho eq 178a-28

5200

if OP.COMPUTE_COM

5201

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

5202

sampling_offset = mod(cursor_i-1, M)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

5203

hisi=h(sampling_offset:M:end);

5204

hisi=hisi(:).';

5205

if num_ui>length(hisi)

5206

hisi=[hisi zeros(1,num_ui-length(hisi))];

5207

else

5208

hisi=hisi(1:num_ui);

5209

end

5210

cursor_n=floor(cursor_i/M)+1;

5211

for ii=1:length(hisi)

5212

if ii==cursor_n % cursor

5213

cursor=hisi(ii);

5214

hisi(ii)= 0;

5215

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

5216

ib_indx=ii-cursor_n;

5217

if hisi(ii) >= bmax(ib_indx)*cursor

5218

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

5219

elseif hisi(ii) <= bmin(ib_indx)*cursor

5220

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

5221

else

5222

hisi(ii)=0;

5223

end

5224

end

5225

end

5226

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

5227

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

5228

%%

5229

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

5230

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

5231

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

5232

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

5233

end

5234

end

5049

end

5235

function result=get_PulseR(ir,param,cb_step,ZT)

5050

function result=get_PulseR(ir,param,cb_step,ZT)

5236

%ir = impulse response

5051

%ir = impulse response

5237

%t_base=time array with equal time steps

5052

%t_base=time array with equal time steps

5238

%samp_UI = number of samples per UI for ir

5053

%samp_UI = number of samples per UI for ir

5239

5054

5240

% t for debug

5055

% t for debug

5241

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5056

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5242

5057

5243

if cb_step

5058

if cb_step

5244

Ag=1;

5059

Ag=1;

5245

dt=1/param.fb/param.samples_per_ui;

5060

dt=1/param.fb/param.samples_per_ui;

5246

edge_time=param.TR_TDR*1e-9;

5061

edge_time=param.TR_TDR*1e-9;

5247

fedge=1/edge_time;

5062

fedge=1/edge_time;

5248

tedge=0:dt:edge_time*2;

5063

tedge=0:dt:edge_time*2;

5249

%

5064

%

5250

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5065

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5251

drive_pulse=[edge ones(1,param.samples_per_ui)];

5066

drive_pulse=[edge ones(1,param.samples_per_ui)];

5252

%pulse=filter(UI_ones,1,ir);

5067

%pulse=filter(UI_ones,1,ir);

5253

% t for debug

5068

% t for debug

5254

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5069

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5255

5070

5256

pulse=filter(drive_pulse,1,ir);

5071

pulse=filter(drive_pulse,1,ir);

5257

else

5072

else

5258

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5073

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5259

end

5074

end

5260

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5075

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5261

result.PDR=PDR_response;

5076

result.PDR=PDR_response;

5262

result.pulse=pulse;

5077

result.pulse=pulse;

5263

5078

5264

5079

5265

5080

5266

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5081

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5267

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

5082

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

5268

if ~iscolumn(H), H=H.';end

5083

if ~iscolumn(H), H=H.';end

5269

if ~iscolumn(H_r), H_r=H_r.';end

5084

if ~iscolumn(H_r), H_r=H_r.';end

5270

H=H(:).*H_r;

5085

H=H(:).*H_r;

5271

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5086

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5272

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5087

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5273

5088

5274

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5089

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5275

% Complex reflection and re-reflection noise using the concept of zero'ing

5090

% Complex reflection and re-reflection noise using the concept of zero'ing

5276

% out of reflections

5091

% out of reflections

5277

% sdd21 us a complex insertion loss

5092

% sdd21 us a complex insertion loss

5278

% RIL_struct is the output of capture_RIL_RILN()

5093

% RIL_struct is the output of capture_RIL_RILN()

5279

% faxix_f2 needs to be at least to fb

5094

% faxix_f2 needs to be at least to fb

5280

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5095

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5281

% still need to settle on voltage scaling.

5096

% still need to settle on voltage scaling.

5282

% maybe db(peak/Rss

5097

% maybe db(peak/Rss

5283

db = @(x) 20*log10(abs(x));

5098

db = @(x) 20*log10(abs(x));

5284

fprintf('computing TD_RILN (dB) ...');

5099

fprintf('computing TD_RILN (dB) ...');

5285

5100

5286

OP.interp_sparam_mag= 'trend_to_DC';

5101

OP.interp_sparam_mag= 'trend_to_DC';

5287

OP.interp_sparam_phase= 'interp_to_DC';

5102

OP.interp_sparam_phase= 'interp_to_DC';

5288

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5103

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5289

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5104

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5290

5105

5291

sdd21=squeeze(sdd21);

5106

sdd21=squeeze(sdd21);

5292

if iscolumn(sdd21)

5107

if iscolumn(sdd21)

5293

sdd21=sdd21.';

5108

sdd21=sdd21.';

5294

end

5109

end

5295

RIL=squeeze(RIL_struct.RIL);

5110

RIL=squeeze(RIL_struct.RIL);

5296

if iscolumn(RIL)

5111

if iscolumn(RIL)

5297

RIL=RIL.';

5112

RIL=RIL.';

5298

end

5113

end

5299

rho_port1=squeeze(RIL_struct.rho_port1);

5114

rho_port1=squeeze(RIL_struct.rho_port1);

5300

if iscolumn(rho_port1)

5115

if iscolumn(rho_port1)

5301

rho_port1=rho_port1.';

5116

rho_port1=rho_port1.';

5302

end

5117

end

5303

rho_port2=squeeze(RIL_struct.rho_port2);

5118

rho_port2=squeeze(RIL_struct.rho_port2);

5304

if iscolumn(rho_port2)

5119

if iscolumn(rho_port2)

5305

rho_port2=rho_port2.';

5120

rho_port2=rho_port2.';

5306

end

5121

end

5307

RIL_f=squeeze(RIL_struct.freq);

5122

RIL_f=squeeze(RIL_struct.freq);

5308

if iscolumn(RIL_f)

5123

if iscolumn(RIL_f)

5309

RIL_f=RIL_f.';

5124

RIL_f=RIL_f.';

5310

end

5125

end

5311

5126

5312

%---start. Calculate the reflection and re-reflection noise

5127

%---start. Calculate the reflection and re-reflection noise

5313

number_of_echos= 1e3;

5128

number_of_echos= 1e3;

5314

fmin= 1e9;%<-------------

5129

fmin= 1e9;%<-------------

5315

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5130

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5316

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5131

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5317

for m= 1:number_of_echos

5132

for m= 1:number_of_echos

5318

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m)).*(rho_port1.^m).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port2);

5133

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m)).*(rho_port1.^m).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port2);

5319

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m-1)).*(rho_port1.^(m-1)).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port1);

5134

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m-1)).*(rho_port1.^(m-1)).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port1);

5320

end

5135

end

5321

5136

5322

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5137

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5323

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5138

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5324

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5139

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5325

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5140

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5326

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5141

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5327

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5142

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5328

5143

5329

% clear RIL RIL_f rho_port1 rho_port2

5144

% clear RIL RIL_f rho_port1 rho_port2

5330

% clear fmin m

5145

% clear fmin m

5331

%---end. Calculate the reflection and re-reflection noise

5146

%---end. Calculate the reflection and re-reflection noise

5332

5147

5333

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5148

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5334

warning('off','MATLAB:nearlySingularMatrix');

5149

warning('off','MATLAB:nearlySingularMatrix');

5335

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5150

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5336

LGw=transpose(sdd21.*unwraplog);

5151

LGw=transpose(sdd21.*unwraplog);

5337

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5152

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5338

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5153

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5339

FIT=transpose(exp(transpose(efit_C)));

5154

FIT=transpose(exp(transpose(efit_C)));

5340

efit=db(abs(FIT));

5155

efit=db(abs(FIT));

5341

ILN = db(sdd21)-efit;

5156

ILN = db(sdd21)-efit;

5342

5157

5343

5158

5344

OP.impulse_response_truncation_threshold =1e-7;

5159

OP.impulse_response_truncation_threshold =1e-7;

5345

5160

5346

print_for_codereview=0;

5161

print_for_codereview=0;

5347

if exist('OP','var')

5162

if exist('OP','var')

5348

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5163

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5349

H_bw=Butterworth_Filter(param,faxis_f2,1);

5164

H_bw=Butterworth_Filter(param,faxis_f2,1);

5350

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5165

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5351

H_tw=Tukey_Window(faxis_f2,param);

5166

H_tw=Tukey_Window(faxis_f2,param);

5352

H_tw=ones(1,length(faxis_f2) );

5167

H_tw=ones(1,length(faxis_f2) );

5353

[RILN_TD_struct.REF.FIR, ...

5168

[RILN_TD_struct.REF.FIR, ...

5354

RILN_TD_struct.REF.t, ...

5169

RILN_TD_struct.REF.t, ...

5355

RILN_TD_struct.REF.causality_correction_dB, ...

5170

RILN_TD_struct.REF.causality_correction_dB, ...

5356

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5171

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5357

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5172

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5358

5173

5359

5174

5360

[RILN_TD_struct.FIT.FIR, ...

5175

[RILN_TD_struct.FIT.FIR, ...

5361

RILN_TD_struct.FIT.t, ...

5176

RILN_TD_struct.FIT.t, ...

5362

RILN_TD_struct.FIT.causality_correction_dB, ...

5177

RILN_TD_struct.FIT.causality_correction_dB, ...

5363

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5178

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5364

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5179

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5365

5180

5366

5181

5367

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5182

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5368

H_bw=Butterworth_Filter(param,RIL_f,1);

5183

H_bw=Butterworth_Filter(param,RIL_f,1);

5369

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5184

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5370

H_tw=Tukey_Window(RIL_f,param);

5185

H_tw=Tukey_Window(RIL_f,param);

5371

H_tw=ones(1,length(RIL_f) );

5186

H_tw=ones(1,length(RIL_f) );

5372

[RILN_TD_struct.RIL.FIR, ...

5187

[RILN_TD_struct.RIL.FIR, ...

5373

RILN_TD_struct.RIL.t, ...

5188

RILN_TD_struct.RIL.t, ...

5374

RILN_TD_struct.RIL.causality_correction_dB, ...

5189

RILN_TD_struct.RIL.causality_correction_dB, ...

5375

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5190

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5376

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5191

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5377

5192

5378

5193

5379

%---start. Calculate the channel delay

5194

%---start. Calculate the channel delay

5380

try

5195

try

5381

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5196

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5382

catch

5197

catch

5383

end

5198

end

5384

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5199

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5385

clear delay_sec delay_idx

5200

clear delay_sec delay_idx

5386

%---end. Calculate the channel delay

5201

%---end. Calculate the channel delay

5387

5202

5388

5203

5389

5204

5390

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5205

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5391

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5206

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5392

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5207

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5393

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5208

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5394

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5209

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5395

[RILN_TD_struct.REF_noise.FIR, ...

5210

[RILN_TD_struct.REF_noise.FIR, ...

5396

RILN_TD_struct.REF_noise.t, ...

5211

RILN_TD_struct.REF_noise.t, ...

5397

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5212

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5398

RILN_TD_struct.REF_noise.truncation_dB] = s21_to_impulse_DC(port2_reflection_rereflection_noise.*H_bw.*H_t.*H_tw ,f_reflection_rereflection_noise, param.sample_dt, OP) ;

5213

RILN_TD_struct.REF_noise.truncation_dB] = s21_to_impulse_DC(port2_reflection_rereflection_noise.*H_bw.*H_t.*H_tw ,f_reflection_rereflection_noise, param.sample_dt, OP) ;

5399

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5214

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5400

5215

5401

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5216

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5402

% NrangeUI=1000;

5217

% NrangeUI=1000;

5403

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(RILN_TD_struct.FIT.PR)-param.samples_per_ui ),length(RILN_TD_struct.REF.PR)-param.samples_per_ui);

5218

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(RILN_TD_struct.FIT.PR)-param.samples_per_ui ),length(RILN_TD_struct.REF.PR)-param.samples_per_ui);

5404

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5219

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5405

range=ipeak:range_end;

5220

range=ipeak:range_end;

5406

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5221

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5407

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5222

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5408

RILN_TD_struct.FOM=-inf;

5223

RILN_TD_struct.FOM=-inf;

5409

RILN_TD_struct.FOM_PDF=-inf;

5224

RILN_TD_struct.FOM_PDF=-inf;

5410

rms_fom=-inf;

5225

rms_fom=-inf;

5411

for im=1:param.samples_per_ui

5226

for im=1:param.samples_per_ui

5412

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5227

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5413

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5228

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5414

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5229

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5415

cdf=pdf; cdf.y=cumsum(pdf.y);

5230

cdf=pdf; cdf.y=cumsum(pdf.y);

5416

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5231

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5417

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5232

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5418

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5233

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5419

if print_for_codereview % remove once all checked out

5234

if print_for_codereview % remove once all checked out

5420

h=figure(190);set(gcf,'Tag','COM');

5235

h=figure(190);set(gcf,'Tag','COM');

5421

semilogy(-cdf.x,cdf.y);

5236

semilogy(-cdf.x,cdf.y);

5422

% xlim ([0,-cdf.x(1)])

5237

% xlim ([0,-cdf.x(1)])

5423

ylim([param.specBER 1]);title ('CDF of ILN')

5238

ylim([param.specBER 1]);title ('CDF of ILN')

5424

hold on

5239

hold on

5425

end

5240

end

5426

if rms>rms_fom

5241

if rms>rms_fom

5427

rms_fom=rms;

5242

rms_fom=rms;

5428

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5243

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5429

RILN_TD_struct.PDF=pdf;

5244

RILN_TD_struct.PDF=pdf;

5430

end

5245

end

5431

end

5246

end

5432

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5247

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5433

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5248

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5434

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5249

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5435

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5250

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5436

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5251

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5437

if print_for_codereview % remove once all checked out

5252

if print_for_codereview % remove once all checked out

5438

figure(9000);set(gcf,'Tag','COM');

5253

figure(9000);set(gcf,'Tag','COM');

5439

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5254

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5440

hold on

5255

hold on

5441

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5256

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5442

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5257

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5443

yyaxis right

5258

yyaxis right

5444

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5259

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5445

hold off

5260

hold off

5446

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

5261

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

5447

figure(9002);set(gcf,'Tag','COM');

5262

figure(9002);set(gcf,'Tag','COM');

5448

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5263

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5449

hold on

5264

hold on

5450

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5265

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5451

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5266

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5452

grid on

5267

grid on

5453

legend('show')

5268

legend('show')

5454

end

5269

end

5455

end

5270

end

5456

function result=get_StepR(ir,param,cb_step,ZT)

5271

function result=get_StepR(ir,param,cb_step,ZT)

5457

%ir = impulse response

5272

%ir = impulse response

5458

%t_base=time array with equal time steps

5273

%t_base=time array with equal time steps

5459

%samp_UI = number of samples per UI for ir

5274

%samp_UI = number of samples per UI for ir

5460

% result.SBR

5275

% result.SBR

5461

% t for debug

5276

% t for debug

5462

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5277

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5463

5278

5464

if cb_step

5279

if cb_step

5465

Ag=1;

5280

Ag=1;

5466

dt=1/param.fb/param.samples_per_ui;

5281

dt=1/param.fb/param.samples_per_ui;

5467

edge_time=param.TR_TDR*1e-9;

5282

edge_time=param.TR_TDR*1e-9;

5468

fedge=1/edge_time;

5283

fedge=1/edge_time;

5469

tedge=0:dt:edge_time*2;

5284

tedge=0:dt:edge_time*2;

5470

%

5285

%

5471

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5286

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5472

drive_pulse=[edge ones(1,param.samples_per_ui)];

5287

drive_pulse=[edge ones(1,param.samples_per_ui)];

5473

%pulse=filter(UI_ones,1,ir);

5288

%pulse=filter(UI_ones,1,ir);

5474

5289

5475

pulse=filter(drive_pulse,1,ir);

5290

pulse=filter(drive_pulse,1,ir);

5476

else

5291

else

5477

pulse=cumsum(ir);

5292

pulse=cumsum(ir);

5478

end

5293

end

5479

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5294

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5480

result.ZSR=TDR_response;

5295

result.ZSR=TDR_response;

5481

result.pulse=pulse;

5296

result.pulse=pulse;

5482

5297

5483

5298

5484

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5299

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5485

% sdd is differential s-parameters structure (2 port assumed)

5300

% sdd is differential s-parameters structure (2 port assumed)

5486

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5301

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5487

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5302

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5488

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5303

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5489

% TDR_results.t starting at t=0

5304

% TDR_results.t starting at t=0

5490

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5305

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5491

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5306

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5492

% TDR_results.f frequency for filter and s parameters

5307

% TDR_results.f frequency for filter and s parameters

5493

% TDR_results.ptdr_RL reflection waveform from the pulse

5308

% TDR_results.ptdr_RL reflection waveform from the pulse

5494

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5309

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5495

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5310

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5496

% TDR_results.ERL reported effective return loss

5311

% TDR_results.ERL reported effective return loss

5497

%

5312

%

5498

db = @(x) 20*log10(abs(x));

5313

db = @(x) 20*log10(abs(x));

5499

rms =@(x) norm(x)/sqrt(length(x));

5314

rms =@(x) norm(x)/sqrt(length(x));

5500

if isfield(OP,'TDR_duration')

5315

if isfield(OP,'TDR_duration')

5501

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5316

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5502

else

5317

else

5503

TDR_duration=5;

5318

TDR_duration=5;

5504

end

5319

end

5505

if ~isfield(OP,'DISPLAY_WINDOW')

5320

if ~isfield(OP,'DISPLAY_WINDOW')

5506

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5321

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5507

end

5322

end

5508

f=sdd.Frequencies;

5323

f=sdd.Frequencies;

5509

TDR_results.f=f;

5324

TDR_results.f=f;

5510

% OP.Zt_adj=2;

5325

% OP.Zt_adj=2;

5511

if param.FLAG.S2P == 0

5326

if param.FLAG.S2P == 0

5512

5327

5513

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5328

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5514

TDR_RL =@(Zin,Zout,s11,s12,s21,s22)(Zin.^2.*s11+Zin.^2.*s22+Zout.^2.*s11+Zout.^2.*s22+Zin.^2-Zout.^2+Zin.*Zout.*s11.*2.0-Zin.*Zout.*s22.*2.0+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21-Zout.^2.*s11.*s22+Zout.^2.*s12.*s21)./(Zin.*Zout.*2.0+Zin.^2.*s11+Zin.^2.*s22-Zout.^2.*s11-Zout.^2.*s22+Zin.^2+Zout.^2+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21+Zout.^2.*s11.*s22-Zout.^2.*s12.*s21-Zin.*Zout.*s11.*s22.*2.0+Zin.*Zout.*s12.*s21.*2.0);

5329

TDR_RL =@(Zin,Zout,s11,s12,s21,s22)(Zin.^2.*s11+Zin.^2.*s22+Zout.^2.*s11+Zout.^2.*s22+Zin.^2-Zout.^2+Zin.*Zout.*s11.*2.0-Zin.*Zout.*s22.*2.0+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21-Zout.^2.*s11.*s22+Zout.^2.*s12.*s21)./(Zin.*Zout.*2.0+Zin.^2.*s11+Zin.^2.*s22-Zout.^2.*s11-Zout.^2.*s22+Zin.^2+Zout.^2+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21+Zout.^2.*s11.*s22-Zout.^2.*s12.*s21-Zin.*Zout.*s11.*s22.*2.0+Zin.*Zout.*s12.*s21.*2.0);

5515

5330

5516

if param.RL_sel==1, other_port=2;end

5331

if param.RL_sel==1, other_port=2;end

5517

if param.RL_sel==2, other_port=1;end

5332

if param.RL_sel==2, other_port=1;end

5518

for i = 1:length(sdd.Frequencies)

5333

for i = 1:length(sdd.Frequencies)

5519

if size(sdd.Parameters,2) ==1 % for s2p files

5334

if size(sdd.Parameters,2) ==1 % for s2p files

5520

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,1, 1 ,sdd.Parameters(param.RL_sel,param.RL_sel,i) );

5335

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,1, 1 ,sdd.Parameters(param.RL_sel,param.RL_sel,i) );

5521

else

5336

else

5522

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,sdd.Parameters( 1,2 ,i), sdd.Parameters( 2,1 ,i),sdd.Parameters( other_port,other_port ,i) );

5337

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,sdd.Parameters( 1,2 ,i), sdd.Parameters( 2,1 ,i),sdd.Parameters( other_port,other_port ,i) );

5523

end

5338

end

5524

end

5339

end

5525

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5340

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5526

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5341

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5527

% Z_t=ZT;

5342

% Z_t=ZT;

5528

% zref=sdd.Impedance/2;

5343

% zref=sdd.Impedance/2;

5529

% if Z_t > zref

5344

% if Z_t > zref

5530

% radjust= (zref-Z_t);

5345

% radjust= (zref-Z_t);

5531

% S11adjust= radjust./(radjust + 2*zref);

5346

% S11adjust= radjust./(radjust + 2*zref);

5532

% RL=RL +S11adjust;

5347

% RL=RL +S11adjust;

5533

% elseif Z_t < zref

5348

% elseif Z_t < zref

5534

% rpad=-Z_t*zref/(Z_t-zref);

5349

% rpad=-Z_t*zref/(Z_t-zref);

5535

% S11adjust=zref/(rpad*(zref/rpad + 2));

5350

% S11adjust=zref/(rpad*(zref/rpad + 2));

5536

% RL=RL + S11adjust;

5351

% RL=RL + S11adjust;

5537

% else

5352

% else

5538

% RL=RL;

5353

% RL=RL;

5539

% end

5354

% end

5540

else

5355

else

5541

for i = 1:length(sdd.Frequencies)

5356

for i = 1:length(sdd.Frequencies)

5542

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5357

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5543

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5358

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5544

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5359

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5545

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5360

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5546

end

5361

end

5547

end

5362

end

5548

5363

5549

% end

5364

% end

5550

RL=squeeze(RL);

5365

RL=squeeze(RL);

5551

f9=f/1e9;

5366

f9=f/1e9;

5552

tr=param.TR_TDR;

5367

tr=param.TR_TDR;

5553

TDR_results.delay=500e-12 ;

5368

TDR_results.delay=500e-12 ;

5554

% determine max time from thue

5369

% determine max time from thue

5555

% if sdd.NumPorts==1

5370

% if sdd.NumPorts==1

5556

% try

5371

% try

5557

% maxtime=OP.N*param.ui;

5372

% maxtime=OP.N*param.ui;

5558

% catch

5373

% catch

5559

% maxtime=2e-9;

5374

% maxtime=2e-9;

5560

% end

5375

% end

5561

% pix=1;

5376

% pix=1;

5562

% else

5377

% else

5563

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5378

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5564

% pix=find(fir4del==max(fir4del),1);

5379

% pix=find(fir4del==max(fir4del),1);

5565

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5380

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5566

% if maxtime > tu(end); maxtime=tu(end);end

5381

% if maxtime > tu(end); maxtime=tu(end);end

5567

% endS

5382

% endS

5568

5383

5569

try

5384

try

5570

maxtime=OP.N*param.ui;

5385

maxtime=OP.N*param.ui;

5571

catch

5386

catch

5572

maxtime=2e-9;

5387

maxtime=2e-9;

5573

end

5388

end

5574

if OP.N==0

5389

if OP.N==0

5575

if sdd.NumPorts==1

5390

if sdd.NumPorts==1

5576

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5391

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5577

else

5392

else

5578

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5393

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5579

pix=find(fir4del==max(fir4del),1);

5394

pix=find(fir4del==max(fir4del),1);

5580

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5395

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5581

if maxtime > tu(end); maxtime=tu(end);end

5396

if maxtime > tu(end); maxtime=tu(end);end

5582

end

5397

end

5583

end

5398

end

5584

5399

5585

5400

5586

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5401

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5587

% (makes gausian edge somewhat causal)

5402

% (makes gausian edge somewhat causal)

5588

H_t = exp( -2*(pi*f9*(tr)/1.6832).^2 ).*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9).*exp(-1j*2*pi*f9*tr*3);

5403

H_t = exp( -2*(pi*f9*(tr)/1.6832).^2 ).*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9).*exp(-1j*2*pi*f9*tr*3);

5589

if ~isfield(OP,'cb_Guassian')

5404

if ~isfield(OP,'cb_Guassian')

5590

Use_gaussian=1;

5405

Use_gaussian=1;

5591

else

5406

else

5592

Use_gaussian=OP.cb_Guassian;

5407

Use_gaussian=OP.cb_Guassian;

5593

end

5408

end

5594

if Use_gaussian

5409

if Use_gaussian

5595

if iscolumn(H_t), H_t=H_t.'; end

5410

if iscolumn(H_t), H_t=H_t.'; end

5596

RLf=RL(:).'.*H_t;

5411

RLf=RL(:).'.*H_t;

5597

else % add extra 3x tr delay for causality

5412

else % add extra 3x tr delay for causality

5598

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5413

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5599

end

5414

end

5600

5415

5601

%Bessesl-Thomson turned off here (3rd input=0)

5416

%Bessesl-Thomson turned off here (3rd input=0)

5602

H_bt=Bessel_Thomson_Filter(param,f,0);

5417

H_bt=Bessel_Thomson_Filter(param,f,0);

5603

5418

5604

if isfield(OP,'TDR_Butterworth')

5419

if isfield(OP,'TDR_Butterworth')

5605

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5420

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5606

else

5421

else

5607

H_bw=ones(1,length(f));

5422

H_bw=ones(1,length(f));

5608

end

5423

end

5609

5424

5610

5425

5611

if param.Tukey_Window ~= 0

5426

if param.Tukey_Window ~= 0

5612

H_tw= Tukey_Window(f,param);

5427

H_tw= Tukey_Window(f,param);

5613

else

5428

else

5614

H_tw=ones(1,length(f));

5429

H_tw=ones(1,length(f));

5615

end

5430

end

5616

5431

5617

5432

5618

if iscolumn(H_tw), H_tw=H_tw.';end

5433

if iscolumn(H_tw), H_tw=H_tw.';end

5619

if iscolumn(H_bt), H_bt=H_bt.';end

5434

if iscolumn(H_bt), H_bt=H_bt.';end

5620

if iscolumn(H_bw), H_bw=H_bw.';end

5435

if iscolumn(H_bw), H_bw=H_bw.';end

5621

if iscolumn(RLf), RLf=RLf.';end

5436

if iscolumn(RLf), RLf=RLf.';end

5622

5437

5623

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5438

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5624

RLf=RLf.*TDR_results.Rx_filter;

5439

RLf=RLf.*TDR_results.Rx_filter;

5625

TDR_results.tx_filter=H_t;

5440

TDR_results.tx_filter=H_t;

5626

5441

5627

5442

5628

[IR, t, causality_correction_dB, truncation_dB] = ...

5443

[IR, t, causality_correction_dB, truncation_dB] = ...

5629

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5444

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5630

5445

5631

5446

5632

%

5447

%

5633

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5448

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5634

tfx=param.tfx(np); % use fixture delay for port (np)

5449

tfx=param.tfx(np); % use fixture delay for port (np)

5635

5450

5636

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5451

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5637

5452

5638

t = t-TDR_results.delay;

5453

t = t-TDR_results.delay;

5639

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5454

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5640

if isempty(tend), tend=length(t); end

5455

if isempty(tend), tend=length(t); end

5641

IR=IR(1:tend);

5456

IR=IR(1:tend);

5642

t=t(1:tend);

5457

t=t(1:tend);

5643

if isempty(tend), tend=length(t); end

5458

if isempty(tend), tend=length(t); end

5644

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5459

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5645

if isempty(tstart), tstart=1;end

5460

if isempty(tstart), tstart=1;end

5646

if isempty(tend) || tstart >= tend

5461

if isempty(tend) || tstart >= tend

5647

if isempty(tend) || tstart >= tend

5462

if isempty(tend) || tstart >= tend

5648

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5463

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5649

end

5464

end

5650

tend=length(t);

5465

tend=length(t);

5651

tstart=1;

5466

tstart=1;

5652

end

5467

end

5653

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5468

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5654

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5469

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5655

TDR_results.tdr= ch.ZSR;

5470

TDR_results.tdr= ch.ZSR;

5656

TDR_results.t = t(tstart:tend);

5471

TDR_results.t = t(tstart:tend);

5657

5472

5658

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5473

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5659

if OP.TDR || OP.PTDR % determin average impededance with

5474

if OP.TDR || OP.PTDR % determin average impededance with

5660

try

5475

try

5661

tfstart=find(t>=3*tr*1e-9,1);

5476

tfstart=find(t>=3*tr*1e-9,1);

5662

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5477

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5663

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5478

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5664

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5479

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5665

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5480

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5666

catch

5481

catch

5667

TDR_results.avgZport=0;

5482

TDR_results.avgZport=0;

5668

fit=zeros(1,1);

5483

fit=zeros(1,1);

5669

p=[0 0 0 0 ];

5484

p=[0 0 0 0 ];

5670

end

5485

end

5671

TDR_results.RL=RL;

5486

TDR_results.RL=RL;

5672

end

5487

end

5673

if OP.PTDR

5488

if OP.PTDR

5674

% param.N_bx=param.ndfe;

5489

% param.N_bx=param.ndfe;

5675

RL_equiv=-inf;

5490

RL_equiv=-inf;

5676

L=param.levels;

5491

L=param.levels;

5677

BinSize=OP.BinSize;

5492

BinSize=OP.BinSize;

5678

% param.specBER=1e-5;

5493

% param.specBER=1e-5;

5679

if OP.DISPLAY_WINDOW

5494

if OP.DISPLAY_WINDOW

5680

hwaitbar=waitbar(0);

5495

hwaitbar=waitbar(0);

5681

else

5496

else

5682

fprintf('Worst ERL searching');

5497

fprintf('Worst ERL searching');

5683

end

5498

end

5684

% adjust PTDR for NDFE

5499

% adjust PTDR for NDFE

5685

% ---------------------- 2.7 code

5500

% ---------------------- 2.7 code

5686

% ntx=find(TDR_results.t >= tfx,1,'first');

5501

% ntx=find(TDR_results.t >= tfx,1,'first');

5687

% % gatestartt=TDR_results.t(ntx);

5502

% % gatestartt=TDR_results.t(ntx);

5688

% % gatestartV=PTDR.pulse(ntx);

5503

% % gatestartV=PTDR.pulse(ntx);

5689

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5504

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5690

% tk=param.ui*1*(param.N_bx+1)+tfx;

5505

% tk=param.ui*1*(param.N_bx+1)+tfx;

5691

% -------------------

5506

% -------------------

5692

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5507

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5693

% time filter.

5508

% time filter.

5694

% ntx=find(TDR_results.t >= tfx,1,'first');

5509

% ntx=find(TDR_results.t >= tfx,1,'first');

5695

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5510

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5696

% gatestartt=TDR_results.t(ntx);

5511

% gatestartt=TDR_results.t(ntx);

5697

% gatestartV=PTDR.pulse(ntx);

5512

% gatestartV=PTDR.pulse(ntx);

5698

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5513

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5699

% tk=param.ui*1*(param.N_bx+1)+tfx;

5514

% tk=param.ui*1*(param.N_bx+1)+tfx;

5700

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5515

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5701

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5516

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5702

% [ahealey] End of modifications.

5517

% [ahealey] End of modifications.

5703

if isempty(ndfex), ndfex=length(TDR_results.t); end

5518

if isempty(ndfex), ndfex=length(TDR_results.t); end

5704

PTDR.pulse_orig=PTDR.pulse;

5519

PTDR.pulse_orig=PTDR.pulse;

5705

5520

5706

switch param.Grr

5521

switch param.Grr

5707

case 0 % pre .3cd release

5522

case 0 % pre .3cd release

5708

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5523

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5709

case 1 % .3cd release

5524

case 1 % .3cd release

5710

fctrx(1:length(PTDR.pulse_orig))=1;

5525

fctrx(1:length(PTDR.pulse_orig))=1;

5711

case 2 % .3ck working

5526

case 2 % .3ck working

5712

fctrx(1:length(PTDR.pulse_orig))=1;

5527

fctrx(1:length(PTDR.pulse_orig))=1;

5713

end

5528

end

5714

Gloss(1:length(TDR_results.t))=1;

5529

Gloss(1:length(TDR_results.t))=1;

5715

Grr(1:length(TDR_results.t))=1;

5530

Grr(1:length(TDR_results.t))=1;

5716

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5531

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5717

5532

5718

for ii=ntx:ndfex

5533

for ii=ntx:ndfex

5719

% adjust for near end loss

5534

% adjust for near end loss

5720

if param.N_bx>0 && param.beta_x~=0;

5535

if param.N_bx>0 && param.beta_x~=0;

5721

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5536

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5722

else

5537

else

5723

Gloss(ii)=1;

5538

Gloss(ii)=1;

5724

end

5539

end

5725

% ---------------------- 2.7 code

5540

% ---------------------- 2.7 code

5726

% x=(TDR_results.t(ii)-tfx)/param.ui;

5541

% x=(TDR_results.t(ii)-tfx)/param.ui;

5727

% ----------------------

5542

% ----------------------

5728

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5543

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5729

% rise time filter.

5544

% rise time filter.

5730

% x=(TDR_results.t(ii)-tfx)/param.ui;

5545

% x=(TDR_results.t(ii)-tfx)/param.ui;

5731

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5546

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5732

% determine how much of the return loss to use base on expected

5547

% determine how much of the return loss to use base on expected

5733

% missing reflections

5548

% missing reflections

5734

switch param.Grr

5549

switch param.Grr

5735

case 0 % pre .3cd release

5550

case 0 % pre .3cd release

5736

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5551

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5737

case 1 % .3cd release

5552

case 1 % .3cd release

5738

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5553

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5739

case 2 % .3ck working

5554

case 2 % .3ck working

5740

Grr(ii)= param.rho_x ;

5555

Grr(ii)= param.rho_x ;

5741

end

5556

end

5742

fctrx(ii)=Gloss(ii).*Grr(ii);

5557

fctrx(ii)=Gloss(ii).*Grr(ii);

5743

end

5558

end

5744

5559

5745

if isrow(fctrx), fctrx=fctrx(:);end

5560

if isrow(fctrx), fctrx=fctrx(:);end

5746

PTDR.pulse=PTDR.pulse.*fctrx;

5561

PTDR.pulse=PTDR.pulse.*fctrx;

5747

if 0

5562

if 0

5748

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5563

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5749

s1=subplot(2,1,1);

5564

s1=subplot(2,1,1);

5750

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5565

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5751

hold on

5566

hold on

5752

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5567

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5753

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5568

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5754

grid on

5569

grid on

5755

ylim([ 0 1.2])

5570

ylim([ 0 1.2])

5756

s2=subplot(2,1,2);

5571

s2=subplot(2,1,2);

5757

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5572

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5758

grid on

5573

grid on

5759

linkaxes([s1,s2],'x')

5574

linkaxes([s1,s2],'x')

5760

xlabel 'UI'

5575

xlabel 'UI'

5761

xlim ([ 1 200])

5576

xlim ([ 1 200])

5762

end

5577

end

5763

5578

5764

FAST_NOISE_CONV=0;

5579

FAST_NOISE_CONV=0;

5765

ERLRMS=rms(PTDR.pulse);

5580

ERLRMS=rms(PTDR.pulse);

5766

for ki=1:param.samples_per_ui

5581

for ki=1:param.samples_per_ui

5767

progress = ki/param.samples_per_ui;

5582

progress = ki/param.samples_per_ui;

5768

if OP.DISPLAY_WINDOW

5583

if OP.DISPLAY_WINDOW

5769

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5584

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5770

else

5585

else

5771

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5586

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5772

end

5587

end

5773

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5588

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5774

if OP.RL_norm_test

5589

if OP.RL_norm_test

5775

rl_fom=(norm(tps));

5590

rl_fom=(norm(tps));

5776

else

5591

else

5777

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5592

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5778

cdf_test=cumsum(testpdf.y);

5593

cdf_test=cumsum(testpdf.y);

5779

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5594

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5780

rl_fom=rl_test;

5595

rl_fom=rl_test;

5781

end

5596

end

5782

if rl_fom > RL_equiv

5597

if rl_fom > RL_equiv

5783

RL_equiv=rl_fom;

5598

RL_equiv=rl_fom;

5784

best_ki=ki;

5599

best_ki=ki;

5785

end

5600

end

5786

if ~OP.RL_norm_test

5601

if ~OP.RL_norm_test

5787

best_erl=rl_test;

5602

best_erl=rl_test;

5788

best_pdf=testpdf;

5603

best_pdf=testpdf;

5789

best_cdf=cdf_test;

5604

best_cdf=cdf_test;

5790

end

5605

end

5791

5606

5792

end

5607

end

5793

if OP.RL_norm_test

5608

if OP.RL_norm_test

5794

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5609

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5795

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5610

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5796

cdf_test=cumsum(testpdf.y);

5611

cdf_test=cumsum(testpdf.y);

5797

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5612

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5798

end

5613

end

5799

5614

5800

fprintf('\n');

5615

fprintf('\n');

5801

try

5616

try

5802

close(hwaitbar)

5617

close(hwaitbar)

5803

catch

5618

catch

5804

end

5619

end

5805

if ~exist('best_ki','var'),best_ki=1;end

5620

if ~exist('best_ki','var'),best_ki=1;end

5806

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5621

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5807

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5622

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5808

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5623

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5809

TDR_results.ERL=-db(best_erl);

5624

TDR_results.ERL=-db(best_erl);

5810

TDR_results.ERLRMS=-db(ERLRMS);

5625

TDR_results.ERLRMS=-db(ERLRMS);

5811

5626

5812

end

5627

end

5813

5628

5814

5629

5815

% end get TDR

5630

% end get TDR

5816

%%

5631

%%

5817

5632

5818

5633

5819

5634

5820

5635

5821

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5636

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5822

% filename parsing and acquisition

5637

% filename parsing and acquisition

5823

%------------------------------------------------------------------

5638

%------------------------------------------------------------------

5824

%----------put files names into chdata structure ---------

5639

%----------put files names into chdata structure ---------

5825

% The thru file has the index of 1

5640

% The thru file has the index of 1

5826

% crosstalk file are indexed from 2

5641

% crosstalk file are indexed from 2

5827

% nxi is incremented each time a file is read in so that nxi will end

5642

% nxi is incremented each time a file is read in so that nxi will end

5828

filepath=[]; % path name for file

5643

filepath=[]; % path name for file

5829

nxi=0; % file index

5644

nxi=0; % file index

5830

% get the THRU file

5645

% get the THRU file

5831

if size(file_list,2) ~= 0

5646

if size(file_list,2) ~= 0

5832

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5647

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5833

[filepath, basename, fileext]=fileparts(file_list{1});

5648

[filepath, basename, fileext]=fileparts(file_list{1});

5834

5649

5835

else

5650

else

5836

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5651

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5837

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5652

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5838

movegui(h,'northeast')

5653

movegui(h,'northeast')

5839

end

5654

end

5840

dir=fullfile(filepath, '*.csv');

5655

dir=fullfile(filepath, '*.csv');

5841

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5656

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5842

if filepath == 0

5657

if filepath == 0

5843

error('No Thru file')

5658

error('No Thru file')

5844

end

5659

end

5845

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5660

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5846

end

5661

end

5847

nxi=nxi+1;

5662

nxi=nxi+1;

5848

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5663

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5849

chdata(nxi).ext = fileext;

5664

chdata(nxi).ext = fileext;

5850

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5665

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5851

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5666

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5852

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5667

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5853

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5668

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5854

chdata(nxi).type='THRU';

5669

chdata(nxi).type='THRU';

5855

chdata(nxi).ftr=param.fb*param.f_v;

5670

chdata(nxi).ftr=param.fb*param.f_v;

5856

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5671

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5857

5672

5858

% now get FEXT file names into chdata structure

5673

% now get FEXT file names into chdata structure

5859

kxi=nxi;

5674

kxi=nxi;

5860

for nxi=kxi+1:num_fext+kxi

5675

for nxi=kxi+1:num_fext+kxi

5861

lastfilepath=filepath;

5676

lastfilepath=filepath;

5862

if size(file_list,2) ~= 0

5677

if size(file_list,2) ~= 0

5863

[filepath, basename, fileext]=fileparts(file_list{nxi});

5678

[filepath, basename, fileext]=fileparts(file_list{nxi});

5864

else

5679

else

5865

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5680

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5866

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5681

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5867

movegui(h,'northeast')

5682

movegui(h,'northeast')

5868

end

5683

end

5869

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5684

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5870

dir=fullfile(filepath, '*.csv');

5685

dir=fullfile(filepath, '*.csv');

5871

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5686

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5872

if filepath==0

5687

if filepath==0

5873

error('Not enough NEXT files')

5688

error('Not enough NEXT files')

5874

end

5689

end

5875

else

5690

else

5876

dir=fullfile(filepath, '*.csv');

5691

dir=fullfile(filepath, '*.csv');

5877

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5692

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5878

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5693

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5879

else

5694

else

5880

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5695

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5881

end

5696

end

5882

if filepath==0

5697

if filepath==0

5883

error('Not enough NEXT files')

5698

error('Not enough NEXT files')

5884

end

5699

end

5885

end

5700

end

5886

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5701

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5887

end

5702

end

5888

if isempty( filepath), filepath=lastfilepath; end

5703

if isempty( filepath), filepath=lastfilepath; end

5889

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5704

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5890

chdata(nxi).ext = fileext;

5705

chdata(nxi).ext = fileext;

5891

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5706

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5892

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5707

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5893

% chdata(nxi).A=param.a_fext;

5708

% chdata(nxi).A=param.a_fext;

5894

chdata(nxi).ftr=param.fb*param.f_f;

5709

chdata(nxi).ftr=param.fb*param.f_f;

5895

chdata(nxi).type='FEXT';

5710

chdata(nxi).type='FEXT';

5896

end

5711

end

5897

% now get NEXT file names into chdata structure

5712

% now get NEXT file names into chdata structure

5898

kxi=num_fext+kxi;

5713

kxi=num_fext+kxi;

5899

for nxi=kxi+1:num_next+kxi

5714

for nxi=kxi+1:num_next+kxi

5900

lastfilepath=filepath;

5715

lastfilepath=filepath;

5901

if size(file_list,2) ~= 0

5716

if size(file_list,2) ~= 0

5902

[filepath, basename, fileext]=fileparts(file_list{nxi});

5717

[filepath, basename, fileext]=fileparts(file_list{nxi});

5903

else

5718

else

5904

dir=fullfile(filepath, '*.csv');

5719

dir=fullfile(filepath, '*.csv');

5905

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5720

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5906

if filepath==0

5721

if filepath==0

5907

error('Not enough NEXT files')

5722

error('Not enough NEXT files')

5908

end

5723

end

5909

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5724

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5910

end

5725

end

5911

if isempty( filepath), filepath=lastfilepath; end

5726

if isempty( filepath), filepath=lastfilepath; end

5912

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5727

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5913

chdata(nxi).ext = fileext;

5728

chdata(nxi).ext = fileext;

5914

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5729

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5915

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5730

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5916

% chdata(nxi).A=param.A_next;

5731

% chdata(nxi).A=param.A_next;

5917

chdata(nxi).ftr=param.fb*param.f_n;

5732

chdata(nxi).ftr=param.fb*param.f_n;

5918

chdata(nxi).type='NEXT';

5733

chdata(nxi).type='NEXT';

5919

end

5734

end

5920

function half_UI=get_center_of_UI(samples_per_UI)

5735

function half_UI=get_center_of_UI(samples_per_UI)

5921

5736

5922

%half_UI reveals which value to use for the center of the UI. For eye

5737

%half_UI reveals which value to use for the center of the UI. For eye

5923

%width calculations, it is necessary to place the cursor in the center of the

5738

%width calculations, it is necessary to place the cursor in the center of the

5924

%UI window to ensure a 0 crossing on both left/right inside the window.

5739

%UI window to ensure a 0 crossing on both left/right inside the window.

5925

%This function was written in order to support even and odd samples_per_UI

5740

%This function was written in order to support even and odd samples_per_UI

5926

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

5741

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

5927

5742

5928

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

5743

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

5929

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

5744

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

5930

%the center of the UI is sample closest to 0.5

5745

%the center of the UI is sample closest to 0.5

5931

[temp_diff,half_UI]=min(abs(UI_window-0.5));

5746

[temp_diff,half_UI]=min(abs(UI_window-0.5));

5932

function results= get_cm_noise(M,PR,L,BER,OP)

5747

function results= get_cm_noise(M,PR,L,BER,OP)

5933

5748

5934

if ~exist('OP')

5749

if ~exist('OP')

5935

OP.DC_norm_test=0;

5750

OP.DC_norm_test=0;

5936

OP.DISPLAY_WINDOW=1;

5751

OP.DISPLAY_WINDOW=1;

5937

end

5752

end

5938

param.BinSize=1e-5;

5753

param.BinSize=1e-5;

5939

PR_test=-inf;

5754

PR_test=-inf;

5940

PR_fom_best=-inf;

5755

PR_fom_best=-inf;

5941

% hwaitbar=waitbar(0);

5756

% hwaitbar=waitbar(0);

5942

for ki=1:M

5757

for ki=1:M

5943

progress = ki/M;

5758

progress = ki/M;

5944

% if OP.DISPLAY_WINDOW

5759

% if OP.DISPLAY_WINDOW

5945

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

5760

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

5946

% else

5761

% else

5947

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5762

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5948

% end

5763

% end

5949

tps=PR(ki:M:end);

5764

tps=PR(ki:M:end);

5950

if OP.DC_norm_test

5765

if OP.DC_norm_test

5951

PR_fom=(norm(tps));

5766

PR_fom=(norm(tps));

5952

else

5767

else

5953

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

5768

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

5954

cdf_test=cumsum(testpdf.y);

5769

cdf_test=cumsum(testpdf.y);

5955

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

5770

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

5956

PR_fom=PRn_test;

5771

PR_fom=PRn_test;

5957

end

5772

end

5958

if PR_fom > PR_fom_best

5773

if PR_fom > PR_fom_best

5959

PR_fom_best=PR_fom;

5774

PR_fom_best=PR_fom;

5960

best_ki=ki;

5775

best_ki=ki;

5961

end

5776

end

5962

if ~OP.DC_norm_test

5777

if ~OP.DC_norm_test

5963

results.DCn=PR_fom_best;

5778

results.DCn=PR_fom_best;

5964

results.DCn_pdf=testpdf;

5779

results.DCn_pdf=testpdf;

5965

results.DCn_cdf=cdf_test;

5780

results.DCn_cdf=cdf_test;

5966

else

5781

else

5967

results.DCn=PR_fom_best;

5782

results.DCn=PR_fom_best;

5968

end

5783

end

5969

results.DCn_p2p=max(PR)-min(PR);

5784

results.DCn_p2p=max(PR)-min(PR);

5970

end

5785

end

5971

5786

5972

5787

5973

5788

5974

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

5789

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

5975

SBR=chdata.eq_pulse_response(:)'; % row vector

5790

SBR=chdata.eq_pulse_response(:)'; % row vector

5976

type=chdata.type;

5791

type=chdata.type;

5977

samp_UI=param.samples_per_ui;

5792

samp_UI=param.samples_per_ui;

5978

residual_response = SBR;

5793

residual_response = SBR;

5979

5794

5980

if isequal(type, 'THRU')

5795

if isequal(type, 'THRU')

5981

% for thru pulse response:

5796

% for thru pulse response:

5982

% remove the cursor and the DFE postcursors (up to their limit), since

5797

% remove the cursor and the DFE postcursors (up to their limit), since

5983

% we only care about the residuals.

5798

% we only care about the residuals.

5984

5799

5985

if ~param.Floating_DFE

5800

if ~param.Floating_DFE

5986

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

5801

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

5987

else

5802

else

5988

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

5803

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

5989

end

5804

end

5990

if param.dfe_delta ~= 0

5805

if param.dfe_delta ~= 0

5991

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

5806

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

5992

else

5807

else

5993

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5808

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5994

end

5809

end

5995

5810

5996

%AJG021820

5811

%AJG021820

5997

if ~param.Floating_DFE

5812

if ~param.Floating_DFE

5998

bmax_vec=residual_response(t_s)*[1,param.bmax];

5813

bmax_vec=residual_response(t_s)*[1,param.bmax];

5999

bmin_vec=residual_response(t_s)*[1,param.bmin];

5814

bmin_vec=residual_response(t_s)*[1,param.bmin];

6000

else

5815

else

6001

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

5816

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

6002

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

5817

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

6003

end

5818

end

6004

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5819

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6005

5820

6006

5821

6007

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

5822

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

6008

dfetaps=effective_cancelled_cursors/SBR(t_s);

5823

dfetaps=effective_cancelled_cursors/SBR(t_s);

6009

5824

6010

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5825

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6011

% really needed for COM, but helps debugging. May be factored out in future revisions.

5826

% really needed for COM, but helps debugging. May be factored out in future revisions.

6012

start_cancel = t_s-param.samples_per_ui/2;

5827

start_cancel = t_s-param.samples_per_ui/2;

6013

if ~param.Floating_DFE

5828

if ~param.Floating_DFE

6014

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

5829

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

6015

else

5830

else

6016

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

5831

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

6017

end

5832

end

6018

residual_response(start_cancel:end_cancel) = ...

5833

residual_response(start_cancel:end_cancel) = ...

6019

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5834

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6020

%else

5835

%else

6021

% for crosstalk pulse responses, nothing is cancelled, and all phases

5836

% for crosstalk pulse responses, nothing is cancelled, and all phases

6022

% are equally important.

5837

% are equally important.

6023

end

5838

end

6024

5839

6025

nui=round(length(residual_response)/param.samples_per_ui);

5840

nui=round(length(residual_response)/param.samples_per_ui);

6026

5841

6027

vs=zeros(nui-2, param.samples_per_ui);

5842

vs=zeros(nui-2, param.samples_per_ui);

6028

for i=1:param.samples_per_ui

5843

for i=1:param.samples_per_ui

6029

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

5844

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

6030

end

5845

end

6031

5846

6032

if OP.DISPLAY_WINDOW,

5847

if OP.DISPLAY_WINDOW,

6033

hwaitbar=waitbar(0);

5848

hwaitbar=waitbar(0);

6034

end

5849

end

6035

5850

6036

% determine which pdf to use

5851

% determine which pdf to use

6037

if isequal(type, 'THRU')

5852

if isequal(type, 'THRU')

6038

% one phase is interesting for thru

5853

% one phase is interesting for thru

6039

phases = mod(t_s,param.samples_per_ui);

5854

phases = mod(t_s,param.samples_per_ui);

6040

if phases==0, phases = param.samples_per_ui; end

5855

if phases==0, phases = param.samples_per_ui; end

6041

else

5856

else

6042

phases=1:samp_UI;

5857

phases=1:samp_UI;

6043

end

5858

end

6044

5859

6045

mxV = zeros(size(phases));

5860

mxV = zeros(size(phases));

6046

% we already found the phase in the PSD process for MMSE

5861

% we already found the phase in the PSD process for MMSE

6047

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

5862

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

6048

if isequal(type, 'THRU')

5863

if isequal(type, 'THRU')

6049

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

5864

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

6050

else

5865

else

6051

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

5866

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

6052

end

5867

end

6053

else

5868

else

6054

for k=phases

5869

for k=phases

6055

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

5870

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

6056

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

5871

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6057

progress = k/length(phases);

5872

progress = k/length(phases);

6058

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

5873

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6059

end

5874

end

6060

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

5875

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

6061

pdf=pdf_samples(pxi);

5876

pdf=pdf_samples(pxi);

6062

end

5877

end

6063

5878

6064

5879

6065

5880

6066

if OP.DISPLAY_WINDOW

5881

if OP.DISPLAY_WINDOW

6067

close(hwaitbar);

5882

close(hwaitbar);

6068

end

5883

end

6069

5884

6070

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

5885

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

6071

% Create PDF from interference vector using successive delta-set convolutions.

5886

% Create PDF from interference vector using successive delta-set convolutions.

6072

% input_vector = list of values of samples

5887

% input_vector = list of values of samples

6073

% return

5888

% return

6074

% pdf.x

5889

% pdf.x

6075

% pdf.y

5890

% pdf.y

6076

% pdf.vec

5891

% pdf.vec

6077

% pdf.bin

5892

% pdf.bin

6078

if ~exist('FAST_NOISE_CONV','var')

5893

if ~exist('FAST_NOISE_CONV','var')

6079

FAST_NOISE_CONV=0;

5894

FAST_NOISE_CONV=0;

6080

end

5895

end

6081

if max(input_vector) > BinSize

5896

if max(input_vector) > BinSize

6082

input_vector=input_vector(abs(input_vector)>BinSize);

5897

input_vector=input_vector(abs(input_vector)>BinSize);

6083

end

5898

end

6084

% for i = 1:length(input_vector)

5899

% for i = 1:length(input_vector)

6085

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

5900

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

6086

%end

5901

%end

6087

5902

6088

input_vector(abs(input_vector)<BinSize) = 0;

5903

input_vector(abs(input_vector)<BinSize) = 0;

6089

b=sign(input_vector);

5904

b=sign(input_vector);

6090

[input_vector,index]=sort(abs(input_vector),'descend');

5905

[input_vector,index]=sort(abs(input_vector),'descend');

6091

input_vector=input_vector.*b(index);

5906

input_vector=input_vector.*b(index);

6092

if FAST_NOISE_CONV

5907

if FAST_NOISE_CONV

6093

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

5908

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

6094

res_pdf= normal_dist(sig_res,5,BinSize);

5909

res_pdf= normal_dist(sig_res,5,BinSize);

6095

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

5910

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

6096

end

5911

end

6097

%% Equation 93A-39 %%

5912

%% Equation 93A-39 %%

6098

values = 2*(0:L-1)/(L-1)-1;

5913

values = 2*(0:L-1)/(L-1)-1;

6099

prob = ones(1,L)/L;

5914

prob = ones(1,L)/L;

6100

5915

6101

%% Initialize pdf to delta at 0

5916

%% Initialize pdf to delta at 0

6102

pdf=d_cpdf(BinSize, 0, 1);

5917

pdf=d_cpdf(BinSize, 0, 1);

6103

empty_pdf=pdf;

5918

empty_pdf=pdf;

6104

for k = 1:length(input_vector)

5919

for k = 1:length(input_vector)

6105

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

5920

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

6106

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

5921

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

6107

pdf=conv_fct(pdf, pdfn);

5922

pdf=conv_fct(pdf, pdfn);

6108

end

5923

end

6109

if FAST_NOISE_CONV

5924

if FAST_NOISE_CONV

6110

% pdf=conv_fct(pdf,res_pdf);

5925

% pdf=conv_fct(pdf,res_pdf);

6111

pdf=conv_fct_TEST(pdf,res_pdf);

5926

pdf=conv_fct_TEST(pdf,res_pdf);

6112

end

5927

end

6113

5928

6114

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

5929

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

6115

t_s_orig=t_s;

5930

t_s_orig=t_s;

6116

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

5931

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

6117

type=chdata.type;

5932

type=chdata.type;

6118

5933

6119

pulse_orig=chdata.eq_pulse_response(:)';

5934

pulse_orig=chdata.eq_pulse_response(:)';

6120

%build arbitrary time axis with step size = 1/samples per ui

5935

%build arbitrary time axis with step size = 1/samples per ui

6121

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

5936

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

6122

%force t_s at time =0 (makes the other things below easy)

5937

%force t_s at time =0 (makes the other things below easy)

6123

original_sample_time=old_time(t_s_orig);

5938

original_sample_time=old_time(t_s_orig);

6124

old_time=old_time-original_sample_time;

5939

old_time=old_time-original_sample_time;

6125

%build new time axis that forces time=0 to be in the axis

5940

%build new time axis that forces time=0 to be in the axis

6126

%unless the new/old samples per UI are integer ratios, time 0 will not be

5941

%unless the new/old samples per UI are integer ratios, time 0 will not be

6127

%there by default

5942

%there by default

6128

samp_UI=param.samples_for_C2M;

5943

samp_UI=param.samples_for_C2M;

6129

new_timea=[0:-1/samp_UI:min(old_time)];

5944

new_timea=[0:-1/samp_UI:min(old_time)];

6130

new_timeb=[0:1/samp_UI:max(old_time)];

5945

new_timeb=[0:1/samp_UI:max(old_time)];

6131

new_time=[fliplr(new_timea) new_timeb(2:end)];

5946

new_time=[fliplr(new_timea) new_timeb(2:end)];

6132

SBR=interp1(old_time,pulse_orig,new_time);

5947

SBR=interp1(old_time,pulse_orig,new_time);

6133

%new sample time is simply the point where new_time = 0

5948

%new sample time is simply the point where new_time = 0

6134

[tmp,t_s]=min(abs(new_time));

5949

[tmp,t_s]=min(abs(new_time));

6135

5950

6136

residual_response = SBR;

5951

residual_response = SBR;

6137

5952

6138

half_UI=get_center_of_UI(samp_UI);

5953

half_UI=get_center_of_UI(samp_UI);

6139

5954

6140

if isequal(type, 'THRU')

5955

if isequal(type, 'THRU')

6141

% for thru pulse response:

5956

% for thru pulse response:

6142

% remove the cursor and the DFE postcursors (up to their limit), since

5957

% remove the cursor and the DFE postcursors (up to their limit), since

6143

% we only care about the residuals.

5958

% we only care about the residuals.

6144

5959

6145

%AJG021820

5960

%AJG021820

6146

if ~param.Floating_DFE

5961

if ~param.Floating_DFE

6147

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

5962

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

6148

else

5963

else

6149

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

5964

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

6150

end

5965

end

6151

if param.dfe_delta ~= 0

5966

if param.dfe_delta ~= 0

6152

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

5967

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

6153

else

5968

else

6154

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5969

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

6155

end

5970

end

6156

5971

6157

if ~param.Floating_DFE

5972

if ~param.Floating_DFE

6158

bmax_vec=residual_response(t_s)*[param.bmax];

5973

bmax_vec=residual_response(t_s)*[param.bmax];

6159

bmin_vec=residual_response(t_s)*[param.bmin];

5974

bmin_vec=residual_response(t_s)*[param.bmin];

6160

else

5975

else

6161

bmax_vec=residual_response(t_s)*[param.use_bmax];

5976

bmax_vec=residual_response(t_s)*[param.use_bmax];

6162

bmin_vec=residual_response(t_s)*[param.use_bmin];

5977

bmin_vec=residual_response(t_s)*[param.use_bmin];

6163

end

5978

end

6164

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5979

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6165

5980

6166

5981

6167

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

5982

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

6168

dfetaps=effective_cancelled_cursors/SBR(t_s);

5983

dfetaps=effective_cancelled_cursors/SBR(t_s);

6169

5984

6170

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5985

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6171

% really needed for COM, but helps debugging. May be factored out in future revisions.

5986

% really needed for COM, but helps debugging. May be factored out in future revisions.

6172

5987

6173

%avoid dividing samp_UI by 2 in case it is not even

5988

%avoid dividing samp_UI by 2 in case it is not even

6174

start_cancel=t_s-half_UI+1+samp_UI;

5989

start_cancel=t_s-half_UI+1+samp_UI;

6175

%AJG021820

5990

%AJG021820

6176

if ~param.Floating_DFE

5991

if ~param.Floating_DFE

6177

end_cancel=start_cancel+param.ndfe*samp_UI-1;

5992

end_cancel=start_cancel+param.ndfe*samp_UI-1;

6178

else

5993

else

6179

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

5994

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

6180

end

5995

end

6181

residual_response(start_cancel:end_cancel) = ...

5996

residual_response(start_cancel:end_cancel) = ...

6182

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5997

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6183

%else

5998

%else

6184

% for crosstalk pulse responses, nothing is cancelled, and all phases

5999

% for crosstalk pulse responses, nothing is cancelled, and all phases

6185

% are equally important.

6000

% are equally important.

6186

6001

6187

%remove entire cursor UI

6002

%remove entire cursor UI

6188

uiv_start=start_cancel-samp_UI;

6003

uiv_start=start_cancel-samp_UI;

6189

uiv_end=uiv_start+samp_UI-1;

6004

uiv_end=uiv_start+samp_UI-1;

6190

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

6005

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

6191

residual_response(uiv_start:uiv_end)=0;

6006

residual_response(uiv_start:uiv_end)=0;

6192

end

6007

end

6193

6008

6194

nui=round(length(residual_response)/samp_UI);

6009

nui=round(length(residual_response)/samp_UI);

6195

6010

6196

6011

6197

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6012

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6198

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

6013

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

6199

%response without DFE included. (Can't include DFE for jitter calc)

6014

%response without DFE included. (Can't include DFE for jitter calc)

6200

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6015

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6201

6016

6202

% if OP.DISPLAY_WINDOW,

6017

% if OP.DISPLAY_WINDOW,

6203

% hwaitbar=waitbar(0);

6018

% hwaitbar=waitbar(0);

6204

% end

6019

% end

6205

6020

6206

% determine which pdf to use

6021

% determine which pdf to use

6207

if isequal(type, 'THRU')

6022

if isequal(type, 'THRU')

6208

% one phase is interesting for thru

6023

% one phase is interesting for thru

6209

phases = mod(t_s,samp_UI);

6024

phases = mod(t_s,samp_UI);

6210

if phases==0, phases = samp_UI; end

6025

if phases==0, phases = samp_UI; end

6211

else

6026

else

6212

phases=1:samp_UI;

6027

phases=1:samp_UI;

6213

end

6028

end

6214

6029

6215

mxV = zeros(size(phases));

6030

mxV = zeros(size(phases));

6216

6031

6217

%phases reveals the raw position in the UI window of the cursor.

6032

%phases reveals the raw position in the UI window of the cursor.

6218

%shift_amount is the amount to shift so that it aligns with half_UI

6033

%shift_amount is the amount to shift so that it aligns with half_UI

6219

shift_amount=half_UI-phases;

6034

shift_amount=half_UI-phases;

6220

%vs_shift puts the cursor at the center

6035

%vs_shift puts the cursor at the center

6221

vs_shift=circshift(vs,[0 shift_amount]);

6036

vs_shift=circshift(vs,[0 shift_amount]);

6222

L=size(vs_raw,1);

6037

L=size(vs_raw,1);

6223

%allow partial UI computation through pdf_range

6038

%allow partial UI computation through pdf_range

6224

%if pdf_range is empty, do full UI

6039

%if pdf_range is empty, do full UI

6225

if isempty(pdf_range)

6040

if isempty(pdf_range)

6226

pdf_range=1:samp_UI;

6041

pdf_range=1:samp_UI;

6227

else

6042

else

6228

pdf_range=min(pdf_range):max(pdf_range);

6043

pdf_range=min(pdf_range):max(pdf_range);

6229

end

6044

end

6230

h_j_full=zeros(L,samp_UI);

6045

h_j_full=zeros(L,samp_UI);

6231

for k=pdf_range

6046

for k=pdf_range

6232

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6047

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6233

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6048

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6234

%progress = k/length(phases);

6049

%progress = k/length(phases);

6235

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6050

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6236

6051

6237

%build the circshift of h_j_full into the loop to support a reduced

6052

%build the circshift of h_j_full into the loop to support a reduced

6238

%range of sampling points. circshift at the end only works if doing the

6053

%range of sampling points. circshift at the end only works if doing the

6239

%full range of sampling points. And shifting before the loop will

6054

%full range of sampling points. And shifting before the loop will

6240

%yield the wrong answer at the edges of the UI

6055

%yield the wrong answer at the edges of the UI

6241

hk=k-shift_amount;

6056

hk=k-shift_amount;

6242

if hk<1

6057

if hk<1

6243

hk=hk+samp_UI;

6058

hk=hk+samp_UI;

6244

elseif hk>samp_UI

6059

elseif hk>samp_UI

6245

hk=hk-samp_UI;

6060

hk=hk-samp_UI;

6246

end

6061

end

6247

if hk==1

6062

if hk==1

6248

%when hk=1, the early UI is the last column

6063

%when hk=1, the early UI is the last column

6249

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6064

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6250

elseif hk==samp_UI

6065

elseif hk==samp_UI

6251

%when hk=samp_UI, the late UI is the first column

6066

%when hk=samp_UI, the late UI is the first column

6252

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6067

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6253

else

6068

else

6254

%for all other cases, do the normal late=+1, early = -1

6069

%for all other cases, do the normal late=+1, early = -1

6255

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6070

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6256

end

6071

end

6257

end

6072

end

6258

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6073

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6259

% filename parsing and acquisition

6074

% filename parsing and acquisition

6260

%------------------------------------------------------------------

6075

%------------------------------------------------------------------

6261

%----------put files names into chdata structure ---------

6076

%----------put files names into chdata structure ---------

6262

% The thru file has the index of 1

6077

% The thru file has the index of 1

6263

% crosstalk file are indexed from 2

6078

% crosstalk file are indexed from 2

6264

% nxi is incremented each time a file is read in so that nxi will end

6079

% nxi is incremented each time a file is read in so that nxi will end

6265

filepath=[]; % path name for file

6080

filepath=[]; % path name for file

6266

nxi=0; % file index

6081

nxi=0; % file index

6267

% get the THRU file

6082

% get the THRU file

6268

if size(file_list,2) ~= 0

6083

if size(file_list,2) ~= 0

6269

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6084

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6270

[filepath, basename, fileext]=fileparts(file_list{1});

6085

[filepath, basename, fileext]=fileparts(file_list{1});

6271

6086

6272

else

6087

else

6273

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6088

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6274

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6089

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6275

movegui(h,'northeast')

6090

movegui(h,'northeast')

6276

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6091

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6277

end

6092

end

6278

if OP.ERL == 2

6093

if OP.ERL == 2

6279

dir=fullfile(filepath, '*.s2p');

6094

dir=fullfile(filepath, '*.s2p');

6280

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6095

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6281

if filepath == 0

6096

if filepath == 0

6282

error('No RL measurement file')

6097

error('No RL measurement file')

6283

end

6098

end

6284

else

6099

else

6285

dir=fullfile(filepath, '*.s4p');

6100

dir=fullfile(filepath, '*.s4p');

6286

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6101

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6287

if filepath == 0

6102

if filepath == 0

6288

error('No Thru file')

6103

error('No Thru file')

6289

end

6104

end

6290

end

6105

end

6291

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6106

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6292

end

6107

end

6293

nxi=nxi+1;

6108

nxi=nxi+1;

6294

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6109

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6295

chdata(nxi).ext = fileext;

6110

chdata(nxi).ext = fileext;

6296

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6111

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6297

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6112

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6298

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6113

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6299

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6114

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6300

chdata(nxi).type='THRU';

6115

chdata(nxi).type='THRU';

6301

chdata(nxi).ftr=param.fb*param.f_v;

6116

chdata(nxi).ftr=param.fb*param.f_v;

6302

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6117

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6303

6118

6304

% now get FEXT file names into chdata structure

6119

% now get FEXT file names into chdata structure

6305

kxi=nxi;

6120

kxi=nxi;

6306

for nxi=kxi+1:num_fext+kxi

6121

for nxi=kxi+1:num_fext+kxi

6307

lastfilepath=filepath;

6122

lastfilepath=filepath;

6308

if size(file_list,2) ~= 0

6123

if size(file_list,2) ~= 0

6309

[filepath, basename, fileext]=fileparts(file_list{nxi});

6124

[filepath, basename, fileext]=fileparts(file_list{nxi});

6310

else

6125

else

6311

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6126

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6312

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6127

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6313

movegui(h,'northeast')

6128

movegui(h,'northeast')

6314

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6129

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6315

end

6130

end

6316

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6131

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6317

dir=fullfile(filepath, '*.s4p');

6132

dir=fullfile(filepath, '*.s4p');

6318

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6133

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6319

if filepath==0

6134

if filepath==0

6320

error('Not enough NEXT files')

6135

error('Not enough NEXT files')

6321

end

6136

end

6322

else

6137

else

6323

dir=fullfile(filepath, '*.s4p');

6138

dir=fullfile(filepath, '*.s4p');

6324

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6139

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6325

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6140

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6326

else

6141

else

6327

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6142

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6328

end

6143

end

6329

if filepath==0

6144

if filepath==0

6330

error('Not enough NEXT files')

6145

error('Not enough NEXT files')

6331

end

6146

end

6332

end

6147

end

6333

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6148

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6334

end

6149

end

6335

if isempty( filepath), filepath=lastfilepath; end

6150

if isempty( filepath), filepath=lastfilepath; end

6336

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6151

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6337

chdata(nxi).ext = fileext;

6152

chdata(nxi).ext = fileext;

6338

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6153

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6339

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6154

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6340

% chdata(nxi).A=param.a_fext;

6155

% chdata(nxi).A=param.a_fext;

6341

chdata(nxi).ftr=param.fb*param.f_f;

6156

chdata(nxi).ftr=param.fb*param.f_f;

6342

chdata(nxi).type='FEXT';

6157

chdata(nxi).type='FEXT';

6343

end

6158

end

6344

% now get NEXT file names into chdata structure

6159

% now get NEXT file names into chdata structure

6345

kxi=num_fext+kxi;

6160

kxi=num_fext+kxi;

6346

for nxi=kxi+1:num_next+kxi

6161

for nxi=kxi+1:num_next+kxi

6347

lastfilepath=filepath;

6162

lastfilepath=filepath;

6348

if size(file_list,2) ~= 0

6163

if size(file_list,2) ~= 0

6349

[filepath, basename, fileext]=fileparts(file_list{nxi});

6164

[filepath, basename, fileext]=fileparts(file_list{nxi});

6350

else

6165

else

6351

dir=fullfile(filepath, '*.s4p');

6166

dir=fullfile(filepath, '*.s4p');

6352

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6167

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6353

if filepath==0

6168

if filepath==0

6354

error('Not enough NEXT files')

6169

error('Not enough NEXT files')

6355

end

6170

end

6356

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6171

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6357

end

6172

end

6358

if isempty( filepath), filepath=lastfilepath; end

6173

if isempty( filepath), filepath=lastfilepath; end

6359

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6174

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6360

chdata(nxi).ext = fileext;

6175

chdata(nxi).ext = fileext;

6361

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6176

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6362

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6177

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6363

% chdata(nxi).A=param.A_next;

6178

% chdata(nxi).A=param.A_next;

6364

chdata(nxi).ftr=param.fb*param.f_n;

6179

chdata(nxi).ftr=param.fb*param.f_n;

6365

chdata(nxi).type='NEXT';

6180

chdata(nxi).type='NEXT';

6366

end

6181

end

6367

6182

6368

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6183

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6369

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6184

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6370

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6185

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6371

% H_r - receiver filter, Butterworth

6186

% H_r - receiver filter, Butterworth

6372

% H_ctf - total gain of CTLE and low freq filtering

6187

% H_ctf - total gain of CTLE and low freq filtering

6373

% H_dc - the common mode channel gain

6188

% H_dc - the common mode channel gain

6374

% param.eta_0 -input referred Rx noise

6189

% param.eta_0 -input referred Rx noise

6375

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6190

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6376

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6191

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6377

%% Equation 93A-35 - independent of FFE setting %%

6192

%% Equation 93A-35 - independent of FFE setting %%

6378

sigma_N1 = sqrt(param.eta_0*sum( abs(H_sy(2:end) .* H_r(2:end) .* H_ctf(2:end) ).^2 .* diff(chdata(1).faxis)/1e9));% eta_0 is V^2/Ghz i.e. /1

6193

sigma_N1 = sqrt(param.eta_0*sum( abs(H_sy(2:end) .* H_r(2:end) .* H_ctf(2:end) ).^2 .* diff(chdata(1).faxis)/1e9));% eta_0 is V^2/Ghz i.e. /1

6379

if sum(param.AC_CM_RMS) ~= 0

6194

if sum(param.AC_CM_RMS) ~= 0

6380

sigma_ACCM=0;

6195

sigma_ACCM=0;

6381

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6196

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6382

for i=1:length(chdata)

6197

for i=1:length(chdata)

6383

H_dc=abs(squeeze(chdata(i).sdc21));

6198

H_dc=abs(squeeze(chdata(i).sdc21));

6384

sigma_ACCM_acc= sqrt( 2*param.AC_CM_RMS_TX^2.*sum( abs(H_sy(2:length(f_int)) .* H_r(2:length(f_int)) .* H_ctf(2:length(f_int)).*H_dc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end) );

6199

sigma_ACCM_acc= sqrt( 2*param.AC_CM_RMS_TX^2.*sum( abs(H_sy(2:length(f_int)) .* H_r(2:length(f_int)) .* H_ctf(2:length(f_int)).*H_dc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end) );

6385

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6200

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6386

end

6201

end

6387

sigma_N=norm([sigma_N1,sigma_ACCM]);

6202

sigma_N=norm([sigma_N1,sigma_ACCM]);

6388

else

6203

else

6389

sigma_N=sigma_N1;

6204

sigma_N=sigma_N1;

6390

end

6205

end

6391

%%

6206

%%

6392

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6207

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6393

% for Rx calibratrion only

6208

% for Rx calibratrion only

6394

% the FEXT channel for calibration basically a DC connection unlike normal

6209

% the FEXT channel for calibration basically a DC connection unlike normal

6395

% FEXT channels which are nearly open at DC channels

6210

% FEXT channels which are nearly open at DC channels

6396

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6211

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6397

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6212

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6398

if size(chdata,2) >= 2

6213

if size(chdata,2) >= 2

6399

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6214

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6400

else

6215

else

6401

Hnoise_channel=1;

6216

Hnoise_channel=1;

6402

end

6217

end

6403

f=chdata(2).faxis;

6218

f=chdata(2).faxis;

6404

f_hp=param.f_hp;

6219

f_hp=param.f_hp;

6405

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6220

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6406

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6221

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6407

else

6222

else

6408

H_hp=ones(1,length(f));

6223

H_hp=ones(1,length(f));

6409

end

6224

end

6410

%% Equation 93A-47 or 162-12

6225

%% Equation 93A-47 or 162-12

6411

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6226

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6412

6227

6413

%% Equation 93A-48 or 162-14%%

6228

%% Equation 93A-48 or 162-14%%

6414

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6229

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6415

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6230

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6416

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6231

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6417

% Modified not to double count crosstalk: John Ewen 13/12/2018

6232

% Modified not to double count crosstalk: John Ewen 13/12/2018

6418

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6233

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6419

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6234

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6420

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6235

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6421

f=chdata(1).faxis;

6236

f=chdata(1).faxis;

6422

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6237

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6423

if(f(1)==0)

6238

if(f(1)==0)

6424

temp_angle(1)=1e-20;% we don't want to divide by zero

6239

temp_angle(1)=1e-20;% we don't want to divide by zero

6425

end

6240

end

6426

PWF_tx=ones(1,length(f));

6241

PWF_tx=ones(1,length(f));

6427

if max(upsampled_txffe) > 0

6242

if max(upsampled_txffe) > 0

6428

PWF_tx=zeros(1,length(f));

6243

PWF_tx=zeros(1,length(f));

6429

[mcur,icur] = max(upsampled_txffe);

6244

[mcur,icur] = max(upsampled_txffe);

6430

if exist('phase_memory','var') && ~isempty(phase_memory)

6245

if exist('phase_memory','var') && ~isempty(phase_memory)

6431

pre_calc=1;

6246

pre_calc=1;

6432

else

6247

else

6433

pre_calc=0;

6248

pre_calc=0;

6434

end

6249

end

6435

for ii=1:length(upsampled_txffe)

6250

for ii=1:length(upsampled_txffe)

6436

if upsampled_txffe(ii)==0

6251

if upsampled_txffe(ii)==0

6437

%speed up: skip cases when txffe=0

6252

%speed up: skip cases when txffe=0

6438

continue;

6253

continue;

6439

end

6254

end

6440

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6255

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6441

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6256

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6442

% that is needed

6257

% that is needed

6443

if ii==icur

6258

if ii==icur

6444

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6259

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6445

PWF_tx = PWF_tx + upsampled_txffe(ii);

6260

PWF_tx = PWF_tx + upsampled_txffe(ii);

6446

else

6261

else

6447

if pre_calc

6262

if pre_calc

6448

%speed up: avoid vector exp calculation by externally pre-calculating it

6263

%speed up: avoid vector exp calculation by externally pre-calculating it

6449

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6264

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6450

else

6265

else

6451

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6266

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6452

end

6267

end

6453

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6268

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6454

PWF_tx = PWF_tx + transpose(term_ii(:));

6269

PWF_tx = PWF_tx + transpose(term_ii(:));

6455

end

6270

end

6456

% /Adee

6271

% /Adee

6457

end

6272

end

6458

end

6273

end

6459

PWF_rx=ones(1,length(f));

6274

PWF_rx=ones(1,length(f));

6460

if exist('C','var')

6275

if exist('C','var')

6461

PWF_rx=zeros(1,length(f));

6276

PWF_rx=zeros(1,length(f));

6462

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6277

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6463

if C(ii+param.RxFFE_cmx+1)==0

6278

if C(ii+param.RxFFE_cmx+1)==0

6464

%speed up: skip cases when rxffe=0

6279

%speed up: skip cases when rxffe=0

6465

continue;

6280

continue;

6466

end

6281

end

6467

if ii+1==0

6282

if ii+1==0

6468

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6283

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6469

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6284

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6470

else

6285

else

6471

if pre_calc

6286

if pre_calc

6472

%speed up: avoid vector exp calculation by externally pre-calculating it

6287

%speed up: avoid vector exp calculation by externally pre-calculating it

6473

%The latter columns of phase_memory hold RXFFE shift vectors

6288

%The latter columns of phase_memory hold RXFFE shift vectors

6474

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6289

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6475

term_ii=transpose(term_ii);

6290

term_ii=transpose(term_ii);

6476

else

6291

else

6477

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6292

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6478

end

6293

end

6479

PWF_rx=PWF_rx+term_ii;

6294

PWF_rx=PWF_rx+term_ii;

6480

end

6295

end

6481

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6296

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6482

end

6297

end

6483

end

6298

end

6484

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6299

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6485

for ii=2:size(chdata,2)

6300

for ii=2:size(chdata,2)

6486

SINC = sin(temp_angle)./temp_angle;

6301

SINC = sin(temp_angle)./temp_angle;

6487

PWF_data=SINC.^2;

6302

PWF_data=SINC.^2;

6488

PWF=PWF_data.*PWF_rx; % power weight function

6303

PWF=PWF_data.*PWF_rx; % power weight function

6489

PWFnext=abs(PWF);

6304

PWFnext=abs(PWF);

6490

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6305

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6491

PWFfext=abs(PWF);

6306

PWFfext=abs(PWF);

6492

if isequal(chdata(ii).type, 'FEXT')

6307

if isequal(chdata(ii).type, 'FEXT')

6493

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6308

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6494

MDFEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFfext(1:index_f2).*abs(MDFEXT(1:index_f2)).^2)); %eq 46

6309

MDFEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFfext(1:index_f2).*abs(MDFEXT(1:index_f2)).^2)); %eq 46

6495

elseif isequal(chdata(ii).type, 'NEXT')

6310

elseif isequal(chdata(ii).type, 'NEXT')

6496

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6311

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6497

MDNEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFnext(1:index_f2).*abs(MDNEXT(1:index_f2)).^2)); %eq 47

6312

MDNEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFnext(1:index_f2).*abs(MDNEXT(1:index_f2)).^2)); %eq 47

6498

end

6313

end

6499

end

6314

end

6500

if nargout == 1 && isequal(type,'NEXT')

6315

if nargout == 1 && isequal(type,'NEXT')

6501

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6316

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6502

elseif nargout == 1 && isequal(type,'FEXT')

6317

elseif nargout == 1 && isequal(type,'FEXT')

6503

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6318

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6504

elseif nargout == 3

6319

elseif nargout == 3

6505

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6320

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6506

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6321

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6507

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6322

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6508

end

6323

end

6509

6324

6510

function out=hrem(h,index,N_bf,bmaxg)

6325

function out=hrem(h,index,N_bf,bmaxg)

6511

6326

6512

out=[ h(1:index-1) h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) h(index+N_bf:end) ];

6327

out=[ h(1:index-1) h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) h(index+N_bf:end) ];

6513

% faster than single line function

6328

% faster than single line function

6514

% hrem =@(h,index,N_bf,bmaxg) ...

6329

% hrem =@(h,index,N_bf,bmaxg) ...

6515

% [ h(1:index-1) ...

6330

% [ h(1:index-1) ...

6516

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6331

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6517

% h(index+N_bf:end) ]...

6332

% h(index+N_bf:end) ]...

6518

% ;

6333

% ;

6519

6334

6520

%% floating DFE taps

6335

%% floating DFE taps

6521

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6336

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6522

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6337

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6523

% Sout = interp_Sparam(Sin,fin,fout)

6338

% Sout = interp_Sparam(Sin,fin,fout)

6524

%

6339

%

6525

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6340

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6526

% fout.

6341

% fout.

6527

6342

6528

if ( fin(end)<fout(end) )

6343

if ( fin(end)<fout(end) )

6529

% warning('Channel high frequencies extrapolation might be inaccurate!');

6344

% warning('Channel high frequencies extrapolation might be inaccurate!');

6530

end

6345

end

6531

6346

6532

H_mag = abs(Sin);

6347

H_mag = abs(Sin);

6533

H_mag(H_mag<eps)=eps; % handle ill cases...

6348

H_mag(H_mag<eps)=eps; % handle ill cases...

6534

H_ph = unwrap(angle(Sin));

6349

H_ph = unwrap(angle(Sin));

6535

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6350

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6536

% user ignore that.

6351

% user ignore that.

6537

if mean(diff(H_ph))>0

6352

if mean(diff(H_ph))>0

6538

if OP.DEBUG

6353

if OP.DEBUG

6539

warning('Anti-causal response found. Finer frequency step is required for this channel');

6354

warning('Anti-causal response found. Finer frequency step is required for this channel');

6540

else

6355

else

6541

error('Anti-causal response found. Finer frequency step is required for this channel');

6356

error('Anti-causal response found. Finer frequency step is required for this channel');

6542

end

6357

end

6543

end

6358

end

6544

6359

6545

%opt_interp_Sparam_mag='linear_trend_to_DC';

6360

%opt_interp_Sparam_mag='linear_trend_to_DC';

6546

switch opt_interp_Sparam_mag

6361

switch opt_interp_Sparam_mag

6547

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6362

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6548

if -iscolumn(H_mag), H_mag=H_mag.';end

6363

if -iscolumn(H_mag), H_mag=H_mag.';end

6549

if -iscolumn(fin), fin=fin.';end

6364

if -iscolumn(fin), fin=fin.';end

6550

fin_x=fin;

6365

fin_x=fin;

6551

H_mag_x=H_mag(:);

6366

H_mag_x=H_mag(:);

6552

if fin(1)>0

6367

if fin(1)>0

6553

p=polyfit(fin(1:10), H_mag(1:10), 1);

6368

p=polyfit(fin(1:10), H_mag(1:10), 1);

6554

dc_trend_val=polyval(p, 0);

6369

dc_trend_val=polyval(p, 0);

6555

fin_x=[0, fin_x];

6370

fin_x=[0, fin_x];

6556

H_mag_x = [dc_trend_val; H_mag_x];

6371

H_mag_x = [dc_trend_val; H_mag_x];

6557

end

6372

end

6558

if fin(end)<fout(end)

6373

if fin(end)<fout(end)

6559

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6374

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6560

mid_freq_ind=round(length(fin)/2);

6375

mid_freq_ind=round(length(fin)/2);

6561

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6376

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6562

warning(warn_state);

6377

warning(warn_state);

6563

hf_trend_val=polyval(p, fout(end));

6378

hf_trend_val=polyval(p, fout(end));

6564

if hf_trend_val>H_mag(end)

6379

if hf_trend_val>H_mag(end)

6565

hf_trend_val=H_mag(end);

6380

hf_trend_val=H_mag(end);

6566

hf_logtrend_val = H_mag(end);

6381

hf_logtrend_val = H_mag(end);

6567

elseif hf_trend_val<eps

6382

elseif hf_trend_val<eps

6568

hf_trend_val=eps;

6383

hf_trend_val=eps;

6569

hf_logtrend_val = realmin;

6384

hf_logtrend_val = realmin;

6570

end

6385

end

6571

fin_x=[fin_x, fout(end)];

6386

fin_x=[fin_x, fout(end)];

6572

H_mag_x = [H_mag_x; hf_trend_val];

6387

H_mag_x = [H_mag_x; hf_trend_val];

6573

end

6388

end

6574

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6389

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6575

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6390

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6576

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6391

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6577

indx = find(fout > fin(end),1,'first');

6392

indx = find(fout > fin(end),1,'first');

6578

H_mag_i(indx:end) = H_logmag_i(indx:end);

6393

H_mag_i(indx:end) = H_logmag_i(indx:end);

6579

end

6394

end

6580

case 'trend_to_DC'

6395

case 'trend_to_DC'

6581

% extrapolate to trend value at DC.

6396

% extrapolate to trend value at DC.

6582

if -iscolumn(H_mag), H_mag=H_mag.';end

6397

if -iscolumn(H_mag), H_mag=H_mag.';end

6583

if -iscolumn(fin), fin=fin.';end

6398

if -iscolumn(fin), fin=fin.';end

6584

fin_x=fin;

6399

fin_x=fin;

6585

H_mag_x=H_mag;

6400

H_mag_x=H_mag;

6586

if fin(1)>0

6401

if fin(1)>0

6587

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6402

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6588

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6403

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6589

dc_trend_val=10^polyval(p, 0);

6404

dc_trend_val=10^polyval(p, 0);

6590

fin_x=[0, fin_x];

6405

fin_x=[0, fin_x];

6591

H_mag_x = [dc_trend_val H_mag_x];

6406

H_mag_x = [dc_trend_val H_mag_x];

6592

end

6407

end

6593

if fin(end)<fout(end)

6408

if fin(end)<fout(end)

6594

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6409

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6595

mid_freq_ind=round(length(fin)/2);

6410

mid_freq_ind=round(length(fin)/2);

6596

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6411

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6597

warning(warn_state);

6412

warning(warn_state);

6598

hf_trend_val=10^polyval(p, fout(end));

6413

hf_trend_val=10^polyval(p, fout(end));

6599

if hf_trend_val>H_mag(end)

6414

if hf_trend_val>H_mag(end)

6600

hf_trend_val=H_mag(end);

6415

hf_trend_val=H_mag(end);

6601

end

6416

end

6602

fin_x=[fin_x, fout(end)];

6417

fin_x=[fin_x, fout(end)];

6603

H_mag_x = [H_mag_x hf_trend_val];

6418

H_mag_x = [H_mag_x hf_trend_val];

6604

end

6419

end

6605

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6420

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6606

case 'extrap_to_DC_or_zero'

6421

case 'extrap_to_DC_or_zero'

6607

% same as extrap_to_DC but detect AC-coupled channels and

6422

% same as extrap_to_DC but detect AC-coupled channels and

6608

% extrapolate them to 0.

6423

% extrapolate them to 0.

6609

if fin(1)>0 && 20*log10(H_mag(1))<-20

6424

if fin(1)>0 && 20*log10(H_mag(1))<-20

6610

% assume AC coupling, with 0 at DC

6425

% assume AC coupling, with 0 at DC

6611

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6426

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6612

else

6427

else

6613

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6428

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6614

end

6429

end

6615

H_mag_i(fout>fin(end)) = H_mag(end);

6430

H_mag_i(fout>fin(end)) = H_mag(end);

6616

case 'extrap_to_DC'

6431

case 'extrap_to_DC'

6617

% first extrapolate down to DC, then use highest available frequency

6432

% first extrapolate down to DC, then use highest available frequency

6618

% for higher frequencies

6433

% for higher frequencies

6619

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6434

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6620

H_mag_i(fout>fin(end)) = H_mag(end);

6435

H_mag_i(fout>fin(end)) = H_mag(end);

6621

case 'old'

6436

case 'old'

6622

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6437

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6623

otherwise

6438

otherwise

6624

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6439

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6625

end

6440

end

6626

6441

6627

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6442

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6628

6443

6629

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6444

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6630

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6445

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6631

switch opt_interp_Sparam_phase

6446

switch opt_interp_Sparam_phase

6632

case 'old'

6447

case 'old'

6633

H_ph_i = H_ph_i-H_ph_i(1);

6448

H_ph_i = H_ph_i-H_ph_i(1);

6634

case 'zero_DC'

6449

case 'zero_DC'

6635

H_ph_i(1) = 0;

6450

H_ph_i(1) = 0;

6636

case 'interp_to_DC'

6451

case 'interp_to_DC'

6637

if fin(1) ~= 0

6452

if fin(1) ~= 0

6638

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6453

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6639

end

6454

end

6640

case 'extrap_cubic_to_dc_linear_to_inf'

6455

case 'extrap_cubic_to_dc_linear_to_inf'

6641

if fin(1) ~= 0

6456

if fin(1) ~= 0

6642

% estimate low frequency group delay

6457

% estimate low frequency group delay

6643

group_delay = -diff(H_ph(:))./diff(fin(:));

6458

group_delay = -diff(H_ph(:))./diff(fin(:));

6644

low_freq_gd = group_delay(1:50);

6459

low_freq_gd = group_delay(1:50);

6645

% calculate trend, throwing away outliers

6460

% calculate trend, throwing away outliers

6646

m = median(low_freq_gd); sigma = std(low_freq_gd);

6461

m = median(low_freq_gd); sigma = std(low_freq_gd);

6647

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6462

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6648

% correct outliers in first 10 phase samples

6463

% correct outliers in first 10 phase samples

6649

for k=10:-1:1

6464

for k=10:-1:1

6650

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6465

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6651

end

6466

end

6652

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6467

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6653

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6468

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6654

% modification - trend to inf

6469

% modification - trend to inf

6655

if (1)

6470

if (1)

6656

high_freq_gd = group_delay(end-50:end);

6471

high_freq_gd = group_delay(end-50:end);

6657

% calculate trend, throwing away outliers

6472

% calculate trend, throwing away outliers

6658

m = median(high_freq_gd); sigma = std(high_freq_gd);

6473

m = median(high_freq_gd); sigma = std(high_freq_gd);

6659

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6474

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6660

hf_extrap_range = find(fout>fin(end));

6475

hf_extrap_range = find(fout>fin(end));

6661

last_data_sample = hf_extrap_range(1)-1;

6476

last_data_sample = hf_extrap_range(1)-1;

6662

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6477

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6663

% for k=hf_range

6478

% for k=hf_range

6664

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6479

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6665

% end

6480

% end

6666

end

6481

end

6667

6482

6668

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6483

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6669

H_ph_i=H_ph_cubic;

6484

H_ph_i=H_ph_cubic;

6670

H_ph_i(indx:end) = H_ph_linear(indx:end);

6485

H_ph_i(indx:end) = H_ph_linear(indx:end);

6671

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6486

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6672

end

6487

end

6673

case 'interp_and_shift_to_DC'

6488

case 'interp_and_shift_to_DC'

6674

if fin(1) ~= 0

6489

if fin(1) ~= 0

6675

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6490

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6676

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6491

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6677

end

6492

end

6678

case 'trend_and_shift_to_DC'

6493

case 'trend_and_shift_to_DC'

6679

% estimate low frequency group delay

6494

% estimate low frequency group delay

6680

group_delay = -diff(H_ph(:))./diff(fin(:));

6495

group_delay = -diff(H_ph(:))./diff(fin(:));

6681

low_freq_gd = group_delay(1:50);

6496

low_freq_gd = group_delay(1:50);

6682

% calculate trend, throwing away outliers

6497

% calculate trend, throwing away outliers

6683

m = median(low_freq_gd); sigma = std(low_freq_gd);

6498

m = median(low_freq_gd); sigma = std(low_freq_gd);

6684

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6499

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6685

fin_x=fin;

6500

fin_x=fin;

6686

H_ph_x=H_ph(:);

6501

H_ph_x=H_ph(:);

6687

if fin(1) ~= 0

6502

if fin(1) ~= 0

6688

% correct outliers in first 10 phase samples

6503

% correct outliers in first 10 phase samples

6689

for k=10:-1:1

6504

for k=10:-1:1

6690

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6505

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6691

end

6506

end

6692

6507

6693

% shift all phase data so that DC extrapolation to 0 follows trend

6508

% shift all phase data so that DC extrapolation to 0 follows trend

6694

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6509

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6695

fin_x=[0, fin_x];

6510

fin_x=[0, fin_x];

6696

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6511

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6697

end

6512

end

6698

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6513

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6699

% the last two samples, so noise can create an inverted slope and

6514

% the last two samples, so noise can create an inverted slope and

6700

% non-causal response).

6515

% non-causal response).

6701

if fout(end)>fin(end)

6516

if fout(end)>fin(end)

6702

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6517

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6703

% p=polyfit(fin_x', H_ph_x, 1);

6518

% p=polyfit(fin_x', H_ph_x, 1);

6704

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6519

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6705

% hf_phase_trend=polyval(p,max(fout));

6520

% hf_phase_trend=polyval(p,max(fout));

6706

fin_x=[fin_x, fout(end)];

6521

fin_x=[fin_x, fout(end)];

6707

H_ph_x=[H_ph_x; hf_phase_trend];

6522

H_ph_x=[H_ph_x; hf_phase_trend];

6708

end

6523

end

6709

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6524

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6710

6525

6711

otherwise

6526

otherwise

6712

error('COM:Extrap:InvalidOption', ...

6527

error('COM:Extrap:InvalidOption', ...

6713

'debug_interp_Sparam valid values are "old", "zero_DC", "interp_to_DC", "interp_and_shift_to_DC", "trend_and_shift_to_DC", "interp_cubic_to_dc_linear_to_inf"');

6528

'debug_interp_Sparam valid values are "old", "zero_DC", "interp_to_DC", "interp_and_shift_to_DC", "trend_and_shift_to_DC", "interp_cubic_to_dc_linear_to_inf"');

6714

end

6529

end

6715

H_i = H_mag_i.*exp(1j*H_ph_i);

6530

H_i = H_mag_i.*exp(1j*H_ph_i);

6716

Sout=H_i;

6531

Sout=H_i;

6717

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6532

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6718

6533

6719

%This function makes the TX or RX package. The type input must be

6534

%This function makes the TX or RX package. The type input must be

6720

%'TX' or 'RX'

6535

%'TX' or 'RX'

6721

%If the mode argument is omitted, mode='dd' is assumed. Currently

6536

%If the mode argument is omitted, mode='dd' is assumed. Currently

6722

%mode='dc' is only used when making the TX package for AC CM noise

6537

%mode='dc' is only used when making the TX package for AC CM noise

6723

%inclusion. The Rx package for 'dc' mode is still generated using

6538

%inclusion. The Rx package for 'dc' mode is still generated using

6724

%the same parameters as 'dd' mode

6539

%the same parameters as 'dd' mode

6725

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6540

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6726

%

6541

%

6727

%One instance of package block looks like this (if no elements are set to 0):

6542

%One instance of package block looks like this (if no elements are set to 0):

6728

%-------------Lcomp----------Tline---------------

6543

%-------------Lcomp----------Tline---------------

6729

% | | |

6544

% | | |

6730

% Cpad Cbump Cball

6545

% Cpad Cbump Cball

6731

% | | |

6546

% | | |

6732

%------------------------------------------------

6547

%------------------------------------------------

6733

6548

6734

if nargin<6

6549

if nargin<6

6735

%optional input "include_die"=0 allows die parameters to be forced to 0

6550

%optional input "include_die"=0 allows die parameters to be forced to 0

6736

%this includes Cpad, Lcomp, and Cbump

6551

%this includes Cpad, Lcomp, and Cbump

6737

include_die=1;

6552

include_die=1;

6738

end

6553

end

6739

if nargin<5

6554

if nargin<5

6740

mode='dd';

6555

mode='dd';

6741

end

6556

end

6742

6557

6743

6558

6744

if ~isempty(param.PKG_NAME)

6559

if ~isempty(param.PKG_NAME)

6745

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6560

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6746

%so they are swapped in depending on if Tx or Rx is set for type

6561

%so they are swapped in depending on if Tx or Rx is set for type

6747

%Note that param is not returned from this function, so the swap does not persist

6562

%Note that param is not returned from this function, so the swap does not persist

6748

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6563

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6749

if strcmpi(type,'tx')

6564

if strcmpi(type,'tx')

6750

pkg_name = param.PKG_NAME{1};

6565

pkg_name = param.PKG_NAME{1};

6751

elseif strcmpi(type,'rx')

6566

elseif strcmpi(type,'rx')

6752

pkg_name = param.PKG_NAME{2};

6567

pkg_name = param.PKG_NAME{2};

6753

else

6568

else

6754

error('Pkg type must be Tx or Rx');

6569

error('Pkg type must be Tx or Rx');

6755

end

6570

end

6756

pkg_parameter_struct = param.PKG.(pkg_name);

6571

pkg_parameter_struct = param.PKG.(pkg_name);

6757

6572

6758

6573

6759

for j=1:length(swap_fields)

6574

for j=1:length(swap_fields)

6760

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6575

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6761

end

6576

end

6762

6577

6763

end

6578

end

6764

6579

6765

C_diepad = param.C_diepad;

6580

C_diepad = param.C_diepad;

6766

C_pkg_board = param.C_pkg_board;

6581

C_pkg_board = param.C_pkg_board;

6767

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6582

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6768

L_comp = param.L_comp;

6583

L_comp = param.L_comp;

6769

C_bump = param.C_bump;

6584

C_bump = param.C_bump;

6770

if ~include_die

6585

if ~include_die

6771

%best to multiply by 0. that way vectors maintain original size

6586

%best to multiply by 0. that way vectors maintain original size

6772

C_diepad=C_diepad*0;

6587

C_diepad=C_diepad*0;

6773

L_comp=L_comp*0;

6588

L_comp=L_comp*0;

6774

C_bump=C_bump*0;

6589

C_bump=C_bump*0;

6775

end

6590

end

6776

% [ahealey] End of modifications.

6591

% [ahealey] End of modifications.

6777

% generate TX package according to channel type.

6592

% generate TX package according to channel type.

6778

[ncases, mele]=size(param.z_p_next_cases);

6593

[ncases, mele]=size(param.z_p_next_cases);

6779

6594

6780

%Syntax update for C_diepad and L_comp

6595

%Syntax update for C_diepad and L_comp

6781

%Allow a chain of values to be entered as a matrix:

6596

%Allow a chain of values to be entered as a matrix:

6782

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6597

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6783

if isvector(C_diepad)

6598

if isvector(C_diepad)

6784

Cd_Tx=C_diepad(1);

6599

Cd_Tx=C_diepad(1);

6785

Cd_Rx=C_diepad(2);

6600

Cd_Rx=C_diepad(2);

6786

L_comp_Tx=L_comp(1);

6601

L_comp_Tx=L_comp(1);

6787

L_comp_Rx=L_comp(2);

6602

L_comp_Rx=L_comp(2);

6788

num_blocks=mele;

6603

num_blocks=mele;

6789

else

6604

else

6790

Cd_Tx=C_diepad(1,:);

6605

Cd_Tx=C_diepad(1,:);

6791

Cd_Rx=C_diepad(2,:);

6606

Cd_Rx=C_diepad(2,:);

6792

L_comp_Tx=L_comp(1,:);

6607

L_comp_Tx=L_comp(1,:);

6793

L_comp_Rx=L_comp(2,:);

6608

L_comp_Rx=L_comp(2,:);

6794

num_blocks=mele+length(Cd_Tx)-1;

6609

num_blocks=mele+length(Cd_Tx)-1;

6795

end

6610

end

6796

extra_LC=length(Cd_Tx)-1;

6611

extra_LC=length(Cd_Tx)-1;

6797

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6612

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6798

insert_zeros=zeros([1 extra_LC]);

6613

insert_zeros=zeros([1 extra_LC]);

6799

6614

6800

%Updated technique of building Tx/Rx packages

6615

%Updated technique of building Tx/Rx packages

6801

%each index corresponds to the package segment

6616

%each index corresponds to the package segment

6802

switch type

6617

switch type

6803

case 'TX'

6618

case 'TX'

6804

switch mele

6619

switch mele

6805

case 1

6620

case 1

6806

Cpad=Cd_Tx;

6621

Cpad=Cd_Tx;

6807

Lcomp=L_comp_Tx;

6622

Lcomp=L_comp_Tx;

6808

Cbump=C_bump(1);

6623

Cbump=C_bump(1);

6809

Cball=C_pkg_board(1);

6624

Cball=C_pkg_board(1);

6810

Zpkg=param.pkg_Z_c(1);

6625

Zpkg=param.pkg_Z_c(1);

6811

case 4

6626

case 4

6812

Cpad=[Cd_Tx 0 0 0];

6627

Cpad=[Cd_Tx 0 0 0];

6813

Lcomp=[L_comp_Tx 0 0 0];

6628

Lcomp=[L_comp_Tx 0 0 0];

6814

Cbump=[C_bump(1) 0 0 0];

6629

Cbump=[C_bump(1) 0 0 0];

6815

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6630

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6816

Zpkg=param.pkg_Z_c(1,:);

6631

Zpkg=param.pkg_Z_c(1,:);

6817

otherwise

6632

otherwise

6818

error('package syntax error')

6633

error('package syntax error')

6819

end

6634

end

6820

switch upper(channel_type)

6635

switch upper(channel_type)

6821

case 'THRU'

6636

case 'THRU'

6822

Len=param.Pkg_len_TX;

6637

Len=param.Pkg_len_TX;

6823

case 'NEXT'

6638

case 'NEXT'

6824

Len=param.Pkg_len_NEXT;

6639

Len=param.Pkg_len_NEXT;

6825

case 'FEXT'

6640

case 'FEXT'

6826

Len=param.Pkg_len_FEXT;

6641

Len=param.Pkg_len_FEXT;

6827

end

6642

end

6828

case 'RX'

6643

case 'RX'

6829

switch mele

6644

switch mele

6830

case 1

6645

case 1

6831

Cpad=Cd_Rx;

6646

Cpad=Cd_Rx;

6832

Lcomp=L_comp_Rx;

6647

Lcomp=L_comp_Rx;

6833

Cbump=C_bump(2);

6648

Cbump=C_bump(2);

6834

Cball=C_pkg_board(2);

6649

Cball=C_pkg_board(2);

6835

Zpkg=param.pkg_Z_c(2);

6650

Zpkg=param.pkg_Z_c(2);

6836

case 4

6651

case 4

6837

Cpad=[Cd_Rx 0 0 0];

6652

Cpad=[Cd_Rx 0 0 0];

6838

Lcomp=[L_comp_Rx 0 0 0];

6653

Lcomp=[L_comp_Rx 0 0 0];

6839

Cbump=[C_bump(2) 0 0 0];

6654

Cbump=[C_bump(2) 0 0 0];

6840

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6655

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6841

Zpkg=param.pkg_Z_c(2,:);

6656

Zpkg=param.pkg_Z_c(2,:);

6842

otherwise

6657

otherwise

6843

error('package syntax error')

6658

error('package syntax error')

6844

end

6659

end

6845

switch upper(channel_type)

6660

switch upper(channel_type)

6846

case 'THRU'

6661

case 'THRU'

6847

Len=param.Pkg_len_RX;

6662

Len=param.Pkg_len_RX;

6848

case 'NEXT'

6663

case 'NEXT'

6849

Len=param.Pkg_len_RX;

6664

Len=param.Pkg_len_RX;

6850

case 'FEXT'

6665

case 'FEXT'

6851

Len=param.Pkg_len_RX;

6666

Len=param.Pkg_len_RX;

6852

end

6667

end

6853

end

6668

end

6854

6669

6855

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6670

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6856

Cball=[insert_zeros Cball];

6671

Cball=[insert_zeros Cball];

6857

Cbump=[insert_zeros Cbump];

6672

Cbump=[insert_zeros Cbump];

6858

Len=[insert_zeros Len];

6673

Len=[insert_zeros Len];

6859

Zpkg=[insert_zeros Zpkg];

6674

Zpkg=[insert_zeros Zpkg];

6860

6675

6861

% debug_string='';

6676

% debug_string='';

6862

% for j=1:length(Zpkg)

6677

% for j=1:length(Zpkg)

6863

% if Cpad(j)~=0

6678

% if Cpad(j)~=0

6864

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6679

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6865

% end

6680

% end

6866

% if Lcomp(j)~=0

6681

% if Lcomp(j)~=0

6867

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6682

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6868

% end

6683

% end

6869

% if Cbump(j)~=0

6684

% if Cbump(j)~=0

6870

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6685

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6871

% end

6686

% end

6872

% if Len(j)~=0

6687

% if Len(j)~=0

6873

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6688

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6874

% end

6689

% end

6875

% if Cball(j)~=0

6690

% if Cball(j)~=0

6876

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6691

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6877

% end

6692

% end

6878

% end

6693

% end

6879

% if length(debug_string)>2

6694

% if length(debug_string)>2

6880

% debug_string=debug_string(3:end);

6695

% debug_string=debug_string(3:end);

6881

% end

6696

% end

6882

6697

6883

% tx package

6698

% tx package

6884

pkg_param=param;

6699

pkg_param=param;

6885

if strcmpi(mode,'dc')

6700

if strcmpi(mode,'dc')

6886

% change tx package to CC mode

6701

% change tx package to CC mode

6887

pkg_param.Z0=pkg_param.Z0/2;

6702

pkg_param.Z0=pkg_param.Z0/2;

6888

Cpad=Cpad*2;

6703

Cpad=Cpad*2;

6889

Cball=Cball*2;

6704

Cball=Cball*2;

6890

Zpkg=Zpkg*2;

6705

Zpkg=Zpkg*2;

6891

Lcomp=Lcomp/2;

6706

Lcomp=Lcomp/2;

6892

Cbump=Cbump*2;

6707

Cbump=Cbump*2;

6893

end

6708

end

6894

switch num_blocks

6709

switch num_blocks

6895

case 1

6710

case 1

6896

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6711

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6897

otherwise

6712

otherwise

6898

for j=1:num_blocks

6713

for j=1:num_blocks

6899

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6714

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6900

if j==1

6715

if j==1

6901

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6716

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6902

else

6717

else

6903

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6718

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6904

end

6719

end

6905

end

6720

end

6906

end

6721

end

6907

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6722

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6908

f(f<eps)=eps;

6723

f(f<eps)=eps;

6909

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6724

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6910

%% Equation 93A-8

6725

%% Equation 93A-8

6911

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6726

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6912

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6727

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6913

6728

6914

% [ahealey] Add compensating L and shunt C (bump) when requested.

6729

% [ahealey] Add compensating L and shunt C (bump) when requested.

6915

s12pad = s21pad;

6730

s12pad = s21pad;

6916

s22pad = s11pad;

6731

s22pad = s11pad;

6917

if nargin > 6

6732

if nargin > 6

6918

lcomp = varargin{1};

6733

lcomp = varargin{1};

6919

if lcomp>0

6734

if lcomp>0

6920

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6735

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6921

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6736

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6922

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6737

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6923

s11pad, s12pad, s21pad, s22pad, ...

6738

s11pad, s12pad, s21pad, s22pad, ...

6924

s11comp, s21comp, s21comp, s11comp);

6739

s11comp, s21comp, s21comp, s11comp);

6925

end

6740

end

6926

end

6741

end

6927

if nargin > 7

6742

if nargin > 7

6928

cbump = varargin{2};

6743

cbump = varargin{2};

6929

if cbump>0

6744

if cbump>0

6930

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

6745

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

6931

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

6746

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

6932

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6747

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6933

s11pad, s12pad, s21pad, s22pad, ...

6748

s11pad, s12pad, s21pad, s22pad, ...

6934

s11bump, s21bump, s21bump, s11bump);

6749

s11bump, s21bump, s21bump, s11bump);

6935

end

6750

end

6936

end

6751

end

6937

% [ahealey] End of modifications.

6752

% [ahealey] End of modifications.

6938

6753

6939

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

6754

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

6940

% [ahealey] Symmetry cannot be assumed with more complex termination models.

6755

% [ahealey] Symmetry cannot be assumed with more complex termination models.

6941

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

6756

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

6942

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

6757

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

6943

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

6758

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

6944

s11pad, s12pad, s21pad, s22pad, ...

6759

s11pad, s12pad, s21pad, s22pad, ...

6945

S11, S21, S21, S11);

6760

S11, S21, S21, S11);

6946

% [ahealey] End of modifications.

6761

% [ahealey] End of modifications.

6947

6762

6948

%% Equation 93A-8

6763

%% Equation 93A-8

6949

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

6764

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

6950

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

6765

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

6951

[ s11out, s12out, s21out, s22out ]= ...

6766

[ s11out, s12out, s21out, s22out ]= ...

6952

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

6767

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

6953

6768

6954

function missingParameter (parameterName)

6769

function missingParameter (parameterName)

6955

error( 'error:badParameterInformation', ...

6770

error( 'error:badParameterInformation', ...

6956

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

6771

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

6957

6772

6958

function pdf = normal_dist(sigma,nsigma,binsize)

6773

function pdf = normal_dist(sigma,nsigma,binsize)

6959

pdf.BinSize=binsize;

6774

pdf.BinSize=binsize;

6960

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

6775

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

6961

pdf.x=(pdf.Min:-pdf.Min)*binsize;

6776

pdf.x=(pdf.Min:-pdf.Min)*binsize;

6962

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

6777

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

6963

pdf.y=pdf.y/sum(pdf.y);

6778

pdf.y=pdf.y/sum(pdf.y);

6964

6779

6965

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

6780

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

6966

%% input

6781

%% input

6967

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

6782

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

6968

% baud_rate - baud rate in seconds

6783

% baud_rate - baud rate in seconds

6969

% param.samples_per_ui = samples per UI of IR

6784

% param.samples_per_ui = samples per UI of IR

6970

% param.max_ctle - maximum ac to dc gain in dB

6785

% param.max_ctle - maximum ac to dc gain in dB

6971

% param.tx_ffe(1) - maximum pre cursor (positive value)

6786

% param.tx_ffe(1) - maximum pre cursor (positive value)

6972

% param.tx_ffe(2) - maximum post cursor (positive value)

6787

% param.tx_ffe(2) - maximum post cursor (positive value)

6973

% param.tx_ffe_step - sweep step size for tx pre and post taps

6788

% param.tx_ffe_step - sweep step size for tx pre and post taps

6974

% param.ndfe - number of reference dfe taps

6789

% param.ndfe - number of reference dfe taps

6975

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

6790

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

6976

% output

6791

% output

6977

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

6792

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

6978

% result.eq.ctle - index of CTLE parameters in table

6793

% result.eq.ctle - index of CTLE parameters in table

6979

% result.IR - impulse response

6794

% result.IR - impulse response

6980

% result.avail_signal - maximum signal after equalization

6795

% result.avail_signal - maximum signal after equalization

6981

% result.avail_sig_index - index in result.IR of max signal

6796

% result.avail_sig_index - index in result.IR of max signal

6982

% result.best_FOM - best raw ISI

6797

% result.best_FOM - best raw ISI

+6798

6983

6799

6984

min_number_of_UI_in_response=40;

6800

min_number_of_UI_in_response=40;

6985

baud_rate=1/param.ui;

6801

baud_rate=1/param.ui;

6986

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

6802

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

6987

f=chdata(1).faxis;

6803

f=chdata(1).faxis;

6988

6804

6989

%Read user input of ts_sample_adj_range

6805

%Read user input of ts_sample_adj_range

6990

%if one value was entered, go from 0 to that value

6806

%if one value was entered, go from 0 to that value

6991

%if 2 values were entered, go from the 1st value to the 2nd value

6807

%if 2 values were entered, go from the 1st value to the 2nd value

6992

if length(param.ts_sample_adj_range)==1

6808

if length(param.ts_sample_adj_range)==1

6993

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

6809

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

6994

param.ts_sample_adj_range(1)=0;

6810

param.ts_sample_adj_range(1)=0;

6995

end

6811

end

6996

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

6812

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

6997

6813

6998

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

6814

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

6999

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

6815

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

7000

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

6816

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7001

% need to include H_RCos in noise and when computing the system ir for thru

6817

% need to include H_RCos in noise and when computing the system ir for thru

7002

% and crosstalk

6818

% and crosstalk

7003

H_r=H_bw.*H_bt.*H_RCos;

6819

H_r=H_bw.*H_bt.*H_RCos;

7004

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

6820

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

7005

% Get f vector from 0 to Fs/2-delta_f.

6821

% Get f vector from 0 to Fs/2-delta_f.

7006

N_fft_by2 = 512;

6822

N_fft_by2 = 512;

7007

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

6823

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

7008

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

6824

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

7009

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

6825

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

7010

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

6826

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

7011

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

6827

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

7012

%%

6828

%%

7013

6829

7014

% system noise H_sy PSD

6830

% system noise H_sy PSD

7015

if OP.USE_ETA0_PSD

6831

if OP.USE_ETA0_PSD

7016

fspike=1e9;

6832

fspike=1e9;

7017

% requires communication tool box if used

6833

% requires communication tool box if used

7018

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

6834

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

7019

else

6835

else

7020

H_sy=ones(1,length(chdata(1).faxis));

6836

H_sy=ones(1,length(chdata(1).faxis));

7021

end

6837

end

7022

6838

7023

%Build txffe values dynamically

6839

%Build txffe values dynamically

7024

%any param field that is "tx_ffe_cm<X>_values" is a precursor

6840

%any param field that is "tx_ffe_cm<X>_values" is a precursor

7025

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

6841

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

7026

%where <X> is any integer

6842

%where <X> is any integer

7027

param_fields=fieldnames(param);

6843

param_fields=fieldnames(param);

7028

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

6844

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

7029

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

6845

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

7030

num_taps=num_pre+num_post;

6846

num_taps=num_pre+num_post;

7031

cur=num_pre+1;

6847

cur=num_pre+1;

7032

%txffe_cell combines all the txffe values into a single cell array

6848

%txffe_cell combines all the txffe values into a single cell array

7033

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

6849

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

7034

txffe_cell=cell(1,num_taps);

6850

txffe_cell=cell(1,num_taps);

7035

for k=num_pre:-1:1

6851

for k=num_pre:-1:1

7036

idx=num_pre-k+1;

6852

idx=num_pre-k+1;

7037

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

6853

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

7038

txffe_cell{idx}=param.(this_tx_field);

6854

txffe_cell{idx}=param.(this_tx_field);

7039

end

6855

end

7040

for k=1:num_post

6856

for k=1:num_post

7041

idx=k+num_pre;

6857

idx=k+num_pre;

7042

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

6858

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

7043

txffe_cell{idx}=param.(this_tx_field);

6859

txffe_cell{idx}=param.(this_tx_field);

7044

end

6860

end

7045

%total number of txffe runs is the product of the lengths of each tap

6861

%total number of txffe runs is the product of the lengths of each tap

7046

txffe_lengths=cellfun('length',txffe_cell);

6862

txffe_lengths=cellfun('length',txffe_cell);

7047

if isempty(txffe_cell)

6863

if isempty(txffe_cell)

7048

num_txffe_runs=1;

6864

num_txffe_runs=1;

7049

else

6865

else

7050

num_txffe_runs=prod(txffe_lengths);

6866

num_txffe_runs=prod(txffe_lengths);

7051

end

6867

end

7052

%txffe_sweep_indices are used in the LOCAL_SEARCH block

6868

%txffe_sweep_indices are used in the LOCAL_SEARCH block

7053

%any tap with length=1 can be ignored

6869

%any tap with length=1 can be ignored

7054

%Also is statistically likely that taps with greater number of values

6870

%Also is statistically likely that taps with greater number of values

7055

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

6871

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

7056

txffe_sweep_indices=find(txffe_lengths>1);

6872

txffe_sweep_indices=find(txffe_lengths>1);

7057

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

6873

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

7058

txffe_sweep_indices=txffe_sweep_indices(length_sort);

6874

txffe_sweep_indices=txffe_sweep_indices(length_sort);

7059

num_txffe_sweep_indices=length(txffe_sweep_indices);

6875

num_txffe_sweep_indices=length(txffe_sweep_indices);

7060

6876

7061

gdc_values = param.ctle_gdc_values;

6877

gdc_values = param.ctle_gdc_values;

7062

Gffe_values = param.cursor_gain;

6878

Gffe_values = param.cursor_gain;

7063

switch param.CTLE_type

6879

switch param.CTLE_type

7064

case 'CL93'

6880

case 'CL93'

7065

case 'CL120d'

6881

case 'CL120d'

7066

g_DC_HP_values =param.g_DC_HP_values;

6882

g_DC_HP_values =param.g_DC_HP_values;

7067

case 'CL120e'

6883

case 'CL120e'

7068

f_HP_Z=param.f_HP_Z;

6884

f_HP_Z=param.f_HP_Z;

7069

f_HP_P=param.f_HP_P;

6885

f_HP_P=param.f_HP_P;

7070

6886

7071

end

6887

end

7072

best_ctle = [];

6888

best_ctle = [];

7073

best_FOM = -inf;

6889

best_FOM = -inf;

7074

best_txffe = [];

6890

best_txffe = [];

7075

delta_sbr = [];

6891

delta_sbr = [];

7076

PSD_results=[];

6892

PSD_results=[];

7077

MMSE_results=[];

6893

MMSE_results=[];

7078

best_bmax=param.bmax;

6894

best_bmax=param.bmax;

7079

%AJG021820

6895

%AJG021820

7080

best_bmin=param.bmin;

6896

best_bmin=param.bmin;

7081

h_J=[];

6897

h_J=[];

7082

pxi=0;

6898

pxi=0;

7083

if OP.DISPLAY_WINDOW

6899

if OP.DISPLAY_WINDOW

7084

hwaitbar=waitbar(0);

6900

hwaitbar=waitbar(0);

7085

else

6901

else

7086

fprintf('FOM search ');

6902

fprintf('FOM search ');

7087

end

6903

end

7088

FOM=0;

6904

FOM=0;

7089

if ~OP.RxFFE

6905

if ~OP.RxFFE

7090

Gffe_values=0;

6906

Gffe_values=0;

7091

end

6907

end

7092

param.ndfe_passed=param.ndfe;

6908

param.ndfe_passed=param.ndfe;

7093

old_loops=0;

6909

old_loops=0;

7094

new_loops=0;

6910

new_loops=0;

7095

6911

7096

%GDC Qual construction

6912

%GDC Qual construction

7097

gqual= param.gqual;

6913

gqual= param.gqual;

7098

g2qual=param.g2qual;

6914

g2qual=param.g2qual;

7099

if ~strcmp(param.CTLE_type,'CL120d')

6915

if ~strcmp(param.CTLE_type,'CL120d')

7100

qual=ones(1,length(gdc_values));

6916

qual=ones(1,length(gdc_values));

7101

else

6917

else

7102

if isempty(gqual) && isempty(g2qual)

6918

if isempty(gqual) && isempty(g2qual)

7103

qual=ones(length(g_DC_HP_values),length(gdc_values));

6919

qual=ones(length(g_DC_HP_values),length(gdc_values));

7104

else

6920

else

7105

qual=zeros(length(g_DC_HP_values),length(gdc_values));

6921

qual=zeros(length(g_DC_HP_values),length(gdc_values));

7106

6922

7107

%prepare gqual and g2qual

6923

%prepare gqual and g2qual

7108

[g2qual,si]=sort(g2qual,'descend');

6924

[g2qual,si]=sort(g2qual,'descend');

7109

gqual=gqual(si,:);

6925

gqual=gqual(si,:);

7110

tmp=g2qual;

6926

tmp=g2qual;

7111

g2qual=zeros(length(tmp),2);

6927

g2qual=zeros(length(tmp),2);

7112

for kk=1:length(tmp)

6928

for kk=1:length(tmp)

7113

if kk==1

6929

if kk==1

7114

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

6930

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

7115

else

6931

else

7116

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

6932

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

7117

end

6933

end

7118

gqual(kk,:)=sort(gqual(kk,:),'descend');

6934

gqual(kk,:)=sort(gqual(kk,:),'descend');

7119

end

6935

end

7120

6936

7121

%Qual Construction

6937

%Qual Construction

7122

for jj=1:length(g_DC_HP_values)

6938

for jj=1:length(g_DC_HP_values)

7123

for ii=1:length(gdc_values)

6939

for ii=1:length(gdc_values)

7124

for kk=1:size(gqual,1)

6940

for kk=1:size(gqual,1)

7125

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

6941

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

7126

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

6942

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

7127

qual(jj,ii)=1;

6943

qual(jj,ii)=1;

7128

break;

6944

break;

7129

end

6945

end

7130

end

6946

end

7131

end

6947

end

7132

end

6948

end

7133

end

6949

end

7134

end

6950

end

7135

end

6951

end

7136

6952

7137

progress_interval=0.025;

6953

progress_interval=0.025;

7138

if do_C2M

6954

if do_C2M

7139

loop_count=[1 2];

6955

loop_count=[1 2];

7140

T_O=floor((param.T_O/1000)*param.samples_per_ui);

6956

T_O=floor((param.T_O/1000)*param.samples_per_ui);

7141

T_O=max(0,T_O);

6957

T_O=max(0,T_O);

7142

else

6958

else

7143

loop_count=1;

6959

loop_count=1;

7144

T_O=0;

6960

T_O=0;

7145

end

6961

end

7146

switch param.CTLE_type

6962

switch param.CTLE_type

7147

case 'CL93'

6963

case 'CL93'

7148

lf_indx=1;

6964

lf_indx=1;

7149

case 'CL120d'

6965

case 'CL120d'

7150

lf_indx=length(g_DC_HP_values);

6966

lf_indx=length(g_DC_HP_values);

7151

case 'CL120e'

6967

case 'CL120e'

7152

lf_indx=1;

6968

lf_indx=1;

7153

end

6969

end

7154

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

6970

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

7155

if OP.Optimize_loop_speed_up == 1

6971

if OP.Optimize_loop_speed_up == 1

7156

OP.BinSize = 1e-4;

6972

OP.BinSize = 1e-4;

7157

OP.impulse_response_truncation_threshold = 1e-3;

6973

OP.impulse_response_truncation_threshold = 1e-3;

7158

end

6974

end

7159

6975

7160

%Used to speed up FFE by only performing circshift when necessary

6976

%Used to speed up FFE by only performing circshift when necessary

7161

pulse_struc(1).pulse_ctle_circshift=[];

6977

pulse_ctle_circshift=[];

7162

ctle_response_updated=1;

6978

ctle_response_updated=1;

7163

6979

7164

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

6980

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

7165

calc_exp_phase=0;

6981

calc_exp_phase=0;

7166

6982

7167

%calculate cur index and pre/post indices outside of the loop

6983

%calculate cur index and pre/post indices outside of the loop

7168

cur_start=cur;

6984

cur_start=cur;

7169

precursor_indices=[];

6985

precursor_indices=[];

7170

postcursor_indices=[];

6986

postcursor_indices=[];

7171

auto_count_trigger=0;

6987

auto_count_trigger=0;

7172

for kv=1:num_taps

6988

for kv=1:num_taps

7173

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

6989

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

7174

%precursor values fill the beginning of the vector. Any empty precursor means

6990

%precursor values fill the beginning of the vector. Any empty precursor means

7175

%cursor position must be subtracted by 1

6991

%cursor position must be subtracted by 1

7176

if kv<cur_start

6992

if kv<cur_start

7177

cur=cur-1;

6993

cur=cur-1;

7178

end

6994

end

7179

else

6995

else

7180

%non empty value: add to precursor or postcursor indices depending on position

6996

%non empty value: add to precursor or postcursor indices depending on position

7181

%in the vector

6997

%in the vector

7182

if kv<cur_start

6998

if kv<cur_start

7183

auto_count_trigger=1;

6999

auto_count_trigger=1;

7184

precursor_indices=[precursor_indices kv];

7000

precursor_indices=[precursor_indices kv];

7185

else

7001

else

7186

auto_count_trigger=0;

7002

auto_count_trigger=0;

7187

postcursor_indices=[postcursor_indices kv];

7003

postcursor_indices=[postcursor_indices kv];

7188

end

7004

end

7189

end

7005

end

7190

end

7006

end

7191

if ~isempty(postcursor_indices)

7007

if ~isempty(postcursor_indices)

7192

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

7008

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

7193

end

7009

end

7194

7010

7195

%Calculate the full grid matrix of all txffe combinations

7011

%Calculate the full grid matrix of all txffe combinations

7196

if isempty(txffe_cell)

7012

if isempty(txffe_cell)

7197

TXFFE_grid=0;

7013

TXFFE_grid=0;

7198

FULL_tx_index_vector=1;

7014

FULL_tx_index_vector=1;

7199

else

7015

else

7200

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

7016

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

7201

%Also calculate the full grid matrix for the index used in each txffe combination

7017

%Also calculate the full grid matrix for the index used in each txffe combination

7202

%(the index is used in the LOCAL SEARCH block)

7018

%(the index is used in the LOCAL SEARCH block)

7203

for k=1:num_taps

7019

for k=1:num_taps

7204

txffe_index_cell{k}=1:txffe_lengths(k);

7020

txffe_index_cell{k}=1:txffe_lengths(k);

7205

end

7021

end

7206

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

7022

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

7207

end

7023

end

7208

7024

7209

%pre-calculate cursor to save time

7025

%pre-calculate cursor to save time

7210

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

7026

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

7211

7027

7212

%pre-calculate full txffe for each iteration to save time

7028

%pre-calculate full txffe for each iteration to save time

7213

precursor_matrix=TXFFE_grid(:,precursor_indices);

7029

precursor_matrix=TXFFE_grid(:,precursor_indices);

7214

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7030

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7215

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7031

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7216

7032

7217

if OP.TDMODE

7033

if OP.TDMODE

7218

uneq_field='uneq_pulse_response';

7034

uneq_field='uneq_pulse_response';

7219

ctle_field='ctle_pulse_response';

7035

ctle_field='ctle_pulse_response';

7220

else

7036

else

7221

uneq_field='uneq_imp_response';

7037

uneq_field='uneq_imp_response';

7222

ctle_field='ctle_imp_response';

7038

ctle_field='ctle_imp_response';

7223

end

7039

end

7224

7040

7225

%Speed up search for max(sbr)

7041

%Speed up search for max(sbr)

7226

if OP.TDMODE

7042

if OP.TDMODE

7227

[~,init_max]=max(chdata(1).uneq_pulse_response);

7043

[~,init_max]=max(chdata(1).uneq_pulse_response);

7228

else

7044

else

7229

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7045

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7230

end

7046

end

7231

UI_max_window=20;

7047

UI_max_window=20;

7232

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7048

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7233

if start_max_idx<1

7049

if start_max_idx<1

7234

start_max_idx=1;

7050

start_max_idx=1;

7235

end

7051

end

7236

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7052

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7237

if end_max_idx>length(chdata(1).(uneq_field))

7053

if end_max_idx>length(chdata(1).(uneq_field))

7238

end_max_idx=length(chdata(1).(uneq_field));

7054

end_max_idx=length(chdata(1).(uneq_field));

7239

end

7055

end

7240

7056

7241

itick_skips=0;

7057

itick_skips=0;

7242

itick_cases=0;

7058

itick_cases=0;

7243

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7059

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7244

for i=loop_count

7060

for i=loop_count

7245

7061

7246

for Gffe_index=1:length(Gffe_values)

7062

for Gffe_index=1:length(Gffe_values)

7247

param.current_ffegain=Gffe_values(Gffe_index);

7063

param.current_ffegain=Gffe_values(Gffe_index);

7248

for ctle_index=1:length(gdc_values)

7064

for ctle_index=1:length(gdc_values)

7249

g_dc = gdc_values(ctle_index);

7065

g_dc = gdc_values(ctle_index);

7250

kacdc = 10^(g_dc/20);

7066

kacdc = 10^(g_dc/20);

7251

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7067

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7252

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7068

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7253

CTLE_fz = param.CTLE_fz(ctle_index);

7069

CTLE_fz = param.CTLE_fz(ctle_index);

7254

switch param.CTLE_type

7070

switch param.CTLE_type

7255

case 'CL93'

7071

case 'CL93'

7256

%

7072

%

7257

case 'CL120d'

7073

case 'CL120d'

7258

%

7074

%

7259

case 'CL120e'

7075

case 'CL120e'

7260

HP_Z = param.f_HP_Z(ctle_index);

7076

HP_Z = param.f_HP_Z(ctle_index);

7261

HP_P = param.f_HP_P(ctle_index);

7077

HP_P = param.f_HP_P(ctle_index);

7262

end

7078

end

7263

%% HF Boost

7079

%% HF Boost

7264

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7080

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7265

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7081

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7266

%% Mid Frequency Boost

7082

%% Mid Frequency Boost

7267

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7083

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7268

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7084

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7269

for g_LP_index=1:lf_indx

7085

for g_LP_index=1:lf_indx

7270

7086

7271

%GDC Qual Check

7087

%GDC Qual Check

7272

if qual(g_LP_index,ctle_index)==0

7088

if qual(g_LP_index,ctle_index)==0

7273

pxi=pxi+num_txffe_runs;

7089

pxi=pxi+num_txffe_runs;

7274

continue;

7090

continue;

7275

end

7091

end

7276

7092

7277

switch param.CTLE_type

7093

switch param.CTLE_type

7278

case 'CL93'

7094

case 'CL93'

7279

H_low=1;

7095

H_low=1;

7280

kacde_DC_low=1;

7096

kacde_DC_low=1;

7281

case 'CL120d'

7097

case 'CL120d'

7282

g_DC_low = g_DC_HP_values(g_LP_index);

7098

g_DC_low = g_DC_HP_values(g_LP_index);

7283

f_HP=param.f_HP(g_LP_index);

7099

f_HP=param.f_HP(g_LP_index);

7284

kacde_DC_low = 10^(g_DC_low/20);

7100

kacde_DC_low = 10^(g_DC_low/20);

7285

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7101

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7286

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7102

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7287

case 'CL120e' % z1 has been adusted on read in

7103

case 'CL120e' % z1 has been adusted on read in

7288

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7104

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7289

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7105

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7290

end

7106

end

7291

H_ctf=H_low.*ctle_gain;

7107

H_ctf=H_low.*ctle_gain;

7292

switch upper(OP.FFE_OPT_METHOD)

7108

switch upper(OP.FFE_OPT_METHOD)

7293

case 'WIENER-HOPF'

7109

case 'WIENER-HOPF'

7294

%% Bill Kirkland

7110

%% Bill Kirkland

7295

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7111

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7296

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7112

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7297

% use Fourier Transform pair for correlation as we have to

7113

% use Fourier Transform pair for correlation as we have to

7298

% take ifft of H_r anyways.

7114

% take ifft of H_r anyways.

7299

% onesided and two sided responses - tricky, tricky, tricky

7115

% onesided and two sided responses - tricky, tricky, tricky

7300

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7116

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7301

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7117

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7302

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7118

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7303

7119

7304

if OP.Do_White_Noise

7120

if OP.Do_White_Noise

7305

Noise_XC = Noise_XC(1);

7121

Noise_XC = Noise_XC(1);

7306

end

7122

end

7307

otherwise

7123

otherwise

7308

Noise_XC=[];

7124

Noise_XC=[];

7309

end

7125

end

7310

7126

7311

7127

7312

7128

7313

if OP.INCLUDE_CTLE==1

7129

if OP.INCLUDE_CTLE==1

7314

for k=1:param.num_s4p_files

7130

for k=1:param.num_s4p_files

7315

ir_peak = max(abs(chdata(k).(uneq_field)));

7131

ir_peak = max(abs(chdata(k).(uneq_field)));

7316

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7132

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7317

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7133

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7318

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7134

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7319

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7135

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7320

switch param.CTLE_type

7136

switch param.CTLE_type

7321

case 'CL93'

7137

case 'CL93'

7322

case 'CL120d'

7138

case 'CL120d'

7323

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7139

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7324

case 'CL120e' % z1 has been adusted on read in

7140

case 'CL120e' % z1 has been adusted on read in

7325

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7141

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7326

end

7142

end

7327

end

7143

end

7328

%set the flag to show ctle response was updated

7144

%set the flag to show ctle response was updated

7329

ctle_response_updated=1;

7145

ctle_response_updated=1;

7330

else

7146

else

7331

for k=1:param.num_s4p_files

7147

for k=1:param.num_s4p_files

7332

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7148

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7333

end

7149

end

7334

end

7150

end

7335

for k=1:param.num_s4p_files

7151

for k=1:param.num_s4p_files

7336

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7152

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7337

end

7153

end

7338

%% Equation 93A-22 %%

7154

%% Equation 93A-22 %%

7339

% figure(1000)

7155

% figure(1000)

7340

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7156

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7341

% hold on

7157

% hold on

7342

if OP.RX_CALIBRATION

7158

if OP.RX_CALIBRATION

7343

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7159

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7344

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7160

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7345

switch param.CTLE_type

7161

switch param.CTLE_type

7346

case 'CL93'

7162

case 'CL93'

7347

H_low2=1;

7163

H_low2=1;

7348

case 'CL120d'

7164

case 'CL120d'

7349

g_DC_low = g_DC_HP_values(g_LP_index);

7165

g_DC_low = g_DC_HP_values(g_LP_index);

7350

f_HP=param.f_HP(g_LP_index);

7166

f_HP=param.f_HP(g_LP_index);

7351

kacde_DC_low = 10^(g_DC_low/20);

7167

kacde_DC_low = 10^(g_DC_low/20);

7352

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7168

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7353

case 'CL120e' % z1 has been adusted on read in

7169

case 'CL120e' % z1 has been adusted on read in

7354

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7170

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7355

end

7171

end

7356

H_ctf2=H_low2.*ctle_gain2;

7172

H_ctf2=H_low2.*ctle_gain2;

7357

end

7173

end

7358

% RIM 11-30-2020 moved to a subfunction

7174

% RIM 11-30-2020 moved to a subfunction

7359

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7175

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7360

if OP.RX_CALIBRATION

7176

if OP.RX_CALIBRATION

7361

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7177

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7362

sigma_NEXT=sqrt(param.eta_0*sum( abs(H_sy(2:end).^2 .* H_r(2:end).*2 .* H_ctf(2:end).^2 ) .* diff(chdata(1).faxis)/1e9));% changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7178

sigma_NEXT=sqrt(param.eta_0*sum( abs(H_sy(2:end).^2 .* H_r(2:end).*2 .* H_ctf(2:end).^2 ) .* diff(chdata(1).faxis)/1e9));% changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7363

else

7179

else

7364

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7180

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7365

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7366

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7181

sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7367

sigma_ne=0;

7182

sigma_ne=0;

7368

end

7183

end

7369

7184

7370

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7185

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7371

pxi=pxi+num_txffe_runs;

7186

pxi=pxi+num_txffe_runs;

7372

continue; % change per 0.3k draft 2.3

7187

continue; % change per 0.3k draft 2.3

7373

end

7188

end

7374

%%

7189

%%

7375

PSD_results=[];

7190

PSD_results=[];

7376

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7191

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7377

OP.WO_TXFFE=1;

7192

OP.WO_TXFFE=1;

7378

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7193

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7379

end

7194

end

7380

%TXFFE Loop

7195

%TXFFE Loop

7381

%Originally this was a separate for loop for each tap, but it is now all contained in the TXFFE_grid matrix to use a single modular loop

7196

%Originally this was a separate for loop for each tap, but it is now all contained in the TXFFE_grid matrix to use a single modular loop

7382

for TK=1:size(TXFFE_grid,1)

7197

for TK=1:size(TXFFE_grid,1)

7383

7198

7384

pxi=pxi+1;

7199

pxi=pxi+1;

7385

progress = pxi/runs;

7200

progress = pxi/runs;

7386

if OP.DISPLAY_WINDOW

7201

if OP.DISPLAY_WINDOW

7387

if ~mod(pxi,floor(runs*progress_interval))

7202

if ~mod(pxi,floor(runs*progress_interval))

7388

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7203

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7389

end

7204

end

7390

else

7205

else

7391

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7206

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7392

end

7207

end

7393

7208

7394

%get the cursor for this iteration

7209

%get the cursor for this iteration

7395

txffe_cur=txffe_cursor_vector(TK);

7210

txffe_cur=txffe_cursor_vector(TK);

7396

7211

7397

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7212

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7398

if txffe_cur<param.tx_ffe_c0_min

7213

if txffe_cur<param.tx_ffe_c0_min

7399

continue;

7214

continue;

7400

end

7215

end

7401

old_loops=old_loops+1;

7216

old_loops=old_loops+1;

7402

7217

7403

%get the index used for each tap on this iteration

7218

%get the index used for each tap on this iteration

7404

%this is needed for the LOCAL SEARCH block

7219

%this is needed for the LOCAL SEARCH block

7405

tx_index_vector=FULL_tx_index_vector(TK,:);

7220

tx_index_vector=FULL_tx_index_vector(TK,:);

7406

7221

7407

%Original LOCAL SEARCH Block:

7222

%Original LOCAL SEARCH Block:

7408

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7223

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7409

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7224

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7410

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7225

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7411

% % skip configurations more than

7226

% % skip configurations more than

7412

% % 2 steps away from current "best" point on any grid direction

7227

% % 2 steps away from current "best" point on any grid direction

7413

% % Matt Brown 11/19/2021 for cp2 and cp3

7228

% % Matt Brown 11/19/2021 for cp2 and cp3

7414

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7229

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7415

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7230

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7416

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7231

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7417

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7232

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7418

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7233

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7419

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7234

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7420

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7235

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7421

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7236

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7422

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7237

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7423

%

7238

%

7424

% continue;

7239

% continue;

7425

% end

7240

% end

7426

7241

7427

%Modular LOCAL_SEARCH block:

7242

%Modular LOCAL_SEARCH block:

7428

% speedup "local search" heuristic - Adee Ran 03-17-2020

7243

% speedup "local search" heuristic - Adee Ran 03-17-2020

7429

% skip configurations more than 2 steps away from current "best" point on any grid direction

7244

% skip configurations more than 2 steps away from current "best" point on any grid direction

7430

skip_it=0;

7245

skip_it=0;

7431

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7246

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7432

%instead of looping across all taps, only loop across

7247

%instead of looping across all taps, only loop across

7433

%those with length>1 (txffe_sweep_indices).

7248

%those with length>1 (txffe_sweep_indices).

7434

%It saves time since this block is encountered so often

7249

%It saves time since this block is encountered so often

7435

for kj=1:num_txffe_sweep_indices

7250

for kj=1:num_txffe_sweep_indices

7436

kv=txffe_sweep_indices(kj);

7251

kv=txffe_sweep_indices(kj);

7437

if kv==1

7252

if kv==1

7438

previous_loop_val=g_LP_index;

7253

previous_loop_val=g_LP_index;

7439

else

7254

else

7440

previous_loop_val=tx_index_vector(kv-1);

7255

previous_loop_val=tx_index_vector(kv-1);

7441

end

7256

end

7442

if previous_loop_val>1

7257

if previous_loop_val>1

7443

best_index_this_tap=best_txffe_index(kv);

7258

best_index_this_tap=best_txffe_index(kv);

7444

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7259

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7445

skip_it=1;

7260

skip_it=1;

7446

break;

7261

break;

7447

end

7262

end

7448

end

7263

end

7449

end

7264

end

7450

7265

7451

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7266

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7452

skip_it=1;

7267

skip_it=1;

7453

end

7268

end

7454

end

7269

end

7455

if skip_it

7270

if skip_it

7456

continue;

7271

continue;

7457

end

7272

end

7458

%End Modular LOCAL SEARCH block

7273

%End Modular LOCAL SEARCH block

7459

7274

7460

new_loops=new_loops+1;

7275

new_loops=new_loops+1;

7461

7276

7462

%fetch txffe for this iteration

7277

%fetch txffe for this iteration

7463

txffe=txffe_matrix(TK,:);

7278

txffe=txffe_matrix(TK,:);

7464

7279

7465

%The phase shift exponentials used in get_xtlk_noise are independent of

7280

%The phase shift exponentials used in get_xtlk_noise are independent of

7466

%everything except number of taps and cursor position

7281

%everything except number of taps and cursor position

7467

%So it can be calculated 1 time here to avoid thousands of re-calcs

7282

%So it can be calculated 1 time here to avoid thousands of re-calcs

7468

if ~calc_exp_phase

7283

if ~calc_exp_phase

7469

calc_exp_phase=1;

7284

calc_exp_phase=1;

7470

for k=1:length(txffe)

7285

for k=1:length(txffe)

7471

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7286

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7472

end

7287

end

7473

if OP.RxFFE

7288

if OP.RxFFE

7474

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7289

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7475

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7290

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7476

end

7291

end

7477

phase_memory=[phase_memory phase_memoryRXFFE];

7292

phase_memory=[phase_memory phase_memoryRXFFE];

7478

end

7293

end

7479

end

7294

end

7480

7295

7481

%% Unequalized Pulse Reponse & circshift for FFE

7296

%% Unequalized Pulse Reponse & circshift for FFE

7482

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7297

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7483

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7298

%in the pre-shifted matrix

7484

if ctle_response_updated

7299

if ctle_response_updated

7485

ctle_response_updated=0;

7300

ctle_response_updated=0;

7486

num_pre=cur-1;

7301

num_pre=cur-1;

7487

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7302

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7488

%Calculating here reduces number of convolutions by thousands

7303

%Calculating here reduces number of convolutions by thousands

7489

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7490

ich=1;

7491

else

7492

ich=param.num_s4p_files;

7493

end

7494

for ii=1:ich

7495

if OP.TDMODE

7304

if OP.TDMODE

7496

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7305

pulse_ctle=chdata(1).(ctle_field)(:);

7497

else

7306

else

7498

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7307

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7499

%"conv2" is faster than filter. Just need to chop off extra points at the end

7308

%"conv2" is faster than filter. Just need to chop off extra points at the end

7500

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7309

pulse_ctle=conv2(chdata(1).(ctle_field)(:),ones(param.samples_per_ui, 1));

7501

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7310

pulse_ctle=pulse_ctle(1:end-param.samples_per_ui+1);

7502

end

7311

end

7503

for k=1:length(txffe)

7312

for k=1:length(txffe)

7504

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7313

pulse_ctle_circshift(:,k)=circshift(pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7505

end

7506

end

7314

end

7507

end

7315

end

7508

7316

7509

%% Apply TXFFE to pre-shifted pulse response

7317

%% Apply TXFFE to pre-shifted pulse response

7510

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7318

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7511

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7319

sbr=FFE_Fast(txffe,pulse_ctle_circshift);

7512

sbr_from_txffe=sbr;

7320

sbr_from_txffe=sbr;

7513

for ii=1:ich

7514

% this is sbr when ii=1; to be used in get_PSDs

7321

sbr1=sbr;

7515

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7516

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7517

else

7518

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7519

end

7520

end

+7322

7521

7323

7522

%% Find Sample Location

7324

%% Find Sample Location

7523

% If RXFFE is included, the sample location will be found again below

7325

% If RXFFE is included, the sample location will be found again below

7524

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7326

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7525

if param.ts_anchor==0

7327

if param.ts_anchor==0

7526

%keep MM

7328

%keep MM

7527

elseif param.ts_anchor==1

7329

elseif param.ts_anchor==1

7528

%peak sample

7330

%peak sample

7529

cursor_i=sbr_peak_i;

7331

cursor_i=sbr_peak_i;

7530

no_zero_crossing=0;

7332

no_zero_crossing=0;

7531

elseif param.ts_anchor==2

7333

elseif param.ts_anchor==2

7532

%max DV

7334

%max DV

7533

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7335

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7534

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7336

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7535

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7337

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7536

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7338

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7537

no_zero_crossing=0;

7339

no_zero_crossing=0;

7538

else

7340

else

7539

error('ts_anchor parameter must be 0, 1, or 2');

7341

error('ts_anchor parameter must be 0, 1, or 2');

7540

end

7342

end

7541

if no_zero_crossing

7343

if no_zero_crossing

7542

continue;

7344

continue;

7543

end

7345

end

7544

raw_cursor_i=cursor_i;

7346

raw_cursor_i=cursor_i;

7545

7347

7546

%%%%%%%%%%

7348

%%%%%%%%%%

7547

%%%%%%%%%%

7349

%%%%%%%%%%

7548

%%%%%%%%%%

7350

%%%%%%%%%%

7549

%NEW ITICK LOOP (not indenting everything yet)

7351

%NEW ITICK LOOP (not indenting everything yet)

7550

[~,si]=sort(abs(full_sample_range));

7352

[~,si]=sort(abs(full_sample_range));

7551

best_positive_itick_FOM=-inf;

7353

best_positive_itick_FOM=-inf;

7552

best_negative_itick_FOM=-inf;

7354

best_negative_itick_FOM=-inf;

7553

best_positive_itick_in_loop=[];

7355

best_positive_itick_in_loop=[];

7554

best_negative_itick_in_loop=[];

7356

best_negative_itick_in_loop=[];

7555

best_itick_FOM=-inf;

7357

best_itick_FOM=-inf;

7556

best_itick_in_cluster=[];

7358

best_itick_in_cluster=[];

7557

best_cluster=[];

7359

best_cluster=[];

7558

7360

7559

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7361

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7560

%middle_search: start from itick=0 and work outwards in negative and positive direction. stop searching when FOM starts to go down (using LOCAL SEARCH)

7362

%middle_search: start from itick=0 and work outwards in negative and positive direction. stop searching when FOM starts to go down (using LOCAL SEARCH)

7561

% Commit request4p4_7 healey_3dj_COM_01_240416

7562

%box_search=0;

7563

%middle_search=1;% should set 0 so all Ts sample points are used

7564

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7565

case 'full-sweep'

7566

box_search=0;

7567

middle_search=0;

7568

case 'middle'

7569

box_search=0;

7363

box_search=0;

7570

middle_search=1;

7364

middle_search=1;

7571

otherwise

7365

7572

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7573

end

7574

if box_search

7366

if box_search

7575

box_size=5;

7367

box_size=5;

7576

box_mid=floor(box_size/2);

7368

box_mid=floor(box_size/2);

7577

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7369

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7578

CL=length(cluster);

7370

CL=length(cluster);

7579

loop_range=1:CL+box_mid*2;

7371

loop_range=1:CL+box_mid*2;

7580

elseif middle_search

7372

elseif middle_search

7581

loop_range=si;

7373

loop_range=si;

7582

else

7374

else

7583

loop_range=1:length(full_sample_range);

7375

loop_range=1:length(full_sample_range);

7584

end

7376

end

7585

7377

7586

for itickn=loop_range

7378

for itickn=loop_range

7587

if box_search

7379

if box_search

7588

if itickn<=CL

7380

if itickn<=CL

7589

itick=cluster(itickn);

7381

itick=cluster(itickn);

7590

else

7382

else

7591

if itickn==CL+1

7383

if itickn==CL+1

7592

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7384

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7593

end

7385

end

7594

if isempty(best_cluster)

7386

if isempty(best_cluster)

7595

continue;

7387

continue;

7596

end

7388

end

7597

itick=best_cluster(itickn-CL);

7389

itick=best_cluster(itickn-CL);

7598

end

7390

end

7599

else

7391

else

7600

itick=full_sample_range(itickn);

7392

itick=full_sample_range(itickn);

7601

end

7393

end

7602

7394

7603

itick_cases=itick_cases+1;

7395

itick_cases=itick_cases+1;

7604

7396

7605

sbr=sbr_from_txffe;

7397

sbr=sbr_from_txffe;

7606

cursor_i = raw_cursor_i+itick;

7398

cursor_i = raw_cursor_i+itick;

7607

7399

7608

%Local Search for +/- itick sweep

7400

%Local Search for +/- itick sweep

7609

if middle_search && param.LOCAL_SEARCH>0

7401

if middle_search && param.LOCAL_SEARCH>0

7610

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7402

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7611

itick_skips=itick_skips+1;

7403

itick_skips=itick_skips+1;

7612

continue;

7404

continue;

7613

end

7405

end

7614

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7406

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7615

itick_skips=itick_skips+1;

7407

itick_skips=itick_skips+1;

7616

continue;

7408

continue;

7617

end

7409

end

7618

end

7410

end

7619

7411

7620

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7412

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7621

if min_number_of_UI_in_response < triple_transit_time

7413

if min_number_of_UI_in_response < triple_transit_time

7622

min_number_of_UI_in_response = triple_transit_time;

7414

min_number_of_UI_in_response = triple_transit_time;

7623

end

7415

end

7624

7416

7625

cursor = sbr(cursor_i);

7417

cursor = sbr(cursor_i);

7626

7418

7627

%% RXFFE

7419

%% RXFFE

7628

if OP.RxFFE

7420

if OP.RxFFE

7629

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7421

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7630

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7422

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7631

%if isrow(sbr), sbr=sbr';end

7423

%if isrow(sbr), sbr=sbr';end

7632

7424

7633

%AJG: do not return sbr here (run time improvement)

7425

%AJG: do not return sbr here (run time improvement)

7634

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7426

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7635

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7427

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7636

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7428

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7637

% sbr at this point include the current setting

7429

% sbr at this point include the current setting

7638

% under consideration of txffe h21 ctf and fr

7430

% under consideration of txffe h21 ctf and fr

7639

switch upper(OP.FFE_OPT_METHOD)

7431

switch upper(OP.FFE_OPT_METHOD)

7640

case 'MMSE'

7432

case 'MMSE'

7641

OP.WO_TXFFE=0;

7433

OP.WO_TXFFE=0;

7642

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7434

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7643

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn;

7435

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn;

7644

if 0 % for debug

7436

if 0 % for debug

7645

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7437

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7646

hold on

7438

hold on

7647

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7439

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7648

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7440

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7649

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7441

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7650

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7442

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7651

xlim([0 0.5])

7443

xlim([0 0.5])

7652

% ylim([-190 -160])

7444

% ylim([-190 -160])

7653

set(gcf,'defaulttextinterpreter','none')

7445

set(gcf,'defaulttextinterpreter','none')

7654

xlabel('Normalized Frequency')

7446

xlabel('Normalized Frequency')

7655

ylabel('PSD dBm/Hz')

7447

ylabel('PSD dBm/Hz')

7656

hold on

7448

hold on

7657

grid on

7449

grid on

7658

legend show

7450

legend show

7659

title('PSD')

7451

title('PSD')

7660

end

7452

end

7661

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7453

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7662

% floating_tap_locations=MMSE_results.MLSE_results;

7454

% floating_tap_locations=MMSE_results.MLSE_results;

7663

C=MMSE_results.C;

7455

C=MMSE_results.C;

7664

FOM=MMSE_results.FOM;

7456

FOM=MMSE_results.FOM;

7665

floating_tap_locations=MMSE_results.floating_tap_locations;

7457

floating_tap_locations=MMSE_results.floating_tap_locations;

7666

otherwise

7458

otherwise

7667

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7459

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7668

end

7460

end

7669

%Now there is a stand alone function for determining if RXFFE taps are illegal

7461

%Now there is a stand alone function for determining if RXFFE taps are illegal

7670

%This is because the "force" function will also do a legality check when "backoff" is enabled

7462

%This is because the "force" function will also do a legality check when "backoff" is enabled

7671

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7463

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7672

if RXFFE_Illegal(C,param)

7464

if RXFFE_Illegal(C,param)

7673

continue;

7465

continue;

7674

end

7466

end

7675

end

7467

end

7676

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7468

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7677

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7469

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7678

if isrow(sbr), sbr=sbr';end

7470

if isrow(sbr), sbr=sbr';end

7679

7471

7680

%% second guess at cursor location (t_s) - based on approximate zero crossing

7472

%% second guess at cursor location (t_s) - based on approximate zero crossing

7681

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7473

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7682

%UPDATE: NOT RESAMPLING AFTER RXFFE

7474

%UPDATE: NOT RESAMPLING AFTER RXFFE

7683

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7475

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7684

% if no_zero_crossing

7476

% if no_zero_crossing

7685

% continue;

7477

% continue;

7686

% end

7478

% end

7687

7479

7688

cursor = sbr(cursor_i);

7480

cursor = sbr(cursor_i);

7689

end

7481

end

7690

A_p=sbr(sbr_peak_i);

7482

A_p=sbr(sbr_peak_i);

7691

%% 93A.1.6 step c defines A_s %%

7483

%% 93A.1.6 step c defines A_s %%

7692

A_s = param.R_LM*cursor/(param.levels-1);

7484

A_s = param.R_LM*cursor/(param.levels-1);

7693

if isempty(delta_sbr)

7485

if isempty(delta_sbr)

7694

delta_sbr = sbr;

7486

delta_sbr = sbr;

7695

end

7487

end

7696

sbr=sbr(:);

7488

sbr=sbr(:);

7697

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7489

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7698

7490

7699

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7491

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7700

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7492

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7701

t=((cursor_i+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:length(sbr))-(cursor_i+param.samples_per_ui*(param.ndfe+1)))*...

7493

t=((cursor_i+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:length(sbr))-(cursor_i+param.samples_per_ui*(param.ndfe+1)))*...

7702

param.ui/param.samples_per_ui;

7494

param.ui/param.samples_per_ui;

7703

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7495

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7704

precursors = precursors(end:-1:1);

7496

precursors = precursors(end:-1:1);

7705

7497

7706

% % Error message if the sbr is not long enough for the specified range of Nb

7498

% % Error message if the sbr is not long enough for the specified range of Nb

7707

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7499

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7708

% close(hwaitbar);

7500

% close(hwaitbar);

7709

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7501

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7710

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7502

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7711

% end

7503

% end

7712

7504

7713

7505

7714

7506

7715

%% skip this case if FOM has no chance of beating old FOM

7507

%% skip this case if FOM has no chance of beating old FOM

7716

%this is also done below but with excess_dfe_cursors included.

7508

%this is also done below but with excess_dfe_cursors included.

7717

%excess_dfe_cursors requires the floating DFE computation which is

7509

%excess_dfe_cursors requires the floating DFE computation which is

7718

%time consuming, so checking here can have significant run time improvements

7510

%time consuming, so checking here can have significant run time improvements

7719

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7511

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7720

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7512

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7721

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7513

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7722

continue

7514

continue

7723

end

7515

end

7724

end

7516

end

7725

7517

7726

%% Equation 93A-27, when 1<=n<=N_b

7518

%% Equation 93A-27, when 1<=n<=N_b

7727

%required length = cursor + all DFE UI + 1 additional UI

7519

%required length = cursor + all DFE UI + 1 additional UI

7728

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7520

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7729

if length(sbr)<sbr_required_length

7521

if length(sbr)<sbr_required_length

7730

sbr(end+1:sbr_required_length)=0;

7522

sbr(end+1:sbr_required_length)=0;

7731

end

7523

end

7732

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7524

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7733

if param.dfe_delta ~= 0

7525

if param.dfe_delta ~= 0

7734

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7526

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7735

7527

7736

else

7528

else

7737

dfecursors_q=dfecursors;

7529

dfecursors_q=dfecursors;

7738

end

7530

end

7739

if param.Floating_DFE

7531

if param.Floating_DFE

7740

%% floating taps

7532

%% floating taps

7741

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7533

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7742

7534

7743

[floating_tap_locations, floating_tap_coef, hisi, bmax]= floatingDFE( postcurors ,param.ndfe_passed,param.N_bf,param.N_bg,param.N_bmax, param.bmaxg, sbr(cursor_i), param.dfe_delta );

7535

[floating_tap_locations, floating_tap_coef, hisi, bmax]= floatingDFE( postcurors ,param.ndfe_passed,param.N_bf,param.N_bg,param.N_bmax, param.bmaxg, sbr(cursor_i), param.dfe_delta );

7744

7536

7745

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7537

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7746

param.use_bmax=newbmax;

7538

param.use_bmax=newbmax;

7747

%AJG021820

7539

%AJG021820

7748

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7540

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7749

else

7541

else

7750

param.use_bmax=param.bmax;

7542

param.use_bmax=param.bmax;

7751

%AJG021820

7543

%AJG021820

7752

param.use_bmin=param.bmin;

7544

param.use_bmin=param.bmin;

7753

end

7545

end

7754

7546

7755

%AJG021820

7547

%AJG021820

7756

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7548

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7757

if do_C2M

7549

if do_C2M

7758

dfecursors_windowed=sbr(cursor_i-T_O+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe)-T_O);

7550

dfecursors_windowed=sbr(cursor_i-T_O+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe)-T_O);

7759

% readjust SBR

7551

% readjust SBR

7760

if 0

7552

if 0

7761

%PR_DFE_center not currently used, so this is in "if 0" statement

7553

%PR_DFE_center not currently used, so this is in "if 0" statement

7762

PR_DFE_center=sbr;

7554

PR_DFE_center=sbr;

7763

for n=1:param.ndfe

7555

for n=1:param.ndfe

7764

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7556

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7765

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7557

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7766

% dper=sbr(i_sample)- actual_dfecursors(n);

7558

% dper=sbr(i_sample)- actual_dfecursors(n);

7767

% PR_DFE_center(i_sample)=dper;

7559

% PR_DFE_center(i_sample)=dper;

7768

% end

7560

% end

7769

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7561

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7770

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7562

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7771

end

7563

end

7772

end

7564

end

7773

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7565

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7774

else

7566

else

7775

excess_dfe_cursors=dfecursors-actual_dfecursors;

7567

excess_dfe_cursors=dfecursors-actual_dfecursors;

7776

end

7568

end

7777

dfetaps=actual_dfecursors/sbr(cursor_i);

7569

dfetaps=actual_dfecursors/sbr(cursor_i);

7778

7570

7779

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7571

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7780

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7572

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7781

if tail_RSS ~= 0

7573

if tail_RSS ~= 0

7782

if tail_RSS >= param.B_float_RSS_MAX

7574

if tail_RSS >= param.B_float_RSS_MAX

7783

param.use_bmax(param.N_tail_start:end)= ...

7575

param.use_bmax(param.N_tail_start:end)= ...

7784

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7576

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7785

%AJG021820

7577

%AJG021820

7786

param.use_bmin(param.N_tail_start:end)= ...

7578

param.use_bmin(param.N_tail_start:end)= ...

7787

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7579

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7788

end

7580

end

7789

end

7581

end

7790

7582

7791

%AJG021820

7583

%AJG021820

7792

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7584

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7793

if do_C2M

7585

if do_C2M

7794

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7586

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7795

else

7587

else

7796

excess_dfe_cursors=dfecursors-actual_dfecursors;

7588

excess_dfe_cursors=dfecursors-actual_dfecursors;

7797

end

7589

end

7798

dfetaps=actual_dfecursors/sbr(cursor_i);

7590

dfetaps=actual_dfecursors/sbr(cursor_i);

7799

7591

7800

else

7592

else

7801

tail_RSS=0;

7593

tail_RSS=0;

7802

end

7594

end

7803

%% Eq. 93A-28 %%

7595

%% Eq. 93A-28 %%

7804

sampling_offset = mod(cursor_i, param.samples_per_ui);

7596

sampling_offset = mod(cursor_i, param.samples_per_ui);

7805

%ensure we can take early sample

7597

%ensure we can take early sample

7806

if sampling_offset<=1

7598

if sampling_offset<=1

7807

sampling_offset=sampling_offset+param.samples_per_ui;

7599

sampling_offset=sampling_offset+param.samples_per_ui;

7808

end

7600

end

7809

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7601

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7810

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7602

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7811

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7603

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7812

else

7604

else

7813

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7605

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7814

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7606

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7815

end

7607

end

7816

% ensure lengths are equal

7608

% ensure lengths are equal

7817

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7609

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7818

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7610

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7819

if ~OP.SNR_TXwC0

7611

if ~OP.SNR_TXwC0

7820

%% Equation 93A-30 %%

7612

%% Equation 93A-30 %%

7821

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7613

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7822

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7614

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7823

else

7615

else

7824

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7616

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7825

end

7617

end

7826

%% Equation 93A-31 %%

7618

%% Equation 93A-31 %%

7827

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7619

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7828

ISI_N=param.sigma_X*norm( far_cursors);

7620

ISI_N=param.sigma_X*norm( far_cursors);

7829

%% break if FOM has no chance of beating old e

7621

%% break if FOM has no chance of beating old e

7830

OP.exe_mode=1;

7622

OP.EXE_MODE=1;

7831

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7623

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7832

switch OP.EXE_MODE

7624

switch OP.EXE_MODE

7833

case 0

7625

case 0

7834

case 1

7626

case 1

7835

if (20*log10(A_s/sigma_ISI) < best_FOM)

7627

if (20*log10(A_s/sigma_ISI) < best_FOM)

7836

continue

7628

continue

7837

end

7629

end

7838

case 2

7630

case 2

7839

if (20*log10(A_s/sigma_ISI) < best_FOM)

7631

if (20*log10(A_s/sigma_ISI) < best_FOM)

7840

break

7632

break

7841

end

7633

end

7842

end

7634

end

7843

end

7635

end

7844

%% Equation 93A-32 %%

7636

%% Equation 93A-32 %%

7845

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7637

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7846

7638

7847

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7639

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7848

if OP.RX_CALIBRATION

7640

if OP.RX_CALIBRATION

7849

sigma_XT=0;

7641

sigma_XT=0;

7850

else

7642

else

7851

if ~OP.RxFFE

7643

if ~OP.RxFFE

+7644

% sigma_FEXT = get_xtlk_noise( 0, 'FEXT', param ,chdata);

7645

% sigma_XT = norm([sigma_NEXT sigma_FEXT]);

7852

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata,phase_memory); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7646

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata,phase_memory); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7853

%% Equation 93A-36 denominator (actually its sqrt)

7647

%% Equation 93A-36 denominator (actually its sqrt)

7854

else % John Ewen: 13/12/20018

7648

else % John Ewen: 13/12/20018

7855

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7856

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata, phase_memory,C); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7649

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata, phase_memory,C); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

+7650

% sigma_FEXT_ffe= get_xtlk_noise( 0, 'FEXT', param, chdata, C );

7651

% if ~OP.RxFFE

7652

% sigma_NEXT_ffe = get_xtlk_noise(0, 'NEXT', param, chdata);

7653

% else

7857

else % use results from get_PSDs RIM 3/28/2024

7654

% sigma_NEXT_ffe = get_xtlk_noise(0, 'NEXT', param, chdata , C);

+7655

% end

7858

sigma_XT=PSD_results.S_xn_rms;

7656

% sigma_XT = norm([sigma_NEXT_ffe sigma_FEXT_ffe])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

7859

end

7860

end

7657

end

7861

end

7658

end

7862

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7659

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7863

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7660

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7864

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7661

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7865

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7662

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7866

f=chdata(1).faxis;

7663

f=chdata(1).faxis;

7867

H_Rx_FFE=zeros(1,length(f));

7664

H_Rx_FFE=zeros(1,length(f));

7868

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7665

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7869

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7666

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7870

if C(ii+param.RxFFE_cmx+1)==0

7667

if C(ii+param.RxFFE_cmx+1)==0

7871

%speed up: skip cases when rxffe=0

7668

%speed up: skip cases when rxffe=0

7872

continue;

7669

continue;

7873

end

7670

end

7874

if ii+1==0

7671

if ii+1==0

7875

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7672

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7876

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7673

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7877

else

7674

else

7878

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7675

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7879

end

7676

end

7880

end

7677

end

7881

sigma_N =sqrt(param.eta_0*sum(H_sy(2:end) .* abs(H_r(2:end) .* H_ctf(2:end) .*H_Rx_FFE(2:end)).^2 .* diff(chdata(1).faxis)/1e9)); % changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7678

sigma_N =sqrt(param.eta_0*sum(H_sy(2:end) .* abs(H_r(2:end) .* H_ctf(2:end) .*H_Rx_FFE(2:end)).^2 .* diff(chdata(1).faxis)/1e9)); % changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7882

end

7679

end

7883

end

7680

end

7884

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7681

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7885

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7886

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7682

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7887

else

7888

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7889

end

7890

if do_C2M

7683

if do_C2M

7891

if param.Noise_Crest_Factor == 0

7684

if param.Noise_Crest_Factor == 0

7892

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7685

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7893

else

7686

else

7894

ber_q=param.Noise_Crest_Factor;

7687

ber_q=param.Noise_Crest_Factor;

7895

end

7688

end

7896

if OP.force_pdf_bin_size

7689

if OP.force_pdf_bin_size

7897

delta_y = OP.BinSize;

7690

delta_y = OP.BinSize;

7898

else

7691

else

7899

delta_y = min(A_s/1000, OP.BinSize);

7692

delta_y = min(A_s/1000, OP.BinSize);

7900

end

7693

end

7901

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7694

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7902

cci_pdf = normal_dist(0, ber_q, delta_y);

7695

cci_pdf = normal_dist(0, ber_q, delta_y);

7903

chdata(1).eq_pulse_response=sbr;

7696

chdata(1).eq_pulse_response=sbr;

7904

tmp_result.t_s= cursor_i;

7697

tmp_result.t_s= cursor_i;

7905

tmp_result.A_s=A_s;

7698

tmp_result.A_s=A_s;

7906

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7699

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7907

if EH_1st <= param.Min_VEO_Test/1000 -.001

7700

if EH_1st <= param.Min_VEO_Test/1000 -.001

7908

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7701

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7909

continue

7702

continue

7910

else

7703

else

7911

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7704

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7912

end

7705

end

7913

Struct_Noise.sigma_N=sigma_N;

7706

Struct_Noise.sigma_N=sigma_N;

7914

Struct_Noise.sigma_TX=sigma_TX;

7707

Struct_Noise.sigma_TX=sigma_TX;

7915

Struct_Noise.cci_pdf=cci_pdf;

7708

Struct_Noise.cci_pdf=cci_pdf;

7916

Struct_Noise.ber_q=ber_q;

7709

Struct_Noise.ber_q=ber_q;

7917

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7710

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7918

[Left_EW,Right_EW,eye_contour,EH_T_C2M,EH_B_C2M]=COM_eye_width(chdata,delta_y,tmp_result,param,OP,Struct_Noise,1);

7711

[Left_EW,Right_EW,eye_contour,EH_T_C2M,EH_B_C2M]=COM_eye_width(chdata,delta_y,tmp_result,param,OP,Struct_Noise,1);

7919

EH=EH_T_C2M-EH_B_C2M;

7712

EH=EH_T_C2M-EH_B_C2M;

7920

N_i=(A_s*2-EH)/2;

7713

N_i=(A_s*2-EH)/2;

7921

if EH <= param.Min_VEO_Test/1000

7714

if EH <= param.Min_VEO_Test/1000

7922

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7715

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7923

continue

7716

continue

7924

else

7717

else

7925

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

7718

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

7926

end

7719

end

7927

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7720

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7928

FOM =20*log10(A_s/N_i);

7721

FOM =20*log10(A_s/N_i);

7929

end

7722

end

7930

else

7723

else

7931

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7724

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7932

FOM = 20*log10(A_s/total_noise_rms);

7725

FOM = 20*log10(A_s/total_noise_rms);

7933

end

7726

end

7934

% if strfind(param.CTLE_type,'CL120e')

7727

% if strfind(param.CTLE_type,'CL120e')

7935

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

7728

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

7936

end

7729

end

7937

if 0 % for loop analysis

7730

if 0 % for loop analysis

7938

result.FOM_array(new_loops)=FOM;

7731

result.FOM_array(new_loops)=FOM;

7939

end

7732

end

7940

7733

7941

if FOM>best_itick_FOM

7734

if FOM>best_itick_FOM

7942

best_itick_FOM=FOM;

7735

best_itick_FOM=FOM;

7943

best_itick_in_cluster=itick;

7736

best_itick_in_cluster=itick;

7944

end

7737

end

7945

7738

7946

if itick>=0 && FOM>best_positive_itick_FOM

7739

if itick>=0 && FOM>best_positive_itick_FOM

7947

best_positive_itick_FOM=FOM;

7740

best_positive_itick_FOM=FOM;

7948

best_positive_itick_in_loop=itick;

7741

best_positive_itick_in_loop=itick;

7949

end

7742

end

7950

if itick<=0 && FOM>best_negative_itick_FOM

7743

if itick<=0 && FOM>best_negative_itick_FOM

7951

best_negative_itick_FOM=FOM;

7744

best_negative_itick_FOM=FOM;

7952

best_negative_itick_in_loop=itick;

7745

best_negative_itick_in_loop=itick;

7953

end

7746

end

7954

7747

7955

itick_index=find(itick==full_sample_range);

7748

itick_index=find(itick==full_sample_range);

7956

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

7749

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

7957

7750

7958

if (FOM > best_FOM)

7751

if (FOM > best_FOM)

7959

best_current_ffegain=param.current_ffegain;

7752

best_current_ffegain=param.current_ffegain;

7960

best_txffe = txffe;

7753

best_txffe = txffe;

7961

%along with best_txffe, save the indices of the best_txffe

7754

%along with best_txffe, save the indices of the best_txffe

7962

%(saves time in LOCAL SEARCH block)

7755

%(saves time in LOCAL SEARCH block)

7963

best_txffe_index=tx_index_vector;

7756

best_txffe_index=tx_index_vector;

7964

best_sbr = sbr;

7757

best_sbr = sbr;

7965

best_ctle = ctle_index;

7758

best_ctle = ctle_index;

7966

best_G_high_pass =g_LP_index;

7759

best_G_high_pass =g_LP_index;

7967

best_FOM = FOM;

7760

best_FOM = FOM;

7968

best_cursor_i = cursor_i;

7761

best_cursor_i = cursor_i;

7969

best_itick = itick;

7762

best_itick = itick;

7970

if ~OP.TDMODE

7763

if ~OP.TDMODE

7971

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7764

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7972

best_IR=effective_channel;

7765

best_IR=effective_channel;

7973

end

7766

end

7974

best_sigma_N = sigma_N;

7767

best_sigma_N = sigma_N;

7975

best_h_J = h_J;

7768

best_h_J = h_J;

7976

best_A_s=A_s;

7769

best_A_s=A_s;

7977

best_A_p=A_p;

7770

best_A_p=A_p;

7978

best_ISI=ISI_N;

7771

best_ISI=ISI_N;

7979

best_bmax=param.use_bmax;

7772

best_bmax=param.use_bmax;

7980

%AJG021820

7773

%AJG021820

7981

best_bmin=param.use_bmin;

7774

best_bmin=param.use_bmin;

7982

best_tail_RSS=tail_RSS;

7775

best_tail_RSS=tail_RSS;

7983

best_dfetaps=dfetaps;

7776

best_dfetaps=dfetaps;

7984

if param.Floating_DFE

7777

if param.Floating_DFE

7985

best_floating_tap_locations=floating_tap_locations;

7778

best_floating_tap_locations=floating_tap_locations;

7986

best_floating_tap_coef=floating_tap_coef;

7779

best_floating_tap_coef=floating_tap_coef;

7987

end

7780

end

7988

if param.Floating_RXFFE

7781

if param.Floating_RXFFE

7989

best_floating_tap_locations=floating_tap_locations;

7782

best_floating_tap_locations=floating_tap_locations;

7990

% best_floating_tap_coef=floating_tap_coef;

7783

% best_floating_tap_coef=floating_tap_coef;

7991

end

7784

end

7992

if OP.RxFFE

7785

if OP.RxFFE

7993

best_RxFFE=C;

7786

best_RxFFE=C;

7994

best_PSD_results=PSD_results;

7787

best_PSD_results=PSD_results;

7995

best_MMSE_results=MMSE_results;

7788

best_MMSE_results=MMSE_results;

7996

end

7789

end

7997

end

7790

end

7998

end

7791

end

7999

end

7792

end

8000

7793

8001

end

7794

end

8002

end

7795

end

8003

end

7796

end

8004

if do_C2M

7797

if do_C2M

8005

if best_FOM == -inf

7798

if best_FOM == -inf

8006

param.Min_VEO_Test=0;

7799

param.Min_VEO_Test=0;

8007

else

7800

else

8008

break

7801

break

8009

end

7802

end

8010

end

7803

end

8011

end

7804

end

8012

if 0

7805

if 0

8013

fprintf('old loops = %d\n',old_loops);

7806

fprintf('old loops = %d\n',old_loops);

8014

fprintf('new loops = %d\n',new_loops);

7807

fprintf('new loops = %d\n',new_loops);

8015

display(sprintf('\n :loops = %g',pxi))

7808

display(sprintf('\n :loops = %g',pxi))

8016

end

7809

end

8017

7810

8018

%turn this on to review if FOM changes sign more than once in an itick loop

7811

%turn this on to review if FOM changes sign more than once in an itick loop

8019

if 0

7812

if 0

8020

DIR_CHANGE={};

7813

DIR_CHANGE={};

8021

for m=1:length(Gffe_values)

7814

for m=1:length(Gffe_values)

8022

for n=1:length(gdc_values)

7815

for n=1:length(gdc_values)

8023

for k=1:lf_indx

7816

for k=1:lf_indx

8024

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

7817

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

8025

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

7818

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

8026

%1 = goes up, -1=goes down

7819

%1 = goes up, -1=goes down

8027

x=sign(diff(FOM_this_mat')');

7820

x=sign(diff(FOM_this_mat')');

8028

%y = change in sign on x. the location of a "2" is where FOM changes direction

7821

%y = change in sign on x. the location of a "2" is where FOM changes direction

8029

y=abs(diff(x'))';

7822

y=abs(diff(x'))';

8030

%the goal is the FOM only changes direction once. so count the occurences of the 2

7823

%the goal is the FOM only changes direction once. so count the occurences of the 2

8031

for j=1:size(FOM_this_mat,1)

7824

for j=1:size(FOM_this_mat,1)

8032

z{j}=find(y(j,:)==2);

7825

z{j}=find(y(j,:)==2);

8033

end

7826

end

8034

zL=cellfun('length',z);

7827

zL=cellfun('length',z);

8035

%return any row where FOM changed direction more than once

7828

%return any row where FOM changed direction more than once

8036

DIR_CHANGE{j,k}=find(zL>1);

7829

DIR_CHANGE{j,k}=find(zL>1);

8037

end

7830

end

8038

end

7831

end

8039

end

7832

end

8040

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

7833

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

8041

end

7834

end

8042

7835

8043

if ~exist('best_cursor_i', 'var')% take last setting

7836

if ~exist('best_cursor_i', 'var')% take last setting

8044

result.eq_failed=true;

7837

result.eq_failed=true;

8045

display('equalization failed')

7838

display('equalization failed')

8046

best_bmax=param.bmax;

7839

best_bmax=param.bmax;

8047

%AJG021820

7840

%AJG021820

8048

best_bmin=param.bmin;

7841

best_bmin=param.bmin;

8049

best_tail_RSS=0;

7842

best_tail_RSS=0;

8050

best_current_ffegain=0;

7843

best_current_ffegain=0;

8051

best_txffe = txffe;

7844

best_txffe = txffe;

8052

best_sbr = sbr;

7845

best_sbr = sbr;

8053

best_ctle = ctle_index;

7846

best_ctle = ctle_index;

8054

if OP.RxFFE

7847

if OP.RxFFE

8055

best_PSD_results=PSD_results;

7848

best_PSD_results=PSD_results;

8056

best_MMSE_results=MMSE_results;

7849

best_MMSE_results=MMSE_results;

8057

best_RxFFE=C;

7850

best_RxFFE=C;

8058

end

7851

end

8059

best_G_high_pass =g_LP_index;

7852

best_G_high_pass =g_LP_index;

8060

best_FOM = FOM;

7853

best_FOM = FOM;

8061

%if this block is reached, the last encountered EQ parameters are used

7854

%if this block is reached, the last encountered EQ parameters are used

8062

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

7855

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

8063

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

7856

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

8064

if isempty(cursor_i)

7857

if isempty(cursor_i)

8065

[~,cursor_i]=max(sbr);

7858

[~,cursor_i]=max(sbr);

8066

end

7859

end

8067

best_cursor_i = cursor_i;

7860

best_cursor_i = cursor_i;

8068

best_itick = itick;

7861

best_itick = itick;

8069

if ~OP.TDMODE

7862

if ~OP.TDMODE

8070

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7863

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

8071

best_IR=effective_channel;

7864

best_IR=effective_channel;

8072

end

7865

end

8073

best_sigma_N = sigma_N;

7866

best_sigma_N = sigma_N;

8074

best_h_J = h_J;

7867

best_h_J = h_J;

8075

best_A_p=max(sbr);

7868

best_A_p=max(sbr);

8076

best_ISI=1;

7869

best_ISI=1;

8077

best_dfetaps= sbr( cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe))/sbr(cursor_i) ;

7870

best_dfetaps= sbr( cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe))/sbr(cursor_i) ;

8078

best_A_s= sbr( cursor_i);

7871

best_A_s= sbr( cursor_i);

8079

if param.Floating_DFE

7872

if param.Floating_DFE

8080

best_floating_tap_locations=[];

7873

best_floating_tap_locations=[];

8081

best_floating_tap_coef=[];

7874

best_floating_tap_coef=[];

8082

end

7875

end

8083

if do_C2M

7876

if do_C2M

8084

return

7877

return

8085

end

7878

end

8086

% return

7879

% return

8087

else

7880

else

8088

result.eq_failed=false; % RIM 12/30/2023

7881

result.eq_failed=false; % RIM 12/30/2023

8089

end

7882

end

8090

7883

8091

best_cursor = best_sbr(best_cursor_i);

7884

best_cursor = best_sbr(best_cursor_i);

8092

% report during debug

7885

% report during debug

8093

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

7886

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

8094

%If sbr was zero padded, then PRin needs to do so as well)

7887

%If sbr was zero padded, then PRin needs to do so as well)

8095

if length(PRin)<length(best_sbr)

7888

if length(PRin)<length(best_sbr)

8096

PRin(end+1:length(best_sbr))=0;

7889

PRin(end+1:length(best_sbr))=0;

8097

end

7890

end

8098

f=1e8:1e8:100e9;

7891

f=1e8:1e8:100e9;

8099

7892

8100

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

7893

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

8101

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

7894

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

8102

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7895

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

8103

% need to include H_RCos in noise and when computing the system ir for thru

7896

% need to include H_RCos in noise and when computing the system ir for thru

8104

% and crosstalk

7897

% and crosstalk

8105

H_r=H_bw.*H_bt.*H_RCos;

7898

H_r=H_bw.*H_bt.*H_RCos;

8106

7899

8107

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

7900

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

8108

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

7901

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

8109

7902

8110

switch param.CTLE_type

7903

switch param.CTLE_type

8111

case 'CL93'

7904

case 'CL93'

8112

H_low=1;

7905

H_low=1;

8113

case 'CL120d'

7906

case 'CL120d'

8114

H_low=(10^(param.g_DC_HP_values(best_G_high_pass)/20) + 1i*f/param.f_HP(best_G_high_pass))./(1 + 1i*f/param.f_HP(best_G_high_pass));

7907

H_low=(10^(param.g_DC_HP_values(best_G_high_pass)/20) + 1i*f/param.f_HP(best_G_high_pass))./(1 + 1i*f/param.f_HP(best_G_high_pass));

8115

case 'CL120e'

7908

case 'CL120e'

8116

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

7909

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

8117

end

7910

end

8118

ctle_gain=H_low.*ctle_gain1.*H_r;

7911

ctle_gain=H_low.*ctle_gain1.*H_r;

8119

7912

8120

7913

8121

7914

8122

%lsbr=length(sbr);

7915

%lsbr=length(sbr);

8123

%use length of best_sbr in case zero padding was performed

7916

%use length of best_sbr in case zero padding was performed

8124

%check "sbr_required_length" variable

7917

%check "sbr_required_length" variable

8125

lsbr=length(best_sbr);

7918

lsbr=length(best_sbr);

8126

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

7919

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

8127

7920

8128

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

7921

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

8129

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

7922

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

8130

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

7923

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

8131

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

7924

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

8132

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

7925

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

8133

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

7926

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

8134

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

7927

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

8135

if param.Floating_DFE

7928

if param.Floating_DFE

8136

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

7929

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

8137

end

7930

end

8138

% apply max tap value constraint

7931

% apply max tap value constraint

8139

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

7932

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

8140

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

7933

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

8141

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

7934

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

8142

7935

8143

%AJG021820

7936

%AJG021820

8144

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

7937

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

8145

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

7938

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

8146

if param.Floating_DFE

7939

if param.Floating_DFE

8147

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

7940

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

8148

end

7941

end

8149

7942

8150

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

7943

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

8151

Symbol_Adj = (param.levels-1);% 3A.1.6

7944

Symbol_Adj = (param.levels-1);% 3A.1.6

8152

if OP.DEBUG ~=0

7945

if OP.DEBUG ~=0

8153

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

7946

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

8154

% display pulse responses in one axis per test case.

7947

% display pulse responses in one axis per test case.

8155

switch upper(OP.TIME_AXIS)

7948

switch upper(OP.TIME_AXIS)

8156

case 'S' % RIM 11-13-2023 added user selectable xaxis

7949

case 'S' % RIM 11-13-2023 added user selectable xaxis

8157

xnorm=1;

7950

xnorm=1;

8158

xaxis_label='seconds';

7951

xaxis_label='seconds';

8159

offset=0;

7952

offset=0;

8160

case 'UI'

7953

case 'UI'

8161

xnorm=param.ui;

7954

xnorm=param.ui;

8162

xaxis_label='UI';

7955

xaxis_label='UI';

8163

offset=t(best_cursor_i)/xnorm;

7956

offset=t(best_cursor_i)/xnorm;

8164

otherwise

7957

otherwise

8165

xnorm=1;

7958

xnorm=1;

8166

xaxis_label='seconds';

7959

xaxis_label='seconds';

8167

offset=0;

7960

offset=0;

8168

end

7961

end

8169

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

7962

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

8170

fig=findobj('Name', figure_name);

7963

fig=findobj('Name', figure_name);

8171

if isempty(fig), fig=figure('Name', figure_name); end

7964

if isempty(fig), fig=figure('Name', figure_name); end

8172

figure(fig);set(gcf,'Tag','COM');

7965

figure(fig);set(gcf,'Tag','COM');

8173

movegui(fig,'north')

7966

movegui(fig,'north')

8174

%figure(fig.Number);

7967

%figure(fig.Number);

8175

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

7968

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

8176

if OP.RxFFE

7969

if OP.RxFFE

8177

ax1=subplot(2,1,1);

7970

ax1=subplot(2,1,1);

8178

end

7971

end

8179

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

7972

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

8180

hold on

7973

hold on

8181

7974

8182

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

7975

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

8183

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

7976

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

8184

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

7977

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

8185

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

7978

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

8186

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

7979

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

8187

ylabel('volts')

7980

ylabel('volts')

8188

xlabel(xaxis_label)

7981

xlabel(xaxis_label)

8189

grid on

7982

grid on

8190

legend show

7983

legend show

8191

legend( 'Location', 'best')

7984

legend( 'Location', 'best')

8192

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

7985

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

8193

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

7986

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

8194

if param.ndfe_passed ~=0

7987

if param.ndfe_passed ~=0

8195

stem((sampled_best_sbr_dfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,DFE_taps_mV(1:param.ndfe_passed)/Symbol_Adj','m', 'LineWidth',2,'disp','DFE-canceled cursors');

7988

stem((sampled_best_sbr_dfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,DFE_taps_mV(1:param.ndfe_passed)/Symbol_Adj','m', 'LineWidth',2,'disp','DFE-canceled cursors');

8196

end

7989

end

8197

if param.Floating_DFE

7990

if param.Floating_DFE

8198

stem((sampled_best_sbr_fdfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,FDFE_taps_mV/Symbol_Adj, 'MarkerFaceColor','red','MarkerEdgeColor','m','LineWidth',1,'disp','FDFE-canceled cursors');

7991

stem((sampled_best_sbr_fdfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,FDFE_taps_mV/Symbol_Adj, 'MarkerFaceColor','red','MarkerEdgeColor','m','LineWidth',1,'disp','FDFE-canceled cursors');

8199

end

7992

end

8200

if OP.RxFFE

7993

if OP.RxFFE

8201

ax2=subplot(2,1,2);

7994

ax2=subplot(2,1,2);

8202

if param.Floating_RXFFE

7995

if param.Floating_RXFFE

8203

stem((t(best_cursor_i+(best_floating_tap_locations)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

7996

stem((t(best_cursor_i+(best_floating_tap_locations)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

8204

,'filled','disp','RxFFE floating FFE taps')

7997

,'filled','disp','RxFFE floating FFE taps')

8205

hold on

7998

hold on

8206

end

7999

end

8207

stem((t(best_cursor_i+param.samples_per_ui*(-param.RxFFE_cmx:param.RxFFE_cpx)))/xnorm-offset,best_RxFFE(1:param.RxFFE_cmx+param.RxFFE_cpx+1)...

8000

stem((t(best_cursor_i+param.samples_per_ui*(-param.RxFFE_cmx:param.RxFFE_cpx)))/xnorm-offset,best_RxFFE(1:param.RxFFE_cmx+param.RxFFE_cpx+1)...

8208

,'filled','disp','RxFFE fixted FFE taps')

8001

,'filled','disp','RxFFE fixted FFE taps')

8209

legend show

8002

legend show

8210

zoom xon

8003

zoom xon

8211

linkaxes([ax1 ax2],'x')

8004

linkaxes([ax1 ax2],'x')

8212

end

8005

end

8213

8006

8214

8007

8215

grid on

8008

grid on

8216

legend show

8009

legend show

8217

legend( 'Location', 'best')

8010

legend( 'Location', 'best')

8218

zoom xon

8011

zoom xon

8219

% set(hax, 'tag', 'EQE');

8012

% set(hax, 'tag', 'EQE');

8220

%

8013

%

8221

figure(110);set(gcf,'Tag','COM');

8014

figure(110);set(gcf,'Tag','COM');

8222

set(gcf, 'Name', 'CTLE selection');

8015

set(gcf, 'Name', 'CTLE selection');

8223

movegui(gcf, 'southeast');

8016

movegui(gcf, 'southeast');

8224

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8017

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8225

hold on

8018

hold on

8226

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8019

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8227

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8020

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8228

fbaud_tick=find(f >= baud_rate, 1);

8021

fbaud_tick=find(f >= baud_rate, 1);

8229

fnq_tick=find(f >= baud_rate/2, 1);

8022

fnq_tick=find(f >= baud_rate/2, 1);

8230

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8023

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8231

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8024

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8232

recolor_plots(gca);

8025

recolor_plots(gca);

8233

title('CTF/w Rx Filter Response')

8026

title('CTF/w Rx Filter Response')

8234

ylabel('dB')

8027

ylabel('dB')

8235

xlabel('Hz')

8028

xlabel('Hz')

8236

legend show

8029

legend show

8237

end

8030

end

8238

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8031

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8239

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8032

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8240

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8033

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8241

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8034

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8242

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8035

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8243

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8036

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8244

end

8037

end

8245

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

8038

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

8246

eqe_axes = findobj('tag', 'EQE');

8039

eqe_axes = findobj('tag', 'EQE');

8247

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8040

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8248

end

8041

end

8249

if OP.DISPLAY_WINDOW

8042

if OP.DISPLAY_WINDOW

8250

close(hwaitbar);

8043

close(hwaitbar);

8251

else

8044

else

8252

fprintf('\n');

8045

fprintf('\n');

8253

end

8046

end

8254

8047

8255

% % eq_data

8048

% % eq_data

8256

result.cur=cur;

8049

result.cur=cur;

8257

result.txffe = best_txffe;

8050

result.txffe = best_txffe;

8258

result.ctle = best_ctle;

8051

result.ctle = best_ctle;

8259

result.best_G_high_pass=best_G_high_pass;

8052

result.best_G_high_pass=best_G_high_pass;

8260

result.DFE_taps = best_dfetaps; %relative

8053

result.DFE_taps = best_dfetaps; %relative

8261

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8054

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8262

if param.Floating_DFE

8055

if param.Floating_DFE

8263

result.floating_tap_locations=best_floating_tap_locations;

8056

result.floating_tap_locations=best_floating_tap_locations;

8264

result.floating_tap_coef=best_floating_tap_coef;

8057

result.floating_tap_coef=best_floating_tap_coef;

8265

end

8058

end

8266

if param.Floating_RXFFE

8059

if param.Floating_RXFFE

8267

result.floating_tap_locations=best_floating_tap_locations;

8060

result.floating_tap_locations=best_floating_tap_locations;

8268

end

8061

end

8269

result.A_s = best_A_s;

8062

result.A_s = best_A_s;

8270

result.t_s = best_cursor_i;

8063

result.t_s = best_cursor_i;

8271

result.itick = best_itick;

8064

result.itick = best_itick;

8272

result.sigma_N = best_sigma_N;

8065

result.sigma_N = best_sigma_N;

8273

result.h_J = best_h_J;

8066

result.h_J = best_h_J;

8274

result.FOM = best_FOM;

8067

result.FOM = best_FOM;

8275

if ~OP.TDMODE

8068

if ~OP.TDMODE

8276

%If sbr was zero padded, then best_IR needs to do so as well)

8069

%If sbr was zero padded, then best_IR needs to do so as well)

8277

if length(best_IR)<length(best_sbr)

8070

if length(best_IR)<length(best_sbr)

8278

best_IR(end+1:length(best_sbr))=0;

8071

best_IR(end+1:length(best_sbr))=0;

8279

end

8072

end

8280

result.IR = best_IR;

8073

result.IR = best_IR;

8281

end

8074

end

8282

result.t=t;

8075

result.t=t;

8283

result.sbr=best_sbr;

8076

result.sbr=best_sbr;

8284

if OP.RxFFE

8077

if OP.RxFFE

8285

result.RxFFE=best_RxFFE;

8078

result.RxFFE=best_RxFFE;

8286

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8287

result.PSD_results=best_PSD_results;

8079

result.PSD_results=best_PSD_results;

8288

result.MMSE_results=best_MMSE_results;

8080

result.MMSE_results=best_MMSE_results;

8289

end

8290

end

8081

end

8291

8082

8292

8083

8293

8084

8294

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8085

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8295

% updated RIM 12/17/2021

8086

% updated RIM 12/17/2021

8296

result.A_p = max(chdata(1).uneq_pulse_response);

8087

result.A_p = max(chdata(1).uneq_pulse_response);

8297

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8088

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8298

PR=chdata(1).uneq_pulse_response;

8089

PR=chdata(1).uneq_pulse_response;

8299

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8090

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8300

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8091

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8301

if iend >= length(PR)

8092

if iend >= length(PR)

8302

iend = length (PR);

8093

iend = length (PR);

8303

end

8094

end

8304

if ibeg < 1

8095

if ibeg < 1

8305

ibeg = 1;

8096

ibeg = 1;

8306

end

8097

end

8307

PR=PR(ibeg:iend);

8098

PR=PR(ibeg:iend);

8308

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8099

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8309

SRn=PR;

8100

SRn=PR;

8310

for ik=1:floor(length(PR)/param.samples_per_ui)

8101

for ik=1:floor(length(PR)/param.samples_per_ui)

8311

SPR=circshift(PR,param.samples_per_ui*ik);

8102

SPR=circshift(PR,param.samples_per_ui*ik);

8312

SPR(1:ik*param.samples_per_ui)=0;

8103

SPR(1:ik*param.samples_per_ui)=0;

8313

SRn=SRn+ SPR;

8104

SRn=SRn+ SPR;

8314

end

8105

end

8315

codedebug=0;

8106

codedebug=0;

8316

if codedebug

8107

if codedebug

8317

fig=figure('Name', 'step and pulse response for code debug');

8108

fig=figure('Name', 'step and pulse response for code debug');

8318

figure(fig);set(gcf,'Tag','COM');

8109

figure(fig);set(gcf,'Tag','COM');

8319

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8110

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8320

plot(UI,SRn)

8111

plot(UI,SRn)

8321

hold on

8112

hold on

8322

plot(UI,PR)

8113

plot(UI,PR)

8323

xlim([-param.D_p param.N_v])

8114

xlim([-param.D_p param.N_v])

8324

grid on;hold off;

8115

grid on;hold off;

8325

result.step=SRn;

8116

result.step=SRn;

8326

end

8117

end

8327

i20=find(SRn>=0.20*result.A_f,1,'first');

8118

i20=find(SRn>=0.20*result.A_f,1,'first');

8328

i80=find(SRn>=0.80*result.A_f,1,'first');

8119

i80=find(SRn>=0.80*result.A_f,1,'first');

8329

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8120

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8330

result.Pmax_by_Vf=result.A_p/result.A_f;

8121

result.Pmax_by_Vf=result.A_p/result.A_f;

8331

result.ISI =best_ISI;

8122

result.ISI =best_ISI;

8332

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8123

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8333

result.best_current_ffegain=best_current_ffegain;

8124

result.best_current_ffegain=best_current_ffegain;

8334

result.best_bmax=best_bmax;

8125

result.best_bmax=best_bmax;

8335

%AJG021820

8126

%AJG021820

8336

result.best_bmin=best_bmin;

8127

result.best_bmin=best_bmin;

8337

result.tail_RSS=best_tail_RSS;

8128

result.tail_RSS=best_tail_RSS;

8338

function param=parameter_size_adjustment(param,OP)

8129

function param=parameter_size_adjustment(param,OP)

8339

8130

8340

make_length2={'C_pkg_board' 'C_diepad' 'L_comp' 'C_bump' 'tfx' 'C_v' 'C_0' 'C_1' 'pkg_Z_c' 'brd_Z_c' 'R_diepad'};

8131

make_length2={'C_pkg_board' 'C_diepad' 'L_comp' 'C_bump' 'tfx' 'C_v' 'C_0' 'C_1' 'pkg_Z_c' 'brd_Z_c' 'R_diepad'};

8341

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8132

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8342

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8133

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8343

make_length_DCHP={'f_HP'};

8134

make_length_DCHP={'f_HP'};

8344

make_length_ncases={'AC_CM_RMS'};

8135

make_length_ncases={'AC_CM_RMS'};

8345

8136

8346

%ncases used by make_length_ncases fields

8137

%ncases used by make_length_ncases fields

8347

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8138

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8348

8139

8349

%PORTZ_mult used by make_length_WCPORTZ fields

8140

%PORTZ_mult used by make_length_WCPORTZ fields

8350

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8141

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8351

if OP.WC_PORTZ

8142

if OP.WC_PORTZ

8352

PORTZ_mult=[1 1];

8143

PORTZ_mult=[1 1];

8353

else

8144

else

8354

PORTZ_mult=pkg_sel_vec;

8145

PORTZ_mult=pkg_sel_vec;

8355

end

8146

end

8356

8147

8357

%Parameters that have length = 2

8148

%Parameters that have length = 2

8358

for j=1:length(make_length2)

8149

for j=1:length(make_length2)

8359

if numel(param.(make_length2{j}))==1

8150

if numel(param.(make_length2{j}))==1

8360

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8151

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8361

end

8152

end

8362

end

8153

end

8363

8154

8364

%Parameters that have length = ncases

8155

%Parameters that have length = ncases

8365

for j=1:length(make_length_ncases)

8156

for j=1:length(make_length_ncases)

8366

if numel(param.(make_length_ncases{j}))==1

8157

if numel(param.(make_length_ncases{j}))==1

8367

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8158

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8368

end

8159

end

8369

end

8160

end

8370

8161

8371

%Parameters that have length = length(ctle_gdc_values)

8162

%Parameters that have length = length(ctle_gdc_values)

8372

for j=1:length(make_length_GDC)

8163

for j=1:length(make_length_GDC)

8373

if numel(param.(make_length_GDC{j}))==1

8164

if numel(param.(make_length_GDC{j}))==1

8374

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8165

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8375

end

8166

end

8376

end

8167

end

8377

8168

8378

%Parameters that have length = length(g_DC_HP_values)

8169

%Parameters that have length = length(g_DC_HP_values)

8379

for j=1:length(make_length_DCHP)

8170

for j=1:length(make_length_DCHP)

8380

if numel(param.(make_length_DCHP{j}))==1

8171

if numel(param.(make_length_DCHP{j}))==1

8381

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8172

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8382

end

8173

end

8383

end

8174

end

8384

8175

8385

%Parameters that have length associated with PORTZ_mult

8176

%Parameters that have length associated with PORTZ_mult

8386

for j=1:length(make_length_WCPORTZ)

8177

for j=1:length(make_length_WCPORTZ)

8387

if numel(param.(make_length_WCPORTZ{j}))==1

8178

if numel(param.(make_length_WCPORTZ{j}))==1

8388

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8179

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8389

end

8180

end

8390

end

8181

end

8391

function sgm = pdf2sgm(pdf)

8182

function sgm = pdf2sgm(pdf)

8392

avg = sum(pdf.x .* pdf.y);

8183

avg = sum(pdf.x .* pdf.y);

8393

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8184

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8394

% end yasuo patch

8185

% end yasuo patch

8395

8186

8396

8187

8397

%% adding tx packgage

8188

%% adding tx packgage

8398

function cdf=pdf_to_cdf(pdf)

8189

function cdf=pdf_to_cdf(pdf)

8399

8190

8400

%Transform PDF to CDF

8191

%Transform PDF to CDF

8401

%The CDF is natively calculated from negative-to-positive voltage.

8192

%The CDF is natively calculated from negative-to-positive voltage.

8402

%This only gives BER calculation for bottom eye. Need to also

8193

%This only gives BER calculation for bottom eye. Need to also

8403

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8194

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8404

%min of top and bottom CDF values.

8195

%min of top and bottom CDF values.

8405

%If only interested in one side, a simple cumsum on y is all that is needed.

8196

%If only interested in one side, a simple cumsum on y is all that is needed.

8406

8197

8407

cdf.yB=cumsum(pdf.y);

8198

cdf.yB=cumsum(pdf.y);

8408

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8199

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8409

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8200

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8410

cdf.x=pdf.x;

8201

cdf.x=pdf.x;

8411

function plot_bathtub_curves(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf,jitt_pdf, combined_interference_and_noise_pdf, bin_size)

8202

function plot_bathtub_curves(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf,jitt_pdf, combined_interference_and_noise_pdf, bin_size)

8412

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8203

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8413

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8204

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8414

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8205

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8415

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8206

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8416

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8207

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8417

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8208

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8418

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8209

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8419

%% Added by Bill Kirkland, June 14, 2017

8210

%% Added by Bill Kirkland, June 14, 2017

8420

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8211

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8421

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8212

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8422

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8213

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8423

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8214

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8424

8215

8425

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8216

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8426

hold on

8217

hold on

8427

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8218

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8428

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8219

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8429

semilogy(signal_and_system_noise_pdf.x, abs(cumsum(signal_and_system_noise_pdf.y)-0.5) ,'m','Disp','Jitter, SNR_TX,RL_M, eta_0 noise', 'parent', hax)

8220

semilogy(signal_and_system_noise_pdf.x, abs(cumsum(signal_and_system_noise_pdf.y)-0.5) ,'m','Disp','Jitter, SNR_TX,RL_M, eta_0 noise', 'parent', hax)

8430

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8221

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8431

8222

8432

%% Added by Bill Kirkland, June 14, 2017

8223

%% Added by Bill Kirkland, June 14, 2017

8433

% modification allows bathtub curves to cross over and hence one can

8224

% modification allows bathtub curves to cross over and hence one can

8434

% directly read the noise component.

8225

% directly read the noise component.

8435

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8226

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8436

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8227

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8437

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8228

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8438

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8229

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8439

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8230

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8440

8231

8441

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8232

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8442

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8233

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8443

8234

8444

ylabel(hax, 'Probability')

8235

ylabel(hax, 'Probability')

8445

xlabel(hax, 'volts')

8236

xlabel(hax, 'volts')

8446

legend(hax, 'show')

8237

legend(hax, 'show')

8447

% testing code

8238

% testing code

8448

if 0

8239

if 0

8449

figure_name = 'COM curves';

8240

figure_name = 'COM curves';

8450

fig=findobj('Name', figure_name);

8241

fig=findobj('Name', figure_name);

8451

if isempty(fig), fig=figure('Name', figure_name); end

8242

if isempty(fig), fig=figure('Name', figure_name); end

8452

figure(fig);set(gcf,'Tag','COM');

8243

figure(fig);set(gcf,'Tag','COM');

8453

grid on

8244

grid on

8454

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8245

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8455

hold on

8246

hold on

8456

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8247

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8457

ylim([ 1e-6 0.25])

8248

ylim([ 1e-6 0.25])

8458

xlim([0 30])

8249

xlim([0 30])

8459

grid on

8250

grid on

8460

end

8251

end

8461

function plot_pie_com(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf, combined_interference_and_noise_pdf, bin_size,param)

8252

function plot_pie_com(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf, combined_interference_and_noise_pdf, bin_size,param)

8462

BER=param.specBER;

8253

BER=param.specBER;

8463

delta_dB=param.delta_IL;

8254

delta_dB=param.delta_IL;

8464

8255

8465

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8256

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8466

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8257

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8467

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8258

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8468

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8259

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8469

8260

8470

8261

8471

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8262

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8472

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8263

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8473

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8264

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8474

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8265

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8475

8266

8476

COM=20*log10(max_signal/maxn_tot);

8267

COM=20*log10(max_signal/maxn_tot);

8477

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8268

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8478

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8269

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8479

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8270

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8480

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8271

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8481

8272

8482

pfctr=exp(-0.09054*delta_dB);% less loss

8273

pfctr=exp(-0.09054*delta_dB);% less loss

8483

mfctr=exp(0.09054*delta_dB); % more loss

8274

mfctr=exp(0.09054*delta_dB); % more loss

8484

8275

8485

%less loss

8276

%less loss

8486

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8277

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8487

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8278

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8488

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8279

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8489

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8280

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8490

plus_maxn_tot=norm(plus_maxn);

8281

plus_maxn_tot=norm(plus_maxn);

8491

8282

8492

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8283

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8493

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8284

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8494

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8285

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8495

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8286

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8496

minus_maxn_tot=norm(minus_maxn);

8287

minus_maxn_tot=norm(minus_maxn);

8497

8288

8498

% more loss

8289

% more loss

8499

COMp=20*log10(max_signal*pfctr/maxn_tot);

8290

COMp=20*log10(max_signal*pfctr/maxn_tot);

8500

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8291

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8501

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8292

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8502

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8293

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8503

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8294

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8504

% less loss

8295

% less loss

8505

COMm=20*log10(max_signal*mfctr/maxn_tot);

8296

COMm=20*log10(max_signal*mfctr/maxn_tot);

8506

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8297

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8507

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8298

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8508

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8299

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8509

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8300

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8510

8301

8511

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8302

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8512

8303

8513

8304

8514

if(COM<0)

8305

if(COM<0)

8515

return

8306

return

8516

end

8307

end

8517

8308

8518

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8309

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8519

8310

8520

% pie(COM_per_noise,labels)

8311

% pie(COM_per_noise,labels)

8521

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8312

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8522

% legend('show','Location','bestoutside')

8313

% legend('show','Location','bestoutside')

8523

nullbar= [ 0 0 0 ];

8314

nullbar= [ 0 0 0 ];

8524

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8315

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8525

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8316

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8526

hold on

8317

hold on

8527

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8318

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8528

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8319

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8529

8320

8530

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8321

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8531

% ax=gca;

8322

% ax=gca;

8532

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8323

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8533

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8324

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8534

grid on

8325

grid on

8535

legend(labels,'Location','north')

8326

legend(labels,'Location','north')

8536

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8327

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8537

ylabel('COM (dB)')

8328

ylabel('COM (dB)')

8538

hold off

8329

hold off

8539

8330

8540

8331

8541

8332

8542

8333

8543

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8334

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8544

num_files=length(chdata);

8335

num_files=length(chdata);

8545

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8336

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8546

for i=1:num_files

8337

for i=1:num_files

8547

if param.package_testcase_i==1 && i==1

8338

if param.package_testcase_i==1 && i==1

8548

if OP.TDR && i==1

8339

if OP.TDR && i==1

8549

S.Frequencies=chdata(i).faxis;

8340

S.Frequencies=chdata(i).faxis;

8550

S.Impedance=100;

8341

S.Impedance=100;

8551

if ~OP.SHOW_BRD

8342

if ~OP.SHOW_BRD

8552

Sfield='_orig';

8343

Sfield='_orig';

8553

else

8344

else

8554

Sfield='_raw';

8345

Sfield='_raw';

8555

end

8346

end

8556

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8347

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8557

if ~param.FLAG.S2P

8348

if ~param.FLAG.S2P

8558

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8349

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8559

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8350

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8560

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8351

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8561

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8352

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8562

else

8353

else

8563

S.NumPorts=1;

8354

S.NumPorts=1;

8564

end

8355

end

8565

if OP.TDR_W_TXPKG

8356

if OP.TDR_W_TXPKG

8566

if OP.ERL == 2

8357

if OP.ERL == 2

8567

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8358

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8568

end

8359

end

8569

R_diepad = param.R_diepad;

8360

R_diepad = param.R_diepad;

8570

% RX package length is assumed to be the same for all

8361

% RX package length is assumed to be the same for all

8571

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8362

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8572

% for Rx pkg

8363

% for Rx pkg

8573

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8364

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8574

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8365

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8575

combines4p( s11in, s12in, s21in, s22in, ...

8366

combines4p( s11in, s12in, s21in, s22in, ...

8576

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8367

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8577

% S=sparameters(S.Parameters,S.Frequencies,100);

8368

% S=sparameters(S.Parameters,S.Frequencies,100);

8578

S=SL(S,S.Frequencies,R_diepad(1)*2);

8369

S=SL(S,S.Frequencies,R_diepad(1)*2);

8579

chdata(i).TX_RL=S.Parameters(2,2,:);

8370

chdata(i).TX_RL=S.Parameters(2,2,:);

8580

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8371

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8581

end

8372

end

8582

8373

8583

% need to combine S wiht is page and channel

8374

% need to combine S wiht is page and channel

8584

if param.FLAG.S2P

8375

if param.FLAG.S2P

8585

port_sel=1;

8376

port_sel=1;

8586

else

8377

else

8587

port_sel=[1 2];

8378

port_sel=[1 2];

8588

if OP.AUTO_TFX

8379

if OP.AUTO_TFX

8589

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8380

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8590

pix=find(fir4del==max(fir4del),1);

8381

pix=find(fir4del==max(fir4del),1);

8591

param.tfx(2)=2*tu(pix);

8382

param.tfx(2)=2*tu(pix);

8592

end

8383

end

8593

end

8384

end

8594

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8385

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8595

for ipsl=1:length(port_sel) % do for both port if s4p

8386

for ipsl=1:length(port_sel) % do for both port if s4p

8596

for izt=1:length(param.Z_t) % do for all tdr impedances

8387

for izt=1:length(param.Z_t) % do for all tdr impedances

8597

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8388

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8598

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8389

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8599

% OP.interp_sparam_mag='trend_to_DC';

8390

% OP.interp_sparam_mag='trend_to_DC';

8600

OP.interp_sparam_mag='linear_trend_to_DC';

8391

OP.interp_sparam_mag='linear_trend_to_DC';

8601

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8392

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8602

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8393

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8603

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8394

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8604

if ipsl ==1

8395

if ipsl ==1

8605

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8396

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8606

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8397

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8607

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8398

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8608

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8399

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8609

else

8400

else

8610

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8401

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8611

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8402

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8612

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8403

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8613

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8404

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8614

end

8405

end

8615

if OP.PTDR && i==1

8406

if OP.PTDR && i==1

8616

if ipsl ==1

8407

if ipsl ==1

8617

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8408

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8618

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8409

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8619

else

8410

else

8620

if ~param.FLAG.S2P

8411

if ~param.FLAG.S2P

8621

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8412

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8622

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8413

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8623

else

8414

else

8624

chdata(i).TDR22(izt).ERL=[];

8415

chdata(i).TDR22(izt).ERL=[];

8625

chdata(i).TDR22(izt).ERLRMS=[];

8416

chdata(i).TDR22(izt).ERLRMS=[];

8626

end

8417

end

8627

end

8418

end

8628

else

8419

else

8629

chdata(i).TDR11(izt).ERL=[];

8420

chdata(i).TDR11(izt).ERL=[];

8630

chdata(i).TDR22(izt).ERL=[];

8421

chdata(i).TDR22(izt).ERL=[];

8631

chdata(i).TDR11(izt).ERLRMS=[];

8422

chdata(i).TDR11(izt).ERLRMS=[];

8632

chdata(i).TDR22(izt).ERLRMS=[];

8423

chdata(i).TDR22(izt).ERLRMS=[];

8633

end

8424

end

8634

end

8425

end

8635

end

8426

end

8636

end

8427

end

8637

8428

8638

end

8429

end

8639

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8430

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8640

h=figure(180);set(gcf,'Tag','COM');

8431

h=figure(180);set(gcf,'Tag','COM');

8641

if param.package_testcase_i==1 && i == 1

8432

if param.package_testcase_i==1 && i == 1

8642

if i==1

8433

if i==1

8643

htabgroup = uitabgroup(h);

8434

htabgroup = uitabgroup(h);

8644

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8435

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8645

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8436

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8646

hax1 = axes('Parent', htab1);

8437

hax1 = axes('Parent', htab1);

8647

hax3 = axes('Parent', htab3);

8438

hax3 = axes('Parent', htab3);

8648

if ~param.FLAG.S2P

8439

if ~param.FLAG.S2P

8649

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8440

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8650

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8441

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8651

hax2 = axes('Parent', htab2);

8442

hax2 = axes('Parent', htab2);

8652

hax4 = axes('Parent', htab4);

8443

hax4 = axes('Parent', htab4);

8653

end

8444

end

8654

end

8445

end

8655

set(h,'CurrentAxes',hax1)

8446

set(h,'CurrentAxes',hax1)

8656

hold on

8447

hold on

8657

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8448

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8658

hold off

8449

hold off

8659

legend (hax1, 'off');grid on;zoom xon;

8450

legend (hax1, 'off');grid on;zoom xon;

8660

set(legend (hax1, 'show'), 'interp', 'none');

8451

set(legend (hax1, 'show'), 'interp', 'none');

8661

8452

8662

if ~param.FLAG.S2P

8453

if ~param.FLAG.S2P

8663

set(h,'CurrentAxes',hax2)

8454

set(h,'CurrentAxes',hax2)

8664

hold on

8455

hold on

8665

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8456

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8666

hold off

8457

hold off

8667

legend (hax2, 'off');grid on;zoom xon;

8458

legend (hax2, 'off');grid on;zoom xon;

8668

set(legend (hax2, 'show'), 'interp', 'none');

8459

set(legend (hax2, 'show'), 'interp', 'none');

8669

end

8460

end

8670

8461

8671

set(h,'CurrentAxes',hax3)

8462

set(h,'CurrentAxes',hax3)

8672

hold on

8463

hold on

8673

if OP.PTDR

8464

if OP.PTDR

8674

for izt=1:length(param.Z_t)

8465

for izt=1:length(param.Z_t)

8675

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8466

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8676

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8467

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8677

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8468

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8678

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8469

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8679

end

8470

end

8680

end

8471

end

8681

hold off

8472

hold off

8682

legend (hax3, 'off');grid on;zoom xon;

8473

legend (hax3, 'off');grid on;zoom xon;

8683

set(legend (hax3, 'show'), 'interp', 'none');

8474

set(legend (hax3, 'show'), 'interp', 'none');

8684

if ~param.FLAG.S2P

8475

if ~param.FLAG.S2P

8685

set(h,'CurrentAxes',hax4)

8476

set(h,'CurrentAxes',hax4)

8686

hold on

8477

hold on

8687

if OP.PTDR

8478

if OP.PTDR

8688

for izt=1:length(param.Z_t)

8479

for izt=1:length(param.Z_t)

8689

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8480

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8690

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8481

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8691

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8482

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8692

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8483

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8693

end

8484

end

8694

end

8485

end

8695

hold off

8486

hold off

8696

legend (hax4, 'off');grid on;zoom xon;

8487

legend (hax4, 'off');grid on;zoom xon;

8697

set(legend (hax4, 'show'), 'interp', 'none');

8488

set(legend (hax4, 'show'), 'interp', 'none');

8698

end

8489

end

8699

end

8490

end

8700

end

8491

end

8701

if param.FLAG.S2P, return; end

8492

if param.FLAG.S2P, return; end

8702

end

8493

end

8703

function S =r_parrelell2(zref,f,rpad)

8494

function S =r_parrelell2(zref,f,rpad)

8704

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8495

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8705

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8496

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8706

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8497

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8707

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8498

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8708

% Sm=sparameters(S.Parameters,f,zref);

8499

% Sm=sparameters(S.Parameters,f,zref);

8709

8500

8710

8501

8711

8502

8712

8503

8713

8504

8714

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8505

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8715

8506

8716

%touchstone_file: .sNp touchstone file to read

8507

%touchstone_file: .sNp touchstone file to read

8717

%port_order: port reorder vector

8508

%port_order: port reorder vector

8718

%

8509

%

8719

%sch: sparameter matrix

8510

%sch: sparameter matrix

8720

%schFreqAxis: frequency axis

8511

%schFreqAxis: frequency axis

8721

8512

8722

[file_path,root_name,extension]=fileparts(touchstone_file);

8513

[file_path,root_name,extension]=fileparts(touchstone_file);

8723

fid=fopen(touchstone_file);

8514

fid=fopen(touchstone_file);

8724

8515

8725

%fetch number of ports from extension

8516

%fetch number of ports from extension

8726

num_ports=str2num(char(regexp(extension,'\d*','match')));

8517

num_ports=str2num(char(regexp(extension,'\d*','match')));

8727

8518

8728

%Get option line

8519

%Get option line

8729

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8520

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8730

optcell=textscan(optstr{1}{1},'%s');

8521

optcell=textscan(optstr{1}{1},'%s');

8731

optcell=optcell{1};

8522

optcell=optcell{1};

8732

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8523

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8733

%Some touchstone files need this. can't remember why now. maybe lines

8524

%Some touchstone files need this. can't remember why now. maybe lines

8734

%with whitespace but not empty but not commented

8525

%with whitespace but not empty but not commented

8735

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8526

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8736

optcell=textscan(optstr{1}{1},'%s');

8527

optcell=textscan(optstr{1}{1},'%s');

8737

optcell=optcell{1};

8528

optcell=optcell{1};

8738

end

8529

end

8739

8530

8740

%read the entire file

8531

%read the entire file

8741

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8532

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8742

raw_column_data=raw_read_data{1};

8533

raw_column_data=raw_read_data{1};

8743

fclose(fid);

8534

fclose(fid);

8744

8535

8745

%number of columns for 2D matrix

8536

%number of columns for 2D matrix

8746

columns=num_ports*num_ports*2+1;

8537

columns=num_ports*num_ports*2+1;

8747

8538

8748

%find the frequency lines by searching for the right number of NaN

8539

%find the frequency lines by searching for the right number of NaN

8749

a=sum(isnan(raw_column_data),2);

8540

a=sum(isnan(raw_column_data),2);

8750

if num_ports==3

8541

if num_ports==3

8751

b=find(a==2);

8542

b=find(a==2);

8752

elseif num_ports==1

8543

elseif num_ports==1

8753

b=find(a==6);

8544

b=find(a==6);

8754

else

8545

else

8755

b=find(a==0);

8546

b=find(a==0);

8756

end

8547

end

8757

8548

8758

num_freq=length(b);

8549

num_freq=length(b);

8759

8550

8760

%toss out the NaN and reshape into a 2D matrix

8551

%toss out the NaN and reshape into a 2D matrix

8761

raw_input = raw_column_data.';

8552

raw_input = raw_column_data.';

8762

raw_input = raw_input(~isnan(raw_input));

8553

raw_input = raw_input(~isnan(raw_input));

8763

raw_input = reshape(raw_input,columns,num_freq).';

8554

raw_input = reshape(raw_input,columns,num_freq).';

8764

8555

8765

%get the frequency mult

8556

%get the frequency mult

8766

frequency_mult_text=optcell{2};

8557

frequency_mult_text=optcell{2};

8767

if(strcmpi(frequency_mult_text,'hz'))

8558

if(strcmpi(frequency_mult_text,'hz'))

8768

frequency_mult=1;

8559

frequency_mult=1;

8769

elseif(strcmpi(frequency_mult_text,'khz'))

8560

elseif(strcmpi(frequency_mult_text,'khz'))

8770

frequency_mult=1e3;

8561

frequency_mult=1e3;

8771

elseif(strcmpi(frequency_mult_text,'mhz'))

8562

elseif(strcmpi(frequency_mult_text,'mhz'))

8772

frequency_mult=1e6;

8563

frequency_mult=1e6;

8773

elseif(strcmpi(frequency_mult_text,'ghz'))

8564

elseif(strcmpi(frequency_mult_text,'ghz'))

8774

frequency_mult=1e9;

8565

frequency_mult=1e9;

8775

else

8566

else

8776

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8567

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8777

end

8568

end

8778

8569

8779

%get the RI/MA/DB format

8570

%get the RI/MA/DB format

8780

format=optcell{4};

8571

format=optcell{4};

8781

%get Z0

8572

%get Z0

8782

port_impedance=str2double(optcell(6:end))';

8573

port_impedance=str2double(optcell(6:end))';

8783

8574

8784

8575

8785

%grab frequency

8576

%grab frequency

8786

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8577

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8787

Spar.F=raw_input(:,1);

8578

Spar.F=raw_input(:,1);

8788

Spar.F=transpose(Spar.F(:));

8579

Spar.F=transpose(Spar.F(:));

8789

8580

8790

8581

8791

%transform data to real imaginary

8582

%transform data to real imaginary

8792

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8583

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8793

if(strcmpi(format,'ri'))

8584

if(strcmpi(format,'ri'))

8794

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8585

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8795

elseif(strcmpi(format,'ma'))

8586

elseif(strcmpi(format,'ma'))

8796

mag_data=raw_input(:,2:2:end);

8587

mag_data=raw_input(:,2:2:end);

8797

rad_data=raw_input(:,3:2:end)*pi/180;

8588

rad_data=raw_input(:,3:2:end)*pi/180;

8798

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8589

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8799

elseif(strcmpi(format,'db'))

8590

elseif(strcmpi(format,'db'))

8800

mag_data=10.^(raw_input(:,2:2:end)/20);

8591

mag_data=10.^(raw_input(:,2:2:end)/20);

8801

rad_data=raw_input(:,3:2:end)*pi/180;

8592

rad_data=raw_input(:,3:2:end)*pi/180;

8802

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8593

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8803

else

8594

else

8804

error('Format %s is not supported. Use RI MA or DB',format);

8595

error('Format %s is not supported. Use RI MA or DB',format);

8805

end

8596

end

8806

8597

8807

8598

8808

8599

8809

%transform to 3D

8600

%transform to 3D

8810

%allow for upper/lower matrix specification for touchstone 2.0 support

8601

%allow for upper/lower matrix specification for touchstone 2.0 support

8811

matrix_format=0;

8602

matrix_format=0;

8812

if(matrix_format==0)

8603

if(matrix_format==0)

8813

%full

8604

%full

8814

for j=1:num_ports

8605

for j=1:num_ports

8815

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8606

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8816

end

8607

end

8817

elseif(matrix_format==1)

8608

elseif(matrix_format==1)

8818

%upper

8609

%upper

8819

used_ports=0;

8610

used_ports=0;

8820

for j=1:num_ports

8611

for j=1:num_ports

8821

stated_ports=num_ports-j+1;

8612

stated_ports=num_ports-j+1;

8822

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8613

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8823

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8614

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8824

used_ports=used_ports+stated_ports;

8615

used_ports=used_ports+stated_ports;

8825

end

8616

end

8826

elseif(matrix_format==2)

8617

elseif(matrix_format==2)

8827

%lower

8618

%lower

8828

used_ports=0;

8619

used_ports=0;

8829

for j=1:num_ports

8620

for j=1:num_ports

8830

stated_ports=j;

8621

stated_ports=j;

8831

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8622

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8832

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8623

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8833

used_ports=used_ports+stated_ports;

8624

used_ports=used_ports+stated_ports;

8834

end

8625

end

8835

else

8626

else

8836

error('Matrix format is not supported. Use Full, Lower, or Upper');

8627

error('Matrix format is not supported. Use Full, Lower, or Upper');

8837

end

8628

end

8838

8629

8839

8630

8840

%check for swapping the 2 port matrix (required on 1.x spec)

8631

%check for swapping the 2 port matrix (required on 1.x spec)

8841

two_port_swap=1;

8632

two_port_swap=1;

8842

if(num_ports==2 && two_port_swap==1)

8633

if(num_ports==2 && two_port_swap==1)

8843

temp=pre_out.sp(1,2,:);

8634

temp=pre_out.sp(1,2,:);

8844

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8635

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8845

pre_out.sp(2,1,:)=temp;

8636

pre_out.sp(2,1,:)=temp;

8846

end

8637

end

8847

8638

8848

Spar.S=pre_out.sp;

8639

Spar.S=pre_out.sp;

8849

Spar.Z0=transpose(port_impedance(:));

8640

Spar.Z0=transpose(port_impedance(:));

8850

8641

8851

if length(Spar.Z0)>1

8642

if length(Spar.Z0)>1

8852

error('Each port must have the same reference impedance');

8643

error('Each port must have the same reference impedance');

8853

end

8644

end

8854

if ~isequal(Spar.Z0,50)

8645

if ~isequal(Spar.Z0,50)

8855

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8646

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8856

%Renormalize to 50 ohms

8647

%Renormalize to 50 ohms

8857

rho=(50-Spar.Z0)/(50+Spar.Z0);

8648

rho=(50-Spar.Z0)/(50+Spar.Z0);

8858

p=num_ports;

8649

p=num_ports;

8859

s_old=Spar.S;

8650

s_old=Spar.S;

8860

for k=1:num_freq

8651

for k=1:num_freq

8861

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8652

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8862

end

8653

end

8863

end

8654

end

8864

8655

8865

%These operations sync up with COM style Spar matrix

8656

%These operations sync up with COM style Spar matrix

8866

%1: put frequency as first dimension

8657

%1: put frequency as first dimension

8867

sch=shiftdim(Spar.S,2);

8658

sch=shiftdim(Spar.S,2);

8868

%2: reorder ports according to "ports" input

8659

%2: reorder ports according to "ports" input

8869

sch=sch(:,port_order,port_order);

8660

sch=sch(:,port_order,port_order);

8870

schFreqAxis=Spar.F;

8661

schFreqAxis=Spar.F;

8871

function [chdata, param] = read_PR_files(param, OP, chdata)

8662

function [chdata, param] = read_PR_files(param, OP, chdata)

8872

%% Read in pulse response

8663

%% Read in pulse response

8873

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8664

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8874

num_files=length(chdata);

8665

num_files=length(chdata);

8875

M=param.samples_per_ui;

8666

M=param.samples_per_ui;

8876

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8667

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8877

for i=1:num_files

8668

for i=1:num_files

8878

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8669

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8879

progress = i/num_files;

8670

progress = i/num_files;

8880

if OP.DISPLAY_WINDOW

8671

if OP.DISPLAY_WINDOW

8881

[~,a]=fileparts(chdata(i).filename);

8672

[~,a]=fileparts(chdata(i).filename);

8882

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8673

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8883

else

8674

else

8884

fprintf('%i ',i);

8675

fprintf('%i ',i);

8885

end

8676

end

8886

switch chdata(i).ext

8677

switch chdata(i).ext

8887

case '.csv'

8678

case '.csv'

8888

vt=load(chdata(i).filename);

8679

vt=load(chdata(i).filename);

8889

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8680

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8890

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8681

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8891

dt=vt(2,1)-vt(1,1);

8682

dt=vt(2,1)-vt(1,1);

8892

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8683

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8893

8684

8894

8685

8895

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8686

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8896

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8687

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8897

Vf=step_response(end);

8688

Vf=step_response(end);

8898

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8689

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8899

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8690

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8900

8691

8901

end

8692

end

8902

end

8693

end

8903

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8694

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8904

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8695

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8905

[filepath,name,ext] = fileparts(paramFile);

8696

[filepath,name,ext] = fileparts(paramFile);

8906

if ~isempty(filepath)

8697

if ~isempty(filepath)

8907

filepath=[filepath '\'];

8698

filepath=[filepath '\'];

8908

end

8699

end

8909

matcongfile=[filepath name '.mat'];

8700

matcongfile=[filepath name '.mat'];

8910

try

8701

try

8911

switch upper(ext)

8702

switch upper(ext)

8912

case upper('.mat')

8703

case upper('.mat')

8913

load(matcongfile)

8704

load(matcongfile)

8914

case upper('.csv')

8705

case upper('.csv')

8915

[na1, na2, parameter] = xlsread(paramFile);

8706

[na1, na2, parameter] = xlsread(paramFile);

8916

otherwise

8707

otherwise

8917

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8708

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8918

end

8709

end

8919

8710

8920

catch ME %#ok<NASGU>

8711

catch ME %#ok<NASGU>

8921

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8712

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8922

switch upper(ext)

8713

switch upper(ext)

8923

case upper('.mat')

8714

case upper('.mat')

8924

load(matcongfile)

8715

load(matcongfile)

8925

case upper('.csv')

8716

case upper('.csv')

8926

[na1, na2, parameter] = xlsread(paramFile);

8717

[na1, na2, parameter] = xlsread(paramFile);

8927

otherwise

8718

otherwise

8928

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8719

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8929

end

8720

end

8930

end

8721

end

8931

8722

8932

%% New section to parse .START package data

8723

%% New section to parse .START package data

8933

first_column_data = parameter(:,1);

8724

first_column_data = parameter(:,1);

8934

start_data_rows = find(strcmp(first_column_data,'.START'));

8725

start_data_rows = find(strcmp(first_column_data,'.START'));

8935

if ~isempty(start_data_rows)

8726

if ~isempty(start_data_rows)

8936

end_data_rows = find(strcmp(first_column_data,'.END'));

8727

end_data_rows = find(strcmp(first_column_data,'.END'));

8937

if length(start_data_rows) ~= length(end_data_rows)

8728

if length(start_data_rows) ~= length(end_data_rows)

8938

error('Number of .START and .END must be the same');

8729

error('Number of .START and .END must be the same');

8939

end

8730

end

8940

first_start_row = start_data_rows(1);

8731

first_start_row = start_data_rows(1);

8941

special_parameter = parameter;

8732

special_parameter = parameter;

8942

parameter = parameter(1:first_start_row-1,:);

8733

parameter = parameter(1:first_start_row-1,:);

8943

for j=1:length(start_data_rows)

8734

for j=1:length(start_data_rows)

8944

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

8735

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

8945

pkg_name = special_parameter{start_data_rows(j),2};

8736

pkg_name = special_parameter{start_data_rows(j),2};

8946

8737

8947

%Read all the parameters that make up a package

8738

%Read all the parameters that make up a package

8948

PKG_param = read_package_parameters(this_block);

8739

PKG_param = read_package_parameters(this_block);

8949

8740

8950

%save the data in a field revealed by pkg_name

8741

%save the data in a field revealed by pkg_name

8951

param.PKG.(pkg_name) = PKG_param;

8742

param.PKG.(pkg_name) = PKG_param;

8952

8743

8953

8744

8954

end

8745

end

8955

end

8746

end

8956

%Allow specification of TX and RX package section through PKG_NAME keyword

8747

%Allow specification of TX and RX package section through PKG_NAME keyword

8957

%the values must match package blocks specified in .START sections

8748

%the values must match package blocks specified in .START sections

8958

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

8749

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

8959

if isnan(param.PKG_NAME)

8750

if isnan(param.PKG_NAME)

8960

param.PKG_NAME = '';

8751

param.PKG_NAME = '';

8961

end

8752

end

8962

if isempty(param.PKG_NAME)

8753

if isempty(param.PKG_NAME)

8963

param.PKG_NAME = {};

8754

param.PKG_NAME = {};

8964

else

8755

else

8965

param.PKG_NAME = strsplit(param.PKG_NAME);

8756

param.PKG_NAME = strsplit(param.PKG_NAME);

8966

end

8757

end

8967

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

8758

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

8968

error('PKG_NAME can only be used if .START blocks for package parameters are used');

8759

error('PKG_NAME can only be used if .START blocks for package parameters are used');

8969

end

8760

end

8970

for j=1:length(param.PKG_NAME)

8761

for j=1:length(param.PKG_NAME)

8971

if ~isfield(param.PKG,param.PKG_NAME{j})

8762

if ~isfield(param.PKG,param.PKG_NAME{j})

8972

error('Package Block "%s" not found',param.PKG_NAME{j});

8763

error('Package Block "%s" not found',param.PKG_NAME{j});

8973

end

8764

end

8974

end

8765

end

8975

8766

8976

%%

8767

%%

8977

% just need to define so we can pass

8768

% just need to define so we can pass

8978

param.c=[.4e-12 .4e-12];

8769

param.c=[.4e-12 .4e-12];

8979

param.alen=[ 20 30 550 ];

8770

param.alen=[ 20 30 550 ];

8980

param.az=[100 120 100];

8771

param.az=[100 120 100];

8981

8772

8982

% make control for package/channel reflection control

8773

% make control for package/channel reflection control

8983

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

8774

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

8984

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

8775

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

8985

8776

8986

8777

8987

% make compatible with presentation of kappa

8778

% make compatible with presentation of kappa

8988

8779

8989

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

8780

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

8990

8781

8991

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

8782

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

8992

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

8783

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

8993

8784

8994

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

8785

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

8995

param.f2 = xls_parameter(parameter, 'f_2', true, param.fb/1e9 )*1e9; % frequency in GHz for intergration compuation of ICN or FOM_Ild in GHz

8786

param.f2 = xls_parameter(parameter, 'f_2', true, param.fb/1e9 )*1e9; % frequency in GHz for intergration compuation of ICN or FOM_Ild in GHz

8996

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

8787

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

8997

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

8788

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

8998

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

8789

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

8999

param.tx_ffe_c0_min = xls_parameter(parameter, 'c(0)', false); % TX equalizer cursor minimum value (actual value is calculated as 1-sum(abs(tap)), Grid seat ingored for when C(0) is below this value

8790

param.tx_ffe_c0_min = xls_parameter(parameter, 'c(0)', false); % TX equalizer cursor minimum value (actual value is calculated as 1-sum(abs(tap)), Grid seat ingored for when C(0) is below this value

9000

8791

9001

if OP.dynamic_txffe

8792

if OP.dynamic_txffe

9002

found_pre=1;

8793

found_pre=1;

9003

pre_count=1;

8794

pre_count=1;

9004

while found_pre

8795

while found_pre

9005

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

8796

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

9006

if found_pre

8797

if found_pre

9007

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

8798

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

9008

param.(field_name)=p;

8799

param.(field_name)=p;

9009

pre_count=pre_count+1;

8800

pre_count=pre_count+1;

9010

end

8801

end

9011

end

8802

end

9012

found_post=1;

8803

found_post=1;

9013

post_count=1;

8804

post_count=1;

9014

while found_post

8805

while found_post

9015

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

8806

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

9016

if found_post

8807

if found_post

9017

field_name=sprintf('tx_ffe_cp%d_values',post_count);

8808

field_name=sprintf('tx_ffe_cp%d_values',post_count);

9018

param.(field_name)=p;

8809

param.(field_name)=p;

9019

post_count=post_count+1;

8810

post_count=post_count+1;

9020

end

8811

end

9021

end

8812

end

9022

else

8813

else

9023

param.tx_ffe_cm4_values = xls_parameter(parameter, 'c(-4)', true,0); % TX equalizer pre cursor tap -4 individual settings or range. If not present ignored

8814

param.tx_ffe_cm4_values = xls_parameter(parameter, 'c(-4)', true,0); % TX equalizer pre cursor tap -4 individual settings or range. If not present ignored

9024

param.tx_ffe_cm3_values = xls_parameter(parameter, 'c(-3)', true,0); % TX equalizer pre cursor tap -3 individual settings or range. If not present ignored

8815

param.tx_ffe_cm3_values = xls_parameter(parameter, 'c(-3)', true,0); % TX equalizer pre cursor tap -3 individual settings or range. If not present ignored

9025

param.tx_ffe_cm2_values = xls_parameter(parameter, 'c(-2)', true,0); % TX equalizer pre cursor tap -2 individual settings or range. If not present ignored

8816

param.tx_ffe_cm2_values = xls_parameter(parameter, 'c(-2)', true,0); % TX equalizer pre cursor tap -2 individual settings or range. If not present ignored

9026

param.tx_ffe_cm1_values = xls_parameter(parameter, 'c(-1)', true,0); % TX equalizer pre cursor tap -1 individual settings or range. If not present ignored

8817

param.tx_ffe_cm1_values = xls_parameter(parameter, 'c(-1)', true,0); % TX equalizer pre cursor tap -1 individual settings or range. If not present ignored

9027

param.tx_ffe_cp1_values = xls_parameter(parameter, 'c(1)', true,0); % TX equalizer post cursor tap 1 individual settings or range. If not present ignored

8818

param.tx_ffe_cp1_values = xls_parameter(parameter, 'c(1)', true,0); % TX equalizer post cursor tap 1 individual settings or range. If not present ignored

9028

param.tx_ffe_cp2_values = xls_parameter(parameter, 'c(2)', true,0); % TX equalizer post cursor tap 2 individual settings or range. If not present ignored

8819

param.tx_ffe_cp2_values = xls_parameter(parameter, 'c(2)', true,0); % TX equalizer post cursor tap 2 individual settings or range. If not present ignored

9029

param.tx_ffe_cp3_values = xls_parameter(parameter, 'c(3)', true,0); % TX equalizer post cursor tap 3 individual settings or range. If not present ignored

8820

param.tx_ffe_cp3_values = xls_parameter(parameter, 'c(3)', true,0); % TX equalizer post cursor tap 3 individual settings or range. If not present ignored

9030

end

8821

end

9031

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

8822

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

9032

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

8823

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

9033

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

8824

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

9034

param.N_bx = xls_parameter(parameter, 'N_bx', true, param.ndfe ); % Used for ERL to Compensate for a number of Ui assoicated with the DFE

8825

param.N_bx = xls_parameter(parameter, 'N_bx', true, param.ndfe ); % Used for ERL to Compensate for a number of Ui assoicated with the DFE

9035

% support for floating taps

8826

% support for floating taps

9036

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

8827

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

9037

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

8828

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

9038

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

8829

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

9039

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

8830

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

9040

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

8831

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

9041

if param.N_bg == 0, param.N_bmax=param.ndfe; end

8832

if param.N_bg == 0, param.N_bmax=param.ndfe; end

9042

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

8833

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

9043

8834

9044

% support for tail tap power limitations

8835

% support for tail tap power limitations

9045

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

8836

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

9046

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

8837

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

9047

%

8838

%

9048

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

8839

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

9049

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

8840

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

9050

param.RxFFE_cmx=param.ffe_pre_tap_len;

8841

param.RxFFE_cmx=param.ffe_pre_tap_len;

9051

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

8842

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

9052

param.RxFFE_cpx=param.ffe_post_tap_len;

8843

param.RxFFE_cpx=param.ffe_post_tap_len;

9053

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

8844

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

9054

param.RxFFE_stepz=param.ffe_tap_step_size;

8845

param.RxFFE_stepz=param.ffe_tap_step_size;

9055

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

8846

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

9056

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

8847

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

9057

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

8848

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

9058

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

8849

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

9059

param.ffe_backoff=xls_parameter(parameter, 'ffe_backoff', true,0); % see if better zero foreced solution is better by backing off the number specified FFE taps one at at time

8850

param.ffe_backoff=xls_parameter(parameter, 'ffe_backoff', true,0); % see if better zero foreced solution is better by backing off the number specified FFE taps one at at time

9060

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

8851

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

9061

OP.RxFFE= true;

8852

OP.RxFFE= true;

9062

else

8853

else

9063

OP.RxFFE=false;

8854

OP.RxFFE=false;

9064

end

8855

end

9065

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

8856

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

9066

8857

9067

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

8858

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

9068

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

8859

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

9069

param.f_HP_Z = 1e9*xls_parameter(parameter, 'f_HP_Z', true, []); % CFT zero fz1 is in GHz. Normally a list for 120e. Not normally use elsewise

8860

param.f_HP_Z = 1e9*xls_parameter(parameter, 'f_HP_Z', true, []); % CFT zero fz1 is in GHz. Normally a list for 120e. Not normally use elsewise

9070

param.f_HP_P = 1e9*xls_parameter(parameter, 'f_HP_P', true, []); % CFT pole fp2 is in GHz. Normally a list for 120e. Not normally use elsewise

8861

param.f_HP_P = 1e9*xls_parameter(parameter, 'f_HP_P', true, []); % CFT pole fp2 is in GHz. Normally a list for 120e. Not normally use elsewise

9071

8862

9072

8863

9073

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

8864

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

9074

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

8865

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

9075

param.Min_VEO_Test= xls_parameter(parameter, 'EH_min_test', true,0); % Older syntax. Used when PMD_type is C2M. This allow EH to go below EH_min. If set to zero it is ignored (same as Min_VEO_test)

8866

param.Min_VEO_Test= xls_parameter(parameter, 'EH_min_test', true,0); % Older syntax. Used when PMD_type is C2M. This allow EH to go below EH_min. If set to zero it is ignored (same as Min_VEO_test)

9076

param.Min_VEO_Test= xls_parameter(parameter, 'Min_VEO_Test', true,param.Min_VEO_Test); % used when PMD_type is C2M. This allow EH to go blow EH_min. If set to Zero it is ignored

8867

param.Min_VEO_Test= xls_parameter(parameter, 'Min_VEO_Test', true,param.Min_VEO_Test); % used when PMD_type is C2M. This allow EH to go blow EH_min. If set to Zero it is ignored

9077

8868

9078

param.CTLE_type= xls_parameter(parameter, 'CTLE_type', false,'CL93'); % Sets the CTLE type default is poles and zeros (i.e. not a list of poles as in 120e)

8869

param.CTLE_type= xls_parameter(parameter, 'CTLE_type', false,'CL93'); % Sets the CTLE type default is poles and zeros (i.e. not a list of poles as in 120e)

9079

if ~isempty(param.g_DC_HP_values) ; param.CTLE_type='CL120d';end % overrides CL93 if g_DC_HP_values are a spreadsheet entry. Mostly used when baud rare is >= 50Gbps

8870

if ~isempty(param.g_DC_HP_values) ; param.CTLE_type='CL120d';end % overrides CL93 if g_DC_HP_values are a spreadsheet entry. Mostly used when baud rare is >= 50Gbps

9080

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

8871

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

9081

% always read in main ctle values. They would be interpreted different baseed

8872

% always read in main ctle values. They would be interpreted different baseed

9082

% on the clause they apply because of different CTF equations

8873

% on the clause they apply because of different CTF equations

9083

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

8874

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

9084

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8875

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9085

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8876

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9086

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8877

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9087

% the contex of the poles an zeros are determined by the clause

8878

% the contex of the poles an zeros are determined by the clause

9088

switch param.CTLE_type

8879

switch param.CTLE_type

9089

case 'CL93'

8880

case 'CL93'

9090

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % Continuous time filter DC gain settings (G_DC) or range as specified in Annex 93A

8881

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % Continuous time filter DC gain settings (G_DC) or range as specified in Annex 93A

9091

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8882

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9092

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8883

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9093

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8884

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9094

case 'CL120d'

8885

case 'CL120d'

9095

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

8886

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

9096

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

8887

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

9097

case 'CL120e'

8888

case 'CL120e'

9098

% re adjust to get TD_CTLE to work with C:120e equation without

8889

% re adjust to get TD_CTLE to work with C:120e equation without

9099

% changing TD_CTLE code

8890

% changing TD_CTLE code

9100

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

8891

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

9101

end

8892

end

9102

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

8893

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

9103

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

8894

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

9104

param.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

8895

param.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9105

param.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

8896

param.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9106

param.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

8897

param.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9107

param.a_icn_fext = xls_parameter(parameter, 'A_ft', true, param.a_fext); % FEXT aggressor amplitude for ICN. Defaults to A_fe if not specified

8898

param.a_icn_fext = xls_parameter(parameter, 'A_ft', true, param.a_fext); % FEXT aggressor amplitude for ICN. Defaults to A_fe if not specified

9108

param.a_icn_next = xls_parameter(parameter, 'A_nt', true, param.a_next );% NEXT aggressor amplitude for ICN. Defaults to A_ne if not specified

8899

param.a_icn_next = xls_parameter(parameter, 'A_nt', true, param.a_next );% NEXT aggressor amplitude for ICN. Defaults to A_ne if not specified

9109

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

8900

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

9110

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

8901

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

9111

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

8902

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

9112

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

8903

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

9113

param.VEC_pass_threshold = xls_parameter(parameter, 'VEC Pass threshold',false,0);% the pass fail threshold for VEC in dB only used when PMD_type is C2M

8904

param.VEC_pass_threshold = xls_parameter(parameter, 'VEC Pass threshold',false,0);% the pass fail threshold for VEC in dB only used when PMD_type is C2M

9114

8905

9115

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

8906

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

9116

param.A_DD = xls_parameter(parameter, 'A_DD'); % Normalized peak dual-Dirac noise, this is half of the total bound uncorrelated jitter (BUJ) in UI

8907

param.A_DD = xls_parameter(parameter, 'A_DD'); % Normalized peak dual-Dirac noise, this is half of the total bound uncorrelated jitter (BUJ) in UI

9117

param.eta_0 = xls_parameter(parameter, 'eta_0'); % One-sided noise spectral density (V^2/GHz).Input refered noise at TP5. Input referred noise at TP5

8908

param.eta_0 = xls_parameter(parameter, 'eta_0'); % One-sided noise spectral density (V^2/GHz).Input refered noise at TP5. Input referred noise at TP5

9118

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

8909

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

9119

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

8910

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

9120

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

8911

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

9121

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

8912

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

9122

param.ts_anchor = xls_parameter(parameter, 'ts_anchor', true, 0); %choice of sampling routine. 0=MM, 1=Peak, 2=max DV (max cursor minus precursor)

8913

param.ts_anchor = xls_parameter(parameter, 'ts_anchor', true, 0); %choice of sampling routine. 0=MM, 1=Peak, 2=max DV (max cursor minus precursor)

9123

% This will keep bmax length 0 if Nb=0

8914

% This will keep bmax length 0 if Nb=0

9124

8915

9125

%AJG021820

8916

%AJG021820

9126

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

8917

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

9127

if isempty(param.bmax)

8918

if isempty(param.bmax)

9128

param.bmin=param.bmax;

8919

param.bmin=param.bmax;

9129

else

8920

else

9130

param.bmin(1:param.ndfe) =xls_parameter(parameter, 'b_min(1)', true,-param.bmax(1) ); % DFE negative magnitude limit. If not specified it defaults to -bmax.

8921

param.bmin(1:param.ndfe) =xls_parameter(parameter, 'b_min(1)', true,-param.bmax(1) ); % DFE negative magnitude limit. If not specified it defaults to -bmax.

9131

8922

9132

end

8923

end

9133

if param.ndfe >= 2

8924

if param.ndfe >= 2

9134

param.bmax(2:param.ndfe) = xls_parameter(parameter, 'b_max(2..N_b)', true, .2); % DFE magnitude limit, second coefficient and on (ignored if Nb<2). Can be a regualar expression

8925

param.bmax(2:param.ndfe) = xls_parameter(parameter, 'b_max(2..N_b)', true, .2); % DFE magnitude limit, second coefficient and on (ignored if Nb<2). Can be a regualar expression

9135

param.bmin(2:param.ndfe) = xls_parameter(parameter, 'b_min(2..N_b)', true, -1*param.bmax(2:param.ndfe) ); % DFE negative magnitude limit, if not specified it defaults to -b_max(2..N_b)

8926

param.bmin(2:param.ndfe) = xls_parameter(parameter, 'b_min(2..N_b)', true, -1*param.bmax(2:param.ndfe) ); % DFE negative magnitude limit, if not specified it defaults to -b_max(2..N_b)

9136

end

8927

end

9137

8928

9138

param.gqual=xls_parameter(parameter, 'G_Qual', true,[]);% G_Qual are the dB ranges of g_DC g DC )which correspond tog_DC_HP (g DC2)

8929

param.gqual=xls_parameter(parameter, 'G_Qual', true,[]);% G_Qual are the dB ranges of g_DC g DC )which correspond tog_DC_HP (g DC2)

9139

param.g2qual=xls_parameter(parameter, 'G2_Qual', true,[]); % G2_Qual limit values of g_DC_HP (g DC2 ) which corresponds to ranges of g_DC g DC specified with G_QUAL

8930

param.g2qual=xls_parameter(parameter, 'G2_Qual', true,[]); % G2_Qual limit values of g_DC_HP (g DC2 ) which corresponds to ranges of g_DC g DC specified with G_QUAL

9140

%verify gqual and gqual2 input

8931

%verify gqual and gqual2 input

9141

if ~isempty(param.gqual) || ~isempty(param.g2qual)

8932

if ~isempty(param.gqual) || ~isempty(param.g2qual)

9142

if size(param.gqual,1)~=length(param.g2qual)

8933

if size(param.gqual,1)~=length(param.g2qual)

9143

error('gqual and g2qual size mismatch');

8934

error('gqual and g2qual size mismatch');

9144

end

8935

end

9145

if size(param.gqual,2)~=2

8936

if size(param.gqual,2)~=2

9146

error('gqual must be Nx2 matrix');

8937

error('gqual must be Nx2 matrix');

9147

end

8938

end

9148

end

8939

end

9149

8940

9150

8941

9151

% eval if string for all three - can use different for TX and RX

8942

% eval if string for all three - can use different for TX and RX

9152

param.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

8943

param.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9153

param.C_diepad = xls_parameter(parameter, 'C_d', true)*1e-9; % C_d in nF (single sided)

8944

param.C_diepad = xls_parameter(parameter, 'C_d', true)*1e-9; % C_d in nF (single sided)

9154

% [ahealey] Read values for optional compensating L and "bump" C

8945

% [ahealey] Read values for optional compensating L and "bump" C

9155

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

8946

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

9156

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

8947

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

9157

% [ahealey] End of modifications.

8948

% [ahealey] End of modifications.

9158

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

8949

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

9159

param.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

8950

param.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9160

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

8951

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

9161

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

8952

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

9162

8953

9163

8954

9164

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

8955

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

9165

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

8956

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9166

[ncases, mele]=size(param.z_p_tx_cases);

8957

[ncases, mele]=size(param.z_p_tx_cases);

9167

if mele ==2

8958

if mele ==2

9168

param.flex=2;

8959

param.flex=2;

9169

elseif mele==4

8960

elseif mele==4

9170

param.flex=4;

8961

param.flex=4;

9171

elseif mele==1

8962

elseif mele==1

9172

param.flex=1;

8963

param.flex=1;

9173

else

8964

else

9174

error(sprintf('config file syntax error'))

8965

error(sprintf('config file syntax error'))

9175

end

8966

end

9176

8967

9177

% board parameters

8968

% board parameters

9178

param.C_0 = xls_parameter(parameter, 'C_0', true,0)*1e-9; % If Include PCB is set to 1, near device single ended capacitance C0 in nF is added

8969

param.C_0 = xls_parameter(parameter, 'C_0', true,0)*1e-9; % If Include PCB is set to 1, near device single ended capacitance C0 in nF is added

9179

param.C_1 = xls_parameter(parameter, 'C_1', true,0)*1e-9; % if Include PCB is set to 1, connector side single ended capacitance C1 in nF is added

8970

param.C_1 = xls_parameter(parameter, 'C_1', true,0)*1e-9; % if Include PCB is set to 1, connector side single ended capacitance C1 in nF is added

9180

%

8971

%

9181

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

8972

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9182

[ncases1, mele1]=size(param.z_p_next_cases);

8973

[ncases1, mele1]=size(param.z_p_next_cases);

9183

if ncases ~= ncases1 || mele ~= mele1

8974

if ncases ~= ncases1 || mele ~= mele1

9184

error('All TX, NEXT, FEXT, Rx cases must agree');

8975

error('All TX, NEXT, FEXT, Rx cases must agree');

9185

else

8976

else

9186

end

8977

end

9187

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

8978

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9188

[ncases1, mele1]=size(param.z_p_fext_cases);

8979

[ncases1, mele1]=size(param.z_p_fext_cases);

9189

if ncases ~= ncases1 || mele ~= mele1

8980

if ncases ~= ncases1 || mele ~= mele1

9190

error('All TX, NEXT, FEXT, Rx cases must agree');

8981

error('All TX, NEXT, FEXT, Rx cases must agree');

9191

else

8982

else

9192

end

8983

end

9193

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

8984

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9194

[ncases1, mele1]=size(param.z_p_rx_cases);

8985

[ncases1, mele1]=size(param.z_p_rx_cases);

9195

if ncases ~= ncases1 || mele ~= mele1

8986

if ncases ~= ncases1 || mele ~= mele1

9196

error('All TX, NEXT, FEXT, Rx cases must agree');

8987

error('All TX, NEXT, FEXT, Rx cases must agree');

9197

else

8988

else

9198

end

8989

end

9199

% Table 93A-3 parameters

8990

% Table 93A-3 parameters

9200

param.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

8991

param.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9201

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

8992

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9202

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

8993

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9203

[ ncases1, mele1]=size(param.pkg_Z_c);%

8994

[ ncases1, mele1]=size(param.pkg_Z_c);%

9204

if mele ~= mele1

8995

if mele ~= mele1

9205

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

8996

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9206

else

8997

else

9207

end

8998

end

9208

if mele1==2 % fuill in a array if only a 2 element flex package is specified

8999

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9209

for ii=1:ncases

9000

for ii=1:ncases

9210

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9001

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9211

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9002

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9212

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9003

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9213

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9004

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9214

end

9005

end

9215

param.z_p_fext_cases = param.z_p_fext_casesx;

9006

param.z_p_fext_cases = param.z_p_fext_casesx;

9216

param.z_p_next_cases= param.z_p_next_casesx;

9007

param.z_p_next_cases= param.z_p_next_casesx;

9217

param.z_p_tx_cases= param.z_p_tx_casesx;

9008

param.z_p_tx_cases= param.z_p_tx_casesx;

9218

param.z_p_rx_cases= param.z_p_rx_casesx;

9009

param.z_p_rx_cases= param.z_p_rx_casesx;

9219

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9010

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9220

end

9011

end

9221

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9012

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9222

9013

9223

% Table 92-12 parameters

9014

% Table 92-12 parameters

9224

param.brd_gamma0_a1_a2 = xls_parameter(parameter, 'board_tl_gamma0_a1_a2', true, [0 4.114e-4 2.547e-4]); % Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9015

param.brd_gamma0_a1_a2 = xls_parameter(parameter, 'board_tl_gamma0_a1_a2', true, [0 4.114e-4 2.547e-4]); % Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9225

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9016

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9226

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9017

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9227

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9018

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9228

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9019

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9229

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9020

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9230

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9021

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9231

9022

9232

% Unofficial parameters

9023

% Unofficial parameters

9233

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9024

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9234

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9025

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9235

% Deprecated parameters - affect only frequency domain analysis.

9026

% Deprecated parameters - affect only frequency domain analysis.

9236

param.f_v = xls_parameter(parameter, 'f_v', true, 4); % For FOM_ILD: Transiton rate cut off frequency for ICN/ILD calc in terms of fb

9027

param.f_v = xls_parameter(parameter, 'f_v', true, 4); % For FOM_ILD: Transiton rate cut off frequency for ICN/ILD calc in terms of fb

9237

param.f_f = xls_parameter(parameter, 'f_f', true, 4); % For ICN: Fext transiton rate cut off frequency for ICN calc in terms of fb

9028

param.f_f = xls_parameter(parameter, 'f_f', true, 4); % For ICN: Fext transiton rate cut off frequency for ICN calc in terms of fb

9238

param.f_n = xls_parameter(parameter, 'f_n', true, 4); % For ICN: Next transiton rate cut off frequency for ICN calc in terms of fb

9029

param.f_n = xls_parameter(parameter, 'f_n', true, 4); % For ICN: Next transiton rate cut off frequency for ICN calc in terms of fb

9239

param.f_r = xls_parameter(parameter, 'f_r', true, 4); % reference receive filter in COM and in ICN/FOM_ILD calcs in terms of fb

9030

param.f_r = xls_parameter(parameter, 'f_r', true, 4); % reference receive filter in COM and in ICN/FOM_ILD calcs in terms of fb

9240

param.fb_BT_cutoff= xls_parameter(parameter, 'TDR_f_BT_3db', true, 0.4730); % Bessel-Thomson 3 dB cut off freqeuncy in terms of fb

9031

param.fb_BT_cutoff= xls_parameter(parameter, 'TDR_f_BT_3db', true, 0.4730); % Bessel-Thomson 3 dB cut off freqeuncy in terms of fb

9241

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9032

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9242

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9033

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9243

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9034

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9244

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9035

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9245

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9036

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9246

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9037

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9247

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9038

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9248

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9039

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9249

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9040

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9250

switch param.Gx

9041

switch param.Gx

9251

case 0

9042

case 0

9252

param.Grr=param.Grr; % just use older Grr ir gx not specified

9043

param.Grr=param.Grr; % just use older Grr ir gx not specified

9253

case 1

9044

case 1

9254

param.Grr=2; % use newer Grr

9045

param.Grr=2; % use newer Grr

9255

end

9046

end

9256

9047

9257

param.LOCAL_SEARCH=xls_parameter(parameter,'Local Search',true,0); % Decreases COM compute time. Aetting to 2 seems ok ,if 0 search is full grid

9048

param.LOCAL_SEARCH=xls_parameter(parameter,'Local Search',true,0); % Decreases COM compute time. Aetting to 2 seems ok ,if 0 search is full grid

9258

% Operational control variables

9049

% Operational control variables

9259

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9050

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9260

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9051

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9261

param.Noise_Crest_Factor= xls_parameter(parameter, 'Noise_Crest_Factor', true, 0); % Normally not used. If set this is q factor used for quantized Gaussian PDFs

9052

param.Noise_Crest_Factor= xls_parameter(parameter, 'Noise_Crest_Factor', true, 0); % Normally not used. If set this is q factor used for quantized Gaussian PDFs

9262

param.AC_CM_RMS = xls_parameter(parameter, 'AC_CM_RMS', true, 0); % AC_CM_RMS is the CM BBN AWGN RMS at COM source point. Default is 0. Adds common mode noise source to the COM signal path for the through channel

9053

param.AC_CM_RMS = xls_parameter(parameter, 'AC_CM_RMS', true, 0); % AC_CM_RMS is the CM BBN AWGN RMS at COM source point. Default is 0. Adds common mode noise source to the COM signal path for the through channel

9263

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9054

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9264

param.T_O = xls_parameter(parameter, 'T_O', true, 0 ); % Units are mUI. Histogram for VEC and VEO are computed over T_s +/- T_O.

9055

param.T_O = xls_parameter(parameter, 'T_O', true, 0 ); % Units are mUI. Histogram for VEC and VEO are computed over T_s +/- T_O.

9265

param.T_O = xls_parameter(parameter, 'T_h', true, param.T_O ); % superceded with T_O but is the internal values that is used. Do not use.

9056

param.T_O = xls_parameter(parameter, 'T_h', true, param.T_O ); % superceded with T_O but is the internal values that is used. Do not use.

9266

9057

9267

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9058

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9268

9059

9269

OP.Histogram_Window_Weight=xls_parameter(parameter, 'Histogram_Window_Weight', false, 'rectangle' ); %Weighting for VEC and VEO are histogram processing. Type are Gaussian,Dual Rayleigh,Triangle, and Rectangle (default)

9060

OP.Histogram_Window_Weight=xls_parameter(parameter, 'Histogram_Window_Weight', false, 'rectangle' ); %Weighting for VEC and VEO are histogram processing. Type are Gaussian,Dual Rayleigh,Triangle, and Rectangle (default)

9270

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9061

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9271

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9062

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9272

param.QL=xls_parameter(parameter, 'QL', true, param.T_O/param.Qr/1000 ); % superceded with sigma_r but is the internal values that is used

9063

param.QL=xls_parameter(parameter, 'QL', true, param.T_O/param.Qr/1000 ); % superceded with sigma_r but is the internal values that is used

9273

9064

9274

%%

9065

%%

9275

9066

9276

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9067

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9277

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9068

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9278

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9069

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9279

param.awgn_mv=param.AC_CM_RMS;

9070

param.awgn_mv=param.AC_CM_RMS;

9280

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9071

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9281

param.f_hp=xls_parameter(parameter, 'f_hp', true, 0 ); % for rx testing for eq 162-12 if 0 (default) then rx test using rx bbn

9072

param.f_hp=xls_parameter(parameter, 'f_hp', true, 0 ); % for rx testing for eq 162-12 if 0 (default) then rx test using rx bbn

9282

9073

9283

9074

9284

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9075

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9285

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9076

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9286

param.Floating_RXFFE=false;

9077

param.Floating_RXFFE=false;

9287

param.Floating_DFE=false;

9078

param.Floating_DFE=false;

9288

if param.N_bg > 0

9079

if param.N_bg > 0

9289

param.Floating_DFE=true;

9080

param.Floating_DFE=true;

9290

end

9081

end

9291

if OP.RxFFE

9082

if OP.RxFFE

9292

param.Floating_DFE=false;

9083

param.Floating_DFE=false;

9293

if param.N_bg > 0

9084

if param.N_bg > 0

9294

param.Floating_RXFFE=true;

9085

param.Floating_RXFFE=true;

9295

end

9086

end

9296

end

9087

end

9297

%% for introducing Tx or Rx skew on p leg or n leg

9088

%% for introducing Tx or Rx skew on p leg or n leg

9298

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9089

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9299

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9090

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9300

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9091

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9301

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9092

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9302

9093

9303

%%

9094

%%

9304

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9095

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9305

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9096

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9306

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9097

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9307

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9098

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9308

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9099

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9309

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9100

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9310

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9101

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9311

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9102

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9312

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9103

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9313

OP.CSV_REPORT = xls_parameter(parameter, 'CSV_REPORT', false, true); % saves all the output parameters to a CSV file in the results directory, If DIAGNOSTICS is set then a mat file is also created

9104

OP.CSV_REPORT = xls_parameter(parameter, 'CSV_REPORT', false, true); % saves all the output parameters to a CSV file in the results directory, If DIAGNOSTICS is set then a mat file is also created

9314

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9105

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9315

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9106

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9316

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9107

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9317

OP.GET_FD = xls_parameter(parameter, 'Display frequency domain', false, OP.GET_FD); % Not normally set in the config file. It is normally just set to true to get FD plots

9108

OP.GET_FD = xls_parameter(parameter, 'Display frequency domain', false, OP.GET_FD); % Not normally set in the config file. It is normally just set to true to get FD plots

9318

OP.INC_PACKAGE = xls_parameter(parameter, 'INC_PACKAGE', false, true); % warning: INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1

9109

OP.INC_PACKAGE = xls_parameter(parameter, 'INC_PACKAGE', false, true); % warning: INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1

9319

if ~OP.INC_PACKAGE

9110

if ~OP.INC_PACKAGE

9320

fprintf('<strong> Warning!!! INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9111

fprintf('<strong> Warning!!! INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9321

end

9112

end

9322

9113

9323

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9114

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9324

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9115

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9325

if OP.IDEAL_TX_TERM

9116

if OP.IDEAL_TX_TERM

9326

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9117

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9327

end

9118

end

9328

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9119

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9329

if OP.IDEAL_RX_TERM

9120

if OP.IDEAL_RX_TERM

9330

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9121

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9331

end

9122

end

9332

9123

9333

OP.TDMODE = xls_parameter(parameter, 'TDMODE',false, OP.TDMODE); % Enables the the use of pulse response instead of s-parameters. Assumes no packages or the packages are included in the PR. Default is 0.

9124

OP.TDMODE = xls_parameter(parameter, 'TDMODE',false, OP.TDMODE); % Enables the the use of pulse response instead of s-parameters. Assumes no packages or the packages are included in the PR. Default is 0.

9334

9125

9335

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9126

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9336

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9127

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9337

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9128

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9338

OP.BREAD_CRUMBS = xls_parameter(parameter, 'BREAD_CRUMBS',false, false); % if DIAGNOSTICS is set then param, OP, and chdata are include in the output for each run

9129

OP.BREAD_CRUMBS = xls_parameter(parameter, 'BREAD_CRUMBS',false, false); % if DIAGNOSTICS is set then param, OP, and chdata are include in the output for each run

9339

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9130

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9340

OP.COM_CONTRIBUTION_CURVES = xls_parameter(parameter, 'COM_CONTRIBUTION',false,0); % Default is 0. If set to 1 then a bar graph of COM contributors is produce instead of bathtub curves

9131

OP.COM_CONTRIBUTION_CURVES = xls_parameter(parameter, 'COM_CONTRIBUTION',false,0); % Default is 0. If set to 1 then a bar graph of COM contributors is produce instead of bathtub curves

9341

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9132

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9342

OP.EC_REL_TOL = xls_parameter(parameter, 'Enforce Causality REL_TOL', false, 1e-2); % Relative Tolerance parameter for causality, Hard enforcement, 1e-3, Soft enforcement, 1e-2

9133

OP.EC_REL_TOL = xls_parameter(parameter, 'Enforce Causality REL_TOL', false, 1e-2); % Relative Tolerance parameter for causality, Hard enforcement, 1e-3, Soft enforcement, 1e-2

9343

OP.EC_DIFF_TOL = xls_parameter(parameter, 'Enforce Causality DIFF_TOL', false, 1e-3); % Difference Tolerance parameter for causality, Hard enforcement, 1e-4,Soft enforcement, 1e-3

9134

OP.EC_DIFF_TOL = xls_parameter(parameter, 'Enforce Causality DIFF_TOL', false, 1e-3); % Difference Tolerance parameter for causality, Hard enforcement, 1e-4,Soft enforcement, 1e-3

9344

OP.EC_PULSE_TOL = xls_parameter(parameter, 'Enforce Causality pulse start tolerance', false, 0.01); % Tolerance parameter for causality, Hard enforcement, 0.05, Soft enforcement, .01

9135

OP.EC_PULSE_TOL = xls_parameter(parameter, 'Enforce Causality pulse start tolerance', false, 0.01); % Tolerance parameter for causality, Hard enforcement, 0.05, Soft enforcement, .01

9345

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9136

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9346

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9137

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9347

OP.sigma_bn_STEP = xls_parameter(parameter, 'Sigma BBN step', false, 5e-3); % BBN step for Rx Calibration in volts. Defaults is 0.5e-3

9138

OP.sigma_bn_STEP = xls_parameter(parameter, 'Sigma BBN step', false, 5e-3); % BBN step for Rx Calibration in volts. Defaults is 0.5e-3

9348

OP.BBN_Q_factor = xls_parameter(parameter, 'BBN Q factor', false, 5); % Overrides NEXT/FEXT noise Qfactor for 'Force BBN Q factor' used for reporting. does not affect COM.

9139

OP.BBN_Q_factor = xls_parameter(parameter, 'BBN Q factor', false, 5); % Overrides NEXT/FEXT noise Qfactor for 'Force BBN Q factor' used for reporting. does not affect COM.

9349

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9140

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9350

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9141

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9351

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9142

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9352

9143

9353

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9144

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9354

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9145

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9355

OP.FORCE_TR = xls_parameter(parameter, 'FORCE_TR', false, false);% Included for earlier version support but should be set to 1 in most later config sheets.

9146

OP.FORCE_TR = xls_parameter(parameter, 'FORCE_TR', false, false);% Included for earlier version support but should be set to 1 in most later config sheets.

9356

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9147

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9357

% compatibility

9148

% compatibility

9358

if OP.FORCE_TR

9149

if OP.FORCE_TR

9359

OP.T_r_meas_point=0;

9150

OP.T_r_meas_point=0;

9360

OP.T_r_filter_type=1;

9151

OP.T_r_filter_type=1;

9361

end

9152

end

9362

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9153

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9363

OP.TDR_duration= xls_parameter(parameter, 'TDR_duration', false, 5); % only used if N*UI is longer than the TDR duration time. Default is 5 times the raw s-parameter transit time.

9154

OP.TDR_duration= xls_parameter(parameter, 'TDR_duration', false, 5); % only used if N*UI is longer than the TDR duration time. Default is 5 times the raw s-parameter transit time.

9364

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9155

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9365

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9156

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9366

OP.T_k= xls_parameter(parameter, 'T_k', false, .6)*1e-9; % Time span (ns) for which the impedance of port is determined using TDR.

9157

OP.T_k= xls_parameter(parameter, 'T_k', false, .6)*1e-9; % Time span (ns) for which the impedance of port is determined using TDR.

9367

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9158

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9368

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9159

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9369

if OP.ERL

9160

if OP.ERL

9370

OP.PTDR=1;

9161

OP.PTDR=1;

9371

else

9162

else

9372

OP.PTDR=0;

9163

OP.PTDR=0;

9373

end % ERL needs to do a TDR

9164

end % ERL needs to do a TDR

9374

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9165

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9375

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9166

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9376

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9167

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9377

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9168

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9378

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9169

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9379

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9170

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9380

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9171

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9381

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9172

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9382

OP.AUTO_TFX=xls_parameter(parameter, 'AUTO_TFX', false,0); % Mostly used for device ERL. If sent to 1 the fixture tfx will be estimated.

9173

OP.AUTO_TFX=xls_parameter(parameter, 'AUTO_TFX', false,0); % Mostly used for device ERL. If sent to 1 the fixture tfx will be estimated.

9383

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9174

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9384

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9175

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9385

OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncation threshold', false, 1e-3); % zero padding threshold in fraction of IR peak for the impulse response. Effectively controls the length of time for the PR. Larger values decrease run time and accuracy. Default is 1e-3.

9176

OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncation threshold', false, 1e-3); % zero padding threshold in fraction of IR peak for the impulse response. Effectively controls the length of time for the PR. Larger values decrease run time and accuracy. Default is 1e-3.

9386

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9177

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9387

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9178

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9388

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9179

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9389

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9180

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9390

if strcmpi(OP.PHY,'C2M')

9181

if strcmpi(OP.PHY,'C2M')

9391

OP.EW=true;

9182

OP.EW=true;

9392

else

9183

else

9393

param.T_O=0; % make sure when c2c that sample is at Ts

9184

param.T_O=0; % make sure when c2c that sample is at Ts

9394

end

9185

end

9395

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9186

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9396

OP.PHY='C2Mcom';

9187

OP.PHY='C2Mcom';

9397

end

9188

end

9398

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9189

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9399

switch lower(OP.TDECQ)

9190

switch lower(OP.TDECQ)

9400

case {false 'none' 'vma'}

9191

case {false 'none' 'vma'}

9401

otherwise

9192

otherwise

9402

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9193

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9403

end

9194

end

9404

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9195

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9405

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9196

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9406

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9197

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9407

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9198

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9408

OP.Optimize_loop_speed_up =xls_parameter(parameter, 'Optimize_loop_speed_up', true , 0);% If set to 0 (or default) normal looping, If set to 1 loop speedup by slightly reducing PD Fbin and FIR_threshold for optimize looping only

9199

OP.Optimize_loop_speed_up =xls_parameter(parameter, 'Optimize_loop_speed_up', true , 0);% If set to 0 (or default) normal looping, If set to 1 loop speedup by slightly reducing PD Fbin and FIR_threshold for optimize looping only

9409

% Parameters for error burst probability calculation. Not officially used

9200

% Parameters for error burst probability calculation. Not officially used

9410

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9201

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9411

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9202

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9412

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9203

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9413

OP.USE_ETA0_PSD = xls_parameter(parameter, 'USE_ETA0_PSD', false, 0); % Used eta_0 PSD equaiton for sigma_n. Default is 0. Do not use.

9204

OP.USE_ETA0_PSD = xls_parameter(parameter, 'USE_ETA0_PSD', false, 0); % Used eta_0 PSD equaiton for sigma_n. Default is 0. Do not use.

9414

OP.SAVE_CONFIG2MAT = xls_parameter(parameter, 'SAVE_CONFIG2MAT', false, 0); % If set to 1 (default) saves parameters in mat file. Requires DIAGNOSTICS to be set.

9205

OP.SAVE_CONFIG2MAT = xls_parameter(parameter, 'SAVE_CONFIG2MAT', false, 0); % If set to 1 (default) saves parameters in mat file. Requires DIAGNOSTICS to be set.

9415

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9206

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9416

OP.fraction_of_F_range_start_extrap_from= xls_parameter(parameter, 'fraction_of_F_range_start_extrap_from', true, 0.75); % Frequency (fb) where high frequency extropolation begins for computing IR. Helps control Gibbs phenomena. defualt is 0.75.

9207

OP.fraction_of_F_range_start_extrap_from= xls_parameter(parameter, 'fraction_of_F_range_start_extrap_from', true, 0.75); % Frequency (fb) where high frequency extropolation begins for computing IR. Helps control Gibbs phenomena. defualt is 0.75.

9417

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9208

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9418

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9209

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9419

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9210

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9420

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9211

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9421

OP.MLSE = xls_parameter(parameter, 'MLSE', false, 0); % MLSE 0,1,2, 3 (no MLSE, U1 MLSE, experimetal MLSE, U3 MLSE)

9212

OP.MLSE = xls_parameter(parameter, 'MLSE', false, 0); % MLSE 0,1,2, 3 (no MLSE, U1 MLSE, experimetal MLSE, U3 MLSE)

9422

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9213

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9423

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9214

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9424

if OP.MLSE && param.ndfe==0

9215

if OP.MLSE && param.ndfe==0

9425

error('At least DFE 1 must be set to use MLSE');

9216

error('At least DFE 1 must be set to use MLSE');

9426

end

9217

end

9427

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9218

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9428

% MNSE parameters

9219

% MNSE parameters

9429

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9220

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9430

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9221

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9431

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9222

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9432

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9223

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9433

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9224

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS', 'WIENER-HOPF',

9434

% Commit request 4p4_7, healey_3dj_COM_01_240416

9435

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

+9225

9436

% need to make sure TD mode does not invoke FD operations

9226

% need to make sure TD mode does not invoke FD operations

9437

if OP.TDMODE % need to set GET_FD false of TDMODE

9227

if OP.TDMODE % need to set GET_FD false of TDMODE

9438

OP.GET_FD=false;

9228

OP.GET_FD=false;

9439

OP.ERL_ONLY=0;

9229

OP.ERL_ONLY=0;

9440

OP.ERL=0;

9230

OP.ERL=0;

9441

OP.PTDR=0;

9231

OP.PTDR=0;

9442

OP.TDR=0;

9232

OP.TDR=0;

9443

OP.RX_CALIBRATION=0;

9233

OP.RX_CALIBRATION=0;

9444

end

9234

end

9445

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9235

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9446

save(matcongfile ,'parameter');

9236

save(matcongfile ,'parameter');

9447

end

9237

end

9448

9238

9449

9239

9450

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9240

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9451

if ~isempty(param.PKG_NAME)

9241

if ~isempty(param.PKG_NAME)

9452

if length(param.PKG_NAME) == 1

9242

if length(param.PKG_NAME) == 1

9453

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9243

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9454

end

9244

end

9455

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9245

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9456

tx_rx_fields_matrix = {'pkg_Z_c'};

9246

tx_rx_fields_matrix = {'pkg_Z_c'};

9457

tx_fields = {'z_p_tx_cases' 'z_p_next_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9247

tx_fields = {'z_p_tx_cases' 'z_p_next_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9458

rx_fields = {'z_p_rx_cases' 'a_next'};

9248

rx_fields = {'z_p_rx_cases' 'a_next'};

9459

tx_pkg_name=param.PKG_NAME{1};

9249

tx_pkg_name=param.PKG_NAME{1};

9460

rx_pkg_name=param.PKG_NAME{2};

9250

rx_pkg_name=param.PKG_NAME{2};

9461

tx_pkg_struct=param.PKG.(tx_pkg_name);

9251

tx_pkg_struct=param.PKG.(tx_pkg_name);

9462

rx_pkg_struct=param.PKG.(rx_pkg_name);

9252

rx_pkg_struct=param.PKG.(rx_pkg_name);

9463

9253

9464

%tx_rx_fields: put the value from the tx package in the Tx position and the value from the rx package in the RX position

9254

%tx_rx_fields: put the value from the tx package in the Tx position and the value from the rx package in the RX position

9465

for j=1:length(tx_rx_fields)

9255

for j=1:length(tx_rx_fields)

9466

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9256

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9467

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9257

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9468

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9258

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9469

end

9259

end

9470

9260

9471

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9261

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9472

for j=1:length(tx_rx_fields_matrix)

9262

for j=1:length(tx_rx_fields_matrix)

9473

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9263

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9474

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9264

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9475

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9265

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9476

end

9266

end

9477

9267

9478

%tx_fields: use only the tx package values

9268

%tx_fields: use only the tx package values

9479

for j=1:length(tx_fields)

9269

for j=1:length(tx_fields)

9480

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9270

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9481

end

9271

end

9482

9272

9483

%rx_fields: use only the rx package values

9273

%rx_fields: use only the rx package values

9484

for j=1:length(rx_fields)

9274

for j=1:length(rx_fields)

9485

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9275

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9486

end

9276

end

9487

9277

9488

end

9278

end

9489

9279

9490

9280

9491

%%

9281

%%

9492

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9282

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9493

%% FUNCTION :: read_sp4_sparams

9283

%% FUNCTION :: read_sp4_sparams

9494

%

9284

%

9495

% Description

9285

% Description

9496

% Read the fid of single-ended 4-port complex S-parameters

9286

% Read the fid of single-ended 4-port complex S-parameters

9497

% in Touchstone format 'file' and convert to the internal

9287

% in Touchstone format 'file' and convert to the internal

9498

% format using the port transform 'ports'

9288

% format using the port transform 'ports'

9499

%

9289

%

9500

% Created by Mike Y. He

9290

% Created by Mike Y. He

9501

% April 22, 2005

9291

% April 22, 2005

9502

%

9292

%

9503

% Reused some code from

9293

% Reused some code from

9504

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9294

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9505

% for touchstone 4-port S-matrix import.

9295

% for touchstone 4-port S-matrix import.

9506

%

9296

%

9507

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9297

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9508

% optimized for quicker parameter matching and parsing. also, separated out

9298

% optimized for quicker parameter matching and parsing. also, separated out

9509

% the plotting algorithms into their own sub-function routines

9299

% the plotting algorithms into their own sub-function routines

9510

%

9300

%

9511

% Modified December 2021 to use read_Nport_touchstone

9301

% Modified December 2021 to use read_Nport_touchstone

9512

% This is faster reader that is capable of reading touchstone with any number of ports

9302

% This is faster reader that is capable of reading touchstone with any number of ports

9513

%

9303

%

9514

% Input Variables (required)

9304

% Input Variables (required)

9515

% infile -- The s4p file to be read and converted

9305

% infile -- The s4p file to be read and converted

9516

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9306

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9517

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9307

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9518

% ports -- Re-order the port layout

9308

% ports -- Re-order the port layout

9519

%

9309

%

9520

% Output/Return Variables

9310

% Output/Return Variables

9521

% data -- structure containing network parameter data points and frequency axis

9311

% data -- structure containing network parameter data points and frequency axis

9522

% sdc -- the differential in/common-mode out s-parameter data matrix

9312

% sdc -- the differential in/common-mode out s-parameter data matrix

9523

% sdd -- the differential in/differential out s-parameter data matrix

9313

% sdd -- the differential in/differential out s-parameter data matrix

9524

%

9314

%

9525

9315

9526

9316

9527

% backwards compatibility settings. can be removed in updated code.

9317

% backwards compatibility settings. can be removed in updated code.

9528

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9318

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9529

if isempty(ports); ports = [1 2]; end % default order normally used.

9319

if isempty(ports); ports = [1 2]; end % default order normally used.

9530

ports = [1 2];

9320

ports = [1 2];

9531

9321

9532

9322

9533

if OP.DISPLAY_WINDOW

9323

if OP.DISPLAY_WINDOW

9534

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9324

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9535

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9325

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9536

end

9326

end

9537

9327

9538

%AJG: fast touchstone read for any number of ports

9328

%AJG: fast touchstone read for any number of ports

9539

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9329

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9540

9330

9541

9331

9542

9332

9543

D=NaN(size(sch));

9333

D=NaN(size(sch));

9544

% calculate differential s parameter matrix from single ended

9334

% calculate differential s parameter matrix from single ended

9545

for i=1:size(sch,1)

9335

for i=1:size(sch,1)

9546

S(:,:) = sch(i,:,:);

9336

S(:,:) = sch(i,:,:);

9547

T = [1 1 ; 1 -1 ];

9337

T = [1 1 ; 1 -1 ];

9548

W = T * (S / T);

9338

W = T * (S / T);

9549

D(i,:,:) = W(:,:);

9339

D(i,:,:) = W(:,:);

9550

end

9340

end

9551

9341

9552

% D matrix should be

9342

% D matrix should be

9553

% Scc11 Scd11 Scc12 Scd21

9343

% Scc11 Scd11 Scc12 Scd21

9554

% Sdc11 Sdd11 Sdc12 Sdd12

9344

% Sdc11 Sdd11 Sdc12 Sdd12

9555

% Scc21 Scd21 Scc22 Scd22

9345

% Scc21 Scd21 Scc22 Scd22

9556

% Sdc21 Sdd21 Sdc22 Sdd22

9346

% Sdc21 Sdd21 Sdc22 Sdd22

9557

9347

9558

% proper values

9348

% proper values

9559

%AJG: matrix can be properly referenced after fixing mapping

9349

%AJG: matrix can be properly referenced after fixing mapping

9560

SDD(:,1,1) = D(:,2,2);

9350

SDD(:,1,1) = D(:,2,2);

9561

SDC(:,1,1)= D(:,2,1);

9351

SDC(:,1,1)= D(:,2,1);

9562

SCC(:,1,1)= D(:,1,1);

9352

SCC(:,1,1)= D(:,1,1);

9563

SCD(:,1,1)= D(:,1,2);

9353

SCD(:,1,1)= D(:,1,2);

9564

9354

9565

9355

9566

9356

9567

% backwards compatibility output variables

9357

% backwards compatibility output variables

9568

data.m = sch;

9358

data.m = sch;

9569

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9359

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9570

data.freq = schFreqAxis;

9360

data.freq = schFreqAxis;

9571

colors = 'rgbk';

9361

colors = 'rgbk';

9572

9362

9573

if (plot_ini_s_params == 1)

9363

if (plot_ini_s_params == 1)

9574

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9364

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9575

for mj=1:4

9365

for mj=1:4

9576

% subplot(2,2,mj);

9366

% subplot(2,2,mj);

9577

for mi=1:4

9367

for mi=1:4

9578

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9368

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9579

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9369

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9580

hold on

9370

hold on

9581

end

9371

end

9582

xlabel('Frequency (Hz)');

9372

xlabel('Frequency (Hz)');

9583

ylabel('Magnitude (dB)');

9373

ylabel('Magnitude (dB)');

9584

legend show

9374

legend show

9585

grid on

9375

grid on

9586

title(sprintf('Output port %d', mj));

9376

title(sprintf('Output port %d', mj));

9587

end

9377

end

9588

end

9378

end

9589

plot_dif_s_params =0;

9379

plot_dif_s_params =0;

9590

if (plot_dif_s_params == 1)

9380

if (plot_dif_s_params == 1)

9591

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9381

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9592

% subplot(2,1,1);

9382

% subplot(2,1,1);

9593

for mj=1:1

9383

for mj=1:1

9594

for mi=1:1

9384

for mi=1:1

9595

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9385

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9596

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9386

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9597

hold on

9387

hold on

9598

end

9388

end

9599

end

9389

end

9600

xlabel('Frequency (Hz)');

9390

xlabel('Frequency (Hz)');

9601

ylabel('Magnitude (dB)');

9391

ylabel('Magnitude (dB)');

9602

legend show

9392

legend show

9603

grid on

9393

grid on

9604

title(infile);

9394

title(infile);

9605

9395

9606

% subplot(2,1,2);

9396

% subplot(2,1,2);

9607

% for mj=1:2

9397

% for mj=1:2

9608

% for mi=1:2

9398

% for mi=1:2

9609

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9399

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9610

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9400

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9611

% hold on

9401

% hold on

9612

% end

9402

% end

9613

% end

9403

% end

9614

% xlabel('Frequency (Hz)');

9404

% xlabel('Frequency (Hz)');

9615

% ylabel('Magnitude (dB)');

9405

% ylabel('Magnitude (dB)');

9616

% legend show

9406

% legend show

9617

% grid on

9407

% grid on

9618

end

9408

end

9619

9409

9620

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9410

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9621

% end read_sp2_sparam

9411

% end read_sp2_sparam

9622

9412

9623

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9413

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9624

%% FUNCTION :: read_sp4_sparams

9414

%% FUNCTION :: read_sp4_sparams

9625

%

9415

%

9626

% Description

9416

% Description

9627

% Read the fid of single-ended 4-port complex S-parameters

9417

% Read the fid of single-ended 4-port complex S-parameters

9628

% in Touchstone format 'file' and convert to the internal

9418

% in Touchstone format 'file' and convert to the internal

9629

% format using the port transform 'ports'

9419

% format using the port transform 'ports'

9630

%

9420

%

9631

% Created by Mike Y. He

9421

% Created by Mike Y. He

9632

% April 22, 2005

9422

% April 22, 2005

9633

%

9423

%

9634

% Reused some code from

9424

% Reused some code from

9635

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9425

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9636

% for touchstone 4-port S-matrix import.

9426

% for touchstone 4-port S-matrix import.

9637

%

9427

%

9638

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9428

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9639

% optimized for quicker parameter matching and parsing. also, separated out

9429

% optimized for quicker parameter matching and parsing. also, separated out

9640

% the plotting algorithms into their own sub-function routines

9430

% the plotting algorithms into their own sub-function routines

9641

%

9431

%

9642

% Modified December 2021 to use read_Nport_touchstone

9432

% Modified December 2021 to use read_Nport_touchstone

9643

% This is faster reader that is capable of reading touchstone with any number of ports

9433

% This is faster reader that is capable of reading touchstone with any number of ports

9644

%

9434

%

9645

% Input Variables (required)

9435

% Input Variables (required)

9646

% infile -- The s4p file to be read and converted

9436

% infile -- The s4p file to be read and converted

9647

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9437

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9648

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9438

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9649

% ports -- Re-order the port layout

9439

% ports -- Re-order the port layout

9650

% OP

9440

% OP

9651

% param

9441

% param

9652

% Output/Return Variables

9442

% Output/Return Variables

9653

% data -- structure containing network parameter data points and frequency axis

9443

% data -- structure containing network parameter data points and frequency axis

9654

% sdd -- the differential in/differential out s-parameter data matrix

9444

% sdd -- the differential in/differential out s-parameter data matrix

9655

% sdc -- the differential in/common-mode out s-parameter data matrix

9445

% sdc -- the differential in/common-mode out s-parameter data matrix

9656

% scc -- the common mode in/common-mode out s-parameter data matrix

9446

% scc -- the common mode in/common-mode out s-parameter data matrix

9657

%

9447

%

9658

%

9448

%

9659

9449

9660

9450

9661

% backwards compatibility settings. can be removed in updated code.

9451

% backwards compatibility settings. can be removed in updated code.

9662

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9452

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9663

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9453

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9664

9454

9665

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9455

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9666

% pair is reversed.

9456

% pair is reversed.

9667

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9457

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9668

9458

9669

if OP.DISPLAY_WINDOW

9459

if OP.DISPLAY_WINDOW

9670

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9460

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9671

end

9461

end

9672

9462

9673

%AJG: fast touchstone read for any number of ports

9463

%AJG: fast touchstone read for any number of ports

9674

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9464

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9675

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9465

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9676

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9466

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9677

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9467

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9678

Sigfct = ...

9468

Sigfct = ...

9679

@(sigma2,sigma1,sigma4,sigma3)reshape([sigma1.^2,sigma1.*sigma2,sigma1.*sigma3,sigma1.*sigma4,sigma1.*sigma2,sigma2.^2,sigma2.*sigma3,sigma2.*sigma4,sigma1.*sigma3,sigma2.*sigma3,sigma3.^2,sigma3.*sigma4,sigma1.*sigma4,sigma2.*sigma4,sigma3.*sigma4,sigma4.^2],[4,4]);

9469

@(sigma2,sigma1,sigma4,sigma3)reshape([sigma1.^2,sigma1.*sigma2,sigma1.*sigma3,sigma1.*sigma4,sigma1.*sigma2,sigma2.^2,sigma2.*sigma3,sigma2.*sigma4,sigma1.*sigma3,sigma2.*sigma3,sigma3.^2,sigma3.*sigma4,sigma1.*sigma4,sigma2.*sigma4,sigma3.*sigma4,sigma4.^2],[4,4]);

9680

D=NaN(size(sch));

9470

D=NaN(size(sch));

9681

% calculate differential s parameter matrix from single ended

9471

% calculate differential s parameter matrix from single ended

9682

% skew added RIM 12/29/2023

9472

% skew added RIM 12/29/2023

9683

for i=1:size(sch,1)

9473

for i=1:size(sch,1)

9684

f=schFreqAxis(i);

9474

f=schFreqAxis(i);

9685

sigma_matrix=Sigfct(exp(2i*pi*f*param.Txpskew*1e-12),exp(2i*pi*f*param.Txnskew*1e-12),exp(2i*pi*f*param.Rxpskew*1e-12),exp(2i*pi*f*param.Rxnskew*1e-12) );

9475

sigma_matrix=Sigfct(exp(2i*pi*f*param.Txpskew*1e-12),exp(2i*pi*f*param.Txnskew*1e-12),exp(2i*pi*f*param.Rxpskew*1e-12),exp(2i*pi*f*param.Rxnskew*1e-12) );

9686

S(:,:) = sch(i,:,:);

9476

S(:,:) = sch(i,:,:);

9687

Snew=sigma_matrix.*S;

9477

Snew=sigma_matrix.*S;

9688

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9478

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9689

W = T * (Snew / T);

9479

W = T * (Snew / T);

9690

D(i,:,:) = W(:,:);

9480

D(i,:,:) = W(:,:);

9691

end

9481

end

9692

9482

9693

% D matrix should be

9483

% D matrix should be

9694

% Scc11 Scd11 Scc12 Scd21

9484

% Scc11 Scd11 Scc12 Scd21

9695

% Sdc11 Sdd11 Sdc12 Sdd12

9485

% Sdc11 Sdd11 Sdc12 Sdd12

9696

% Scc21 Scd21 Scc22 Scd22

9486

% Scc21 Scd21 Scc22 Scd22

9697

% Sdc21 Sdd21 Sdc22 Sdd22

9487

% Sdc21 Sdd21 Sdc22 Sdd22

9698

9488

9699

% proper values

9489

% proper values

9700

SDD(:,1,1) = D(:,2,2);

9490

SDD(:,1,1) = D(:,2,2);

9701

SDD(:,2,2) = D(:,4,4);

9491

SDD(:,2,2) = D(:,4,4);

9702

SDD(:,1,2) = D(:,2,4);

9492

SDD(:,1,2) = D(:,2,4);

9703

SDD(:,2,1) = D(:,4,2);

9493

SDD(:,2,1) = D(:,4,2);

9704

9494

9705

SDC(:,1,1) = D(:,2,1);

9495

SDC(:,1,1) = D(:,2,1);

9706

SDC(:,2,2) = D(:,4,3);

9496

SDC(:,2,2) = D(:,4,3);

9707

SDC(:,1,2) = D(:,2,3);

9497

SDC(:,1,2) = D(:,2,3);

9708

SDC(:,2,1) = D(:,4,1);

9498

SDC(:,2,1) = D(:,4,1);

9709

9499

9710

SCC(:,1,1) = D(:,1,1);

9500

SCC(:,1,1) = D(:,1,1);

9711

SCC(:,2,2) = D(:,3,3);

9501

SCC(:,2,2) = D(:,3,3);

9712

SCC(:,1,2) = D(:,1,3);

9502

SCC(:,1,2) = D(:,1,3);

9713

SCC(:,2,1) = D(:,3,1);

9503

SCC(:,2,1) = D(:,3,1);

9714

9504

9715

% backwards compatibility output variables

9505

% backwards compatibility output variables

9716

data.m = sch;

9506

data.m = sch;

9717

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9507

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9718

data.freq = schFreqAxis;

9508

data.freq = schFreqAxis;

9719

colors = 'rgbk';

9509

colors = 'rgbk';

9720

9510

9721

if (plot_ini_s_params == 1)

9511

if (plot_ini_s_params == 1)

9722

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9512

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9723

for mj=1:4

9513

for mj=1:4

9724

subplot(2,2,mj);

9514

subplot(2,2,mj);

9725

for mi=1:4

9515

for mi=1:4

9726

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9516

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9727

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9517

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9728

hold on

9518

hold on

9729

end

9519

end

9730

xlabel('Frequency (Hz)');

9520

xlabel('Frequency (Hz)');

9731

ylabel('Magnitude (dB)');

9521

ylabel('Magnitude (dB)');

9732

legend show

9522

legend show

9733

grid on

9523

grid on

9734

title(sprintf('Output port %d', mj));

9524

title(sprintf('Output port %d', mj));

9735

end

9525

end

9736

end

9526

end

9737

plot_dif_s_params =0;

9527

plot_dif_s_params =0;

9738

if (plot_dif_s_params == 1)

9528

if (plot_dif_s_params == 1)

9739

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9529

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9740

% subplot(2,1,1);

9530

% subplot(2,1,1);

9741

for mj=1:2

9531

for mj=1:2

9742

for mi=1:2

9532

for mi=1:2

9743

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9533

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9744

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9534

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9745

hold on

9535

hold on

9746

end

9536

end

9747

end

9537

end

9748

xlabel('Frequency (Hz)');

9538

xlabel('Frequency (Hz)');

9749

ylabel('Magnitude (dB)');

9539

ylabel('Magnitude (dB)');

9750

legend show

9540

legend show

9751

grid on

9541

grid on

9752

title(infile);

9542

title(infile);

9753

%

9543

%

9754

% subplot(2,1,2);

9544

% subplot(2,1,2);

9755

% for mj=1:2

9545

% for mj=1:2

9756

% for mi=1:2

9546

% for mi=1:2

9757

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9547

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9758

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9548

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9759

% hold on

9549

% hold on

9760

% end

9550

% end

9761

% end

9551

% end

9762

% xlabel('Frequency (Hz)');

9552

% xlabel('Frequency (Hz)');

9763

% ylabel('Magnitude (dB)');

9553

% ylabel('Magnitude (dB)');

9764

% legend show

9554

% legend show

9765

% grid on

9555

% grid on

9766

end

9556

end

9767

9557

9768

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9558

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9769

% end read_sp4_sparam

9559

% end read_sp4_sparam

9770

function param_struct = read_package_parameters(parameter,param_struct)

9560

function param_struct = read_package_parameters(parameter,param_struct)

9771

9561

9772

%With the introduction of Package sections in COM spreadsheet, it makes sense to have a single function that grabs all package parameters from a parameter block

9562

%With the introduction of Package sections in COM spreadsheet, it makes sense to have a single function that grabs all package parameters from a parameter block

9773

%This block should eventually replace what is in read_ParamConfigFile

9563

%This block should eventually replace what is in read_ParamConfigFile

9774

%It can be called as: param = read_package_parameters(parameter, param)

9564

%It can be called as: param = read_package_parameters(parameter, param)

9775

9565

9776

if nargin<2

9566

if nargin<2

9777

%param_struct doesn't need to be passed when building a new package structure

9567

%param_struct doesn't need to be passed when building a new package structure

9778

%it is only needed when appending to regular param structure

9568

%it is only needed when appending to regular param structure

9779

param_struct=struct;

9569

param_struct=struct;

9780

end

9570

end

9781

9571

9782

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9572

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9783

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9573

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9784

9574

9785

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9575

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9786

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9576

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9787

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9577

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9788

9578

9789

param_struct.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9579

param_struct.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9790

[ncases, mele]=size(param_struct.z_p_tx_cases);

9580

[ncases, mele]=size(param_struct.z_p_tx_cases);

9791

if mele ==2

9581

if mele ==2

9792

param_struct.flex=2;

9582

param_struct.flex=2;

9793

elseif mele==4

9583

elseif mele==4

9794

param_struct.flex=4;

9584

param_struct.flex=4;

9795

elseif mele==1

9585

elseif mele==1

9796

param_struct.flex=1;

9586

param_struct.flex=1;

9797

else

9587

else

9798

error('config file syntax error')

9588

error('config file syntax error')

9799

end

9589

end

9800

param_struct.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9590

param_struct.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9801

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9591

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9802

if ncases ~= ncases1 || mele ~= mele1

9592

if ncases ~= ncases1 || mele ~= mele1

9803

error('All TX, NEXT, FEXT, Rx cases must agree');

9593

error('All TX, NEXT, FEXT, Rx cases must agree');

9804

else

9594

else

9805

end

9595

end

9806

param_struct.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9596

param_struct.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9807

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9597

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9808

if ncases ~= ncases1 || mele ~= mele1

9598

if ncases ~= ncases1 || mele ~= mele1

9809

error('All TX, NEXT, FEXT, Rx cases must agree');

9599

error('All TX, NEXT, FEXT, Rx cases must agree');

9810

else

9600

else

9811

end

9601

end

9812

param_struct.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9602

param_struct.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9813

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9603

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9814

if ncases ~= ncases1 || mele ~= mele1

9604

if ncases ~= ncases1 || mele ~= mele1

9815

error('All TX, NEXT, FEXT, Rx cases must agree');

9605

error('All TX, NEXT, FEXT, Rx cases must agree');

9816

else

9606

else

9817

end

9607

end

9818

% Table 93A-3 parameters

9608

% Table 93A-3 parameters

9819

param_struct.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9609

param_struct.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9820

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9610

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9821

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9611

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9822

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9612

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9823

if mele ~= mele1

9613

if mele ~= mele1

9824

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9614

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9825

else

9615

else

9826

end

9616

end

9827

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9617

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9828

for ii=1:ncases

9618

for ii=1:ncases

9829

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9619

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9830

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9620

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9831

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9621

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9832

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9622

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9833

end

9623

end

9834

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9624

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9835

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9625

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9836

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9626

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9837

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9627

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9838

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9628

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9839

end

9629

end

9840

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9630

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9841

%% extract s-parameter and convert to differential mode

9631

%% extract s-parameter and convert to differential mode

9842

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9632

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9843

num_files=length(chdata);

9633

num_files=length(chdata);

9844

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9634

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9845

for i=1:num_files

9635

for i=1:num_files

9846

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9636

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9847

progress = i/num_files;

9637

progress = i/num_files;

9848

if OP.DISPLAY_WINDOW

9638

if OP.DISPLAY_WINDOW

9849

[~,a]=fileparts(chdata(i).filename);

9639

[~,a]=fileparts(chdata(i).filename);

9850

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9640

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9851

else

9641

else

9852

fprintf('%i ',i);

9642

fprintf('%i ',i);

9853

end

9643

end

9854

9644

9855

% Skip reading file if it was already read (multiple test cases)

9645

% Skip reading file if it was already read (multiple test cases)

9856

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9646

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9857

switch lower(chdata(i).ext)

9647

switch lower(chdata(i).ext)

9858

case '.s2p' % for differential return loss

9648

case '.s2p' % for differential return loss

9859

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9649

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9860

chdata(i).fmaxi = length(Sch.freq);

9650

chdata(i).fmaxi = length(Sch.freq);

9861

chdata(i).faxis = Sch.freq;

9651

chdata(i).faxis = Sch.freq;

9862

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9652

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9863

SDDp2p(i)=NaN;

9653

SDDp2p(i)=NaN;

9864

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9654

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9865

chdata(i).sdd11=chdata(i).sdd11_raw;

9655

chdata(i).sdd11=chdata(i).sdd11_raw;

9866

case '.s4p'

9656

case '.s4p'

9867

if length(param.snpPortsOrder) ~= 4

9657

if length(param.snpPortsOrder) ~= 4

9868

error( 'warning:sNpFilePortMismatch', ...

9658

error( 'warning:sNpFilePortMismatch', ...

9869

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9659

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9870

length(param.snpPortsOrder), ...

9660

length(param.snpPortsOrder), ...

9871

chdata(i).ext ...

9661

chdata(i).ext ...

9872

);

9662

);

9873

end

9663

end

9874

% read function returns differnetial mode parameters

9664

% read function returns differnetial mode parameters

9875

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9665

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9876

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9666

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9877

% param.holdsdata(i).Sch= Sch;

9667

% param.holdsdata(i).Sch= Sch;

9878

% param.holdsdata(i).SDDch= SDDch;

9668

% param.holdsdata(i).SDDch= SDDch;

9879

% param.holdsdata(i).SDCch= SDCch;

9669

% param.holdsdata(i).SDCch= SDCch;

9880

else

9670

else

9881

error('If this line is reached, there is a logic error');

9671

error('If this line is reached, there is a logic error');

9882

% Sch=param.holdsdata(i).Sch;

9672

% Sch=param.holdsdata(i).Sch;

9883

% SDDch=param.holdsdata(i).SDDch;

9673

% SDDch=param.holdsdata(i).SDDch;

9884

% SDCch=param.holdsdata(i).SDCch;

9674

% SDCch=param.holdsdata(i).SDCch;

9885

end

9675

end

9886

chdata(i).fmaxi = length(Sch.freq);

9676

chdata(i).fmaxi = length(Sch.freq);

9887

9677

9888

9678

9889

if Sch.freq(chdata(i).fmaxi) < param.fb

9679

if Sch.freq(chdata(i).fmaxi) < param.fb

9890

warning('COM:read_s4p:MaxFreqTooLow', ...

9680

warning('COM:read_s4p:MaxFreqTooLow', ...

9891

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9681

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9892

chdata(i).filename, Sch.freq(end), param.fb);

9682

chdata(i).filename, Sch.freq(end), param.fb);

9893

end

9683

end

9894

if Sch.freq(1) > param.max_start_freq

9684

if Sch.freq(1) > param.max_start_freq

9895

warning('COM:read_s4p:StartFreqTooHigh', ...

9685

warning('COM:read_s4p:StartFreqTooHigh', ...

9896

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9686

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9897

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9687

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9898

end

9688

end

9899

freqstep=diff(Sch.freq);

9689

freqstep=diff(Sch.freq);

9900

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9690

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9901

if max(freqstep)-min(freqstep) > 1

9691

if max(freqstep)-min(freqstep) > 1

9902

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9692

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9903

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9693

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9904

end

9694

end

9905

if max(freqstep) - param.max_freq_step > 1

9695

if max(freqstep) - param.max_freq_step > 1

9906

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9696

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9907

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9697

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9908

end

9698

end

9909

9699

9910

chdata(i).faxis = Sch.freq;

9700

chdata(i).faxis = Sch.freq;

9911

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9701

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9912

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9702

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9913

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9703

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9914

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9704

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9915

% mode conversion

9705

% mode conversion

9916

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9706

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9917

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9707

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9918

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9708

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9919

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9709

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9920

%save original and add board (if required)

9710

%save original and add board (if required)

9921

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9711

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9922

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

9712

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

9923

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

9713

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

9924

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

9714

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

9925

if OP.include_pcb

9715

if OP.include_pcb

9926

% add boards to sdd

9716

% add boards to sdd

9927

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

9717

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

9928

9718

9929

end

9719

end

9930

%save final return loss (after the boards were included)

9720

%save final return loss (after the boards were included)

9931

chdata(i).sdd11=chdata(i).sdd11_raw;

9721

chdata(i).sdd11=chdata(i).sdd11_raw;

9932

chdata(i).sdd22=chdata(i).sdd22_raw;

9722

chdata(i).sdd22=chdata(i).sdd22_raw;

9933

otherwise

9723

otherwise

9934

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

9724

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

9935

end

9725

end

9936

9726

9937

%Crosstalk frequency axis must be the same as Thru

9727

%Crosstalk frequency axis must be the same as Thru

9938

if i>1

9728

if i>1

9939

%error on length difference

9729

%error on length difference

9940

if length(chdata(i).faxis)~=length(chdata(1).faxis)

9730

if length(chdata(i).faxis)~=length(chdata(1).faxis)

9941

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

9731

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

9942

end

9732

end

9943

%error if any value > 1Hz (don't want to check for exact

9733

%error if any value > 1Hz (don't want to check for exact

9944

%equality in case of floating point error)

9734

%equality in case of floating point error)

9945

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

9735

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

9946

if max(Fdiff)>1

9736

if max(Fdiff)>1

9947

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

9737

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

9948

end

9738

end

9949

end

9739

end

9950

else

9740

else

9951

SDDch(:,1,2)=chdata(i).sdd12_raw;

9741

SDDch(:,1,2)=chdata(i).sdd12_raw;

9952

SDDch(:,2,1)=chdata(i).sdd21_raw;

9742

SDDch(:,2,1)=chdata(i).sdd21_raw;

9953

SDDch(:,1,1)=chdata(i).sdd11_raw;

9743

SDDch(:,1,1)=chdata(i).sdd11_raw;

9954

SDDch(:,2,2)=chdata(i).sdd22_raw;

9744

SDDch(:,2,2)=chdata(i).sdd22_raw;

9955

end

9745

end

9956

chdata(i).sigma_ACCM_at_tp0=0;

9746

chdata(i).sigma_ACCM_at_tp0=0;

9957

if ~param.FLAG.S2P

9747

if ~param.FLAG.S2P

9958

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

9748

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

9959

if (OP.RX_CALIBRATION == 1 && i==2)

9749

if (OP.RX_CALIBRATION == 1 && i==2)

9960

chdata(i).sdd21=chdata(i).sdd21_raw;

9750

chdata(i).sdd21=chdata(i).sdd21_raw;

9961

else

9751

else

9962

%updated package construction with single function for both DD and DC

9752

%updated package construction with single function for both DD and DC

9963

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

9753

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

9964

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

9754

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

9965

chdata(i).sdd21=chdata(i).sdd21p;

9755

chdata(i).sdd21=chdata(i).sdd21p;

9966

if 1 % for AC CM noise inclusion

9756

if 1 % for AC CM noise inclusion

9967

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

9757

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

9968

chdata(i).sdc21=chdata(i).sdc21p;

9758

chdata(i).sdc21=chdata(i).sdc21p;

9969

end

9759

end

9970

end

9760

end

9971

else

9761

else

9972

chdata(i).sdd21=chdata(i).sdd21_raw;

9762

chdata(i).sdd21=chdata(i).sdd21_raw;

9973

end

9763

end

9974

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

9764

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

9975

end

9765

end

9976

end

9766

end

9977

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

9767

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

9978

9768

9979

function result = readdataSnPx(filename, nport)

9769

function result = readdataSnPx(filename, nport)

9980

%function [freq, cs] = readdataSnPx(filename, nport)

9770

%function [freq, cs] = readdataSnPx(filename, nport)

9981

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

9771

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

9982

%

9772

%

9983

% Read Touchstone file with frequencies in units of Hertz

9773

% Read Touchstone file with frequencies in units of Hertz

9984

%

9774

%

9985

% Input:

9775

% Input:

9986

% ======

9776

% ======

9987

% filename: Name of the Touchstone/SnP file

9777

% filename: Name of the Touchstone/SnP file

9988

% nport: Number of ports

9778

% nport: Number of ports

9989

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

9779

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

9990

% Touchstone file)

9780

% Touchstone file)

9991

% nheader: Number of header lines (comment lines plus option line in the

9781

% nheader: Number of header lines (comment lines plus option line in the

9992

% Touchstone file)

9782

% Touchstone file)

9993

%

9783

%

9994

% Output:

9784

% Output:

9995

% =======

9785

% =======

9996

% freq: Vector of frequencies [Hz]

9786

% freq: Vector of frequencies [Hz]

9997

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

9787

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

9998

% at frequency freq(k)

9788

% at frequency freq(k)

9999

%

9789

%

10000

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

9790

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

10001

% frequencies appropriately after reading the data.

9791

% frequencies appropriately after reading the data.

10002

%

9792

%

10003

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

9793

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

10004

% EIA/IBIS Open Forum, 2002.

9794

% EIA/IBIS Open Forum, 2002.

10005

%

9795

%

10006

% Written by Henning Braunisch, September 2004.

9796

% Written by Henning Braunisch, September 2004.

10007

% Updated by Steven Krooswyk, April 2006.

9797

% Updated by Steven Krooswyk, April 2006.

10008

9798

10009

9799

10010

fid = fopen(filename, 'r');

9800

fid = fopen(filename, 'r');

10011

9801

10012

9802

10013

% Skip header lines

9803

% Skip header lines

10014

str = ' ';

9804

str = ' ';

10015

n = 0;

9805

n = 0;

10016

while ~strcmp(str(1),'#')

9806

while ~strcmp(str(1),'#')

10017

str = fgetl(fid);

9807

str = fgetl(fid);

10018

if isempty(str)

9808

if isempty(str)

10019

str=' ' ;

9809

str=' ' ;

10020

if n > 1000

9810

if n > 1000

10021

display('error: could not find config line (#)')

9811

display('error: could not find config line (#)')

10022

break

9812

break

10023

end

9813

end

10024

end

9814

end

10025

n = n + 1;

9815

n = n + 1;

10026

end

9816

end

10027

9817

10028

% parse configuration line

9818

% parse configuration line

10029

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

9819

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

10030

p = find(A=='S'); %position of 'S'

9820

p = find(A=='S'); %position of 'S'

10031

units = lower(A(2:p-1)); %units before 'S'

9821

units = lower(A(2:p-1)); %units before 'S'

10032

format = A(p+1:p+2); %format after 'S'

9822

format = A(p+1:p+2); %format after 'S'

10033

9823

10034

% skip any more header lines

9824

% skip any more header lines

10035

%while ~str

9825

%while ~str

10036

9826

10037

nk = 0; % frequency counter

9827

nk = 0; % frequency counter

10038

while 1

9828

while 1

10039

9829

10040

[temp, count] = fscanf(fid, '%f', 1);

9830

[temp, count] = fscanf(fid, '%f', 1);

10041

if count == 0

9831

if count == 0

10042

temp2 = fscanf(fid, '%s', 1);

9832

temp2 = fscanf(fid, '%s', 1);

10043

if ~isempty(temp2), fgetl(fid); continue, end;

9833

if ~isempty(temp2), fgetl(fid); continue, end;

10044

break

9834

break

10045

end

9835

end

10046

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

9836

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

10047

for ni = 1:nport

9837

for ni = 1:nport

10048

for nj = 1:nport

9838

for nj = 1:nport

10049

switch lower(format)

9839

switch lower(format)

10050

case 'ma'

9840

case 'ma'

10051

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9841

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10052

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

9842

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

10053

case 'ri'

9843

case 'ri'

10054

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

9844

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

10055

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9845

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10056

case 'db'

9846

case 'db'

10057

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9847

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10058

M = 10^(db/20);

9848

M = 10^(db/20);

10059

%re = M*cos(ang);

9849

%re = M*cos(ang);

10060

%im = M*sin(ang);

9850

%im = M*sin(ang);

10061

re = M*cos(ang * pi / 180);

9851

re = M*cos(ang * pi / 180);

10062

im = M*sin(ang * pi / 180);

9852

im = M*sin(ang * pi / 180);

10063

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9853

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10064

otherwise

9854

otherwise

10065

error('readdataSnP: Unknown data format');

9855

error('readdataSnP: Unknown data format');

10066

end

9856

end

10067

end

9857

end

10068

end

9858

end

10069

end

9859

end

10070

9860

10071

fclose(fid);

9861

fclose(fid);

10072

9862

10073

% If 2-port then swap S_12 and S_21 per Touchstone spec

9863

% If 2-port then swap S_12 and S_21 per Touchstone spec

10074

if nport == 2

9864

if nport == 2

10075

temp = cs(2,1,:);

9865

temp = cs(2,1,:);

10076

cs(2,1,:) = cs(1,2,:);

9866

cs(2,1,:) = cs(1,2,:);

10077

cs(1,2,:) = temp;

9867

cs(1,2,:) = temp;

10078

end

9868

end

10079

9869

10080

% Update freq units to Hz

9870

% Update freq units to Hz

10081

switch lower(units)

9871

switch lower(units)

10082

case 'hz'

9872

case 'hz'

10083

9873

10084

case 'khz'

9874

case 'khz'

10085

freq=freq.*1e3;

9875

freq=freq.*1e3;

10086

case 'mhz'

9876

case 'mhz'

10087

freq=freq.*1e6;

9877

freq=freq.*1e6;

10088

case 'ghz'

9878

case 'ghz'

10089

freq=freq.*1e9;

9879

freq=freq.*1e9;

10090

end

9880

end

10091

9881

10092

% passivity check

9882

% passivity check

10093

result.freq = freq;

9883

result.freq = freq;

10094

result.cs = cs;

9884

result.cs = cs;

10095

9885

10096

function recolor_plots(ax)

9886

function recolor_plots(ax)

10097

9887

10098

if ~verLessThan('matlab', '8.4.0')

9888

if ~verLessThan('matlab', '8.4.0')

10099

return

9889

return

10100

end

9890

end

10101

colors='brgcmk';

9891

colors='brgcmk';

10102

ch=flipud(get(ax, 'children'));

9892

ch=flipud(get(ax, 'children'));

10103

9893

10104

for k=1:length(ch)

9894

for k=1:length(ch)

10105

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

9895

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

10106

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

9896

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

10107

end

9897

end

10108

legend (ax, 'off');

9898

legend (ax, 'off');

10109

warning('off', 'MATLAB:legend:PlotEmpty');

9899

warning('off', 'MATLAB:legend:PlotEmpty');

10110

set(legend (ax, 'show'), 'interp', 'none');

9900

set(legend (ax, 'show'), 'interp', 'none');

10111

9901

10112

function result = reduce(var1)

9902

function result = reduce(var1)

10113

% --- Reduce 1x1xn array to 1xn (aka squeeze)

9903

% --- Reduce 1x1xn array to 1xn (aka squeeze)

10114

out = zeros(1,length(var1));

9904

out = zeros(1,length(var1));

10115

out(1,:) = var1(1,1,:);

9905

out(1,:) = var1(1,1,:);

10116

result=out;

9906

result=out;

10117

9907

10118

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

9908

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

10119

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

9909

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

10120

% faxis is the frequency array

9910

% faxis is the frequency array

10121

% s21, s11, s22 are the corresponding array of differential parameters

9911

% s21, s11, s22 are the corresponding array of differential parameters

10122

% s21p includes the VFT and Tx filter if include_die=1

9912

% s21p includes the VFT and Tx filter if include_die=1

10123

if nargin<6

9913

if nargin<6

10124

include_die=1;

9914

include_die=1;

10125

end

9915

end

10126

if nargin<5

9916

if nargin<5

10127

mode='dd';

9917

mode='dd';

10128

end

9918

end

10129

9919

10130

s21=chdata.(['s' mode '21_raw']);

9920

s21=chdata.(['s' mode '21_raw']);

10131

s12=chdata.(['s' mode '12_raw']);

9921

s12=chdata.(['s' mode '12_raw']);

10132

s11=chdata.(['s' mode '11_raw']);

9922

s11=chdata.(['s' mode '11_raw']);

10133

s22=chdata.(['s' mode '22_raw']);

9923

s22=chdata.(['s' mode '22_raw']);

10134

faxis=chdata.faxis;

9924

faxis=chdata.faxis;

10135

channel_type=chdata.type;

9925

channel_type=chdata.type;

10136

9926

10137

if strcmpi(mode,'dd')

9927

if strcmpi(mode,'dd')

10138

s11=s11*param.kappa1;

9928

s11=s11*param.kappa1;

10139

s22=s22*param.kappa2;

9929

s22=s22*param.kappa2;

10140

end

9930

end

10141

9931

10142

9932

10143

Z0=param.Z0;

9933

Z0=param.Z0;

10144

%sigma_ACCM_at_tp0 is only used when mode=DC

9934

%sigma_ACCM_at_tp0 is only used when mode=DC

10145

sigma_ACCM_at_tp0=0;

9935

sigma_ACCM_at_tp0=0;

10146

9936

10147

% The following three parameters have possibly different valuesF for TX and

9937

% The following three parameters have possibly different valuesF for TX and

10148

% RX (so can be 2-element vectors).

9938

% RX (so can be 2-element vectors).

10149

R_diepad = param.R_diepad;

9939

R_diepad = param.R_diepad;

10150

9940

10151

%Make TX Package

9941

%Make TX Package

10152

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

9942

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

10153

9943

10154

%Make RX Package

9944

%Make RX Package

10155

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

9945

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

10156

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

9946

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

10157

9947

10158

9948

10159

% p(1 ,1, :)=s11in;

9949

% p(1 ,1, :)=s11in;

10160

% p(2 ,2, :)=s22in;

9950

% p(2 ,2, :)=s22in;

10161

% p(1 ,2, :)=s12in;

9951

% p(1 ,2, :)=s12in;

10162

% p(2 ,1, :)=s21in;

9952

% p(2 ,1, :)=s21in;

10163

%

9953

%

10164

% S=sparameters(p,faxis);

9954

% S=sparameters(p,faxis);

10165

% rfwrite(S,'temp.s4p');

9955

% rfwrite(S,'temp.s4p');

10166

9956

10167

if strcmpi(mode,'dc')

9957

if strcmpi(mode,'dc')

10168

RTX=R_diepad(param.Tx_rd_sel)/2;

9958

RTX=R_diepad(param.Tx_rd_sel)/2;

10169

RRX=R_diepad(param.Rx_rd_sel)/2;

9959

RRX=R_diepad(param.Rx_rd_sel)/2;

10170

Z0gamma=Z0/2;

9960

Z0gamma=Z0/2;

10171

else

9961

else

10172

RTX=R_diepad(param.Tx_rd_sel);

9962

RTX=R_diepad(param.Tx_rd_sel);

10173

RRX=R_diepad(param.Rx_rd_sel);

9963

RRX=R_diepad(param.Rx_rd_sel);

10174

Z0gamma=Z0;

9964

Z0gamma=Z0;

10175

end

9965

end

10176

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

9966

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

10177

gamma_tx=0;

9967

gamma_tx=0;

10178

else

9968

else

10179

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

9969

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

10180

end

9970

end

10181

if OP.IDEAL_RX_TERM

9971

if OP.IDEAL_RX_TERM

10182

gamma_rx=0;

9972

gamma_rx=0;

10183

else

9973

else

10184

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

9974

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

10185

end

9975

end

10186

9976

10187

if OP.INC_PACKAGE==0

9977

if OP.INC_PACKAGE==0

10188

s21p= s21;

9978

s21p= s21;

10189

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

9979

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

10190

else

9980

else

10191

if OP.RX_CALIBRATION == 1 && channel_number == 2

9981

if OP.RX_CALIBRATION == 1 && channel_number == 2

10192

% for calibration do not include the transmitter package

9982

% for calibration do not include the transmitter package

10193

[s11out_rx, s12out_rx, s21out_rx, s22out_rx ] = combines4p( s11, s12, s21, s22, s22out, s12out, s21out, s11out ); %#ok<ASGLU> % s22 is ball side of package

9983

[s11out_rx, s12out_rx, s21out_rx, s22out_rx ] = combines4p( s11, s12, s21, s22, s22out, s12out, s21out, s11out ); %#ok<ASGLU> % s22 is ball side of package

10194

SCH.Frequencies=faxis;

9984

SCH.Frequencies=faxis;

10195

SCH.Parameters(1,1,:)=s11out_rx;

9985

SCH.Parameters(1,1,:)=s11out_rx;

10196

SCH.Parameters(2,2,:)=s22out_rx;

9986

SCH.Parameters(2,2,:)=s22out_rx;

10197

SCH.Parameters(1,2,:)=s12out_rx;

9987

SCH.Parameters(1,2,:)=s12out_rx;

10198

SCH.Parameters(2,1,:)=s21out_rx;

9988

SCH.Parameters(2,1,:)=s21out_rx;

10199

SCH.NumPorts=2;

9989

SCH.NumPorts=2;

10200

SCH.Impedance=100;

9990

SCH.Impedance=100;

10201

%% Equation 93A-18

9991

%% Equation 93A-18

10202

if include_die

9992

if include_die

10203

s21p= s21out_rx.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11out_rx.*gamma_tx - s22out_rx.*gamma_rx -s21out_rx.^2.*gamma_tx.*gamma_rx +s11out_rx.*s22out_rx.*gamma_tx.*gamma_rx);

9993

s21p= s21out_rx.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11out_rx.*gamma_tx - s22out_rx.*gamma_rx -s21out_rx.^2.*gamma_tx.*gamma_rx +s11out_rx.*s22out_rx.*gamma_tx.*gamma_rx);

10204

else

9994

else

10205

s21p=s21out_rx; % if no die we do not want a VTF

9995

s21p=s21out_rx; % if no die we do not want a VTF

10206

end

9996

end

10207

else

9997

else

10208

%% Equations 93A-4 to 93A-7

9998

%% Equations 93A-4 to 93A-7

10209

if ~OP.IDEAL_TX_TERM

9999

if ~OP.IDEAL_TX_TERM

10210

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10000

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10211

end

10001

end

10212

H_t=ones(1,length(faxis)); % .3bj compatibility

10002

H_t=ones(1,length(faxis)); % .3bj compatibility

10213

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10003

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10214

% for RITT testing with good termination as in some instruments

10004

% for RITT testing with good termination as in some instruments

10215

% and tx filter when required

10005

% and tx filter when required

10216

if OP.T_r_filter_type==0

10006

if OP.T_r_filter_type==0

10217

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10007

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10218

else

10008

else

10219

tr=OP.transmitter_transition_time;

10009

tr=OP.transmitter_transition_time;

10220

f9=faxis/1e9;

10010

f9=faxis/1e9;

10221

if OP.T_r_meas_point == 1

10011

if OP.T_r_meas_point == 1

10222

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10012

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10223

H_t=105./(f9.^4*(k*tr)^4 - f9.^3*(k*tr)^3*10i - 45*f9.^2*(k*tr)^2 + f9*(k*tr)*105i + 105);

10013

H_t=105./(f9.^4*(k*tr)^4 - f9.^3*(k*tr)^3*10i - 45*f9.^2*(k*tr)^2 + f9*(k*tr)*105i + 105);

10224

else

10014

else

10225

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10015

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10226

end

10016

end

10227

10017

10228

end

10018

end

10229

end

10019

end

10230

if strcmpi(mode,'dc')

10020

if strcmpi(mode,'dc')

10231

% H_t=ones(1,length(faxis)); % not sure if we need a H_t or not. Is the CM noise correlated to the edge rate?

10021

% H_t=ones(1,length(faxis)); % not sure if we need a H_t or not. Is the CM noise correlated to the edge rate?

10232

end

10022

end

10233

if ~OP.IDEAL_RX_TERM

10023

if ~OP.IDEAL_RX_TERM

10234

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10024

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10235

else

10025

else

10236

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10026

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10237

end

10027

end

10238

%% Equation 93A-18 and part of 93A-1: Ht fix in V290 identified by Bill Kirkland and Ed Frlan ( s21^2 changed to s12*s21 )

10028

%% Equation 93A-18 and part of 93A-1: Ht fix in V290 identified by Bill Kirkland and Ed Frlan ( s21^2 changed to s12*s21 )

10239

if include_die

10029

if include_die

10240

s21p= H_t.*s21.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11.*gamma_tx - s22.*gamma_rx -s21.*s12.*gamma_tx.*gamma_rx +s11.*s22.*gamma_tx.*gamma_rx);

10030

s21p= H_t.*s21.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11.*gamma_tx - s22.*gamma_rx -s21.*s12.*gamma_tx.*gamma_rx +s11.*s22.*gamma_tx.*gamma_rx);

10241

else

10031

else

10242

s21p=s21; % if no die we do not want a VTF

10032

s21p=s21; % if no die we do not want a VTF

10243

end

10033

end

10244

end

10034

end

10245

10035

10246

if strcmpi(mode,'dc')

10036

if strcmpi(mode,'dc')

10247

% compute AC_CM_RMS at tp0

10037

% compute AC_CM_RMS at tp0

10248

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10038

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10249

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10039

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10250

if channel_number == 1

10040

if channel_number == 1

10251

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10041

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10252

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10042

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10253

sigma_ACCM_at_tp0= sqrt(2*param.AC_CM_RMS_TX^2*sum( abs( H_cc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end)) ;

10043

sigma_ACCM_at_tp0= sqrt(2*param.AC_CM_RMS_TX^2*sum( abs( H_cc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end)) ;

10254

% S=sparameters(p,faxis);

10044

% S=sparameters(p,faxis);

10255

% rfwrite(S,'temp.s4p');

10045

% rfwrite(S,'temp.s4p');

10256

end

10046

end

10257

end

10047

end

10258

10048

10259

SCH.Frequencies=faxis;

10049

SCH.Frequencies=faxis;

10260

SCH.Parameters(1,1,:)=s11;

10050

SCH.Parameters(1,1,:)=s11;

10261

SCH.Parameters(2,2,:)=s22;

10051

SCH.Parameters(2,2,:)=s22;

10262

SCH.Parameters(1,2,:)=s12;

10052

SCH.Parameters(1,2,:)=s12;

10263

SCH.Parameters(2,1,:)=s21;

10053

SCH.Parameters(2,1,:)=s21;

10264

SCH.NumPorts=2;

10054

SCH.NumPorts=2;

10265

if strcmpi(mode,'dc')

10055

if strcmpi(mode,'dc')

10266

SCH.Impedance=25;

10056

SCH.Impedance=25;

10267

else

10057

else

10268

SCH.Impedance=100;

10058

SCH.Impedance=100;

10269

end

10059

end

10270

10060

10271

end

10061

end

10272

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10062

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10273

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10063

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10274

% Creates a time-domain impulse response from frequency-domain IL data.

10064

% Creates a time-domain impulse response from frequency-domain IL data.

10275

% IL does not need to have DC but a corresponding frequency array

10065

% IL does not need to have DC but a corresponding frequency array

10276

% (freq_array) is required.

10066

% (freq_array) is required.

10277

%

10067

%

10278

% Causality is imposed using the Alternating Projections Method. See also:

10068

% Causality is imposed using the Alternating Projections Method. See also:

10279

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10069

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10280

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10070

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10281

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10071

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10282

10072

10283

ILin=IL;

10073

ILin=IL;

10284

fmax=1/time_step/2;

10074

fmax=1/time_step/2;

10285

freq_step=(freq_array(3)-freq_array(2))/1;

10075

freq_step=(freq_array(3)-freq_array(2))/1;

10286

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10076

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10287

if all(IL==0)

10077

if all(IL==0)

10288

%response with all zeros is problematic. set to all eps and avoid interp function

10078

%response with all zeros is problematic. set to all eps and avoid interp function

10289

IL=ones(1,length(fout))*eps;

10079

IL=ones(1,length(fout))*eps;

10290

else

10080

else

10291

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10081

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10292

IL_nan = find(isnan(IL));

10082

IL_nan = find(isnan(IL));

10293

for in=IL_nan

10083

for in=IL_nan

10294

IL(in)=IL(in-1);

10084

IL(in)=IL(in-1);

10295

end

10085

end

10296

end

10086

end

10297

IL = IL(:);

10087

IL = IL(:);

10298

% add padding for time steps

10088

% add padding for time steps

10299

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10089

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10300

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10090

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10301

impulse_response = real(ifft(IL_symmetric));

10091

impulse_response = real(ifft(IL_symmetric));

10302

L = length(impulse_response);

10092

L = length(impulse_response);

10303

t_base = (0:L-1)/(freq_step*L);

10093

t_base = (0:L-1)/(freq_step*L);

10304

10094

10305

original_impulse_response=impulse_response;

10095

original_impulse_response=impulse_response;

10306

% Correct non-causal effects frequently caused by extrapolation of IL

10096

% Correct non-causal effects frequently caused by extrapolation of IL

10307

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10097

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10308

abs_ir=abs(impulse_response);

10098

abs_ir=abs(impulse_response);

10309

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10099

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10310

start_ind = a(1);

10100

start_ind = a(1);

10311

10101

10312

err=inf;

10102

err=inf;

10313

while ~all(impulse_response==0)

10103

while ~all(impulse_response==0)

10314

impulse_response(1:start_ind)=0;

10104

impulse_response(1:start_ind)=0;

10315

impulse_response(floor(L/2):end)=0;

10105

impulse_response(floor(L/2):end)=0;

10316

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10106

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10317

ir_modified = real(ifft(IL_modified));

10107

ir_modified = real(ifft(IL_modified));

10318

delta = abs(impulse_response-ir_modified);

10108

delta = abs(impulse_response-ir_modified);

10319

10109

10320

err_prev = err;

10110

err_prev = err;

10321

err=max(delta)/max(impulse_response);

10111

err=max(delta)/max(impulse_response);

10322

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10112

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10323

break;

10113

break;

10324

end

10114

end

10325

10115

10326

impulse_response=ir_modified;

10116

impulse_response=ir_modified;

10327

end

10117

end

10328

10118

10329

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10119

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10330

10120

10331

if ~OP.ENFORCE_CAUSALITY

10121

if ~OP.ENFORCE_CAUSALITY

10332

impulse_response = original_impulse_response;

10122

impulse_response = original_impulse_response;

10333

end

10123

end

10334

% truncate final samples smaller than 1e-3 of the peak

10124

% truncate final samples smaller than 1e-3 of the peak

10335

ir_peak = max(abs(impulse_response));

10125

ir_peak = max(abs(impulse_response));

10336

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10126

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10337

10127

10338

voltage = impulse_response(1:ir_last);

10128

voltage = impulse_response(1:ir_last);

10339

t_base = t_base(1:ir_last);

10129

t_base = t_base(1:ir_last);

10340

10130

10341

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10131

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10342

10132

10343

function S =s_for_c2(zref,f,cpad)

10133

function S =s_for_c2(zref,f,cpad)

10344

% S is 2 port s parameters out

10134

% S is 2 port s parameters out

10345

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10135

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10346

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10136

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10347

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10137

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10348

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10138

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10349

S=sparameters(S_Parameters,f,zref);

10139

S=sparameters(S_Parameters,f,zref);

10350

10140

10351

function S =s_for_c4(zref,f,cpad)

10141

function S =s_for_c4(zref,f,cpad)

10352

10142

10353

S2 = s_for_c2(zref,f,cpad);

10143

S2 = s_for_c2(zref,f,cpad);

10354

S4P=s2_to_s4(S2.Parameters);

10144

S4P=s2_to_s4(S2.Parameters);

10355

S=sparameters(S4P,f,zref);

10145

S=sparameters(S4P,f,zref);

10356

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10146

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10357

10147

10358

10148

10359

10149

10360

10150

10361

%%

10151

%%

10362

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10152

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10363

% save commmend string

10153

% save commmend string

10364

% for saving from interactive queries

10154

% for saving from interactive queries

10365

10155

10366

10156

10367

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10157

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10368

for i=1:num_next+num_fext

10158

for i=1:num_next+num_fext

10369

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10159

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10370

end

10160

end

10371

cmd_str= [ cmd_str ')'];

10161

cmd_str= [ cmd_str ')'];

10372

10162

10373

10163

10374

%%%%% require the RF tool box

10164

%%%%% require the RF tool box

10375

%%

10165

%%

10376

function [ h ] = savefigs( param, OP )

10166

function [ h ] = savefigs( param, OP )

10377

10167

10378

%% find the figures

10168

%% find the figures

10379

hw = waitbar(0,'Saving figures...');

10169

hw = waitbar(0,'Saving figures...');

10380

h = findobj(0, 'Type', 'figure');

10170

h = findobj(0, 'Type', 'figure');

10381

for ii=1:length(h)

10171

for ii=1:length(h)

10382

10172

10383

figname= get(h(ii), 'Name'); % use the figure name as file name

10173

figname= get(h(ii), 'Name'); % use the figure name as file name

10384

if isempty(strfind(figname,param.base))

10174

if isempty(strfind(figname,param.base))

10385

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10175

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10386

end

10176

end

10387

if verLessThan('matlab', '8.4.0')

10177

if verLessThan('matlab', '8.4.0')

10388

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10178

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10389

else

10179

else

10390

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10180

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10391

end

10181

end

10392

figname = strrep(figname,':','-');

10182

figname = strrep(figname,':','-');

10393

figname = strrep(figname,' ','_');

10183

figname = strrep(figname,' ','_');

10394

if OP.SAVE_FIGURES==1

10184

if OP.SAVE_FIGURES==1

10395

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10185

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10396

end

10186

end

10397

%% get x y data

10187

%% get x y data

10398

if OP.SAVE_FIGURE_to_CSV==1

10188

if OP.SAVE_FIGURE_to_CSV==1

10399

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10189

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10400

M=[]; %ncol=1;

10190

M=[]; %ncol=1;

10401

for nk=1:length(h_L)

10191

for nk=1:length(h_L)

10402

% get x and data for a line.

10192

% get x and data for a line.

10403

x_data=get(h_L(nk),'xdata')';

10193

x_data=get(h_L(nk),'xdata')';

10404

y_data=get(h_L(nk),'ydata')';

10194

y_data=get(h_L(nk),'ydata')';

10405

% .........>> need to get data in the line structure (legend or label) for headers

10195

% .........>> need to get data in the line structure (legend or label) for headers

10406

M=[M; x_data; y_data]; %#ok<AGROW>

10196

M=[M; x_data; y_data]; %#ok<AGROW>

10407

end

10197

end

10408

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10198

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10409

% clear M y x header h_L

10199

% clear M y x header h_L

10410

end

10200

end

10411

waitbar(ii/length(h),hw)

10201

waitbar(ii/length(h),hw)

10412

10202

10413

end

10203

end

10414

10204

10415

close(hw)

10205

close(hw)

10416

10206

10417

%%

10207

%%

10418

function [ h ] = savefigs_png( param, OP )

10208

function [ h ] = savefigs_png( param, OP )

10419

10209

10420

%% find the figures

10210

%% find the figures

10421

hw = waitbar(0,'Saving figures...');

10211

hw = waitbar(0,'Saving figures...');

10422

h = findobj(0, 'Type', 'figure');

10212

h = findobj(0, 'Type', 'figure');

10423

for ii=1:length(h)

10213

for ii=1:length(h)

10424

10214

10425

figname= get(h(ii), 'Name'); % use the figure name as file name

10215

figname= get(h(ii), 'Name'); % use the figure name as file name

10426

if isempty(strfind(figname,param.base))

10216

if isempty(strfind(figname,param.base))

10427

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10217

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10428

end

10218

end

10429

if verLessThan('matlab', '8.4.0')

10219

if verLessThan('matlab', '8.4.0')

10430

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10220

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10431

else

10221

else

10432

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10222

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10433

end

10223

end

10434

figname = strrep(figname,':','-');

10224

figname = strrep(figname,':','-');

10435

figname = strrep(figname,' ','_');

10225

figname = strrep(figname,' ','_');

10436

if OP.SAVE_FIGURES==1

10226

if OP.SAVE_FIGURES==1

10437

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10227

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10438

end

10228

end

10439

%% get x y data

10229

%% get x y data

10440

if OP.SAVE_FIGURE_to_CSV==1

10230

if OP.SAVE_FIGURE_to_CSV==1

10441

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10231

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10442

M=[]; %ncol=1;

10232

M=[]; %ncol=1;

10443

for nk=1:length(h_L)

10233

for nk=1:length(h_L)

10444

% get x and data for a line.

10234

% get x and data for a line.

10445

x_data=get(h_L(nk),'xdata')';

10235

x_data=get(h_L(nk),'xdata')';

10446

y_data=get(h_L(nk),'ydata')';

10236

y_data=get(h_L(nk),'ydata')';

10447

% .........>> need to get data in the line structure (legend or label) for headers

10237

% .........>> need to get data in the line structure (legend or label) for headers

10448

M=[M; x_data; y_data]; %#ok<AGROW>

10238

M=[M; x_data; y_data]; %#ok<AGROW>

10449

end

10239

end

10450

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10240

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10451

% clear M y x header h_L

10241

% clear M y x header h_L

10452

end

10242

end

10453

waitbar(ii/length(h),hw)

10243

waitbar(ii/length(h),hw)

10454

10244

10455

end

10245

end

10456

10246

10457

close(hw)

10247

close(hw)

10458

10248

10459

%%

10249

%%

10460

function pdf_out = scalePDF(pdf,scale_factor)

10250

function pdf_out = scalePDF(pdf,scale_factor)

10461

pdf_out=pdf;

10251

pdf_out=pdf;

10462

pdf_out.Min=floor(pdf.Min*scale_factor);

10252

pdf_out.Min=floor(pdf.Min*scale_factor);

10463

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10253

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10464

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10254

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10465

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10255

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10466

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10256

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10467

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10257

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10468

function t_params = stot(s_params)

10258

function t_params = stot(s_params)

10469

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10259

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10470

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10260

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10471

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10261

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10472

delta = (s11.*s22-s12.*s21);

10262

delta = (s11.*s22-s12.*s21);

10473

s21(s21==0)=eps;

10263

s21(s21==0)=eps;

10474

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10264

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10475

10265

10476

function csv_string = str2csv(c)

10266

function csv_string = str2csv(c)

10477

% convert a cell array of strings to a csv string

10267

% convert a cell array of strings to a csv string

10478

cell_tmp = cell(2, length(c));

10268

cell_tmp = cell(2, length(c));

10479

cell_tmp(1,:)=c;

10269

cell_tmp(1,:)=c;

10480

cell_tmp(2,:) = {','};

10270

cell_tmp(2,:) = {','};

10481

cell_tmp{2,end} = '';

10271

cell_tmp{2,end} = '';

10482

csv_string=strcat(cell_tmp{:});

10272

csv_string=strcat(cell_tmp{:});

10483

10273

10484

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10274

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10485

f_GHz=f/1e9;

10275

f_GHz=f/1e9;

10486

%% Equation 93A-10 %%

10276

%% Equation 93A-10 %%

10487

gamma_1 = gamma_coeff(2)*(1+1i);

10277

gamma_1 = gamma_coeff(2)*(1+1i);

10488

%% Equation 93A-11 %%

10278

%% Equation 93A-11 %%

10489

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10279

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10490

%% Equation 93A-9 %%

10280

%% Equation 93A-9 %%

10491

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10281

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10492

gamma(f_GHz==0) = gamma_coeff(1);

10282

gamma(f_GHz==0) = gamma_coeff(1);

10493

10283

10494

%% Equation 93A-12 %%

10284

%% Equation 93A-12 %%

10495

if d==0

10285

if d==0

10496

%force matched impedance if length is 0

10286

%force matched impedance if length is 0

10497

%otherwise divide by zero can occur if Z_c=0

10287

%otherwise divide by zero can occur if Z_c=0

10498

rho_rl=0;

10288

rho_rl=0;

10499

else

10289

else

10500

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10290

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10501

end

10291

end

10502

10292

10503

exp_gamma_d = exp(-d*gamma);

10293

exp_gamma_d = exp(-d*gamma);

10504

%% Equations 93A-13 and 93A-14 %%

10294

%% Equations 93A-13 and 93A-14 %%

10505

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10295

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10506

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10296

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10507

s12 = s21;

10297

s12 = s21;

10508

s22 = s11;

10298

s22 = s11;

10509

10299

10510

function s_params = ttos(t_params)

10300

function s_params = ttos(t_params)

10511

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10301

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10512

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10302

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10513

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10303

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10514

delta = t11.*t22-t21.*t12;

10304

delta = t11.*t22-t21.*t12;

10515

t11(t11==0)=eps;

10305

t11(t11==0)=eps;

10516

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10306

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10517

10307

10518

function [out_var,varg_out]=varargin_extractor(varargin)

10308

function [out_var,varg_out]=varargin_extractor(varargin)

10519

10309

10520

if isempty(varargin)

10310

if isempty(varargin)

10521

out_var=[];

10311

out_var=[];

10522

varg_out={};

10312

varg_out={};

10523

else

10313

else

10524

out_var=varargin{1};

10314

out_var=varargin{1};

10525

varg_out=varargin;

10315

varg_out=varargin;

10526

varg_out(1)=[];

10316

varg_out(1)=[];

10527

end

10317

end

10528

10318

10529

10319

10530

function results= vma(PR, M)

10320

function results= vma(PR, M)

10531

% PR=sbr.Data;

10321

% PR=sbr.Data;

10532

% M=32;

10322

% M=32;

10533

% PR is the pulse response

10323

% PR is the pulse response

10534

% M is samples per UI

10324

% M is samples per UI

10535

[ seq, syms, syms_nrz ] = PRBS13Q( );

10325

[ seq, syms, syms_nrz ] = PRBS13Q( );

10536

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10326

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10537

symbols=seq;

10327

symbols=seq;

10538

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10328

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10539

% start end symbols index for 7 3's and 6 0's

10329

% start end symbols index for 7 3's and 6 0's

10540

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10330

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10541

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10331

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10542

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10332

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10543

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10333

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10544

% superposition code

10334

% superposition code

10545

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10335

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10546

Bit_stream_response=filter(PR,1, shifting_vector);

10336

Bit_stream_response=filter(PR,1, shifting_vector);

10547

% find center of 3's and 0's

10337

% find center of 3's and 0's

10548

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10338

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10549

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10339

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10550

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10340

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10551

% hold on

10341

% hold on

10552

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10342

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10553

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10343

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10554

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10344

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10555

VMA= P_3 - P_0;

10345

VMA= P_3 - P_0;

10556

results.P_3=P_3;

10346

results.P_3=P_3;

10557

results.P_0=P_0;

10347

results.P_0=P_0;

10558

results.VMA=VMA;

10348

results.VMA=VMA;

10559

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10349

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10560

10350

10561

%slope of the 2 sample points around vref crossing

10351

%slope of the 2 sample points around vref crossing

10562

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10352

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10563

%x-intercept for the line

10353

%x-intercept for the line

10564

b1=eye_contour(x_in,1)-m1*x_in;

10354

b1=eye_contour(x_in,1)-m1*x_in;

10565

% drawing a horizontal line through vref so slope = 0

10355

% drawing a horizontal line through vref so slope = 0

10566

m2=0;

10356

m2=0;

10567

%special case for horizontal line, b=y

10357

%special case for horizontal line, b=y

10568

b2=vref;

10358

b2=vref;

10569

%the x-value of line intersection = (b2-b1)/(m1-m2)

10359

%the x-value of line intersection = (b2-b1)/(m1-m2)

10570

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10360

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10571

%And usually vref is 0, so it further reduces to -b1/m1

10361

%And usually vref is 0, so it further reduces to -b1/m1

10572

line_intersection=(b2-b1)/(m1-m2);

10362

line_intersection=(b2-b1)/(m1-m2);

10573

10363

10574

10364

10575

10365

10576

10366

10577

10367

10578

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10368

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10579

% helper function to read parameter values from XLS file. Uses names to find values.

10369

% helper function to read parameter values from XLS file. Uses names to find values.

10580

if nargin<3, eval_if_string=0; end

10370

if nargin<3, eval_if_string=0; end

10581

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10371

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10582

if numel(row)*numel(col)==0

10372

if numel(row)*numel(col)==0

10583

if nargin<4

10373

if nargin<4

10584

missingParameter(param_name);

10374

missingParameter(param_name);

10585

else

10375

else

10586

p = default_value;

10376

p = default_value;

10587

end

10377

end

10588

elseif numel(row)*numel(col)>1

10378

elseif numel(row)*numel(col)>1

10589

% if there are several occurrences, use the first, but warn

10379

% if there are several occurrences, use the first, but warn

10590

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10380

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10591

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10381

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10592

error('COM:XLS_parameter:MultipleOccurrence', ...

10382

error('COM:XLS_parameter:MultipleOccurrence', ...

10593

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10383

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10594

p=param_sheet{row(1), col(1)+1};

10384

p=param_sheet{row(1), col(1)+1};

10595

else

10385

else

10596

p=param_sheet{row, col+1};

10386

p=param_sheet{row, col+1};

10597

end

10387

end

10598

if ischar(p) && eval_if_string

10388

if ischar(p) && eval_if_string

10599

p=eval(p);

10389

p=eval(p);

10600

end

10390

end

10601

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10391

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10602

if OP.SAVE_KEYWORD_FILE

10392

if OP.SAVE_KEYWORD_FILE

10603

10393

10604

if nargin<3 || ~exist('default_value','var')

10394

if nargin<3 || ~exist('default_value','var')

10605

default_value=p;

10395

default_value=p;

10606

end

10396

end

10607

if isempty(default_value)

10397

if isempty(default_value)

10608

default_value='-';

10398

default_value='-';

10609

end

10399

end

10610

%%

10400

%%

10611

% Get call-stack info:

10401

% Get call-stack info:

10612

stDebug = dbstack;

10402

stDebug = dbstack;

10613

callerFileName = stDebug(2).file;

10403

callerFileName = stDebug(2).file;

10614

callerLineNumber = stDebug(2).line;

10404

callerLineNumber = stDebug(2).line;

10615

% Open caller file:

10405

% Open caller file:

10616

fCaller = fopen(callerFileName);

10406

fCaller = fopen(callerFileName);

10617

% Iterate through lines to get to desired line number:

10407

% Iterate through lines to get to desired line number:

10618

for iLine = 1 : callerLineNumber

10408

for iLine = 1 : callerLineNumber

10619

% Read current line of text:

10409

% Read current line of text:

10620

currLine = fgetl(fCaller);

10410

currLine = fgetl(fCaller);

10621

end

10411

end

10622

% (currLine) now reflects calling desired code: display this code:

10412

% (currLine) now reflects calling desired code: display this code:

10623

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10413

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10624

% Close caller file:

10414

% Close caller file:

10625

left_side=currLine(1:strfind(currLine,'=')-1);

10415

left_side=currLine(1:strfind(currLine,'=')-1);

10626

cmt_side=currLine(strfind(currLine,'%')+1:end);

10416

cmt_side=currLine(strfind(currLine,'%')+1:end);

10627

if isempty(cmt_side), cmt_side=' ';end

10417

if isempty(cmt_side), cmt_side=' ';end

10628

fclose(fCaller);

10418

fclose(fCaller);

10629

10419

10630

if ~ischar(default_value)

10420

if ~ischar(default_value)

10631

default_str=sprintf('%g ',default_value);

10421

default_str=sprintf('%g ',default_value);

10632

else

10422

else

10633

default_str=default_value;

10423

default_str=default_value;

10634

end

10424

end

10635

if ~isfile('keyworklog.mat')

10425

if ~isfile('keyworklog.mat')

10636

save_p=param_name;

10426

save_p=param_name;

10637

save_d=default_str;

10427

save_d=default_str;

10638

save_r=left_side;

10428

save_r=left_side;

10639

save_c=cmt_side;

10429

save_c=cmt_side;

10640

param_name = {'keyword'};

10430

param_name = {'keyword'};

10641

default_str = {'default'};

10431

default_str = {'default'};

10642

left_side={'matlab variable'};

10432

left_side={'matlab variable'};

10643

cmt_side={'info'};

10433

cmt_side={'info'};

10644

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10434

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10645

param_name=save_p;

10435

param_name=save_p;

10646

default_str=save_d;

10436

default_str=save_d;

10647

left_side=save_r;

10437

left_side=save_r;

10648

cmt_side=save_c;

10438

cmt_side=save_c;

10649

data=load('keyworklog.mat');

10439

data=load('keyworklog.mat');

10650

else

10440

else

10651

load('keyworklog.mat');

10441

load('keyworklog.mat');

10652

end

10442

end

10653

data.left_side = [ data.left_side; left_side];

10443

data.left_side = [ data.left_side; left_side];

10654

data.param_name = [data.param_name; param_name];

10444

data.param_name = [data.param_name; param_name];

10655

data.default_str = [data.default_str; default_str ];

10445

data.default_str = [data.default_str; default_str ];

10656

data.cmt_side = [ data.cmt_side; cmt_side];

10446

data.cmt_side = [ data.cmt_side; cmt_side];

10657

if length(data.default_str)~=length(data.default_str)

10447

if length(data.default_str)~=length(data.default_str)

10658

a=1;

10448

a=1;

10659

end

10449

end

10660

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10450

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10661

save('keyworklog.mat','data');

10451

save('keyworklog.mat','data');

10662

writetable(T,[ 'keywords_' date '.csv' ]);

10452

writetable(T,[ 'keywords_' date '.csv' ]);

10663

end

10453

end

10664

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10454

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10665

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10455

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10666

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10456

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10667

10457

10668

found=1;

10458

found=1;

10669

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10459

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10670

if numel(row)*numel(col)==0

10460

if numel(row)*numel(col)==0

10671

p = 0;

10461

p = 0;

10672

found=0;

10462

found=0;

10673

elseif numel(row)*numel(col)>1

10463

elseif numel(row)*numel(col)>1

10674

% if there are several occurrences, use the first, but warn

10464

% if there are several occurrences, use the first, but warn

10675

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10465

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10676

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10466

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10677

error('COM:XLS_parameter:MultipleOccurrence', ...

10467

error('COM:XLS_parameter:MultipleOccurrence', ...

10678

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10468

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10679

p=param_sheet{row(1), col(1)+1};

10469

p=param_sheet{row(1), col(1)+1};

10680

else

10470

else

10681

p=param_sheet{row, col+1};

10471

p=param_sheet{row, col+1};

10682

end

10472

end

10683

if ischar(p)

10473

if ischar(p)

10684

p=eval(p);

10474

p=eval(p);

10685

end

10475

end

10686

function zzz_list_of_changes

10476

function zzz_list_of_changes

10687

% structures:

10477

% structures:

10688

% chdata(i)

10478

% chdata(i)

10689

% i= 1 --> THRU index

10479

% i= 1 --> THRU index

10690

% i= 2, num_fext+1 --> FEXT channel index

10480

% i= 2, num_fext+1 --> FEXT channel index

10691

% i= num_fext+2, num_next+num_fext+1

10481

% i= num_fext+2, num_next+num_fext+1

10692

% base: name of THRU file

10482

% base: name of THRU file

10693

% A: amplitude

10483

% A: amplitude

10694

% type: 'THRU', 'NEXT', or 'FEXT'

10484

% type: 'THRU', 'NEXT', or 'FEXT'

10695

% ftr: Rise time frequency

10485

% ftr: Rise time frequency

10696

% fmaxi: max number of frequency points

10486

% fmaxi: max number of frequency points

10697

% faxis: frequency array [Hz]

10487

% faxis: frequency array [Hz]

10698

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10488

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10699

% sdd22: differential RL

10489

% sdd22: differential RL

10700

% sdd11: differential RL

10490

% sdd11: differential RL

10701

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10491

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10702

% sdd21f: raw differential IL not filtered use for FD plots

10492

% sdd21f: raw differential IL not filtered use for FD plots

10703

% added output_args.peak_uneq_pulse_mV

10493

% added output_args.peak_uneq_pulse_mV

10704

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10494

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10705

% added: tap c(-2) c(2) and c(3)

10495

% added: tap c(-2) c(2) and c(3)

10706

% added: g_DC_HP and f_HP_PZ

10496

% added: g_DC_HP and f_HP_PZ

10707

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10497

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10708

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10498

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10709

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10499

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10710

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10500

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10711

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10501

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10712

% fixed INCLUDE_CTLE=0 to really remove from computation

10502

% fixed INCLUDE_CTLE=0 to really remove from computation

10713

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10503

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10714

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10504

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10715

% r162 tx and rx package impedance {Zc)

10505

% r162 tx and rx package impedance {Zc)

10716

% r162a Gaussian equation corrected

10506

% r162a Gaussian equation corrected

10717

% r163 cast snr_tx with package test case

10507

% r163 cast snr_tx with package test case

10718

% r164 fix pdf for very low noise and lo pass filter enhancements

10508

% r164 fix pdf for very low noise and lo pass filter enhancements

10719

% r164 add zero gain at nqyist CTLE as in CL12e

10509

% r164 add zero gain at nqyist CTLE as in CL12e

10720

% r165 add simpler congfig command called FORCE_TR (force risetime)

10510

% r165 add simpler congfig command called FORCE_TR (force risetime)

10721

% r200 cm3 and cm4 added cp3 removed

10511

% r200 cm3 and cm4 added cp3 removed

10722

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10512

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10723

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10513

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10724

% r200 improved phase interpolation for return loss time conversion

10514

% r200 improved phase interpolation for return loss time conversion

10725

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10515

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10726

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10516

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10727

% r200c missed on fix for interpolation

10517

% r200c missed on fix for interpolation

10728

% r210 new ERL with time gating function

10518

% r210 new ERL with time gating function

10729

% r224 update ERL with from D3.1

10519

% r224 update ERL with from D3.1

10730

% r226 fix s2p reading problem

10520

% r226 fix s2p reading problem

10731

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10521

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10732

% Fix Rx calibration issue

10522

% Fix Rx calibration issue

10733

% added ERL limit and Nd

10523

% added ERL limit and Nd

10734

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10524

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10735

% INC_PACKAGE=0 not fully supported message

10525

% INC_PACKAGE=0 not fully supported message

10736

% if N=0 use TDR_duration

10526

% if N=0 use TDR_duration

10737

% red display text for fail ERL and COM

10527

% red display text for fail ERL and COM

10738

% r228 fixed ERL pass fail report, default Grr_limit to 1

10528

% r228 fixed ERL pass fail report, default Grr_limit to 1

10739

% r230 add rx ffe

10529

% r230 add rx ffe

10740

% r231 change crosstalk noise to icn like to speed things up

10530

% r231 change crosstalk noise to icn like to speed things up

10741

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10531

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10742

% 1e-5mof-

10532

% 1e-5mof-

10743

% r232 fix default for Rx eq so old spead sheets work

10533

% r232 fix default for Rx eq so old spead sheets work

10744

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10534

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10745

% r235 adding dfe quantization changed to normalized DFE taps reported

10535

% r235 adding dfe quantization changed to normalized DFE taps reported

10746

% r236 adding ffe gain loop and resample after RxFFE

10536

% r236 adding ffe gain loop and resample after RxFFE

10747

% r240 added output for C2M and setting defaults for some FFE eq

10537

% r240 added output for C2M and setting defaults for some FFE eq

10748

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10538

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10749

% r250 adding more complex package

10539

% r250 adding more complex package

10750

% r251 post cursor fix for DFE in force() and ffe backoff

10540

% r251 post cursor fix for DFE in force() and ffe backoff

10751

% r251 remove TDR threshold noise filter

10541

% r251 remove TDR threshold noise filter

10752

% r252 add rx FFE filter to receiver noise filter

10542

% r252 add rx FFE filter to receiver noise filter

10753

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10543

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10754

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10544

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10755

% r254 precursor check fix in optimize_fom % mod fix in force

10545

% r254 precursor check fix in optimize_fom % mod fix in force

10756

% r254 help to align columns in csv file

10546

% r254 help to align columns in csv file

10757

% r254 accept syntax for 2 tline flex package model

10547

% r254 accept syntax for 2 tline flex package model

10758

% r256 speed up optimize FOM

10548

% r256 speed up optimize FOM

10759

% r256 fix problem reading in config file from q/a

10549

% r256 fix problem reading in config file from q/a

10760

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10550

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10761

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10551

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10762

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10552

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10763

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10553

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10764

% r258 CDR switch 'MM' or 'mod-MM'

10554

% r258 CDR switch 'MM' or 'mod-MM'

10765

% r258 correction for asymentirc tx/Rx packages

10555

% r258 correction for asymentirc tx/Rx packages

10766

% r258 revamped display results display window

10556

% r258 revamped display results display window

10767

% r259 fix problem if Min_VEO is set in spreadsheet.

10557

% r259 fix problem if Min_VEO is set in spreadsheet.

10768

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10558

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10769

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10559

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10770

% r259 putting COM_db and IL last in output to terminal

10560

% r259 putting COM_db and IL last in output to terminal

10771

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10561

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10772

% r259 use N_bx for ERL rather than Nb (ndfe))

10562

% r259 use N_bx for ERL rather than Nb (ndfe))

10773

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10563

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10774

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10564

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10775

% r260 used eta_0 PSD equation for sigma_n

10565

% r260 used eta_0 PSD equation for sigma_n

10776

% r260 fix IL graph legend to w/pkg and Tr

10566

% r260 fix IL graph legend to w/pkg and Tr

10777

% r260 define tfx for each port

10567

% r260 define tfx for each port

10778

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10568

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10779

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10569

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10780

% r262 reset on exit default text interpreter to tex

10570

% r262 reset on exit default text interpreter to tex

10781

% r262 localize run timer (John Buck 1/17/19)

10571

% r262 localize run timer (John Buck 1/17/19)

10782

% r262 set db as internal function in force to avoid tool box

10572

% r262 set db as internal function in force to avoid tool box

10783

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10573

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10784

% r263 added to output_args RL structure and report "struct" in csv file

10574

% r263 added to output_args RL structure and report "struct" in csv file

10785

% r264 added EW estimate

10575

% r264 added EW estimate

10786

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10576

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10787

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10577

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10788

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10578

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10789

% r269 changed param.N_bmax to param.N_f

10579

% r269 changed param.N_bmax to param.N_f

10790

% r270 implement JingBo Li's and Howard Heck's floating tap method

10580

% r270 implement JingBo Li's and Howard Heck's floating tap method

10791

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10581

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10792

% r270 added c_0 and c_1 for CA in add_brd

10582

% r270 added c_0 and c_1 for CA in add_brd

10793

% r272 fixed version syntax problem in output_args RL report

10583

% r272 fixed version syntax problem in output_args RL report

10794

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10584

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10795

% r272 removed eye width report if doing a Rx calibration

10585

% r272 removed eye width report if doing a Rx calibration

10796

% r273 better alignment and control for ICN reporting

10586

% r273 better alignment and control for ICN reporting

10797

% r273 fixed PSXTK graph

10587

% r273 fixed PSXTK graph

10798

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10588

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10799

% r276 go back to reporting channel IL results (output_args.IL_dB_channel_only_at_Fnq) with board added read_s4p_files (as in r270)

10589

% r276 go back to reporting channel IL results (output_args.IL_dB_channel_only_at_Fnq) with board added read_s4p_files (as in r270)

10800

% r276 chdata(i).Aicn=param.a_icn_fext should have been chdata(i).Aicn=param.a_icn_next for the next selection. Since in most spec's they are the same there is little no impact in results

10590

% r276 chdata(i).Aicn=param.a_icn_fext should have been chdata(i).Aicn=param.a_icn_next for the next selection. Since in most spec's they are the same there is little no impact in results

10801

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10591

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10802

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10592

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10803

% r276 C_1 was instantiated as C_0. This was fixed

10593

% r276 C_1 was instantiated as C_0. This was fixed

10804

% r276 fixed rounding problem in reporting of loss at f_nq

10594

% r276 fixed rounding problem in reporting of loss at f_nq

10805

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10595

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10806

% r277 added nv for deterining steady state voltage for fitting compatibility

10596

% r277 added nv for deterining steady state voltage for fitting compatibility

10807

% r278 added b_min to support asymmetric bmax

10597

% r278 added b_min to support asymmetric bmax

10808

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10598

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10809

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10599

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10810

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10600

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10811

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10601

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10812

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10602

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10813

% r292 eq. 93A-19 and 93-20 code implementation bug when include .3by change% to fix edge rate equation 93A-46 (h_T). no effect if Rd=50 or IL > 5 dB

10603

% r292 eq. 93A-19 and 93-20 code implementation bug when include .3by change% to fix edge rate equation 93A-46 (h_T). no effect if Rd=50 or IL > 5 dB

10814

% r292 H_t implemented in s21_pkg

10604

% r292 H_t implemented in s21_pkg

10815

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10605

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10816

% r292 add GDC_MIN to optimize_FOM

10606

% r292 add GDC_MIN to optimize_FOM

10817

% r293 fix if ndfe-0 and ERL only and s2p issue

10607

% r293 fix if ndfe-0 and ERL only and s2p issue

10818

% r293a investigate the Tukey filtering

10608

% r293a investigate the Tukey filtering

10819

% r293a if fix if bmin is missing

10609

% r293a if fix if bmin is missing

10820

% r294 fix problems reading s2p files for ERL computation

10610

% r294 fix problems reading s2p files for ERL computation

10821

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10611

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10822

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10612

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10823

% r294 add gdc and gdc2 range limitations

10613

% r294 add gdc and gdc2 range limitations

10824

% r295 add VEC Pass threshold

10614

% r295 add VEC Pass threshold

10825

% r295 removed close force all. Tagged all figures with "COM"

10615

% r295 removed close force all. Tagged all figures with "COM"

10826

% r295 consolidated print in new function "end_display_control"

10616

% r295 consolidated print in new function "end_display_control"

10827

% r295 report pre/pmax for Txffe

10617

% r295 report pre/pmax for Txffe

10828

% r295 speed up test cases by not re-reading in s4p files

10618

% r295 speed up test cases by not re-reading in s4p files

10829

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10619

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10830

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10620

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10831

% r310 refine VEC and EH for C2M from Adam Gregory in

10621

% r310 refine VEC and EH for C2M from Adam Gregory in

10832

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10622

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10833

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10623

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10834

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10624

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10835

% r311 added RILN

10625

% r311 added RILN

10836

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10626

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10837

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10627

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10838

% r316 remove DC computation for RX Calibration loops

10628

% r316 remove DC computation for RX Calibration loops

10839

% r317 for SAVE_TD to include EQ and unEQ FIR

10629

% r317 for SAVE_TD to include EQ and unEQ FIR

10840

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10630

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10841

% r318 if min_VEO_test fails to find a solution the loop is restarted with min_VEO_test to near zero. Makes sure COM returns results

10631

% r318 if min_VEO_test fails to find a solution the loop is restarted with min_VEO_test to near zero. Makes sure COM returns results

10842

% r320 fixed RX_CALIBRATION which was broken in r310

10632

% r320 fixed RX_CALIBRATION which was broken in r310

10843

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10633

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10844

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10634

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10845

% r320 removed external feature and replace with TDMODE

10635

% r320 removed external feature and replace with TDMODE

10846

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10636

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10847

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10637

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10848

% r335 fixed typo in when processing the bessel thompson filter option

10638

% r335 fixed typo in when processing the bessel thompson filter option

10849

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10639

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10850

% r335 compute and report CD_CM_RMS

10640

% r335 compute and report CD_CM_RMS

10851

% r335 fixed where output_arg is save i.e. move to end

10641

% r335 fixed where output_arg is save i.e. move to end

10852

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10642

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10853

% r335 change raw IL plot to not include boards

10643

% r335 change raw IL plot to not include boards

10854

% r335 set T_0 to zero if not C2M

10644

% r335 set T_0 to zero if not C2M

10855

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10645

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10856

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10646

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10857

% r335 TD_RILN changes from Hansel Dsilva

10647

% r335 TD_RILN changes from Hansel Dsilva

10858

% r335 Fixed sigma_N for RxFFE

10648

% r335 Fixed sigma_N for RxFFE

10859

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10649

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10860

% r335 added c(2) and C(3) back to read_ParamConfigFile

10650

% r335 added c(2) and C(3) back to read_ParamConfigFile

10861

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10651

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10862

% r335 corrected GDC_MIN per 0.3ck D2.3

10652

% r335 corrected GDC_MIN per 0.3ck D2.3

10863

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10653

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10864

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10654

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10865

% r370 speed up

10655

% r370 speed up

10866

% r370 fix for floating tap missing locations

10656

% r370 fix for floating tap missing locations

10867

% r370 variable Tx FFE taps

10657

% r370 variable Tx FFE taps

10868

% r370 package die load with ladder circuit

10658

% r370 package die load with ladder circuit

10869

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10659

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10870

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10660

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10871

% r380 added capabablity to enable a raised cosine Rx filter0

10661

% r380 added capabablity to enable a raised cosine Rx filter0

10872

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10662

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10873

% r380 added plot for VTF

10663

% r380 added plot for VTF

10874

% r385 added capability for additional Tx FFE per package

10664

% r385 added capability for additional Tx FFE per package

10875

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10665

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10876

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10666

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10877

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10667

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10878

% r389 Improvement by A. Ran for reporting loss at Nq

10668

% r389 Improvement by A. Ran for reporting loss at Nq

10879

% r389 Fixed typo: changed VIM to VMP

10669

% r389 Fixed typo: changed VIM to VMP

10880

% r400 fixed PR with zero pad extension

10670

% r400 fixed PR with zero pad extension

10881

% r400 keyword MLSE and SNRADJ_EQUA for future work

10671

% r400 keyword MLSE and SNRADJ_EQUA for future work

10882

% r400 replaced function db with instances of 20*log10(abs(...))

10672

% r400 replaced function db with instances of 20*log10(abs(...))

10883

% r410 widen voltage distriution for normal_dist doubled max Q

10673

% r410 widen voltage distriution for normal_dist doubled max Q

10884

% r410 improve reading in of config files

10674

% r410 improve reading in of config files

10885

% r410 renormalize s-parameter if not 50 ohm ref

10675

% r410 renormalize s-parameter if not 50 ohm ref

10886

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10676

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10887

% r410 remove RL from output_args bc not need and too much storage allocation

10677

% r410 remove RL from output_args bc not need and too much storage allocation

10888

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10678

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10889

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10679

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10890

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10680

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10891

% r420 updade force to account for pulse responces with short delays in force

10681

% r420 updade force to account for pulse responces with short delays in force

10892

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10682

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10893

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10683

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10894

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10684

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10895

% r420 Wiener-Kofp MMSE optimization for RxFFE

10685

% r420 Wiener-Kofp MMSE optimization for RxFFE

10896

% r430 first pass at healey_3dj_01_2401

10686

% r430 first pass at healey_3dj_01_2401

10897

% r430 RxFFE fixed taps

10687

% r430 RxFFE fixed taps

10898

% r440 RxffE fixed tap index corrections and floating taps

10688

% r440 RxffE fixed tap index corrections and floating taps

10899

% r440 first pass implemenation of MLSE U3

10689

% r440 first pass implemenation of MLSE U3

10900

10690