File Comparison Report

C:\Users\richardm\OneDrive - Samtec\COM\COM\src\com_ieee8023_93a_460beta4.m vs. C:\Users\richardm\OneDrive - Samtec\COM\COM\src\com_ieee8023_93a_460beta3.m

richardm

01-Jul-2024

Files

Left FileRight File
File namecom_ieee8023_93a_460beta4com_ieee8023_93a_460beta3
File pathC:\Users\richardm\OneDrive - Samtec\COM\COM\srcC:\Users\richardm\OneDrive - Samtec\COM\COM\src
Last modified01-Jul-2024 08:53:3118-Jun-2024 10:29:59

Environment

MATLAB9.14 (R2023a)

Comparison Results

+

Insertion

Deletion

Modification
1

function results=com_ieee8023_93a(varargin)

1

function results=com_ieee8023_93a(varargin)

2

% This is NOT an official IEEE document.

2

% This is NOT an official IEEE document.

3

%% Implementation example of annex 93A IEEE Std 802.3

3

%% Implementation example of annex 93A IEEE Std 802.3

4

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

4

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

5

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

5

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

6

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

6

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

7

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

7

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

8

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

8

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

9

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

9

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

10

% will ask for each of the files interactively.opupu

10

% will ask for each of the files interactively.opupu

11

%

11

%

12

% This program is intended for the development of standard specifications

12

% This program is intended for the development of standard specifications

13

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

13

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

14

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

14

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

15

% original proposal for COM may be found at

15

% original proposal for COM may be found at

16

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

16

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

17

% from the following authors and affiliations in 2012.

17

% from the following authors and affiliations in 2012.

18

% Richard Mellitz, Intel Corporation

18

% Richard Mellitz, Intel Corporation

19

% Charles Moore, Avago Technologies

19

% Charles Moore, Avago Technologies

20

% Mike Dudek, QLogic Corporation

20

% Mike Dudek, QLogic Corporation

21

% Mike Peng Li, Altera Corporation

21

% Mike Peng Li, Altera Corporation

22

% Adee Ran, Intel Corporation

22

% Adee Ran, Intel Corporation

23

%

23

%

24

% Some of the authors and Contributors:

24

% Some of the authors and Contributors:

25

% Adee Ran

25

% Adee Ran

26

% Richard Mellitz

26

% Richard Mellitz

27

% Yasuo Hidaka

27

% Yasuo Hidaka

28

% John Ewen

28

% John Ewen

29

% Bill Kirkland

29

% Bill Kirkland

30

% Adam Gregory

30

% Adam Gregory

31

% Howard Heck

31

% Howard Heck

32

% Jingbo Li

32

% Jingbo Li

33

% Adam Healey

33

% Adam Healey

34

% Matt Brown

34

% Matt Brown

35

% Sameh Elnagar

35

% Sameh Elnagar

36

% Hossein Shakiba

36

% Hossein Shakiba

37

zzz_list_of_changes()

37

zzz_list_of_changes()

38

38

39

%% Opening Preface

39

%% Opening Preface

40

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

40

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

41

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

41

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

42

try % version number at end of call string

42

try % version number at end of call string

43

cmdfile=mfilename;

43

cmdfile=mfilename;

44

hindx=strfind(mfilename,'_');

44

hindx=strfind(mfilename,'_');

45

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

45

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

46

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

46

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

47

catch

47

catch

48

output_args.code_revision ='';

48

output_args.code_revision ='';

49

end

49

end

50

teststr='';

50

teststr='';

51

OP.TESTING=0;

51

OP.TESTING=0;

52

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

52

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

53

teststr='testing';

53

teststr='testing';

54

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

54

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

55

htest = msgbox(testmsg);

55

htest = msgbox(testmsg);

56

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

56

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

57

end

57

end

58

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

58

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

59

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

59

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

60

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

60

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

61

t0=tic;

61

t0=tic;

62

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

62

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

63

% reset to tex on exit

63

% reset to tex on exit

64

%% file_setup

64

%% file_setup

65

%%

65

%%

66

% need to see what happens for version 8

66

% need to see what happens for version 8

67

if verLessThan('matlab', '7.4.1')

67

if verLessThan('matlab', '7.4.1')

68

error('Matlab version 7.4 or higher required')

68

error('Matlab version 7.4 or higher required')

69

end

69

end

70

70

71

results=[];

71

results=[];

72

72

73

%% New Command Line parser

73

%% New Command Line parser

74

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

74

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

75

75

76

76

77

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

77

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

78

if isempty(config_file)

78

if isempty(config_file)

79

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

79

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

80

if isempty(config_file)

80

if isempty(config_file)

81

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

81

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

82

else

82

else

83

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

83

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

84

config_file=[cname cext];

84

config_file=[cname cext];

85

end

85

end

86

if config_file==0

86

if config_file==0

87

% cancel - exit gracefully

87

% cancel - exit gracefully

88

return;

88

return;

89

end

89

end

90

config_file = fullfile(config_file_path, config_file);

90

config_file = fullfile(config_file_path, config_file);

91

end

91

end

92

output_args.config_file = config_file;

92

output_args.config_file = config_file;

93

OP.SAVE_KEYWORD_FILE=0;

93

OP.SAVE_KEYWORD_FILE=0;

94

if OP.SAVE_KEYWORD_FILE

94

if OP.SAVE_KEYWORD_FILE

95

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

95

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

96

delete('keyworklog.mat');

96

delete('keyworklog.mat');

97

end

97

end

98

end

98

end

99

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

99

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

100

if OP.CONFIG2MAT_ONLY

100

if OP.CONFIG2MAT_ONLY

101

return;

101

return;

102

end

102

end

103

if isempty(num_fext)

103

if isempty(num_fext)

104

if OP.RX_CALIBRATION

104

if OP.RX_CALIBRATION

105

num_fext=1;

105

num_fext=1;

106

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

106

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

107

else

107

else

108

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

108

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

109

num_fext=1;

109

num_fext=1;

110

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

110

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

111

elseif ~OP.ERL_ONLY

111

elseif ~OP.ERL_ONLY

112

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

112

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

113

else

113

else

114

num_fext=0;

114

num_fext=0;

115

end

115

end

116

end

116

end

117

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

117

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

118

end

118

end

119

if isempty(num_next)

119

if isempty(num_next)

120

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

120

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

121

num_next=0;

121

num_next=0;

122

else

122

else

123

if OP.RX_CALIBRATION

123

if OP.RX_CALIBRATION

124

num_next=0;

124

num_next=0;

125

elseif ~OP.ERL_ONLY

125

elseif ~OP.ERL_ONLY

126

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

126

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

127

else

127

else

128

num_next=0;

128

num_next=0;

129

end

129

end

130

end

130

end

131

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

131

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

132

end

132

end

133

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

133

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

134

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

134

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

135

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

135

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

136

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

136

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

137

param.num_next=num_next;

137

param.num_next=num_next;

138

param.num_fext=num_fext;

138

param.num_fext=num_fext;

139

param.num_s4p_files=num_fext+num_next+1;

139

param.num_s4p_files=num_fext+num_next+1;

140

% checking for data when running for rx compliance BBN calibration

140

% checking for data when running for rx compliance BBN calibration

141

if OP.RX_CALIBRATION == 1

141

if OP.RX_CALIBRATION == 1

142

if num_fext ~=1

142

if num_fext ~=1

143

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

143

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

144

movegui(h,'northwest')

144

movegui(h,'northwest')

145

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

145

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

146

if OP.DEBUG ~= 1

146

if OP.DEBUG ~= 1

147

return

147

return

148

end

148

end

149

end

149

end

150

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

150

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

151

movegui(h,'southeast')

151

movegui(h,'southeast')

152

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

152

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

153

end

153

end

154

154

155

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

155

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

156

if num_fext ~=1

156

if num_fext ~=1

157

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

157

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

158

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

158

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

159

movegui(h,'northwest')

159

movegui(h,'northwest')

160

if OP.DEBUG ~= 1

160

if OP.DEBUG ~= 1

161

return

161

return

162

end

162

end

163

end

163

end

164

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

164

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

165

movegui(h,'southeast')

165

movegui(h,'southeast')

166

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

166

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

167

end

167

end

168

168

169

169

170

% create result directory if needed

170

% create result directory if needed

171

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

171

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

172

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

172

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

173

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

173

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

174

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

174

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

175

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

175

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

176

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

176

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

177

%OP.EXTERNAL = true;

177

%OP.EXTERNAL = true;

178

%OP.GET_FD = 0;

178

%OP.GET_FD = 0;

179

%ir1a= varargin(2);

179

%ir1a= varargin(2);

180

%ex_var = varargin(3);

180

%ex_var = varargin(3);

181

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

181

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

182

else

182

else

183

if OP.TDMODE

183

if OP.TDMODE

184

OP.GET_FD=false;

184

OP.GET_FD=false;

185

end

185

end

186

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

186

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

187

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

187

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

188

end

188

end

189

%% eveluate any extra arguments as possible modifications of parameters

189

%% eveluate any extra arguments as possible modifications of parameters

190

extra_args = varargin(xtk+2:end);

190

extra_args = varargin(xtk+2:end);

191

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

191

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

192

try

192

try

193

orig_value_is_str = 1;

193

orig_value_is_str = 1;

194

orig_value=eval(extra_args{k});

194

orig_value=eval(extra_args{k});

195

if ~ischar(orig_value)

195

if ~ischar(orig_value)

196

orig_value_is_str = 0;

196

orig_value_is_str = 0;

197

orig_value=mat2str(orig_value);

197

orig_value=mat2str(orig_value);

198

end

198

end

199

catch eval_err

199

catch eval_err

200

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

200

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

201

% trying to modify a nonexistent parameter - probably a

201

% trying to modify a nonexistent parameter - probably a

202

% typo. save the user from his error.

202

% typo. save the user from his error.

203

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

203

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

204

else

204

else

205

% unexpected condition

205

% unexpected condition

206

rethrow(eval_err);

206

rethrow(eval_err);

207

end

207

end

208

end

208

end

209

try

209

try

210

if orig_value_is_str

210

if orig_value_is_str

211

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

211

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

212

else

212

else

213

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

213

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

214

end

214

end

215

eval(mod_string);

215

eval(mod_string);

216

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

216

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

217

% begin yasuo patch 2/11/2018

217

% begin yasuo patch 2/11/2018

218

% output_args.(fname)=mod_string;

218

% output_args.(fname)=mod_string;

219

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

219

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

220

220

221

% re-patch yasuo 3/18/2019

221

% re-patch yasuo 3/18/2019

222

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

222

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

223

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

223

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

224

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

224

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

225

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

225

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

226

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

226

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

227

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

227

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

228

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

228

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

229

else

229

else

230

output_args.(fname)=mod_string;

230

output_args.(fname)=mod_string;

231

end

231

end

232

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

232

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

233

catch eval_err

233

catch eval_err

234

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

234

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

235

end

235

end

236

end

236

end

237

end

237

end

238

end

238

end

239

%% Parameters computationally defined by values from the settings files

239

%% Parameters computationally defined by values from the settings files

240

param.ui=1/param.fb;

240

param.ui=1/param.fb;

241

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

241

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

242

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

242

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

243

factor_3db=0.473037;

243

factor_3db=0.473037;

244

param.fb_BT_cutoff=factor_3db*param.f_r;

244

param.fb_BT_cutoff=factor_3db*param.f_r;

245

param.fb_BW_cutoff=param.f_r;

245

param.fb_BW_cutoff=param.f_r;

246

param.Tx_rd_sel=1;

246

param.Tx_rd_sel=1;

247

param.Rx_rd_sel=2;

247

param.Rx_rd_sel=2;

248

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

248

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

249

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

249

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

250

end

250

end

251

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

251

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

252

param=parameter_size_adjustment(param,OP);

252

param=parameter_size_adjustment(param,OP);

253

253

254

%% get input models

254

%% get input models

255

param.FLAG.S2P=0;

255

param.FLAG.S2P=0;

256

if OP.TDMODE

256

if OP.TDMODE

257

OP.FIXTURE_CALIBRATION= 0;

257

OP.FIXTURE_CALIBRATION= 0;

258

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

258

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

259

else

259

else

260

OP.FIXTURE_CALIBRATION= 0;

260

OP.FIXTURE_CALIBRATION= 0;

261

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

261

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

262

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

262

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

263

param.FLAG.S2P=1;

263

param.FLAG.S2P=1;

264

end

264

end

265

end

265

end

266

266

267

OP.SAVE_CMD_STR=1;

267

OP.SAVE_CMD_STR=1;

268

if OP.SAVE_CMD_STR

268

if OP.SAVE_CMD_STR

269

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

269

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

270

setappdata(0,'cmd_str',cmd_str);

270

setappdata(0,'cmd_str',cmd_str);

271

end

271

end

272

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

272

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

273

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

273

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

274

COM = inf;

274

COM = inf;

275

min_COM=inf; % reset COM prior to calibration

275

min_COM=inf; % reset COM prior to calibration

276

% min_VEO = inf;

276

% min_VEO = inf;

277

min_VEO_mV = inf;

277

min_VEO_mV = inf;

278

max_VEC_dB = -inf;

278

max_VEC_dB = -inf;

279

threshold_DER=inf;

279

threshold_DER=inf;

280

% begin yasuo patch 3/18/2019

280

% begin yasuo patch 3/18/2019

281

threshold_DER_max = 0; % reset worst DER

281

threshold_DER_max = 0; % reset worst DER

282

% end yasuo patch

282

% end yasuo patch

283

sigma_bn=0;

283

sigma_bn=0;

284

DO_ONCE=true;

284

DO_ONCE=true;

285

low_COM_found = 0;

285

low_COM_found = 0;

286

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

286

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

287

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

287

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

288

if ~DO_ONCE

288

if ~DO_ONCE

289

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

289

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

290

break;

290

break;

291

elseif min_COM > param.pass_threshold

291

elseif min_COM > param.pass_threshold

292

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

292

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

293

if low_COM_found

293

if low_COM_found

294

if OP.sigma_bn_STEP>0 % previous increase too small

294

if OP.sigma_bn_STEP>0 % previous increase too small

295

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

295

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

296

else % previously decrease too large

296

else % previously decrease too large

297

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

297

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

298

end

298

end

299

end

299

end

300

else % binary searchparam.Pkg_len_TX

300

else % binary searchparam.Pkg_len_TX

301

low_COM_found=1;

301

low_COM_found=1;

302

if OP.sigma_bn_STEP>0 % previous increase too large

302

if OP.sigma_bn_STEP>0 % previous increase too large

303

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

303

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

304

else % previously decrease too small

304

else % previously decrease too small

305

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

305

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

306

end

306

end

307

end

307

end

308

min_COM = inf; % ignore previous iterations

308

min_COM = inf; % ignore previous iterations

309

min_VEO_mV = inf;

309

min_VEO_mV = inf;

310

max_VEC_dB = -inf;

310

max_VEC_dB = -inf;

311

sigma_bn = sigma_bn + OP.sigma_bn_STEP;

311

sigma_bn = sigma_bn + OP.sigma_bn_STEP;

312

end

312

end

313

msgctr=1;

313

msgctr=1;

314

for package_testcase_i = 1:length(OP.pkg_len_select)

314

for package_testcase_i = 1:length(OP.pkg_len_select)

315

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

315

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

316

package_testcase=OP.pkg_len_select(package_testcase_i);

316

package_testcase=OP.pkg_len_select(package_testcase_i);

317

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

317

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

318

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

318

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

319

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

319

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

320

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

320

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

321

param.AC_CM_RMS_TX= param.AC_CM_RMS(package_testcase);

321

param.AC_CM_RMS_TX= param.AC_CM_RMS(package_testcase);

322

if param.PKG_Tx_FFE_preset ~=0

322

if param.PKG_Tx_FFE_preset ~=0

323

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

323

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

324

else

324

else

325

param.Pkg_TXFFE_preset=0;

325

param.Pkg_TXFFE_preset=0;

326

end

326

end

327

% ki=package_testcase;

327

% ki=package_testcase;

328

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

328

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

329

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

329

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

330

param.Pkg_Zc= param.pkg_Z_c;

330

param.Pkg_Zc= param.pkg_Z_c;

331

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

331

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

332

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

332

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

333

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

333

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

334

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

334

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

335

end

335

end

336

param.package_testcase_i = package_testcase_i;

336

param.package_testcase_i = package_testcase_i;

337

337

338

%% Fill in chdata

338

%% Fill in chdata

339

if OP.TDMODE

339

if OP.TDMODE

340

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

340

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

341

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

341

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

342

else

342

else

343

%fill in chada with s-parameters

343

%fill in chada with s-parameters

344

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

344

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

345

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

345

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

346

end

346

end

347

if OP.BREAD_CRUMBS

347

if OP.BREAD_CRUMBS

348

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

348

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

349

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

349

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

350

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

350

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

351

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

351

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

352

end

352

end

353

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

353

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

354

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

354

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

355

end

355

end

356

end

356

end

357

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

357

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

358

358

359

%% Process TDR & ERL

359

%% Process TDR & ERL

360

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

360

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

361

if OP.ERL_ONLY

361

if OP.ERL_ONLY

362

results = cell(1);

362

results = cell(1);

363

results{1} = output_args;

363

results{1} = output_args;

364

rt=toc(t0);

364

rt=toc(t0);

365

output_args.rtmin=rt/60;

365

output_args.rtmin=rt/60;

366

if 1

366

if 1

367

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

367

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

368

end

368

end

369

if OP.CSV_REPORT ==1

369

if OP.CSV_REPORT ==1

370

Write_CSV(output_args,CSV_FILE);

370

Write_CSV(output_args,CSV_FILE);

371

end

371

end

372

break;

372

break;

373

end

373

end

374

374

375

%% FD processing s-parameter

375

%% FD processing s-parameter

376

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

376

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

377

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

377

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

378

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

378

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

379

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

379

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

380

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

380

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

381

%most operations now wrapped into FD_Processing function

381

%most operations now wrapped into FD_Processing function

382

param.number_of_s4p_files=length(chdata);

382

param.number_of_s4p_files=length(chdata);

383

%ICN=0;

383

%ICN=0;

384

output_args.ICN_mV=0;

384

output_args.ICN_mV=0;

385

output_args.MDNEXT_ICN_92_46_mV=0;

385

output_args.MDNEXT_ICN_92_46_mV=0;

386

output_args.MDFEXT_ICN_92_47_mV=0;

386

output_args.MDFEXT_ICN_92_47_mV=0;

387

if OP.WC_PORTZ

387

if OP.WC_PORTZ

388

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

388

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

389

else

389

else

390

param.SNR_TX=param.SNDR(package_testcase);

390

param.SNR_TX=param.SNDR(package_testcase);

391

end

391

end

392

392

393

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

393

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

394

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

394

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

395

395

396

%% Convert from Frequency Domain to Time Domain

396

%% Convert from Frequency Domain to Time Domain

397

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

397

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

398

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

398

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

399

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

399

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

400

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

400

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

401

if DO_ONCE

401

if DO_ONCE

402

if ~OP.TDMODE

402

if ~OP.TDMODE

403

chdata=COM_FD_to_TD(chdata,param,OP);

403

chdata=COM_FD_to_TD(chdata,param,OP);

404

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

404

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

405

output_args.SCMR_dB=chdata(1).SCMR;

405

output_args.SCMR_dB=chdata(1).SCMR;

406

end

406

end

407

end

407

end

408

408

409

%% Determine equalization settings

409

%% Determine equalization settings

410

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

410

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

411

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

411

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

412

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

412

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

413

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

413

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

414

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

414

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

415

do_C2M=0;

415

do_C2M=0;

416

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

416

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

417

do_C2M=1;

417

do_C2M=1;

418

end

418

end

419

OP.COMPUTE_COM=false;

419

OP.COMPUTE_COM=false;

420

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

420

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

421

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

421

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

422

OP.COMPUTE_COM=true;

422

OP.COMPUTE_COM=true;

423

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

423

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

424

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

424

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

425

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

425

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

426

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

426

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

427

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

427

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

428

428

429

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

429

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

430

param.use_bmax=fom_result.best_bmax.';

430

param.use_bmax=fom_result.best_bmax.';

431

%AJG021820

431

%AJG021820

432

param.use_bmin=fom_result.best_bmin.';

432

param.use_bmin=fom_result.best_bmin.';

433

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

433

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

434

param.current_ffegain=fom_result.best_current_ffegain;

434

param.current_ffegain=fom_result.best_current_ffegain;

435

if OP.force_pdf_bin_size

435

if OP.force_pdf_bin_size

436

param.delta_y = OP.BinSize;

436

param.delta_y = OP.BinSize;

437

else

437

else

438

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

438

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

439

end

439

end

440

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

440

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

441

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

441

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

442

442

443

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

443

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

444

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

444

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

445

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

445

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

446

OP.WO_TXFFE=1;

446

OP.WO_TXFFE=1;

447

PSD_results.w=fom_result.RxFFE;

447

PSD_results.w=fom_result.RxFFE;

448

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

448

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

449

% well as CTLE (CTF) and tx FFE

449

% well as CTLE (CTF) and tx FFE

450

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

450

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

451

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

451

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

452

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

452

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

453

OP.WO_TXFFE=0;

453

OP.WO_TXFFE=0;

454

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

454

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

455

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

455

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

456

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

456

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

457

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

457

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

458

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

458

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

459

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

459

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

460

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

460

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

461

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

461

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

462

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

462

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

463

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

463

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

464

end

464

end

465

%% Create ISI PDF & Individual Crosstalk PDFs

465

%% Create ISI PDF & Individual Crosstalk PDFs

466

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

466

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

467

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

467

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

468

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

468

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

469

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

469

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

470

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

470

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

471

for i=1:param.number_of_s4p_files

471

for i=1:param.number_of_s4p_files

472

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

472

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

473

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

473

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

474

474

475

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

475

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

476

else

476

else

477

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

477

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

478

end

478

end

479

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

479

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

480

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

480

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

481

subplot(2,1,2);

481

subplot(2,1,2);

482

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

482

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

483

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

483

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

484

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

484

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

485

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

485

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

486

hold on; title('PDF')

486

hold on; title('PDF')

487

recolor_plots(gca);

487

recolor_plots(gca);

488

end

488

end

489

489

490

chdata(i).pdfr=pdf;

490

chdata(i).pdfr=pdf;

491

% reporting

491

% reporting

492

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

492

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

493

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

493

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

494

494

495

end

495

end

496

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

496

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

497

497

498

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

498

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

499

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

499

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

500

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

500

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

501

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

501

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

502

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

502

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

503

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

503

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

504

combined_interference_and_noise_pdf=PDF;

504

combined_interference_and_noise_pdf=PDF;

505

combined_interference_and_noise_cdf=CDF;

505

combined_interference_and_noise_cdf=CDF;

506

506

507

507

508

%% Calculate COM and other associated outputs

508

%% Calculate COM and other associated outputs

509

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

509

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

510

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

510

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

511

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

511

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

512

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

512

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

513

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

513

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

514

% that satisfies the relationship P(y0) = DER_0

514

% that satisfies the relationship P(y0) = DER_0

515

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

515

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

516

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

516

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

517

517

518

% begin yasuo patch 3/18/2019

518

% begin yasuo patch 3/18/2019

519

% estimate DER at threshold COM

519

% estimate DER at threshold COM

520

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

520

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

521

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

521

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

522

threshold_DER_max = max(threshold_DER_max, threshold_DER);

522

threshold_DER_max = max(threshold_DER_max, threshold_DER);

523

% end yasuo patch

523

% end yasuo patch

524

524

525

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

525

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

526

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

526

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

527

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

527

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

528

if OP.DISPLAY_WINDOW && OP.DEBUG

528

if OP.DISPLAY_WINDOW && OP.DEBUG

529

figure_name = 'Eye at DER0 estimate';

529

figure_name = 'Eye at DER0 estimate';

530

fig=findobj('Name', figure_name);

530

fig=findobj('Name', figure_name);

531

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

531

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

532

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

532

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

533

movegui(fig,'southwest')

533

movegui(fig,'southwest')

534

plot(eye_contour)

534

plot(eye_contour)

535

xlabel('UI %')

535

xlabel('UI %')

536

ylabel('V')

536

ylabel('V')

537

end

537

end

538

538

539

else

539

else

540

EW_UI=0;

540

EW_UI=0;

541

eye_contour=[];

541

eye_contour=[];

542

end

542

end

543

if OP.MLSE==0

543

if OP.MLSE==0

544

if param.T_O ~=0

544

if param.T_O ~=0

545

eye_opening=EH_T_C2M-EH_B_C2M;

545

eye_opening=EH_T_C2M-EH_B_C2M;

546

A_ni=2*A_s-eye_opening;

546

A_ni=2*A_s-eye_opening;

547

%eq 124E-4

547

%eq 124E-4

548

vec_arg=2*A_s/eye_opening;

548

vec_arg=2*A_s/eye_opening;

549

if vec_arg<eps

549

if vec_arg<eps

550

vec_arg=eps;

550

vec_arg=eps;

551

end

551

end

552

VEC_dB = 20*log10(vec_arg);

552

VEC_dB = 20*log10(vec_arg);

553

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

553

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

554

VEO_mV=eye_opening*1000;

554

VEO_mV=eye_opening*1000;

555

min_COM = min(min_COM, COM);

555

min_COM = min(min_COM, COM);

556

min_VEO_mV = min(min_VEO_mV,VEO_mV);

556

min_VEO_mV = min(min_VEO_mV,VEO_mV);

557

max_VEC_dB = max(max_VEC_dB, VEC_dB);

557

max_VEC_dB = max(max_VEC_dB, VEC_dB);

558

else

558

else

559

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

559

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

560

vec_arg=(A_s-A_ni)/A_s;

560

vec_arg=(A_s-A_ni)/A_s;

561

if vec_arg<eps

561

if vec_arg<eps

562

vec_arg=eps;

562

vec_arg=eps;

563

end

563

end

564

VEC_dB = -20*log10(vec_arg);

564

VEC_dB = -20*log10(vec_arg);

565

COM=20*log10(A_s/A_ni);

565

COM=20*log10(A_s/A_ni);

566

min_COM = min(min_COM, COM);

566

min_COM = min(min_COM, COM);

567

min_VEO_mV = min(min_VEO_mV,VEO_mV);

567

min_VEO_mV = min(min_VEO_mV,VEO_mV);

568

max_VEC_dB = max(max_VEC_dB, VEC_dB);

568

max_VEC_dB = max(max_VEC_dB, VEC_dB);

569

end

569

end

570

MLSE_results=struct;

570

MLSE_results=struct;

571

else

571

else

572

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

572

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

573

if param.T_O ~=0

573

if param.T_O ~=0

574

eye_opening=EH_T_C2M-EH_B_C2M;

574

eye_opening=EH_T_C2M-EH_B_C2M;

575

A_ni=2*A_s-eye_opening;

575

A_ni=2*A_s-eye_opening;

576

%eq 124E-4

576

%eq 124E-4

577

vec_arg=2*A_s/eye_opening;

577

vec_arg=2*A_s/eye_opening;

578

if vec_arg<eps

578

if vec_arg<eps

579

vec_arg=eps;

579

vec_arg=eps;

580

end

580

end

581

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

581

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

582

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

582

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

583

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

583

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

584

COM=MLSE_results.COM;

584

COM=MLSE_results.COM;

585

VEO_mV=eye_opening*1000;

585

VEO_mV=eye_opening*1000;

586

min_COM = min(min_COM, COM);

586

min_COM = min(min_COM, COM);

587

min_VEO_mV = min(min_VEO_mV,VEO_mV);

587

min_VEO_mV = min(min_VEO_mV,VEO_mV);

588

max_VEC_dB = max(max_VEC_dB, VEC_dB);

588

max_VEC_dB = max(max_VEC_dB, VEC_dB);

589

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

589

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

590

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

590

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

591

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

591

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

592

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

592

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

593

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

593

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

594

COM_SNR_Struct.VEC_dB=VEC_dB;

594

COM_SNR_Struct.VEC_dB=VEC_dB;

595

else

595

else

596

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

596

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

597

vec_arg=(A_s-A_ni)/A_s;

597

vec_arg=(A_s-A_ni)/A_s;

598

if vec_arg<eps

598

if vec_arg<eps

599

vec_arg=eps;

599

vec_arg=eps;

600

end

600

end

601

VEC_dB_orig = -20*log10(vec_arg);

601

VEC_dB_orig = -20*log10(vec_arg);

602

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

602

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

603

COM_orig=20*log10(A_s/A_ni);

603

COM_orig=20*log10(A_s/A_ni);

604

COM=MLSE_results.COM;

604

COM=MLSE_results.COM;

605

min_COM = min(min_COM, COM);

605

min_COM = min(min_COM, COM);

606

min_VEO_mV = min(min_VEO_mV,VEO_mV);

606

min_VEO_mV = min(min_VEO_mV,VEO_mV);

607

max_VEC_dB = max(max_VEC_dB, VEC_dB);

607

max_VEC_dB = max(max_VEC_dB, VEC_dB);

608

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

608

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

609

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

609

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

610

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

610

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

611

COM_SNR_Struct.VEC_dB=VEC_dB;

611

COM_SNR_Struct.VEC_dB=VEC_dB;

612

end

612

end

613

end

613

end

614

614

615

%% Create COM_SNR_Struct to hold the main COM outputs

615

%% Create COM_SNR_Struct to hold the main COM outputs

616

COM_SNR_Struct.A_s=A_s;

616

COM_SNR_Struct.A_s=A_s;

617

COM_SNR_Struct.A_ni=A_ni;

617

COM_SNR_Struct.A_ni=A_ni;

618

COM_SNR_Struct.threshold_DER=threshold_DER;

618

COM_SNR_Struct.threshold_DER=threshold_DER;

619

COM_SNR_Struct.EW_UI=EW_UI;

619

COM_SNR_Struct.EW_UI=EW_UI;

620

COM_SNR_Struct.COM=COM;

620

COM_SNR_Struct.COM=COM;

621

COM_SNR_Struct.VEC_dB=VEC_dB;

621

COM_SNR_Struct.VEC_dB=VEC_dB;

622

if OP.MLSE == 0

622

if OP.MLSE == 0

623

COM_SNR_Struct.COM_orig=[];

623

COM_SNR_Struct.COM_orig=[];

624

COM_SNR_Struct.VEC_dB_orig=[];

624

COM_SNR_Struct.VEC_dB_orig=[];

625

else

625

else

626

COM_SNR_Struct.COM_orig=COM_orig;

626

COM_SNR_Struct.COM_orig=COM_orig;

627

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

627

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

628

end

628

end

629

COM_SNR_Struct.VEO_mV=VEO_mV;

629

COM_SNR_Struct.VEO_mV=VEO_mV;

630

COM_SNR_Struct.combined_interference_and_noise_pdf=combined_interference_and_noise_pdf;

630

COM_SNR_Struct.combined_interference_and_noise_pdf=combined_interference_and_noise_pdf;

631

COM_SNR_Struct.combined_interference_and_noise_cdf=combined_interference_and_noise_cdf;

631

COM_SNR_Struct.combined_interference_and_noise_cdf=combined_interference_and_noise_cdf;

632

COM_SNR_Struct.eye_contour=eye_contour;

632

COM_SNR_Struct.eye_contour=eye_contour;

633

633

634

634

635

%% Save TD

635

%% Save TD

636

if OP.SAVE_TD

636

if OP.SAVE_TD

637

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

637

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

638

if ~OP.TDMODE

638

if ~OP.TDMODE

639

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

639

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

640

end

640

end

641

for i=1:param.number_of_s4p_files

641

for i=1:param.number_of_s4p_files

642

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

642

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

643

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

643

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

644

if ~OP.TDMODE

644

if ~OP.TDMODE

645

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

645

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

646

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

646

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

647

end

647

end

648

end

648

end

649

if OP.TDMODE

649

if OP.TDMODE

650

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

650

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

651

else

651

else

652

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

652

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

653

end

653

end

654

end

654

end

655

655

656

%% Bathtub/Contribution Plot

656

%% Bathtub/Contribution Plot

657

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

657

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

658

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

658

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

659

end

659

end

660

660

661

%% Msg management

661

%% Msg management

662

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

662

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

663

msg=[];

663

msg=[];

664

end

664

end

665

if OP.DEBUG

665

if OP.DEBUG

666

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

666

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

667

switch param.flex

667

switch param.flex

668

case 4

668

case 4

669

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

669

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

670

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

670

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

671

);

671

);

672

case 2

672

case 2

673

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

673

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

674

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

674

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

675

);

675

);

676

otherwise

676

otherwise

677

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

677

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

678

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

678

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

679

);

679

);

680

680

681

end

681

end

682

else

682

else

683

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

683

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

684

end

684

end

685

685

686

if OP.TDMODE

686

if OP.TDMODE

687

min_ERL=inf;

687

min_ERL=inf;

688

ERL=[inf inf];

688

ERL=[inf inf];

689

end

689

end

690

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

690

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

691

691

692

692

693

%% Output Args

693

%% Output Args

694

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

694

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

695

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

695

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

696

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

696

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

697

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

697

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

698

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

698

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

699

rt=toc(t0);

699

rt=toc(t0);

700

output_args.rtmin=rt/60;

700

output_args.rtmin=rt/60;

701

701

702

if OP.BREAD_CRUMBS

702

if OP.BREAD_CRUMBS

703

output_args.OP=OP;

703

output_args.OP=OP;

704

output_args.param=param;

704

output_args.param=param;

705

output_args.chdata=chdata;

705

output_args.chdata=chdata;

706

output_args.fom_result = fom_result;

706

output_args.fom_result = fom_result;

707

output_args.PDF=PDF; % for exploration

707

output_args.PDF=PDF; % for exploration

708

output_args.CDF=CDF; % for exploration

708

output_args.CDF=CDF; % for exploration

709

output_args.MLSE_results=MLSE_results;

709

output_args.MLSE_results=MLSE_results;

710

output_args.PSD_results=PSD_results;

710

output_args.PSD_results=PSD_results;

711

end

711

end

712

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

712

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

713

713

714

%% making csv file

714

%% making csv file

715

if OP.CSV_REPORT ==1

715

if OP.CSV_REPORT ==1

716

Write_CSV(output_args,CSV_FILE);

716

Write_CSV(output_args,CSV_FILE);

717

end

717

end

718

%% making mat file

718

%% making mat file

719

if(OP.DEBUG)

719

if(OP.DEBUG)

720

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

720

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

721

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

721

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

722

end

722

end

723

if 1

723

if 1

724

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

724

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

725

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

725

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

726

end

726

end

727

727

728

if nargout==0

728

if nargout==0

729

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

729

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

730

disp(output_args)

730

disp(output_args)

731

end

731

end

732

732

733

if OP.BREAD_CRUMBS

733

if OP.BREAD_CRUMBS

734

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

734

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

735

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

735

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

736

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

736

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

737

try

737

try

738

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

738

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

739

catch

739

catch

740

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

740

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

741

end

741

end

742

end

742

end

743

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

743

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

744

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

744

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

745

end

745

end

746

746

747

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

747

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

748

end

748

end

749

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

749

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

750

%%

750

%%

751

751

752

if OP.RX_CALIBRATION ==1

752

if OP.RX_CALIBRATION ==1

753

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

753

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

754

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

754

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

755

end

755

end

756

DO_ONCE=false;

756

DO_ONCE=false;

757

end

757

end

758

758

759

%% Final cleanup

759

%% Final cleanup

760

if OP.DISPLAY_WINDOW

760

if OP.DISPLAY_WINDOW

761

savefigs(param, OP);

761

savefigs(param, OP);

762

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

762

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

763

end

763

end

764

764

765

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

765

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

766

if ~param.f_hp==0

766

if ~param.f_hp==0

767

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

767

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

768

if OP.DISPLAY_WINDOW

768

if OP.DISPLAY_WINDOW

769

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

769

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

770

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

770

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

771

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

771

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

772

end

772

end

773

else

773

else

774

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

774

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

775

if OP.DISPLAY_WINDOW

775

if OP.DISPLAY_WINDOW

776

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

776

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

777

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

777

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

778

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

778

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

779

end

779

end

780

end

780

end

781

end

781

end

782

782

783

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

783

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

784

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

784

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

785

disp(redo_cmd_str);

785

disp(redo_cmd_str);

786

if isdeployed

786

if isdeployed

787

if OP.exit_if_deployed

787

if OP.exit_if_deployed

788

quit

788

quit

789

end

789

end

790

end

790

end

791

%%

791

%%

792

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

792

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

793

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

793

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

794

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

794

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

795

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

795

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

796

796

797

FB=param.fb;

797

FB=param.fb;

798

FZ=param.CTLE_fz(fom_result.ctle);

798

FZ=param.CTLE_fz(fom_result.ctle);

799

FP1=param.CTLE_fp1(fom_result.ctle);

799

FP1=param.CTLE_fp1(fom_result.ctle);

800

FP2=param.CTLE_fp2(fom_result.ctle);

800

FP2=param.CTLE_fp2(fom_result.ctle);

801

GDC=param.ctle_gdc_values(fom_result.ctle);

801

GDC=param.ctle_gdc_values(fom_result.ctle);

802

if ~isempty(param.f_HP)

802

if ~isempty(param.f_HP)

803

FHP=param.f_HP(fom_result.best_G_high_pass);

803

FHP=param.f_HP(fom_result.best_G_high_pass);

804

end

804

end

805

if ~isempty(param.g_DC_HP_values)

805

if ~isempty(param.g_DC_HP_values)

806

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

806

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

807

end

807

end

808

if ~isempty(param.f_HP_Z)

808

if ~isempty(param.f_HP_Z)

809

FHPZ=param.f_HP_Z(fom_result.ctle);

809

FHPZ=param.f_HP_Z(fom_result.ctle);

810

end

810

end

811

if ~isempty(param.f_HP_P)

811

if ~isempty(param.f_HP_P)

812

FHPP=param.f_HP_P(fom_result.ctle);

812

FHPP=param.f_HP_P(fom_result.ctle);

813

end

813

end

814

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

814

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

815

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

815

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

816

%length

816

%length

817

SBR_Len=length(fom_result.sbr);

817

SBR_Len=length(fom_result.sbr);

818

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

818

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

819

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

819

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

820

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

820

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

821

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

821

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

822

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

822

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

823

end

823

end

824

for i=1:param.number_of_s4p_files

824

for i=1:param.number_of_s4p_files

825

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

825

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

826

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

826

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

827

if OP.INCLUDE_CTLE==1

827

if OP.INCLUDE_CTLE==1

828

switch param.CTLE_type

828

switch param.CTLE_type

829

case 'CL93'

829

case 'CL93'

830

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

830

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

831

case 'CL120d'

831

case 'CL120d'

832

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

832

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

833

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

833

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

834

case 'CL120e' % z has been adjusted for gain

834

case 'CL120e' % z has been adjusted for gain

835

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

835

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

836

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

836

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

837

end

837

end

838

else

838

else

839

eq_ir=uneq_ir;

839

eq_ir=uneq_ir;

840

end

840

end

841

chdata(i).eq_imp_response=eq_ir;

841

chdata(i).eq_imp_response=eq_ir;

842

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

842

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

843

843

844

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

844

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

845

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

845

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

846

end

846

end

847

% chdata(i).ctle_imp_response

847

% chdata(i).ctle_imp_response

848

if OP.RxFFE

848

if OP.RxFFE

849

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

849

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

850

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

850

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

851

end

851

end

852

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

852

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

853

end

853

end

854

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

854

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

855

end

855

end

856

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

856

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

857

857

858

% display bathtub curves in one axis per test case.

858

% display bathtub curves in one axis per test case.

859

case_number=param.package_testcase_i;

859

case_number=param.package_testcase_i;

860

if ~OP.COM_CONTRIBUTION_CURVES

860

if ~OP.COM_CONTRIBUTION_CURVES

861

figure_name = 'Voltage bathtub curves';

861

figure_name = 'Voltage bathtub curves';

862

fig=findobj('Name', figure_name);

862

fig=findobj('Name', figure_name);

863

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

863

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

864

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

864

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

865

movegui(fig,'south')

865

movegui(fig,'south')

866

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

866

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

867

plot_bathtub_curves( hax ...

867

plot_bathtub_curves( hax ...

868

, COM_SNR_Struct.A_s ...

868

, COM_SNR_Struct.A_s ...

869

, Noise_Struct.sci_pdf ...

869

, Noise_Struct.sci_pdf ...

870

, Noise_Struct.cci_pdf ...

870

, Noise_Struct.cci_pdf ...

871

, Noise_Struct.isi_and_xtalk_pdf ...

871

, Noise_Struct.isi_and_xtalk_pdf ...

872

, Noise_Struct.noise_pdf ...

872

, Noise_Struct.noise_pdf ...

873

, Noise_Struct.jitt_pdf ...

873

, Noise_Struct.jitt_pdf ...

874

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

874

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

875

, param.delta_y ...

875

, param.delta_y ...

876

);

876

);

877

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

877

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

878

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

878

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

879

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

879

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

880

% show BER target line

880

% show BER target line

881

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

881

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

882

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

882

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

883

else

883

else

884

figure_name = 'COM Contributions (Rough Allocations)';

884

figure_name = 'COM Contributions (Rough Allocations)';

885

fig=findobj('Name', figure_name);

885

fig=findobj('Name', figure_name);

886

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

886

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

887

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

887

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

888

movegui(fig,'south')

888

movegui(fig,'south')

889

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

889

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

890

890

891

plot_pie_com( hax ...

891

plot_pie_com( hax ...

892

, COM_SNR_Struct.A_s ...

892

, COM_SNR_Struct.A_s ...

893

, Noise_Struct.sci_pdf ...

893

, Noise_Struct.sci_pdf ...

894

, Noise_Struct.cci_pdf ...

894

, Noise_Struct.cci_pdf ...

895

, Noise_Struct.isi_and_xtalk_pdf ...

895

, Noise_Struct.isi_and_xtalk_pdf ...

896

, Noise_Struct.noise_pdf ...

896

, Noise_Struct.noise_pdf ...

897

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

897

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

898

, param.delta_y, param...

898

, param.delta_y, param...

899

);

899

);

900

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

900

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

901

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

901

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

902

end

902

end

903

903

904

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

904

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

905

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

905

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

906

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

906

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

907

end

907

end

908

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

908

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

909

909

910

if use_BT

910

if use_BT

911

a = bessel( param.BTorder );

911

a = bessel( param.BTorder );

912

acoef=fliplr( a );

912

acoef=fliplr( a );

913

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

913

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

914

else

914

else

915

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

915

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

916

end

916

end

917

917

918

918

919

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

919

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

920

920

921

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

921

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

922

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

922

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

923

%All subsequent lines are field names in chdata

923

%All subsequent lines are field names in chdata

924

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

924

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

925

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

925

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

926

%

926

%

927

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

927

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

928

%#reduce

928

%#reduce

929

%sdd12_raw

929

%sdd12_raw

930

%sdd21_raw

930

%sdd21_raw

931

%sdd22_raw

931

%sdd22_raw

932

%sdd11_raw

932

%sdd11_raw

933

%

933

%

934

934

935

fid=fopen(fields_file,'r');

935

fid=fopen(fields_file,'r');

936

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

936

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

937

937

938

file_data=file_data{1};

938

file_data=file_data{1};

939

fclose(fid);

939

fclose(fid);

940

940

941

%remove blank lines

941

%remove blank lines

942

L=cellfun('length',file_data);

942

L=cellfun('length',file_data);

943

file_data=file_data(L~=0);

943

file_data=file_data(L~=0);

944

944

945

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

945

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

946

type=file_data{1};

946

type=file_data{1};

947

field_names=file_data(2:end);

947

field_names=file_data(2:end);

948

switch lower(type)

948

switch lower(type)

949

case '#reduce'

949

case '#reduce'

950

remove_fields=field_names;

950

remove_fields=field_names;

951

case '#include'

951

case '#include'

952

all_fields=fieldnames(chdata);

952

all_fields=fieldnames(chdata);

953

remove_fields=setdiff(all_fields,field_names);

953

remove_fields=setdiff(all_fields,field_names);

954

otherwise

954

otherwise

955

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

955

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

956

end

956

end

957

957

958

%remove the "remove_fields" from chdata

958

%remove the "remove_fields" from chdata

959

for j=1:length(remove_fields)

959

for j=1:length(remove_fields)

960

this_field=remove_fields{j};

960

this_field=remove_fields{j};

961

if isfield(chdata,this_field)

961

if isfield(chdata,this_field)

962

chdata=rmfield(chdata,this_field);

962

chdata=rmfield(chdata,this_field);

963

end

963

end

964

end

964

end

965

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

965

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

966

966

967

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

967

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

968

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

968

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

969

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

969

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

970

970

971

A_s=COM_SNR_Struct.A_s;

971

A_s=COM_SNR_Struct.A_s;

972

% initialize loop with uncorrelated noise and BER

972

% initialize loop with uncorrelated noise and BER

973

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

973

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

974

974

975

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

975

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

976

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

976

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

977

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

977

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

978

% below target BER).

978

% below target BER).

979

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

979

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

980

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

980

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

981

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

981

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

982

if isempty(x_error_propagation)

982

if isempty(x_error_propagation)

983

p_error_propagation(1) = 1e-20;

983

p_error_propagation(1) = 1e-20;

984

else

984

else

985

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

985

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

986

end

986

end

987

987

988

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

988

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

989

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

989

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

990

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

990

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

991

if OP.use_simple_EP_model

991

if OP.use_simple_EP_model

992

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

992

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

993

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

993

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

994

else

994

else

995

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

995

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

996

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

996

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

997

end

997

end

998

998

999

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

999

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

1000

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

1000

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

1001

if isempty(x_error_propagation)

1001

if isempty(x_error_propagation)

1002

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

1002

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

1003

else

1003

else

1004

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

1004

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

1005

end

1005

end

1006

end

1006

end

1007

1007

1008

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

1008

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

1009

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

1009

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

1010

% of this event by partial sum of the PDF.

1010

% of this event by partial sum of the PDF.

1011

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

1011

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

1012

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

1012

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

1013

1013

1014

% probability of bursts of different lengths

1014

% probability of bursts of different lengths

1015

p_burst = cumprod(p_error_propagation);

1015

p_burst = cumprod(p_error_propagation);

1016

function H_bw=Butterworth_Filter(param,f,use_BW)

1016

function H_bw=Butterworth_Filter(param,f,use_BW)

1017

1017

1018

if use_BW

1018

if use_BW

1019

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

1019

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

1020

else

1020

else

1021

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

1021

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

1022

end

1022

end

1023

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

1023

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

1024

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

1024

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

1025

CDF_ev=CDF(index);

1025

CDF_ev=CDF(index);

1026

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

1026

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

1027

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

1027

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

1028

if isempty(index)

1028

if isempty(index)

1029

CDF_inv_ev=PDF.x(end);

1029

CDF_inv_ev=PDF.x(end);

1030

else

1030

else

1031

CDF_inv_ev=PDF.x(index);

1031

CDF_inv_ev=PDF.x(index);

1032

end

1032

end

1033

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

1033

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

1034

1034

1035

1035

1036

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

1036

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

1037

Remember_keyword='Legacy';

1037

Remember_keyword='Legacy';

1038

OP.TDMODE=false;

1038

OP.TDMODE=false;

1039

OP.GET_FD=true;

1039

OP.GET_FD=true;

1040

OP.CONFIG2MAT_ONLY=false;

1040

OP.CONFIG2MAT_ONLY=false;

1041

config_file='';

1041

config_file='';

1042

num_fext=[];

1042

num_fext=[];

1043

num_next=[];

1043

num_next=[];

1044

if ~isempty(varargin)

1044

if ~isempty(varargin)

1045

if ~ischar(varargin{1})

1045

if ~ischar(varargin{1})

1046

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

1046

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

1047

end

1047

end

1048

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

1048

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

1049

if isempty(keyword_idx)

1049

if isempty(keyword_idx)

1050

%Legacy Mode

1050

%Legacy Mode

1051

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

1051

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

1052

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

1052

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

1053

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

1053

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

1054

else

1054

else

1055

%Keyword Mode

1055

%Keyword Mode

1056

my_keyword=varargin{1};

1056

my_keyword=varargin{1};

1057

Remember_keyword=my_keyword;

1057

Remember_keyword=my_keyword;

1058

varargin(1)=[];

1058

varargin(1)=[];

1059

switch my_keyword

1059

switch my_keyword

1060

1060

1061

case 'Legacy'

1061

case 'Legacy'

1062

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

1062

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

1063

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

1063

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

1064

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

1064

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

1065

case 'TD'

1065

case 'TD'

1066

OP.TDMODE=true;

1066

OP.TDMODE=true;

1067

OP.GET_FD=false;

1067

OP.GET_FD=false;

1068

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

1068

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

1069

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

1069

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

1070

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

1070

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

1071

case 'Config2Mat'

1071

case 'Config2Mat'

1072

OP.CONFIG2MAT_ONLY=true;

1072

OP.CONFIG2MAT_ONLY=true;

1073

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

1073

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

1074

end

1074

end

1075

end

1075

end

1076

end

1076

end

1077

function chdata=COM_FD_to_TD(chdata,param,OP)

1077

function chdata=COM_FD_to_TD(chdata,param,OP)

1078

1078

1079

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

1079

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

1080

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

1080

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

1081

case_number=param.package_testcase_i;

1081

case_number=param.package_testcase_i;

1082

for i=1:param.number_of_s4p_files

1082

for i=1:param.number_of_s4p_files

1083

% RIM 2-01-2023 moved to FD_Processing

1083

% RIM 2-01-2023 moved to FD_Processing

1084

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1084

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1085

% % Equation 93A-20 %%

1085

% % Equation 93A-20 %%

1086

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

1086

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

1087

% f=chdata(i).faxis;

1087

% f=chdata(i).faxis;

1088

% %

1088

% %

1089

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

1089

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

1090

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

1090

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

1091

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

1091

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

1092

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

1092

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

1093

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

1093

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

1094

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

1094

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

1095

% if OP.DISPLAY_WINDOW

1095

% if OP.DISPLAY_WINDOW

1096

% if i==1

1096

% if i==1

1097

% figure(300+param.package_testcase_i);

1097

% figure(300+param.package_testcase_i);

1098

% subplot(3,1,1)

1098

% subplot(3,1,1)

1099

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

1099

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

1100

% try

1100

% try

1101

% legend('NumColumns',2)

1101

% legend('NumColumns',2)

1102

% legend('location','south')

1102

% legend('location','south')

1103

% catch

1103

% catch

1104

% end

1104

% end

1105

% end

1105

% end

1106

% end

1106

% end

1107

% end

1107

% end

1108

[chdata(i).uneq_imp_response, ...

1108

[chdata(i).uneq_imp_response, ...

1109

chdata(i).t, ...

1109

chdata(i).t, ...

1110

chdata(i).causality_correction_dB, ...

1110

chdata(i).causality_correction_dB, ...

1111

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

1111

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

1112

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

1112

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

1113

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

1113

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

1114

[chdata(i).uneq_CD_imp_response, ...

1114

[chdata(i).uneq_CD_imp_response, ...

1115

chdata(i).t_DC, ...

1115

chdata(i).t_DC, ...

1116

chdata(i).causality_correction_DC_dB, ...

1116

chdata(i).causality_correction_DC_dB, ...

1117

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

1117

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

1118

end

1118

end

1119

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

1119

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

1120

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

1120

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

1121

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

1121

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

1122

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

1122

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

1123

1123

1124

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

1124

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

1125

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

1125

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

1126

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

1126

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

1127

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

1127

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

1128

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

1128

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

1129

rss=-inf;

1129

rss=-inf;

1130

for im=1:param.samples_per_ui

1130

for im=1:param.samples_per_ui

1131

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

1131

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

1132

end

1132

end

1133

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

1133

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

1134

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

1134

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

1135

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

1135

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

1136

end

1136

end

1137

if OP.DEBUG && OP.DISPLAY_WINDOW

1137

if OP.DEBUG && OP.DISPLAY_WINDOW

1138

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1138

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1139

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

1139

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

1140

screen_size=get(0,'ScreenSize');

1140

screen_size=get(0,'ScreenSize');

1141

pos = get(gcf, 'OuterPosition');

1141

pos = get(gcf, 'OuterPosition');

1142

set(gcf, 'OuterPosition', ...

1142

set(gcf, 'OuterPosition', ...

1143

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

1143

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

1144

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

1144

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

1145

%movegui(gcf,'northeast')

1145

%movegui(gcf,'northeast')

1146

1146

1147

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

1147

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

1148

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

1148

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

1149

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

1149

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

1150

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

1150

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

1151

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

1151

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

1152

end

1152

end

1153

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

1153

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

1154

% scale. thru is shown in another plot.

1154

% scale. thru is shown in another plot.

1155

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

1155

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

1156

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

1156

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

1157

% set(get(get(hp,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

1157

% set(get(get(hp,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

1158

end

1158

end

1159

title(sprintf('Unequalized Crosstalk and CD Conversion \n Pulse Responses'))

1159

title(sprintf('Unequalized Crosstalk and CD Conversion \n Pulse Responses'))

1160

ylabel('Volts')

1160

ylabel('Volts')

1161

xlabel('seconds')

1161

xlabel('seconds')

1162

1162

1163

recolor_plots(gca);

1163

recolor_plots(gca);

1164

else

1164

else

1165

if param.ndfe~=0

1165

if param.ndfe~=0

1166

fprintf('%s\tUnequalized pulse peak = %.1f mV\n', chdata(i).base, 1000*max(abs(chdata(i).uneq_pulse_response)));

1166

fprintf('%s\tUnequalized pulse peak = %.1f mV\n', chdata(i).base, 1000*max(abs(chdata(i).uneq_pulse_response)));

1167

end

1167

end

1168

end

1168

end

1169

1169

1170

fprintf('%s\tCausality correction = %.1f dB', chdata(i).base, chdata(i).causality_correction_dB);

1170

fprintf('%s\tCausality correction = %.1f dB', chdata(i).base, chdata(i).causality_correction_dB);

1171

if OP.ENFORCE_CAUSALITY

1171

if OP.ENFORCE_CAUSALITY

1172

fprintf('\n');

1172

fprintf('\n');

1173

else

1173

else

1174

fprintf(' (not applied)\n');

1174

fprintf(' (not applied)\n');

1175

end

1175

end

1176

fprintf('%s\tTruncation ratio = %.1f dB\n', chdata(i).base, chdata(i).truncation_dB);

1176

fprintf('%s\tTruncation ratio = %.1f dB\n', chdata(i).base, chdata(i).truncation_dB);

1177

1177

1178

end

1178

end

1179

function [Left_EW,Right_EW,eye_contour,out_VT,out_VB]=COM_eye_width(chdata,delta_y,fom_result,param,OP,Struct_Noise,pdf_range_flag)

1179

function [Left_EW,Right_EW,eye_contour,out_VT,out_VB]=COM_eye_width(chdata,delta_y,fom_result,param,OP,Struct_Noise,pdf_range_flag)

1180

1180

1181

1181

1182

debug_plot=0;

1182

debug_plot=0;

1183

1183

1184

1184

1185

samp_UI=param.samples_for_C2M;

1185

samp_UI=param.samples_for_C2M;

1186

half_UI=get_center_of_UI(samp_UI);

1186

half_UI=get_center_of_UI(samp_UI);

1187

T_O=floor((param.T_O/1000)*param.samples_for_C2M);

1187

T_O=floor((param.T_O/1000)*param.samples_for_C2M);

1188

start_sample=half_UI-T_O;

1188

start_sample=half_UI-T_O;

1189

end_sample=half_UI+T_O;

1189

end_sample=half_UI+T_O;

1190

1190

1191

1191

1192

%pdf_range is a placeholder to allow fractional UI calculation for optimize

1192

%pdf_range is a placeholder to allow fractional UI calculation for optimize

1193

%C2M speedup. For regular COM_eye_width calls, pdf_range will be empty

1193

%C2M speedup. For regular COM_eye_width calls, pdf_range will be empty

1194

%which will force pdf_range=1:samp_UI for stanard full UI calculation.

1194

%which will force pdf_range=1:samp_UI for stanard full UI calculation.

1195

if pdf_range_flag

1195

if pdf_range_flag

1196

pdf_range=[start_sample end_sample];

1196

pdf_range=[start_sample end_sample];

1197

else

1197

else

1198

pdf_range=[];

1198

pdf_range=[];

1199

end

1199

end

1200

1200

1201

%pdf_full is self ISI pdf for each sample point

1201

%pdf_full is self ISI pdf for each sample point

1202

%h_j_full is the v/t calculation for each sample point

1202

%h_j_full is the v/t calculation for each sample point

1203

%the center vector for each should be identical to the standard COM variables

1203

%the center vector for each should be identical to the standard COM variables

1204

[pdf_full_1,h_j_full,A_s_vec] = get_pdf_full(chdata(1), delta_y, fom_result.t_s, param, OP,pdf_range) ;

1204

[pdf_full_1,h_j_full,A_s_vec] = get_pdf_full(chdata(1), delta_y, fom_result.t_s, param, OP,pdf_range) ;

1205

1205

1206

1206

1207

1207

1208

if isempty(pdf_range)

1208

if isempty(pdf_range)

1209

pdf_range=1:samp_UI;

1209

pdf_range=1:samp_UI;

1210

else

1210

else

1211

pdf_range=min(pdf_range):max(pdf_range);

1211

pdf_range=min(pdf_range):max(pdf_range);

1212

end

1212

end

1213

1213

1214

%Test doing Level PDFs

1214

%Test doing Level PDFs

1215

Levels = 2*(0:param.levels-1)/(param.levels-1)-1;

1215

Levels = 2*(0:param.levels-1)/(param.levels-1)-1;

1216

%A_s_vec=A_s_vec*(param.levels-1)/param.R_LM;

1216

%A_s_vec=A_s_vec*(param.levels-1)/param.R_LM;

1217

A_s_vec=A_s_vec*(param.levels-1);

1217

A_s_vec=A_s_vec*(param.levels-1);

1218

1218

1219

%add signal vector into pdf

1219

%add signal vector into pdf

1220

for n=1:param.levels

1220

for n=1:param.levels

1221

pdf_full{n}=pdf_full_1;

1221

pdf_full{n}=pdf_full_1;

1222

for j=pdf_range

1222

for j=pdf_range

1223

pdf_full{n}(j).x=pdf_full{n}(j).x+A_s_vec(j)*Levels(n);

1223

pdf_full{n}(j).x=pdf_full{n}(j).x+A_s_vec(j)*Levels(n);

1224

pdf_full{n}(j).Min=pdf_full{n}(j).x(1)/pdf_full{n}(j).BinSize;

1224

pdf_full{n}(j).Min=pdf_full{n}(j).x(1)/pdf_full{n}(j).BinSize;

1225

end

1225

end

1226

end

1226

end

1227

1227

1228

1228

1229

% figure;

1229

% figure;

1230

% hold on;

1230

% hold on;

1231

%This loop builds the same PDF/CDF structures from regular COM, but it is

1231

%This loop builds the same PDF/CDF structures from regular COM, but it is

1232

%computed for every sample point

1232

%computed for every sample point

1233

for n=1:param.levels

1233

for n=1:param.levels

1234

for j=pdf_range

1234

for j=pdf_range

1235

sigma_G_full(j) = norm([param.sigma_RJ*param.sigma_X*norm(h_j_full(:,j)), Struct_Noise.sigma_N, Struct_Noise.sigma_TX]);

1235

sigma_G_full(j) = norm([param.sigma_RJ*param.sigma_X*norm(h_j_full(:,j)), Struct_Noise.sigma_N, Struct_Noise.sigma_TX]);

1236

gaussian_noise_pdf_full(j) = normal_dist(sigma_G_full(j), Struct_Noise.ber_q, delta_y);

1236

gaussian_noise_pdf_full(j) = normal_dist(sigma_G_full(j), Struct_Noise.ber_q, delta_y);

1237

gaussian_noise_pdf_full(j) = conv_fct(gaussian_noise_pdf_full(j), Struct_Noise.ne_noise_pdf);

1237

gaussian_noise_pdf_full(j) = conv_fct(gaussian_noise_pdf_full(j), Struct_Noise.ne_noise_pdf);

1238

p_DD_full(j) = get_pdf_from_sampled_signal(param.A_DD*h_j_full(:,j), param.levels, delta_y);

1238

p_DD_full(j) = get_pdf_from_sampled_signal(param.A_DD*h_j_full(:,j), param.levels, delta_y);

1239

noise_pdf_full(j)=conv_fct(gaussian_noise_pdf_full(j), p_DD_full(j));

1239

noise_pdf_full(j)=conv_fct(gaussian_noise_pdf_full(j), p_DD_full(j));

1240

isi_and_xtalk_pdf_full(j) = conv_fct_MeanNotZero(pdf_full{n}(j), Struct_Noise.cci_pdf);

1240

isi_and_xtalk_pdf_full(j) = conv_fct_MeanNotZero(pdf_full{n}(j), Struct_Noise.cci_pdf);

1241

% change from adam gregory to include crosstalk

1241

% change from adam gregory to include crosstalk

1242

% combined_interference_and_noise_pdf_full = conv_fct(pdf_full(j), noise_pdf_full(j));

1242

% combined_interference_and_noise_pdf_full = conv_fct(pdf_full(j), noise_pdf_full(j));

1243

combined_interference_and_noise_pdf_full{n}(j) = conv_fct_MeanNotZero(isi_and_xtalk_pdf_full(j), noise_pdf_full(j));

1243

combined_interference_and_noise_pdf_full{n}(j) = conv_fct_MeanNotZero(isi_and_xtalk_pdf_full(j), noise_pdf_full(j));

1244

1244

1245

%PDF to CDF

1245

%PDF to CDF

1246

combined_interference_and_noise_cdf_full{n}(j)=pdf_to_cdf(combined_interference_and_noise_pdf_full{n}(j));

1246

combined_interference_and_noise_cdf_full{n}(j)=pdf_to_cdf(combined_interference_and_noise_pdf_full{n}(j));

1247

1247

1248

end

1248

end

1249

end

1249

end

1250

%hold off;

1250

%hold off;

1251

1251

1252

1252

1253

%For the given BER, find the top & bottom voltage level in the CDF

1253

%For the given BER, find the top & bottom voltage level in the CDF

1254

for n=1:param.levels

1254

for n=1:param.levels

1255

A_ni_bottom{n}=zeros(1,samp_UI);

1255

A_ni_bottom{n}=zeros(1,samp_UI);

1256

A_ni_top{n}=zeros(1,samp_UI);

1256

A_ni_top{n}=zeros(1,samp_UI);

1257

for j=pdf_range

1257

for j=pdf_range

1258

[A_ni_top{n}(j),A_ni_bottom{n}(j)]=cdf_to_ber_contour(combined_interference_and_noise_cdf_full{n}(j),param.specBER);

1258

[A_ni_top{n}(j),A_ni_bottom{n}(j)]=cdf_to_ber_contour(combined_interference_and_noise_cdf_full{n}(j),param.specBER);

1259

end

1259

end

1260

end

1260

end

1261

%plot(1:samp_UI,cursor_vector-A_ni_top,1:samp_UI,-cursor_vector+A_ni_bottom)

1261

%plot(1:samp_UI,cursor_vector-A_ni_top,1:samp_UI,-cursor_vector+A_ni_bottom)

1262

1262

1263

for n=1:param.levels-1

1263

for n=1:param.levels-1

1264

eye_contour{n}(:,1)=A_ni_top{n+1};

1264

eye_contour{n}(:,1)=A_ni_top{n+1};

1265

eye_contour{n}(:,2)=A_ni_bottom{n};

1265

eye_contour{n}(:,2)=A_ni_bottom{n};

1266

end

1266

end

1267

1267

1268

1268

1269

for n=1:param.levels-1

1269

for n=1:param.levels-1

1270

%eye_contour holds the top eye in the 1st column & bottom eye in the 2nd column

1270

%eye_contour holds the top eye in the 1st column & bottom eye in the 2nd column

1271

%define vref as middle of top eye height and bottom eye height. Now

1271

%define vref as middle of top eye height and bottom eye height. Now

1272

%that all eyes are created, vref is non-zero except for middle eye

1272

%that all eyes are created, vref is non-zero except for middle eye

1273

EH_top=eye_contour{n}(half_UI,1);

1273

EH_top=eye_contour{n}(half_UI,1);

1274

EH_bot=eye_contour{n}(half_UI,2);

1274

EH_bot=eye_contour{n}(half_UI,2);

1275

EH=EH_top-EH_bot;

1275

EH=EH_top-EH_bot;

1276

vref=EH_top/2+EH_bot/2;

1276

vref=EH_top/2+EH_bot/2;

1277

%This function finds left/right eye width by finding the vref crossings of

1277

%This function finds left/right eye width by finding the vref crossings of

1278

%the top and bottom eye contours

1278

%the top and bottom eye contours

1279

[Left_EW(n),Right_EW(n)]=find_eye_width(eye_contour{n},half_UI,samp_UI,vref);

1279

[Left_EW(n),Right_EW(n)]=find_eye_width(eye_contour{n},half_UI,samp_UI,vref);

1280

end

1280

end

1281

1281

1282

%For reporting to .csv, need eye contour to be a matrix instead of cell

1282

%For reporting to .csv, need eye contour to be a matrix instead of cell

1283

eye_contour_tmp=eye_contour;

1283

eye_contour_tmp=eye_contour;

1284

eye_contour=[];

1284

eye_contour=[];

1285

for n=1:param.levels-1

1285

for n=1:param.levels-1

1286

eye_contour(:,(n-1)*2+1:n*2)=eye_contour_tmp{n};

1286

eye_contour(:,(n-1)*2+1:n*2)=eye_contour_tmp{n};

1287

end

1287

end

1288

1288

1289

1289

1290

%Find VEC eye height

1290

%Find VEC eye height

1291

out_VT=[];

1291

out_VT=[];

1292

out_VB=[];

1292

out_VB=[];

1293

if param.T_O ~=0

1293

if param.T_O ~=0

1294

1294

1295

switch lower(OP.Histogram_Window_Weight)

1295

switch lower(OP.Histogram_Window_Weight)

1296

case {'gaussian' 'norm' 'normal' 'guassian'}

1296

case {'gaussian' 'norm' 'normal' 'guassian'}

1297

%build a gaussian window of weights that are multiplied by each pdf in the T_O range

1297

%build a gaussian window of weights that are multiplied by each pdf in the T_O range

1298

%Sigma = T_O/QL. Default QL=2.5. This gives a nice descent to near 0 at the edge of the window

1298

%Sigma = T_O/QL. Default QL=2.5. This gives a nice descent to near 0 at the edge of the window

1299

QL_sigma=T_O/param.QL;

1299

QL_sigma=T_O/param.QL;

1300

weights=exp(-1/2 * ([-T_O:T_O]/QL_sigma).^2);

1300

weights=exp(-1/2 * ([-T_O:T_O]/QL_sigma).^2);

1301

case 'triangle'

1301

case 'triangle'

1302

%triangle window. linear slope from 0 to 1 and back down to 0

1302

%triangle window. linear slope from 0 to 1 and back down to 0

1303

%for the weights

1303

%for the weights

1304

t_slope=1/(T_O);

1304

t_slope=1/(T_O);

1305

weights=[0:t_slope:1 1-t_slope:-t_slope:0];

1305

weights=[0:t_slope:1 1-t_slope:-t_slope:0];

1306

case 'rectangle'

1306

case 'rectangle'

1307

%default = rectangle. all weights = 1

1307

%default = rectangle. all weights = 1

1308

weights(1:2*T_O+1)=1;

1308

weights(1:2*T_O+1)=1;

1309

case 'dual_rayleigh'

1309

case 'dual_rayleigh'

1310

QL_sigma=T_O/param.QL;

1310

QL_sigma=T_O/param.QL;

1311

X=-T_O:T_O;

1311

X=-T_O:T_O;

1312

weights=(X+T_O)/QL_sigma^2.*exp(-1/2 * ((X+T_O)/QL_sigma).^2)...

1312

weights=(X+T_O)/QL_sigma^2.*exp(-1/2 * ((X+T_O)/QL_sigma).^2)...

1313

-(X-T_O)/QL_sigma^2.*exp(-1/2 * ((X-T_O)/QL_sigma).^2);

1313

-(X-T_O)/QL_sigma^2.*exp(-1/2 * ((X-T_O)/QL_sigma).^2);

1314

weights=weights/max(weights);

1314

weights=weights/max(weights);

1315

otherwise

1315

otherwise

1316

error('%s not recognized for Histogram_Window_Weight',OP.Histogram_Window_Weight)

1316

error('%s not recognized for Histogram_Window_Weight',OP.Histogram_Window_Weight)

1317

end

1317

end

1318

1318

1319

for n=1:param.levels

1319

for n=1:param.levels

1320

out_pdf{n}=[];

1320

out_pdf{n}=[];

1321

for j=start_sample:end_sample

1321

for j=start_sample:end_sample

1322

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1322

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1323

target_pdf.y=target_pdf.y*weights(j-start_sample+1);

1323

target_pdf.y=target_pdf.y*weights(j-start_sample+1);

1324

if isempty(out_pdf{n})

1324

if isempty(out_pdf{n})

1325

out_pdf{n}=target_pdf;

1325

out_pdf{n}=target_pdf;

1326

else

1326

else

1327

out_pdf{n} = combine_pdf_same_voltage_axis(out_pdf{n}, target_pdf);

1327

out_pdf{n} = combine_pdf_same_voltage_axis(out_pdf{n}, target_pdf);

1328

end

1328

end

1329

end

1329

end

1330

out_pdf{n}.y=out_pdf{n}.y/sum(out_pdf{n}.y);

1330

out_pdf{n}.y=out_pdf{n}.y/sum(out_pdf{n}.y);

1331

end

1331

end

1332

1332

1333

for n=1:param.levels

1333

for n=1:param.levels

1334

out_cdf{n}=pdf_to_cdf(out_pdf{n});

1334

out_cdf{n}=pdf_to_cdf(out_pdf{n});

1335

end

1335

end

1336

1336

1337

for n=1:param.levels

1337

for n=1:param.levels

1338

[A_ni_top_O(n),A_ni_bottom_O(n)]=cdf_to_ber_contour(out_cdf{n},param.specBER);

1338

[A_ni_top_O(n),A_ni_bottom_O(n)]=cdf_to_ber_contour(out_cdf{n},param.specBER);

1339

end

1339

end

1340

1340

1341

for n=1:param.levels-1

1341

for n=1:param.levels-1

1342

OUT_VT_L(n,1)=A_ni_top_O(n+1);

1342

OUT_VT_L(n,1)=A_ni_top_O(n+1);

1343

OUT_VT_L(n,2)=A_ni_bottom_O(n);

1343

OUT_VT_L(n,2)=A_ni_bottom_O(n);

1344

end

1344

end

1345

1345

1346

%Report the top/bottom eye height of the worst eye

1346

%Report the top/bottom eye height of the worst eye

1347

EH_VT=OUT_VT_L(:,1)-OUT_VT_L(:,2);

1347

EH_VT=OUT_VT_L(:,1)-OUT_VT_L(:,2);

1348

[mineh,min_idx]=min(EH_VT);

1348

[mineh,min_idx]=min(EH_VT);

1349

out_VT=OUT_VT_L(min_idx,1);

1349

out_VT=OUT_VT_L(min_idx,1);

1350

out_VB=OUT_VT_L(min_idx,2);

1350

out_VB=OUT_VT_L(min_idx,2);

1351

1351

1352

% CDF_Mean=mean(A_s_vec(start_sample:end_sample));

1352

% CDF_Mean=mean(A_s_vec(start_sample:end_sample));

1353

% out_VT=2*CDF_Mean-A_ni_top_O;

1353

% out_VT=2*CDF_Mean-A_ni_top_O;

1354

% out_VB=-1*A_ni_bottom_O;

1354

% out_VB=-1*A_ni_bottom_O;

1355

1355

1356

if debug_plot

1356

if debug_plot

1357

figure;

1357

figure;

1358

hold on;

1358

hold on;

1359

for j=start_sample:end_sample

1359

for j=start_sample:end_sample

1360

plot(combined_interference_and_noise_pdf_full(j).x,combined_interference_and_noise_pdf_full(j).y);

1360

plot(combined_interference_and_noise_pdf_full(j).x,combined_interference_and_noise_pdf_full(j).y);

1361

end

1361

end

1362

plot(out_pdf.x,out_pdf.y,'color','k','LineWidth',2);

1362

plot(out_pdf.x,out_pdf.y,'color','k','LineWidth',2);

1363

hold off;

1363

hold off;

1364

end

1364

end

1365

end

1365

end

1366

1366

1367

1367

1368

1368

1369

1369

1370

function [PDF,CDF,NS]=Create_Noise_PDF(A_s,param,fom_result,chdata,OP,sigma_bn,PSD_results)

1370

function [PDF,CDF,NS]=Create_Noise_PDF(A_s,param,fom_result,chdata,OP,sigma_bn,PSD_results)

1371

1371

1372

%This block was originally in main COM function but was moved here for

1372

%This block was originally in main COM function but was moved here for

1373

%cleanup. It returns the combined interference and noise PDF & CDF as well

1373

%cleanup. It returns the combined interference and noise PDF & CDF as well

1374

%as a structure "NS" that contains all the noise parameters that are used

1374

%as a structure "NS" that contains all the noise parameters that are used

1375

%in other places in COM

1375

%in other places in COM

1376

1376

1377

if OP.RX_CALIBRATION

1377

if OP.RX_CALIBRATION

1378

ctle_gain2 = (10.^(param.ctle_gdc_values(fom_result.ctle)/20) + 1i*chdata(2).faxis/param.CTLE_fz(fom_result.ctle)) ./ ...

1378

ctle_gain2 = (10.^(param.ctle_gdc_values(fom_result.ctle)/20) + 1i*chdata(2).faxis/param.CTLE_fz(fom_result.ctle)) ./ ...

1379

((1+1i*chdata(2).faxis/param.CTLE_fp1(fom_result.ctle)).*(1+1i*chdata(2).faxis/param.CTLE_fp2(fom_result.ctle)));

1379

((1+1i*chdata(2).faxis/param.CTLE_fp1(fom_result.ctle)).*(1+1i*chdata(2).faxis/param.CTLE_fp2(fom_result.ctle)));

1380

switch param.CTLE_type

1380

switch param.CTLE_type

1381

case 'CL93'

1381

case 'CL93'

1382

H_low2=1;

1382

H_low2=1;

1383

case 'CL120d' % this clause uses two gain indexes

1383

case 'CL120d' % this clause uses two gain indexes

1384

H_low2=(10.^(param.g_DC_HP_values(fom_result.best_G_high_pass)/20) + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass))./(1 + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass));

1384

H_low2=(10.^(param.g_DC_HP_values(fom_result.best_G_high_pass)/20) + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass))./(1 + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass));

1385

case 'CL120e' % Z1 has been adjusted

1385

case 'CL120e' % Z1 has been adjusted

1386

H_low2=(1 + 1i*chdata(2).faxis/f_HP_P(fom_result.ctle))./(1 + 1i*chdata(2).faxis/f_HP_Z(fom_result.ctle));

1386

H_low2=(1 + 1i*chdata(2).faxis/f_HP_P(fom_result.ctle))./(1 + 1i*chdata(2).faxis/f_HP_Z(fom_result.ctle));

1387

end

1387

end

1388

H_ctf2=H_low2.*ctle_gain2;

1388

H_ctf2=H_low2.*ctle_gain2;

1389

[ sigma_ne, NS.sigma_hp] = get_sigma_noise( H_ctf2, param, chdata, sigma_bn );

1389

[ sigma_ne, NS.sigma_hp] = get_sigma_noise( H_ctf2, param, chdata, sigma_bn );

1390

else

1390

else

1391

sigma_ne=0;

1391

sigma_ne=0;

1392

end

1392

end

1393

1393

1394

NS.sigma_N = fom_result.sigma_N; % eta zero noise

1394

NS.sigma_N = fom_result.sigma_N; % eta zero noise

1395

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

1395

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

1396

if ~OP.SNR_TXwC0

1396

if ~OP.SNR_TXwC0

1397

% Equation 93A-30 %% h0(ts0)= A_s*R_lm/(L-1)

1397

% Equation 93A-30 %% h0(ts0)= A_s*R_lm/(L-1)

1398

NS.sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx and RLM

1398

NS.sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx and RLM

1399

else

1399

else

1400

NS.sigma_TX = (param.levels-1)*A_s/fom_result.txffe(fom_result.cur) /param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx from Adee

1400

NS.sigma_TX = (param.levels-1)*A_s/fom_result.txffe(fom_result.cur) /param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx from Adee

1401

end

1401

end

1402

NS.sigma_G = norm([param.sigma_RJ*param.sigma_X*norm(fom_result.h_J), NS.sigma_N, NS.sigma_TX]);

1402

NS.sigma_G = norm([param.sigma_RJ*param.sigma_X*norm(fom_result.h_J), NS.sigma_N, NS.sigma_TX]);

1403

NS.sigma_rjit= param.sigma_RJ*param.sigma_X*norm(fom_result.h_J);

1403

NS.sigma_rjit= param.sigma_RJ*param.sigma_X*norm(fom_result.h_J);

1404

else

1404

else

1405

NS.sigma_TX =PSD_results.S_tn_rms;

1405

NS.sigma_TX =PSD_results.S_tn_rms;

1406

NS.sigma_G = PSD_results.S_G_rms;

1406

NS.sigma_G = PSD_results.S_G_rms;

1407

NS.sigma_rjit=PSD_results.S_rj_rms ;

1407

NS.sigma_rjit=PSD_results.S_rj_rms ;

1408

NS.sigma_N=PSD_results.S_rn_rms ; % Commit request 4p4_8, healey_3dj_COM_01_240416

1408

NS.sigma_N=PSD_results.S_rn_rms ; % Commit request 4p4_8, healey_3dj_COM_01_240416

1409

end

1409

end

1410

% Equation 93A-41 %%

1410

% Equation 93A-41 %%

1411

1411

1412

1412

1413

% Equation 93A-42 %%

1413

% Equation 93A-42 %%

1414

% number of sigmas needed depends on the required BER.

1414

% number of sigmas needed depends on the required BER.

1415

if param.Noise_Crest_Factor == 0

1415

if param.Noise_Crest_Factor == 0

1416

NS.ber_q = sqrt(2)*erfcinv(2*param.specBER);

1416

NS.ber_q = sqrt(2)*erfcinv(2*param.specBER);

1417

else

1417

else

1418

NS.ber_q=param.Noise_Crest_Factor;

1418

NS.ber_q=param.Noise_Crest_Factor;

1419

end

1419

end

1420

NS.gaussian_noise_pdf = normal_dist(NS.sigma_G, NS.ber_q, param.delta_y);

1420

NS.gaussian_noise_pdf = normal_dist(NS.sigma_G, NS.ber_q, param.delta_y);

1421

% enable overriding the Q factor of the BBN instrument.

1421

% enable overriding the Q factor of the BBN instrument.

1422

if OP.force_BBN_Q_factor

1422

if OP.force_BBN_Q_factor

1423

NS.ne_noise_pdf = normal_dist(sigma_ne, OP.BBN_Q_factor, param.delta_y);

1423

NS.ne_noise_pdf = normal_dist(sigma_ne, OP.BBN_Q_factor, param.delta_y);

1424

else

1424

else

1425

NS.ne_noise_pdf = normal_dist(sigma_ne, NS.ber_q, param.delta_y);

1425

NS.ne_noise_pdf = normal_dist(sigma_ne, NS.ber_q, param.delta_y);

1426

end

1426

end

1427

NS.gaussian_noise_pdf = conv_fct(NS.gaussian_noise_pdf, NS.ne_noise_pdf);

1427

NS.gaussian_noise_pdf = conv_fct(NS.gaussian_noise_pdf, NS.ne_noise_pdf);

1428

1428

1429

% p_DD is computed using the procedure defined in 93A.1.7.1 with h(n)=A_DD*h_J(n)

1429

% p_DD is computed using the procedure defined in 93A.1.7.1 with h(n)=A_DD*h_J(n)

1430

NS.p_DD = get_pdf_from_sampled_signal(param.A_DD*fom_result.h_J, param.levels, param.delta_y);

1430

NS.p_DD = get_pdf_from_sampled_signal(param.A_DD*fom_result.h_J, param.levels, param.delta_y);

1431

1431

1432

% Equation 93A-43 % only used for reporting bathtub curves

1432

% Equation 93A-43 % only used for reporting bathtub curves

1433

NS.noise_pdf=conv_fct(NS.gaussian_noise_pdf, NS.p_DD);

1433

NS.noise_pdf=conv_fct(NS.gaussian_noise_pdf, NS.p_DD);

1434

gaussian_rjitt_pdf = normal_dist(NS.sigma_rjit, NS.ber_q, param.delta_y);

1434

gaussian_rjitt_pdf = normal_dist(NS.sigma_rjit, NS.ber_q, param.delta_y);

1435

NS.jitt_pdf=conv_fct(gaussian_rjitt_pdf, NS.p_DD);

1435

NS.jitt_pdf=conv_fct(gaussian_rjitt_pdf, NS.p_DD);

1436

1436

1437

% Implementation of 93A.1.7.3 combination procedure

1437

% Implementation of 93A.1.7.3 combination procedure

1438

% (effectively Equation 93A-44) %%

1438

% (effectively Equation 93A-44) %%

1439

1439

1440

% Self-Channel Interference is thru residual result

1440

% Self-Channel Interference is thru residual result

1441

NS.sci_pdf = chdata(1).pdfr;

1441

NS.sci_pdf = chdata(1).pdfr;

1442

sci_mxi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1442

sci_mxi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1443

NS.thru_peak_interference_at_BER=abs(NS.sci_pdf.x(sci_mxi));

1443

NS.thru_peak_interference_at_BER=abs(NS.sci_pdf.x(sci_mxi));

1444

sci_msi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1444

sci_msi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1445

NS.sci_sigma=abs(NS.sci_pdf.x(sci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1445

NS.sci_sigma=abs(NS.sci_pdf.x(sci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1446

if OP.RX_CALIBRATION ==0

1446

if OP.RX_CALIBRATION ==0

1447

% Co-Channel Interference PDFs (for information only):

1447

% Co-Channel Interference PDFs (for information only):

1448

% initialize to deltas

1448

% initialize to deltas

1449

MDNEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1449

MDNEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1450

MDFEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1450

MDFEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1451

% serially convolve FEXT/NEXT PDFs

1451

% serially convolve FEXT/NEXT PDFs

1452

for k=2:param.number_of_s4p_files

1452

for k=2:param.number_of_s4p_files

1453

if isequal(chdata(k).type, 'NEXT')

1453

if isequal(chdata(k).type, 'NEXT')

1454

MDNEXT_cci_pdf = conv_fct(MDNEXT_cci_pdf, chdata(k).pdfr);

1454

MDNEXT_cci_pdf = conv_fct(MDNEXT_cci_pdf, chdata(k).pdfr);

1455

else % ... must be FEXT

1455

else % ... must be FEXT

1456

MDFEXT_cci_pdf = conv_fct(MDFEXT_cci_pdf, chdata(k).pdfr);

1456

MDFEXT_cci_pdf = conv_fct(MDFEXT_cci_pdf, chdata(k).pdfr);

1457

end

1457

end

1458

end

1458

end

1459

1459

1460

% find "peaks" of MDNEXT/MDFEXT for reporting

1460

% find "peaks" of MDNEXT/MDFEXT for reporting

1461

mdnxi=find(cumsum(MDNEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1461

mdnxi=find(cumsum(MDNEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1462

NS.MDNEXT_peak_interference=abs(MDNEXT_cci_pdf.x(mdnxi));

1462

NS.MDNEXT_peak_interference=abs(MDNEXT_cci_pdf.x(mdnxi));

1463

mdfxi=find(cumsum(MDFEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1463

mdfxi=find(cumsum(MDFEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1464

NS.MDFEXT_peak_interference=abs(MDFEXT_cci_pdf.x(mdfxi));

1464

NS.MDFEXT_peak_interference=abs(MDFEXT_cci_pdf.x(mdfxi));

1465

1465

1466

% Combined crosstalk effect

1466

% Combined crosstalk effect

1467

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1467

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1468

cci_mxi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1468

cci_mxi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1469

cci_msi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1469

cci_msi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1470

NS.cci_sigma=abs(NS.cci_pdf.x(cci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1470

NS.cci_sigma=abs(NS.cci_pdf.x(cci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1471

NS.crosstalk_peak_interference_at_BER=abs(NS.cci_pdf.x(cci_mxi));

1471

NS.crosstalk_peak_interference_at_BER=abs(NS.cci_pdf.x(cci_mxi));

1472

% combine cci and sci

1472

% combine cci and sci

1473

NS.isi_and_xtalk_pdf = conv_fct(NS.sci_pdf, NS.cci_pdf);

1473

NS.isi_and_xtalk_pdf = conv_fct(NS.sci_pdf, NS.cci_pdf);

1474

else

1474

else

1475

% for calibration there is no cci

1475

% for calibration there is no cci

1476

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1476

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1477

end

1477

end

1478

1478

1479

mxi=find(cumsum(NS.isi_and_xtalk_pdf.y)>=param.specBER, 1, 'first');

1479

mxi=find(cumsum(NS.isi_and_xtalk_pdf.y)>=param.specBER, 1, 'first');

1480

NS.peak_interference_at_BER=abs(NS.isi_and_xtalk_pdf.x(mxi));

1480

NS.peak_interference_at_BER=abs(NS.isi_and_xtalk_pdf.x(mxi));

1481

1481

1482

1482

1483

% Equation 93A-45

1483

% Equation 93A-45

1484

combined_interference_and_noise_pdf = conv_fct(NS.isi_and_xtalk_pdf, NS.noise_pdf);

1484

combined_interference_and_noise_pdf = conv_fct(NS.isi_and_xtalk_pdf, NS.noise_pdf);

1485

PDF=combined_interference_and_noise_pdf;

1485

PDF=combined_interference_and_noise_pdf;

1486

1486

1487

% Equation 93A-37

1487

% Equation 93A-37

1488

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1488

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1489

CDF=combined_interference_and_noise_cdf;

1489

CDF=combined_interference_and_noise_cdf;

1490

function [hctf] = FD_CTLE(freq, fb, f_z, f_p1, f_p2, kacdc_dB)

1490

function [hctf] = FD_CTLE(freq, fb, f_z, f_p1, f_p2, kacdc_dB)

1491

hctf = ( 10.^(kacdc_dB/20) + 1i*freq/f_z ) ./ ( (1+1i*freq/f_p1) .* (1+1i*freq/f_p2)) ;

1491

hctf = ( 10.^(kacdc_dB/20) + 1i*freq/f_z ) ./ ( (1+1i*freq/f_p1) .* (1+1i*freq/f_p2)) ;

1492

1492

1493

function [chdata,output_args]=FD_Processing(chdata,output_args,param,OP,SDDp2p,DO_ONCE)

1493

function [chdata,output_args]=FD_Processing(chdata,output_args,param,OP,SDDp2p,DO_ONCE)

1494

%This function calculates various frequency domain metrics

1494

%This function calculates various frequency domain metrics

1495

%Mainly IL_fit, FOM_ILD, ICN, ICN_Fext, and ICN_Next

1495

%Mainly IL_fit, FOM_ILD, ICN, ICN_Fext, and ICN_Next

1496

db = @(x) 20*log10(abs(x));

1496

db = @(x) 20*log10(abs(x));

1497

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1497

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1498

if OP.WC_PORTZ

1498

if OP.WC_PORTZ

1499

A_thru = param.a_thru(param.Tx_rd_sel);

1499

A_thru = param.a_thru(param.Tx_rd_sel);

1500

A_fext = param.a_fext(param.Tx_rd_sel);

1500

A_fext = param.a_fext(param.Tx_rd_sel);

1501

A_next = param.a_next(param.Tx_rd_sel);

1501

A_next = param.a_next(param.Tx_rd_sel);

1502

else

1502

else

1503

A_thru = param.a_thru(package_testcase);

1503

A_thru = param.a_thru(package_testcase);

1504

A_fext = param.a_fext(package_testcase);

1504

A_fext = param.a_fext(package_testcase);

1505

A_next = param.a_next(package_testcase);

1505

A_next = param.a_next(package_testcase);

1506

end

1506

end

1507

for i=1:param.number_of_s4p_files

1507

for i=1:param.number_of_s4p_files

1508

if isequal(chdata(i).type, 'THRU')

1508

if isequal(chdata(i).type, 'THRU')

1509

chdata(i).A=A_thru;

1509

chdata(i).A=A_thru;

1510

chdata(i).Aicn=A_thru;

1510

chdata(i).Aicn=A_thru;

1511

elseif isequal(chdata(i).type, 'FEXT')

1511

elseif isequal(chdata(i).type, 'FEXT')

1512

chdata(i).A=A_fext;

1512

chdata(i).A=A_fext;

1513

chdata(i).Aicn=param.a_icn_fext;

1513

chdata(i).Aicn=param.a_icn_fext;

1514

elseif isequal(chdata(i).type, 'NEXT')

1514

elseif isequal(chdata(i).type, 'NEXT')

1515

chdata(i).A=A_next;

1515

chdata(i).A=A_next;

1516

chdata(i).Aicn=param.a_icn_next;

1516

chdata(i).Aicn=param.a_icn_next;

1517

end

1517

end

1518

end

1518

end

1519

if OP.TDMODE

1519

if OP.TDMODE

1520

for i=1:param.number_of_s4p_files % freq delta for integration

1520

for i=1:param.number_of_s4p_files % freq delta for integration

1521

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1521

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1522

end

1522

end

1523

end

1523

end

1524

if ~DO_ONCE

1524

if ~DO_ONCE

1525

return;

1525

return;

1526

end

1526

end

1527

%Any new output_args fields set in this function should be initialized here as empty

1527

%Any new output_args fields set in this function should be initialized here as empty

1528

output_args.fitted_IL_dB_at_Fnq = [];

1528

output_args.fitted_IL_dB_at_Fnq = [];

1529

output_args.cable__assembley_loss=[];

1529

output_args.cable__assembley_loss=[];

1530

output_args.loss_with_PCB=[];

1530

output_args.loss_with_PCB=[];

1531

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1531

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1532

output_args.IL_dB_channel_only_at_Fnq=[];

1532

output_args.IL_dB_channel_only_at_Fnq=[];

1533

output_args.VTF_loss_dB_at_Fnq=[];

1533

output_args.VTF_loss_dB_at_Fnq=[];

1534

output_args.IL_db_die_to_die_at_Fnq=[];

1534

output_args.IL_db_die_to_die_at_Fnq=[];

1535

output_args.FOM_TDILN=[];

1535

output_args.FOM_TDILN=[];

1536

output_args.TD_ILN=[];

1536

output_args.TD_ILN=[];

1537

output_args.FOM_RILN=[];

1537

output_args.FOM_RILN=[];

1538

output_args.FOM_ILD=[];

1538

output_args.FOM_ILD=[];

1539

%TD_Mode is just a pass through to set the empty values and return

1539

%TD_Mode is just a pass through to set the empty values and return

1540

if ~OP.GET_FD

1540

if ~OP.GET_FD

1541

return;

1541

return;

1542

end

1542

end

1543

case_number=param.package_testcase_i;

1543

case_number=param.package_testcase_i;

1544

f2=param.f2;

1544

f2=param.f2;

1545

f1=param.f1;

1545

f1=param.f1;

1546

MDFEXT_ICN=0; MDNEXT_ICN=0;

1546

MDFEXT_ICN=0; MDNEXT_ICN=0;

1547

for i=1:param.number_of_s4p_files

1547

for i=1:param.number_of_s4p_files

1548

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1548

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1549

% Equation 93A-20 %%

1549

% Equation 93A-20 %%

1550

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(i).faxis./(param.f_r*param.fb));

1550

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(i).faxis./(param.f_r*param.fb));

1551

f=chdata(i).faxis;

1551

f=chdata(i).faxis;

1552

%

1552

%

1553

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

1553

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

1554

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

1554

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

1555

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine); % conditionally include the RCos filter for all IR conversion using COM_FD_to_TD

1555

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine); % conditionally include the RCos filter for all IR conversion using COM_FD_to_TD

1556

H_txffe= Tx_FFE_Filter(param,f,param.Pkg_TXFFE_preset); % RIM 08-18-2022 to add forced TX ffe per package case

1556

H_txffe= Tx_FFE_Filter(param,f,param.Pkg_TXFFE_preset); % RIM 08-18-2022 to add forced TX ffe per package case

1557

H_r=H_bw.*H_bt.*H_RCos.*H_txffe; % RIM 08-18-2022 to add forced TX ffe per package case

1557

H_r=H_bw.*H_bt.*H_RCos.*H_txffe; % RIM 08-18-2022 to add forced TX ffe per package case

1558

chdata(i).sdd21=chdata(i).sdd21.*H_r;

1558

chdata(i).sdd21=chdata(i).sdd21.*H_r;

1559

if OP.DISPLAY_WINDOW

1559

if OP.DISPLAY_WINDOW

1560

if i==1

1560

if i==1

1561

figure(300+param.package_testcase_i);

1561

figure(300+param.package_testcase_i);

1562

subplot(3,1,1)

1562

subplot(3,1,1)

1563

hold on

1563

hold on

1564

plot(chdata(i).faxis/1e9, 20*log10(abs(squeeze(chdata(i).sdd21))), 'k-','linewidth',2, 'Disp',sprintf('VTF (no Tx/Rx eq)')')

1564

plot(chdata(i).faxis/1e9, 20*log10(abs(squeeze(chdata(i).sdd21))), 'k-','linewidth',2, 'Disp',sprintf('VTF (no Tx/Rx eq)')')

1565

try

1565

try

1566

legend('NumColumns',2)

1566

legend('NumColumns',2)

1567

legend('location','south')

1567

legend('location','south')

1568

catch

1568

catch

1569

end

1569

end

1570

end

1570

end

1571

end

1571

end

1572

end

1572

end

1573

end

1573

end

1574

for i=1:param.number_of_s4p_files

1574

for i=1:param.number_of_s4p_files

1575

if i == 2

1575

if i == 2

1576

PSXT(1:length(chdata(i).sdd21f))=0;

1576

PSXT(1:length(chdata(i).sdd21f))=0;

1577

MDFEXT(1:length(chdata(i).sdd21f))=0;

1577

MDFEXT(1:length(chdata(i).sdd21f))=0;

1578

MDNEXT(1:length(chdata(i).sdd21f))=0;

1578

MDNEXT(1:length(chdata(i).sdd21f))=0;

1579

end

1579

end

1580

a=find(chdata(i).faxis(:)>=f2,1,'first');% RIM 01-12-21

1580

a=find(chdata(i).faxis(:)>=f2,1,'first');% RIM 01-12-21

1581

if isempty(a)

1581

if isempty(a)

1582

f2=chdata(i).faxis(end);

1582

f2=chdata(i).faxis(end);

1583

index_f2=length(chdata(i).faxis);

1583

index_f2=length(chdata(i).faxis);

1584

else

1584

else

1585

index_f2=a(1);

1585

index_f2=a(1);

1586

end

1586

end

1587

b=find(chdata(i).faxis(:)<=f1,1,'last');% RIM 01-12-21

1587

b=find(chdata(i).faxis(:)<=f1,1,'last');% RIM 01-12-21

1588

if isempty(b)

1588

if isempty(b)

1589

f1=chdata(i).faxis(1);

1589

f1=chdata(i).faxis(1);

1590

index_f1=1;

1590

index_f1=1;

1591

else

1591

else

1592

index_f1=b(1);

1592

index_f1=b(1);

1593

end

1593

end

1594

% R is the frequency dependent parameter for the sinc function use in the

1594

% R is the frequency dependent parameter for the sinc function use in the

1595

% PWF for ICN

1595

% PWF for ICN

1596

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(i).faxis;

1596

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(i).faxis;

1597

if(chdata(i).faxis(1)==0)

1597

if(chdata(i).faxis(1)==0)

1598

temp_angle(1)=1e-20;% we don't want to divide by zero

1598

temp_angle(1)=1e-20;% we don't want to divide by zero

1599

end

1599

end

1600

SINC = sin(temp_angle)./temp_angle;

1600

SINC = sin(temp_angle)./temp_angle;

1601

PWF_data=SINC.^2;

1601

PWF_data=SINC.^2;

1602

PWF_trf=(1+(chdata(i).faxis/chdata(i).ftr).^4).^-1;

1602

PWF_trf=(1+(chdata(i).faxis/chdata(i).ftr).^4).^-1;

1603

%// bw1=2.613126; bw2=3.4142136; bw3=2.613126;

1603

%// bw1=2.613126; bw2=3.4142136; bw3=2.613126;

1604

fr=param.f_r*param.fb;

1604

fr=param.f_r*param.fb;

1605

PWF_rx=(1+(chdata(i).faxis/fr).^8).^-1;

1605

PWF_rx=(1+(chdata(i).faxis/fr).^8).^-1;

1606

PWF_highpass=1;

1606

PWF_highpass=1;

1607

% Equation 93A-57 %

1607

% Equation 93A-57 %

1608

PWF=PWF_data.*PWF_trf.*PWF_rx.*PWF_highpass; % power weight function

1608

PWF=PWF_data.*PWF_trf.*PWF_rx.*PWF_highpass; % power weight function

1609

% freq delta for integration

1609

% freq delta for integration

1610

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1610

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1611

% from ba spec, this is basically ICN

1611

% from ba spec, this is basically ICN

1612

faxis_GHz = chdata(i).faxis/1e9;

1612

faxis_GHz = chdata(i).faxis/1e9;

1613

if isequal(chdata(i).type, 'THRU')

1613

if isequal(chdata(i).type, 'THRU')

1614

[ILD_magft chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2));

1614

[ILD_magft chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2));

1615

% find fitted loss values by interpolation using full data, no indexing - Adee 2022-08-28

1615

% find fitted loss values by interpolation using full data, no indexing - Adee 2022-08-28

1616

[~, chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f, chdata(i).faxis);

1616

[~, chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f, chdata(i).faxis);

1617

fit_loss = interp1(chdata(i).faxis, -chdata(i).fit_orig, 1/param.ui/2);

1617

fit_loss = interp1(chdata(i).faxis, -chdata(i).fit_orig, 1/param.ui/2);

1618

chdata(i).fit_ILatNq = fit_loss;

1618

chdata(i).fit_ILatNq = fit_loss;

1619

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1619

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1620

IL_interp = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21f)), 1/param.ui/2);

1620

IL_interp = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21f)), 1/param.ui/2);

1621

chdata(i).ILatNq = IL_interp;

1621

chdata(i).ILatNq = IL_interp;

1622

if OP.include_pcb

1622

if OP.include_pcb

1623

cable_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_orig)), 1/param.ui/2);

1623

cable_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_orig)), 1/param.ui/2);

1624

loss_with_PCB = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_raw)), 1/param.ui/2);

1624

loss_with_PCB = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_raw)), 1/param.ui/2);

1625

output_args.cable__assembley_loss=cable_loss;

1625

output_args.cable__assembley_loss=cable_loss;

1626

output_args.loss_with_PCB=loss_with_PCB;

1626

output_args.loss_with_PCB=loss_with_PCB;

1627

end

1627

end

1628

Nq_loss=chdata(i).ILatNq;

1628

Nq_loss=chdata(i).ILatNq;

1629

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1629

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1630

% time domain ref RR = complex fit pulse

1630

% time domain ref RR = complex fit pulse

1631

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1631

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1632

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1632

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1633

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1633

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1634

FOM_ILN_complex= TD_ILN.FOM;

1634

FOM_ILN_complex= TD_ILN.FOM;

1635

end

1635

end

1636

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1636

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1637

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1637

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1638

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1638

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1639

FOM_ILN_complex= TD_ILN.FOM;

1639

FOM_ILN_complex= TD_ILN.FOM;

1640

end

1640

end

1641

if OP.COMPUTE_TDILN

1641

if OP.COMPUTE_TDILN

1642

output_args.FOM_TDILN=FOM_TDILN;

1642

output_args.FOM_TDILN=FOM_TDILN;

1643

output_args.TD_ILN=TD_ILN; % struct

1643

output_args.TD_ILN=TD_ILN; % struct

1644

end

1644

end

1645

if OP.COMPUTE_RILN

1645

if OP.COMPUTE_RILN

1646

% Get RIL, RILN, and TD_RILN

1646

% Get RIL, RILN, and TD_RILN

1647

[RIL_struct]= capture_RIL_RILN(chdata);

1647

[RIL_struct]= capture_RIL_RILN(chdata);

1648

FOM_RILN=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2-1).*RIL_struct.RILN_dB(index_f1:index_f2-1)'.^2));

1648

FOM_RILN=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2-1).*RIL_struct.RILN_dB(index_f1:index_f2-1)'.^2));

1649

output_args.FOM_RILN=FOM_RILN;

1649

output_args.FOM_RILN=FOM_RILN;

1650

%---start. plotting ILN based on ILD and RILN % Hansel 10/18/2021

1650

%---start. plotting ILN based on ILD and RILN % Hansel 10/18/2021

1651

plot_tdomain_debug= 0; % must have OP.COMPUTE_TDILN = 1 to use

1651

plot_tdomain_debug= 0; % must have OP.COMPUTE_TDILN = 1 to use

1652

if plot_tdomain_debug== 1

1652

if plot_tdomain_debug== 1

1653

figure(988); set(gcf,'Tag','COM')

1653

figure(988); set(gcf,'Tag','COM')

1654

ax_1= subplot(3,1,1);

1654

ax_1= subplot(3,1,1);

1655

plot(TD_ILN.REF.t*1e9, TD_ILN.REF.PR*1e3,'disp','ref');

1655

plot(TD_ILN.REF.t*1e9, TD_ILN.REF.PR*1e3,'disp','ref');

1656

hold on;

1656

hold on;

1657

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1657

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1658

hold on;

1658

hold on;

1659

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k','disp','ref - fit (IL noise)');

1659

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k','disp','ref - fit (IL noise)');

1660

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1660

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1661

grid on;

1661

grid on;

1662

box on;

1662

box on;

1663

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1663

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1664

xlabel('Time [nsec]');

1664

xlabel('Time [nsec]');

1665

ylabel('Pulse Response [mV]');

1665

ylabel('Pulse Response [mV]');

1666

1666

1667

ax_2= subplot(3,1,2);

1667

ax_2= subplot(3,1,2);

1668

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1668

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1669

hold on;

1669

hold on;

1670

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1670

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1671

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1671

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1672

grid on;

1672

grid on;

1673

box on;

1673

box on;

1674

legend('REF', 'TD\_RILN');

1674

legend('REF', 'TD\_RILN');

1675

xlabel('Time [nsec]');

1675

xlabel('Time [nsec]');

1676

ylabel('Pulse Response [mV]');

1676

ylabel('Pulse Response [mV]');

1677

ax_3= subplot(3,1,3);

1677

ax_3= subplot(3,1,3);

1678

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1678

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1679

hold on;

1679

hold on;

1680

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1680

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1681

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1681

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1682

grid on;

1682

grid on;

1683

box on;

1683

box on;

1684

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1684

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1685

xlabel('Time [nsec]');

1685

xlabel('Time [nsec]');

1686

ylabel('Pulse Response [mV]');

1686

ylabel('Pulse Response [mV]');

1687

1687

1688

linkaxes([ax_1, ax_2, ax_3], 'x');

1688

linkaxes([ax_1, ax_2, ax_3], 'x');

1689

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1689

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1690

end

1690

end

1691

%---end. plotting ILN based on ILD and RILN

1691

%---end. plotting ILN based on ILD and RILN

1692

end

1692

end

1693

% Equation 93A-56 %

1693

% Equation 93A-56 %

1694

FOM_ILD=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1694

FOM_ILD=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1695

output_args.FOM_ILD=FOM_ILD;

1695

output_args.FOM_ILD=FOM_ILD;

1696

if OP.DEBUG

1696

if OP.DEBUG

1697

if OP.DISPLAY_WINDOW

1697

if OP.DISPLAY_WINDOW

1698

figure(300+case_number);

1698

figure(300+case_number);

1699

set(gcf,'Tag','COM')

1699

set(gcf,'Tag','COM')

1700

screen_size=get(0,'ScreenSize');

1700

screen_size=get(0,'ScreenSize');

1701

pos = get(gcf, 'OuterPosition');

1701

pos = get(gcf, 'OuterPosition');

1702

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1702

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1703

screen_size([3 4 3 4]).*[0 1 0 0] + pos([3 4 3 4]).*[0 -2 1 2] ...IL fit

1703

screen_size([3 4 3 4]).*[0 1 0 0] + pos([3 4 3 4]).*[0 -2 1 2] ...IL fit

1704

- (case_number-1)*[0 20 0 0]);

1704

- (case_number-1)*[0 20 0 0]);

1705

subplot(3,1,1)

1705

subplot(3,1,1)

1706

title('Losses')

1706

title('Losses')

1707

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1707

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1708

hold on

1708

hold on

1709

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1709

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1710

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1710

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1711

ylim(get(gca, 'ylim'));

1711

ylim(get(gca, 'ylim'));

1712

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1712

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1713

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1713

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1714

subplot(3,1,3)

1714

subplot(3,1,3)

1715

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1715

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1716

if OP.PLOT_CM

1716

if OP.PLOT_CM

1717

if case_number ==1

1717

if case_number ==1

1718

h350=figure(350);set(gcf,'Tag','COM')

1718

h350=figure(350);set(gcf,'Tag','COM')

1719

screen_size=get(0,'ScreenSize');

1719

screen_size=get(0,'ScreenSize');

1720

pos = get(gcf, 'OuterPosition');

1720

pos = get(gcf, 'OuterPosition');

1721

set(gcf, 'OuterPosition',screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-2 -2 2 1])

1721

set(gcf, 'OuterPosition',screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-2 -2 2 1])

1722

movegui(gcf,'center');

1722

movegui(gcf,'center');

1723

htabgroup350 = uitabgroup(h350);

1723

htabgroup350 = uitabgroup(h350);

1724

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1724

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1725

hax1 = axes('Parent', htab1);

1725

hax1 = axes('Parent', htab1);

1726

set(h350,'CurrentAxes',hax1)

1726

set(h350,'CurrentAxes',hax1)

1727

hold on

1727

hold on

1728

set(gcf,'Tag','COM')

1728

set(gcf,'Tag','COM')

1729

screen_size=get(0,'ScreenSize');

1729

screen_size=get(0,'ScreenSize');

1730

pos = get(gcf, 'OuterPosition');

1730

pos = get(gcf, 'OuterPosition');

1731

title('IL & CM Losses')

1731

title('IL & CM Losses')

1732

base=strrep(chdata(i).base,'_',' ');

1732

base=strrep(chdata(i).base,'_',' ');

1733

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp', [ 'sdd21(IL) TP0-TP5 ' base])

1733

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp', [ 'sdd21(IL) TP0-TP5 ' base])

1734

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1734

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1735

ylabel('dB')

1735

ylabel('dB')

1736

xlabel('GHz')

1736

xlabel('GHz')

1737

legend show

1737

legend show

1738

legend('Location','eastoutside')

1738

legend('Location','eastoutside')

1739

hold on

1739

hold on

1740

grid on

1740

grid on

1741

if param.number_of_s4p_files > 1

1741

if param.number_of_s4p_files > 1

1742

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1742

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1743

hax2 = axes('Parent', htab2);

1743

hax2 = axes('Parent', htab2);

1744

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1744

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1745

hax3 = axes('Parent', htab3);

1745

hax3 = axes('Parent', htab3);

1746

end

1746

end

1747

1747

1748

end

1748

end

1749

end

1749

end

1750

else

1750

else

1751

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1751

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1752

end

1752

end

1753

end

1753

end

1754

else % NEXT or FEXT

1754

else % NEXT or FEXT

1755

if isequal(chdata(i).type, 'FEXT')

1755

if isequal(chdata(i).type, 'FEXT')

1756

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1756

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1757

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46

1757

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46

1758

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1758

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1759

elseif isequal(chdata(i).type, 'NEXT')

1759

elseif isequal(chdata(i).type, 'NEXT')

1760

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1760

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1761

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47

1761

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47

1762

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1762

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1763

end

1763

end

1764

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1764

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1765

ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));

1765

ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));

1766

output_args.ICN_mV=ICN*1000;

1766

output_args.ICN_mV=ICN*1000;

1767

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1767

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1768

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1768

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1769

if case_number ==1

1769

if case_number ==1

1770

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1770

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1771

% hax2 = axes('Parent', htab2);

1771

% hax2 = axes('Parent', htab2);

1772

set(h350,'CurrentAxes',hax2)

1772

set(h350,'CurrentAxes',hax2)

1773

hold on

1773

hold on

1774

title('CM Losses')

1774

title('CM Losses')

1775

base=strrep(chdata(i).base,'_',' ');

1775

base=strrep(chdata(i).base,'_',' ');

1776

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1776

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1777

legend('Location','eastoutside')

1777

legend('Location','eastoutside')

1778

hold on

1778

hold on

1779

grid on

1779

grid on

1780

set(h350,'CurrentAxes',hax3)

1780

set(h350,'CurrentAxes',hax3)

1781

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1781

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1782

legend('Location','eastoutside')

1782

legend('Location','eastoutside')

1783

hold on

1783

hold on

1784

grid on

1784

grid on

1785

end

1785

end

1786

end

1786

end

1787

end

1787

end

1788

end % for loop

1788

end % for loop

1789

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1789

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1790

if OP.DEBUG && OP.DISPLAY_WINDOW

1790

if OP.DEBUG && OP.DISPLAY_WINDOW

1791

figure(300+case_number);set(gcf,'Tag','COM');

1791

figure(300+case_number);set(gcf,'Tag','COM');

1792

if param.number_of_s4p_files > 1

1792

if param.number_of_s4p_files > 1

1793

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1793

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1794

subplot(3,1,1)

1794

subplot(3,1,1)

1795

hold on

1795

hold on

1796

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1796

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1797

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1797

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1798

subplot(3,1,2)

1798

subplot(3,1,2)

1799

grid on

1799

grid on

1800

ILtemp=20*log10(abs(chdata(1).sdd21f));

1800

ILtemp=20*log10(abs(chdata(1).sdd21f));

1801

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1801

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1802

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1802

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1803

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1803

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1804

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1804

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1805

hold on

1805

hold on

1806

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1806

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1807

end

1807

end

1808

subplot(3,1,1)

1808

subplot(3,1,1)

1809

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1809

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1810

grid on; legend show

1810

grid on; legend show

1811

subplot(3,1,2)

1811

subplot(3,1,2)

1812

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1812

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1813

ylim([0 80])

1813

ylim([0 80])

1814

xlim([.1 100])

1814

xlim([.1 100])

1815

grid on; %legend show

1815

grid on; %legend show

1816

subplot(3,1,3)

1816

subplot(3,1,3)

1817

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1817

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1818

ylim([-3 3])

1818

ylim([-3 3])

1819

grid on; legend show

1819

grid on; legend show

1820

end

1820

end

1821

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1821

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1822

total_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21)), 1/param.ui/2);

1822

total_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21)), 1/param.ui/2);

1823

d2d_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p_nodie)), 1/param.ui/2);

1823

d2d_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p_nodie)), 1/param.ui/2);

1824

VIP_VMP_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p)), 1/param.ui/2);

1824

VIP_VMP_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p)), 1/param.ui/2);

1825

output_args.VTF_loss_dB_at_Fnq=total_loss;

1825

output_args.VTF_loss_dB_at_Fnq=total_loss;

1826

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1826

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1827

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1827

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1828

function [ V0 ] = FFE( C , cmx,spui, V )

1828

function [ V0 ] = FFE( C , cmx,spui, V )

1829

% C FFE taps

1829

% C FFE taps

1830

% cmx number of precursors taps

1830

% cmx number of precursors taps

1831

% spui samples per ui

1831

% spui samples per ui

1832

% V input signal

1832

% V input signal

1833

%speed ups implemented:

1833

%speed ups implemented:

1834

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1834

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1835

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1835

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1836

1836

1837

V0=0;

1837

V0=0;

1838

if iscolumn(V); V=V.';end

1838

if iscolumn(V); V=V.';end

1839

for i=1:length(C)

1839

for i=1:length(C)

1840

if C(i)~=0

1840

if C(i)~=0

1841

ishift=(i-1-cmx)*spui;

1841

ishift=(i-1-cmx)*spui;

1842

V0=circshift(V',[ishift,0])*C(i)+V0;

1842

V0=circshift(V',[ishift,0])*C(i)+V0;

1843

end

1843

end

1844

end

1844

end

1845

%V0=circshift(V0,[(-cmx)*spui,0]);

1845

%V0=circshift(V0,[(-cmx)*spui,0]);

1846

% disp(max(V0));

1846

% disp(max(V0));

1847

1847

1848

1848

1849

% begin yasuo patch 12/11/2018

1849

% begin yasuo patch 12/11/2018

1850

% calculate sigma (standard deviation) value of PDF

1850

% calculate sigma (standard deviation) value of PDF

1851

function [ V0 ] = FFE_Fast( C,V_shift )

1851

function [ V0 ] = FFE_Fast( C,V_shift )

1852

% C FFE taps

1852

% C FFE taps

1853

% V input signal separated into length(C) columns with circshift already performed

1853

% V input signal separated into length(C) columns with circshift already performed

1854

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1854

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1855

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1855

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1856

% saved by pre-shifting it and remembering it across loops

1856

% saved by pre-shifting it and remembering it across loops

1857

% Another speed up: only multiply by indices of C that are not 0

1857

% Another speed up: only multiply by indices of C that are not 0

1858

1858

1859

V0=0;

1859

V0=0;

1860

for i=1:length(C)

1860

for i=1:length(C)

1861

if C(i)~=0

1861

if C(i)~=0

1862

V0=V_shift(:,i)*C(i)+V0;

1862

V0=V_shift(:,i)*C(i)+V0;

1863

end

1863

end

1864

end

1864

end

1865

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1865

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1866

1866

1867

hisi=h(isi_start:isi_end);

1867

hisi=h(isi_start:isi_end);

1868

hisi=hisi(param.RxFFE_cpx+1:param.N_bmax);

1868

hisi=hisi(param.N_tail_start:param.N_bmax);

1869

bank_size = param.N_bf;

1869

bank_size = param.N_bf;

1870

num_groups = param.N_bg;

1870

num_groups = param.N_bg;

1871

1871

1872

1872

1873

%start with one by one Floating Tap

1873

%start with one by one Floating Tap

1874

num_isi=length(hisi);

1874

num_isi=length(hisi);

1875

max_isi=num_isi-bank_size+1;

1875

max_isi=num_isi-bank_size+1;

1876

valid_tap_locations=1:max_isi;

1876

valid_tap_locations=1:max_isi;

1877

all_idx=[];

1877

all_idx=[];

1878

for j=1:num_groups

1878

for j=1:num_groups

1879

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1879

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1880

for k=1:length(valid_tap_locations)

1880

for k=1:length(valid_tap_locations)

1881

this_location=valid_tap_locations(k);

1881

this_location=valid_tap_locations(k);

1882

new_idx = [all_idx this_location:this_location+bank_size-1];

1882

new_idx = [all_idx this_location:this_location+bank_size-1];

1883

new_idx=sort(new_idx);

1883

new_idx=sort(new_idx);

1884

new_idx = new_idx+param.RxFFE_cpx;

1884

new_idx = new_idx+param.N_tail_start-1;

1885

%calculate FOM for each one

1885

%calculate FOM for each one

1886

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1886

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1887

end

1887

end

1888

%choose the location with best FOM

1888

%choose the location with best FOM

1889

%add it to the "all_idx" list and remove it from valid locations

1889

%add it to the "all_idx" list and remove it from valid locations

1890

[~,best_FOM_idx]=max(best_FOM);

1890

[~,best_FOM_idx]=max(best_FOM);

1891

start_tap = valid_tap_locations(best_FOM_idx);

1891

start_tap = valid_tap_locations(best_FOM_idx);

1892

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1892

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1893

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1893

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1894

remove_range(remove_range>length(valid_tap_locations))=[];

1894

remove_range(remove_range>length(valid_tap_locations))=[];

1895

valid_tap_locations(remove_range)=[];

1895

valid_tap_locations(remove_range)=[];

1896

1896

1897

%Also remove illegal taps from valid locations

1897

%Also remove illegal taps from valid locations

1898

%illegal taps are ones that would overlap with the chosen bank

1898

%illegal taps are ones that would overlap with the chosen bank

1899

bad_tap=start_tap-bank_size+1:start_tap-1;

1899

bad_tap=start_tap-bank_size+1:start_tap-1;

1900

bad_tap(bad_tap<1)=[];

1900

bad_tap(bad_tap<1)=[];

1901

for n=1:length(bad_tap)

1901

for n=1:length(bad_tap)

1902

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1902

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1903

if ~isempty(bad_tap_idx)

1903

if ~isempty(bad_tap_idx)

1904

valid_tap_locations(bad_tap_idx)=[];

1904

valid_tap_locations(bad_tap_idx)=[];

1905

end

1905

end

1906

end

1906

end

1907

end

1907

end

1908

1908

1909

%put idx back in the right location (adding RxFFE_cpx)

1909

%put idx back in the right location (adding N_tail_start)

1910

idx = all_idx+param.RxFFE_cpx;

1910

idx = all_idx+param.N_tail_start-1;

1911

idx = sort(idx);

1911

idx = sort(idx);

1912

function [ V0 ] = Fract_T_FFE( V , skew_step)

1912

function [ V0 ] = Fract_T_FFE( V , skew_step)

1913

% skew_step sub UI skew assuming param.samples_per_ui

1913

% skew_step sub UI skew assuming param.samples_per_ui

1914

% V input signal

1914

% V input signal

1915

% V0 output signal

1915

% V0 output signal

1916

% Richard Mellitz 8/17/2021

1916

% Richard Mellitz 8/17/2021

1917

V0=0;

1917

V0=0;

1918

if iscolumn(V); V=V.';end

1918

if iscolumn(V); V=V.';end

1919

ishift=skew_step;

1919

ishift=skew_step;

1920

V0=circshift(V',[ishift,0])'+V;

1920

V0=circshift(V',[ishift,0])'+V;

1921

V0=V0/2;

1921

V0=V0/2;

1922

function out=Full_Grid_Matrix(in)

1922

function out=Full_Grid_Matrix(in)

1923

1923

1924

%create a full grid matrix of input variables

1924

%create a full grid matrix of input variables

1925

%used to create the full grid of all txffe cases

1925

%used to create the full grid of all txffe cases

1926

%example:

1926

%example:

1927

%Full_Grid_Matrix({ [1 2] [100 200] })

1927

%Full_Grid_Matrix({ [1 2] [100 200] })

1928

%out =

1928

%out =

1929

% 1 100

1929

% 1 100

1930

% 1 200

1930

% 1 200

1931

% 2 100

1931

% 2 100

1932

% 2 200

1932

% 2 200

1933

%

1933

%

1934

%input can also be mixed between numeric and cell of char

1934

%input can also be mixed between numeric and cell of char

1935

%example:

1935

%example:

1936

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1936

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1937

%out =

1937

%out =

1938

% {[1]} {'A'}

1938

% {[1]} {'A'}

1939

% {[1]} {'B'}

1939

% {[1]} {'B'}

1940

% {[2]} {'A'}

1940

% {[2]} {'A'}

1941

% {[2]} {'B'}

1941

% {[2]} {'B'}

1942

1942

1943

if ~iscell(in)

1943

if ~iscell(in)

1944

error('input must be cell array of individual sweep variables');

1944

error('input must be cell array of individual sweep variables');

1945

end

1945

end

1946

1946

1947

num_columns=length(in);

1947

num_columns=length(in);

1948

num_cases=prod(cellfun('length',in));

1948

num_cases=prod(cellfun('length',in));

1949

1949

1950

cell_output=0;

1950

cell_output=0;

1951

cell_indices=cellfun(@(x) iscell(x),in);

1951

cell_indices=cellfun(@(x) iscell(x),in);

1952

if any(cell_indices)

1952

if any(cell_indices)

1953

cell_output=1;

1953

cell_output=1;

1954

end

1954

end

1955

if cell_output

1955

if cell_output

1956

for k=find(~cell_indices)

1956

for k=find(~cell_indices)

1957

in{k}=num2cell(in{k});

1957

in{k}=num2cell(in{k});

1958

end

1958

end

1959

end

1959

end

1960

1960

1961

if cell_output

1961

if cell_output

1962

out=cell(num_cases,num_columns);

1962

out=cell(num_cases,num_columns);

1963

else

1963

else

1964

out=zeros(num_cases,num_columns);

1964

out=zeros(num_cases,num_columns);

1965

end

1965

end

1966

1966

1967

%num_repetitions controls how many times each element of the column

1967

%num_repetitions controls how many times each element of the column

1968

%repeats. The first column is always just a copy of itself since every

1968

%repeats. The first column is always just a copy of itself since every

1969

%case will vary.

1969

%case will vary.

1970

num_repetitions=1;

1970

num_repetitions=1;

1971

for k=num_columns:-1:1

1971

for k=num_columns:-1:1

1972

this_column=in{k}(:);

1972

this_column=in{k}(:);

1973

%copy the column into a matrix to create the repetitions needed

1973

%copy the column into a matrix to create the repetitions needed

1974

B=repmat(this_column,[1 num_repetitions]);

1974

B=repmat(this_column,[1 num_repetitions]);

1975

%reshape into single column (actual repetitions)

1975

%reshape into single column (actual repetitions)

1976

C=reshape(B',[numel(B) 1]);

1976

C=reshape(B',[numel(B) 1]);

1977

%repeat the single column to build the entire length required

1977

%repeat the single column to build the entire length required

1978

num_repeats=num_cases/length(C);

1978

num_repeats=num_cases/length(C);

1979

D=repmat(C,[num_repeats 1]);

1979

D=repmat(C,[num_repeats 1]);

1980

out(:,k)=D;

1980

out(:,k)=D;

1981

%determine how many repetitions the next column needs

1981

%determine how many repetitions the next column needs

1982

num_repetitions=num_repetitions*length(this_column);

1982

num_repetitions=num_repetitions*length(this_column);

1983

end

1983

end

1984

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1984

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1985

% p=cpdf(type, ...)

1985

% p=cpdf(type, ...)

1986

%

1986

%

1987

% CPDF is a probability mass function for discrete distributions or an

1987

% CPDF is a probability mass function for discrete distributions or an

1988

% approxmation of a PDF for continuous distributions.

1988

% approxmation of a PDF for continuous distributions.

1989

%

1989

%

1990

% cpdf is internally normalized so that the sum of probabilities is 1

1990

% cpdf is internally normalized so that the sum of probabilities is 1

1991

% (regardless of bin size).

1991

% (regardless of bin size).

1992

1992

1993

% Internal fields:

1993

% Internal fields:

1994

% Min: *bin number* of minimum value.

1994

% Min: *bin number* of minimum value.

1995

% BinSize: size of PDF bins. Bin center is the representative value.

1995

% BinSize: size of PDF bins. Bin center is the representative value.

1996

% Vec: vector of probabilities per bin.

1996

% Vec: vector of probabilities per bin.

1997

1997

1998

pdf=EmptyPDF;

1998

pdf=EmptyPDF;

1999

1999

2000

rounded_values_div_binsize=round(values/pdf.BinSize);

2000

rounded_values_div_binsize=round(values/pdf.BinSize);

2001

%values=pdf.BinSize*rounded_values_div_binsize;

2001

%values=pdf.BinSize*rounded_values_div_binsize;

2002

2002

2003

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2003

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2004

% if all(values==0)

2004

% if all(values==0)

2005

% return;

2005

% return;

2006

% end

2006

% end

2007

%

2007

%

2008

% %speed up for all values rounded to the same bin

2008

% %speed up for all values rounded to the same bin

2009

% %The output pdf is the same as the

2009

% %The output pdf is the same as the

2010

% %empty pdf, but the x value is non-zero (but still scalar)

2010

% %empty pdf, but the x value is non-zero (but still scalar)

2011

% if all(values==values(1))

2011

% if all(values==values(1))

2012

% pdf.Min=rounded_values_div_binsize(1);

2012

% pdf.Min=rounded_values_div_binsize(1);

2013

% pdf.x=values(1);

2013

% pdf.x=values(1);

2014

% return;

2014

% return;

2015

% end

2015

% end

2016

%

2016

%

2017

% %The code below requires that values is

2017

% %The code below requires that values is

2018

% %sorted. Generally this should be true, but check to be sure

2018

% %sorted. Generally this should be true, but check to be sure

2019

% if ~issorted(values)

2019

% if ~issorted(values)

2020

% [values,si]=sort(values);

2020

% [values,si]=sort(values);

2021

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2021

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2022

% probs=probs(si);

2022

% probs=probs(si);

2023

% end

2023

% end

2024

2024

2025

2025

2026

%pdf.x=values(1):pdf.BinSize:values(end);

2026

%pdf.x=values(1):pdf.BinSize:values(end);

2027

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2027

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2028

pdf.Min=rounded_values_div_binsize(1);

2028

pdf.Min=rounded_values_div_binsize(1);

2029

2029

2030

pdf.y=zeros(size(pdf.x));

2030

pdf.y=zeros(size(pdf.x));

2031

%The rounded values divided by binsize will reveal the bin number if

2031

%The rounded values divided by binsize will reveal the bin number if

2032

%pdf.Min is subtracted from it

2032

%pdf.Min is subtracted from it

2033

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2033

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2034

%Can avoid one addition by inserting the first probability

2034

%Can avoid one addition by inserting the first probability

2035

%actually helps when calling this 2 million times

2035

%actually helps when calling this 2 million times

2036

pdf.y(bin_placement(1))=probs(1);

2036

pdf.y(bin_placement(1))=probs(1);

2037

for k=2:length(values)

2037

for k=2:length(values)

2038

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2038

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2039

end

2039

end

2040

2040

2041

2041

2042

%Have already ensured that sum(pdf.y)=1

2042

%Have already ensured that sum(pdf.y)=1

2043

%pdf.y=pdf.y/sum(pdf.y);

2043

%pdf.y=pdf.y/sum(pdf.y);

2044

2044

2045

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2045

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2046

% error('PDF must be real and nonnegative');

2046

% error('PDF must be real and nonnegative');

2047

% end

2047

% end

2048

2048

2049

% pMax=pdf.Min+length(pdf.y)-1;

2049

% pMax=pdf.Min+length(pdf.y)-1;

2050

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2050

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2051

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2051

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2052

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2052

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2053

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2053

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2054

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2054

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2055

2055

2056

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2056

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2057

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2057

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2058

2058

2059

%% step 0

2059

%% step 0

2060

COM_from_matlab=20*log10(A_s/A_ni);

2060

COM_from_matlab=20*log10(A_s/A_ni);

2061

L=param.levels;

2061

L=param.levels;

2062

DER0=param.specBER;

2062

DER0=param.specBER;

2063

%% step 1 from slide 6/5

2063

%% step 1 from slide 6/5

2064

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2064

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2065

main=A_peak;

2065

main=A_peak;

2066

k_DER=qfuncinv(param.specBER);

2066

k_DER=qfuncinv(param.specBER);

2067

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2067

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2068

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2068

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2069

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2069

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2070

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2070

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2071

if A_s >= A_ni

2071

if A_s >= A_ni

2072

%% step 2 slide 10/8

2072

%% step 2 slide 10/8

2073

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2073

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2074

%% step 2 slide 10/8

2074

%% step 2 slide 10/8

2075

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2075

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2076

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2076

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2077

%% step 3 side 11/9

2077

%% step 3 side 11/9

2078

j=1:200;

2078

j=1:200;

2079

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2079

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2080

DER_MLSE_CDF=0; jj=1;

2080

DER_MLSE_CDF=0; jj=1;

2081

DER_delta = inf;

2081

DER_delta = inf;

2082

while DER_delta > .001

2082

while DER_delta > .001

2083

last_DER_MLSE_CDF=DER_MLSE_CDF;

2083

last_DER_MLSE_CDF=DER_MLSE_CDF;

2084

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2084

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2085

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2085

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2086

jj=jj+1;

2086

jj=jj+1;

2087

end

2087

end

2088

%% step 4 slide 12/10

2088

%% step 4 slide 12/10

2089

SNR_DFE_eqivalent=SNR_DFE*(...

2089

SNR_DFE_eqivalent=SNR_DFE*(...

2090

(L-1)*sigma_noise/main * qfuncinv(...

2090

(L-1)*sigma_noise/main * qfuncinv(...

2091

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2091

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2092

) ...

2092

) ...

2093

)^2;

2093

)^2;

2094

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2094

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2095

(L-1)/main * CDF_inv_ev(...

2095

(L-1)/main * CDF_inv_ev(...

2096

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2096

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2097

,PDF, CDF ) ...

2097

,PDF, CDF ) ...

2098

)^2;

2098

)^2;

2099

2099

2100

%% step 5 slide 13/11

2100

%% step 5 slide 13/11

2101

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2101

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2102

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2102

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2103

new_com_CDF=COM_from_matlab+delta_com_CDF;

2103

new_com_CDF=COM_from_matlab+delta_com_CDF;

2104

else

2104

else

2105

warning('MLSE not applied because there is more noise than signal')

2105

warning('MLSE not applied because there is more noise than signal')

2106

DER_MLSE=[];

2106

DER_MLSE=[];

2107

DER_MLSE_CDF=[];

2107

DER_MLSE_CDF=[];

2108

SNR_DFE_eqivalent=[];

2108

SNR_DFE_eqivalent=[];

2109

SNR_DFE_eqivalent_CDF=[];

2109

SNR_DFE_eqivalent_CDF=[];

2110

new_com_CDF=COM_from_matlab;

2110

new_com_CDF=COM_from_matlab;

2111

delta_com_CDF=0;

2111

delta_com_CDF=0;

2112

delta_com=0;

2112

delta_com=0;

2113

SNR_DFE=[];

2113

SNR_DFE=[];

2114

end

2114

end

2115

2115

2116

%%

2116

%%

2117

MLSE_results.COM_from_matlab=COM_from_matlab;

2117

MLSE_results.COM_from_matlab=COM_from_matlab;

2118

MLSE_results.SNR_DFE=SNR_DFE;

2118

MLSE_results.SNR_DFE=SNR_DFE;

2119

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2119

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2120

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2120

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2121

MLSE_results.sigma_noise=sigma_noise;

2121

MLSE_results.sigma_noise=sigma_noise;

2122

MLSE_results.SNR_dB=SNR_dB ;

2122

MLSE_results.SNR_dB=SNR_dB ;

2123

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2123

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2124

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2124

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2125

MLSE_results.COM_Gaussian=new_com_CDF;

2125

MLSE_results.COM_Gaussian=new_com_CDF;

2126

MLSE_results.COM_CDF=new_com_CDF;

2126

MLSE_results.COM_CDF=new_com_CDF;

2127

MLSE_results.k_DER=k_DER;

2127

MLSE_results.k_DER=k_DER;

2128

MLSE_results.delta_com_CDF=delta_com_CDF;

2128

MLSE_results.delta_com_CDF=delta_com_CDF;

2129

MLSE_results.delta_com_Gaussian=delta_com;

2129

MLSE_results.delta_com_Gaussian=delta_com;

2130

2130

2131

2131

2132

2132

2133

function [MLSE_results] = MLSE_U1_c(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2133

function [MLSE_results] = MLSE_U1_c(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2134

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2134

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2135

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2135

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2136

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2136

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2137

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2137

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2138

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2138

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2139

%% step 0

2139

%% step 0

2140

COM_from_matlab=20*log10(A_s/A_ni);

2140

COM_from_matlab=20*log10(A_s/A_ni);

2141

L=param.levels;

2141

L=param.levels;

2142

DER0=param.specBER;

2142

DER0=param.specBER;

2143

%% step 1 from slide 6 shakiba_3dj_01_230116

2143

%% step 1 from slide 6 shakiba_3dj_01_230116

2144

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2144

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2145

main=A_peak;

2145

main=A_peak;

2146

k_DER=qfuncinv(param.specBER);

2146

k_DER=qfuncinv(param.specBER);

2147

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2147

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2148

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2148

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2149

% if A_s >= A_ni

2149

% if A_s >= A_ni

2150

if 1

2150

if 1

2151

%% step 2 slide 10 shakiba_3dj_01_230116

2151

%% step 2 slide 10 shakiba_3dj_01_230116

2152

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2152

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2153

%% step 2 slide 10 not used

2153

%% step 2 slide 10 not used

2154

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2154

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2155

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2155

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2156

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2156

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2157

S_n=PSD_results.Sn_rho; % total agregate noise PSD

2157

S_n=PSD_results.Sn_rho; % total agregate noise PSD

2158

Rn=ifft(S_n)*param.fb;

2158

Rn=ifft(S_n)*param.fb;

2159

Rho_row=Rn/Rn(1);

2159

Rho_row=Rn/Rn(1);

2160

Rn_len=length(Rn);

2160

Rn_len=length(Rn);

2161

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2161

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2162

for j=1:Rn_len

2162

for j=1:Rn_len

2163

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2163

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2164

end

2164

end

2165

rho_noiseEE_row=Rho_row.*alphas_row;

2165

rho_noiseEE_row=Rho_row.*alphas_row;

2166

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2166

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2167

for j=1:Rn_len

2167

for j=1:Rn_len

2168

rho_noiseEE(j,j)=(1-alpha)^2;

2168

rho_noiseEE(j,j)=(1-alpha)^2;

2169

end

2169

end

2170

rho_noiseEE(1,1)=1;

2170

rho_noiseEE(1,1)=1;

2171

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2171

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2172

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2172

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2173

% determine complete matrix

2173

% determine complete matrix

2174

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2174

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2175

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2175

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2176

%% shakiba_3dj_elec_01a_230504 slide 17

2176

%% shakiba_3dj_elec_01a_230504 slide 17

2177

j=1:Rn_len;

2177

j=1:Rn_len;

2178

DER_MLSE=[];

2178

DER_MLSE=[];

2179

DER_MLSE_CDF=0; jj=1;

2179

DER_MLSE_CDF=0; jj=1;

2180

DER_MLSE_CDFold=0;

2180

DER_MLSE_CDFold=0;

2181

DER_delta = inf;

2181

DER_delta = inf;

2182

% slight modified for PAM4 DER vs SER

2182

% slight modified for PAM4 DER vs SER

2183

while DER_delta > .0001 && jj<=Rn_len || jj==1

2183

while DER_delta > .0001 && jj<=Rn_len || jj==1

2184

last_DER_MLSE_CDF=DER_MLSE_CDF;

2184

last_DER_MLSE_CDF=DER_MLSE_CDF;

2185

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2185

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2186

DER_MLSE_CDF= ...

2186

DER_MLSE_CDF= ...

2187

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2187

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2188

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2188

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2189

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2189

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2190

jj=jj+1;

2190

jj=jj+1;

2191

end

2191

end

2192

%% shakiba_3dj_elec_01a_230504 slide 19

2192

%% shakiba_3dj_elec_01a_230504 slide 19

2193

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2193

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2194

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2194

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2195

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2195

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2196

(L-1)/main * CDF_inv_ev(...

2196

(L-1)/main * CDF_inv_ev(...

2197

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2197

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2198

,PDF, CDF ) ...

2198

,PDF, CDF ) ...

2199

)^2;

2199

)^2;

2200

%% step 5 shakiba_3dj_01_230116 slide 13

2200

%% step 5 shakiba_3dj_01_230116 slide 13

2201

delta_com=[];

2201

delta_com=[];

2202

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2202

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2203

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2203

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2204

2204

2205

new_com_CDF=COM_from_matlab+delta_com_CDF;

2205

new_com_CDF=COM_from_matlab+delta_com_CDF;

2206

else

2206

else

2207

warning('MLSE not applied because there is more noise than signal')

2207

warning('MLSE not applied because there is more noise than signal')

2208

DER_MLSE=[];

2208

DER_MLSE=[];

2209

DER_MLSE_CDF=[];

2209

DER_MLSE_CDF=[];

2210

SNR_DFE_eqivalent=[];

2210

SNR_DFE_eqivalent=[];

2211

SNR_DFE_eqivalent_CDF=[];

2211

SNR_DFE_eqivalent_CDF=[];

2212

new_com_CDF=COM_from_matlab;

2212

new_com_CDF=COM_from_matlab;

2213

delta_com_CDF=0;

2213

delta_com_CDF=0;

2214

delta_com=0;

2214

delta_com=0;

2215

SNR_DFE=[];

2215

SNR_DFE=[];

2216

end

2216

end

2217

SNR_DFE_eqivalent=[];

2217

SNR_DFE_eqivalent=[];

2218

%%

2218

%%

2219

MLSE_results.COM_from_matlab=COM_from_matlab;

2219

MLSE_results.COM_from_matlab=COM_from_matlab;

2220

MLSE_results.SNR_DFE=SNR_DFE;

2220

MLSE_results.SNR_DFE=SNR_DFE;

2221

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2221

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2222

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2222

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2223

MLSE_results.sigma_noise=sigma_noise;

2223

MLSE_results.sigma_noise=sigma_noise;

2224

MLSE_results.SNR_dB=SNR_dB ;

2224

MLSE_results.SNR_dB=SNR_dB ;

2225

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2225

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2226

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2226

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2227

MLSE_results.COM_Gaussian=new_com_CDF;

2227

MLSE_results.COM_Gaussian=new_com_CDF;

2228

MLSE_results.COM_CDF=new_com_CDF;

2228

MLSE_results.COM_CDF=new_com_CDF;

2229

MLSE_results.k_DER=k_DER;

2229

MLSE_results.k_DER=k_DER;

2230

MLSE_results.delta_com_CDF=delta_com_CDF;

2230

MLSE_results.delta_com_CDF=delta_com_CDF;

2231

MLSE_results.delta_com_Gaussian=delta_com;

2231

MLSE_results.delta_com_Gaussian=delta_com;

2232

2232

2233

2233

2234

2234

2235

function [MLSE_results] = MLSE_U1_c_178A(param,b,A_s,A_ni,PDF,CDF,PSD_results)

2235

function [MLSE_results] = MLSE_U1_c_178A(param,b,A_s,A_ni,PDF,CDF,PSD_results)

2236

if 1

2236

if 1

2237

num_ui=param.num_ui_RXFF_noise;

2237

num_ui=param.num_ui_RXFF_noise;

2238

M=param.samples_per_ui;

2238

M=param.samples_per_ui;

2239

L=param.levels;

2239

L=param.levels;

2240

sigma_X2=(L^2-1)/(3*(L-1)^2);

2240

sigma_X2=(L^2-1)/(3*(L-1)^2);

2241

f_b=param.fb;

2241

f_b=param.fb;

2242

end

2242

end

2243

COM_from_matlab=20*log10(A_s/A_ni);

2243

COM_from_matlab=20*log10(A_s/A_ni);

2244

DER_DFE= 2*(L-1)/L*CDF_ev(A_s,PDF, CDF);

2244

DER_DFE= 2*(L-1)/L*CDF_ev(A_s,PDF, CDF);

2245

S_ni=PSD_results.Sn_rho;

2245

S_ni=PSD_results.Sn_rho;

2246

R_ni=ifft(S_ni)*f_b;

2246

R_ni=ifft(S_ni)*f_b;

2247

p_scaled_by_b=scalePDF(PDF,b(1));

2247

p_scaled_by_b=scalePDF(PDF,b(1));

2248

p_j=conv_fct(PDF,p_scaled_by_b);

2248

p_j=conv_fct(PDF,p_scaled_by_b);

2249

p_scaled_by_1mb=scalePDF(PDF,1-b(1));

2249

p_scaled_by_1mb=scalePDF(PDF,1-b(1));

2250

%

2250

%

2251

j=1; DER_MLSE=0; DER_MLSE_j= inf;

2251

j=1; DER_MLSE=0; DER_MLSE_j= inf;

2252

P_j.y=cumsum(p_j.y);

2252

P_j.y=cumsum(p_j.y);

2253

smallest_relative_change=.0001;

2253

smallest_relative_change=.0001;

2254

%% 178A–37

2254

%% 178A–37

2255

rou=R_ni'/R_ni(1);

2255

rou=R_ni'/R_ni(1);

2256

if DER_DFE <= param.DER_CDR

2256

if DER_DFE <= param.DER_CDR

2257

while j <= floor(num_ui/2) && DER_MLSE_j> DER_MLSE*smallest_relative_change

2257

while j <= floor(num_ui/2) && DER_MLSE_j> DER_MLSE*smallest_relative_change

2258

u_j=[ 1;(1-b(1))*ones(j-1,1); (-1)^(j+1)*b(1) ] ;% Eq slide (178A–38)

2258

u_j=[ 1;(1-b(1))*ones(j-1,1); (-1)^(j+1)*b(1) ] ;% Eq slide (178A–38)

2259

u_j(2:2:end-1)=-u_j(2:2:end-1);

2259

u_j(2:2:end-1)=-u_j(2:2:end-1);

2260

% V_j=toeplitz(R_ni(1:j+1).'/R_ni(1));

2260

% V_j=toeplitz(R_ni(1:j+1).'/R_ni(1));

2261

V_j=toeplitz(rou(1:j+1));

2261

V_j=toeplitz(rou(1:j+1));

2262

P_j=cumsum(p_j.y);

2262

P_j=cumsum(p_j.y);

2263

DER_MLSE_j= ((L-1)/L)^(j-1) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(1/2), p_j, P_j ) ) ; % CDF_ev is (1-CDF)

2263

DER_MLSE_j= ((L-1)/L)^(j-1) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(1/2), p_j, P_j ) ) ; % CDF_ev is (1-CDF)

2264

% DER_MLSE_j= 2*(3/4)^(j) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(0.5), p_j, P_j ) ) ; % CDF_ev is (1-CDF)

2264

% DER_MLSE_j= 2*(3/4)^(j) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(0.5), p_j, P_j ) ) ; % CDF_ev is (1-CDF)

2265

DER_MLSE=DER_MLSE+DER_MLSE_j;

2265

DER_MLSE=DER_MLSE+DER_MLSE_j;

2266

p_j=conv_fct(p_j,p_scaled_by_1mb);

2266

p_j=conv_fct(p_j,p_scaled_by_1mb);

2267

j=j+1;

2267

j=j+1;

2268

end

2268

end

2269

%% Eq (178A–36) a

2269

%% Eq (178A–36) a

2270

delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE,PDF,CDF ) )- param.Q ;% shakiba_3dj_01_2405

2270

delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE,PDF,CDF ) )- param.Q ;% shakiba_3dj_01_2405

2271

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( 2/3*DER_MLSE,PDF,CDF ) )- param.Q ;% (178A–36)

2271

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( 2/3*DER_MLSE,PDF,CDF ) )- param.Q ;% (178A–36)

2272

new_com=COM_from_matlab+delta_com;

2272

new_com=COM_from_matlab+delta_com;

2273

else

2273

else

2274

warning('MLSE not applied because the DER is less than that required for the CDR to lock')

2274

warning('MLSE not applied because the DER is less than that required for the CDR to lock')

2275

DER_MLSE=NaN;

2275

DER_MLSE=NaN;

2276

new_com=COM_from_matlab;

2276

new_com=COM_from_matlab;

2277

delta_com=0;

2277

delta_com=0;

2278

delta_com=0;

2278

delta_com=0;

2279

end

2279

end

2280

2280

2281

%%

2281

%%

2282

MLSE_results.COM_from_matlab=COM_from_matlab;

2282

MLSE_results.COM_from_matlab=COM_from_matlab;

2283

MLSE_results.DER_MLSE=DER_MLSE;

2283

MLSE_results.DER_MLSE=DER_MLSE;

2284

MLSE_results.DER_DFE=DER_DFE;

2284

MLSE_results.DER_DFE=DER_DFE;

2285

MLSE_results.COM=new_com;

2285

MLSE_results.COM=new_com;

2286

MLSE_results.delta_com=delta_com;

2286

MLSE_results.delta_com=delta_com;

2287

2287

2288

2288

2289

2289

2290

function [MLSE_results] = MLSE_U3(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2290

function [MLSE_results] = MLSE_U3(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2291

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2291

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2292

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2292

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2293

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2293

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2294

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2294

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2295

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2295

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2296

%% step 0

2296

%% step 0

2297

COM_from_matlab=20*log10(A_s/A_ni);

2297

COM_from_matlab=20*log10(A_s/A_ni);

2298

L=param.levels;

2298

L=param.levels;

2299

DER0=param.specBER;

2299

DER0=param.specBER;

2300

%% step 1 from slide 6 shakiba_3dj_01_230116

2300

%% step 1 from slide 6 shakiba_3dj_01_230116

2301

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2301

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2302

main=A_peak;

2302

main=A_peak;

2303

k_DER=qfuncinv(param.specBER);

2303

k_DER=qfuncinv(param.specBER);

2304

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2304

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2305

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2305

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2306

% if A_s >= A_ni

2306

% if A_s >= A_ni

2307

if 1

2307

if 1

2308

%% step 2 slide 10 shakiba_3dj_01_230116

2308

%% step 2 slide 10 shakiba_3dj_01_230116

2309

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2309

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2310

%% step 2 slide 10 not used

2310

%% step 2 slide 10 not used

2311

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2311

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2312

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2312

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2313

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2313

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2314

S_n=PSD_results.S_n; % total agregate noise PSD

2314

S_n=PSD_results.S_n; % total agregate noise PSD

2315

Rn=ifft(S_n)*param.fb;

2315

Rn=ifft(S_n)*param.fb;

2316

Rho_row=Rn/Rn(1);

2316

Rho_row=Rn/Rn(1);

2317

Rn_len=length(Rn);

2317

Rn_len=length(Rn);

2318

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2318

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2319

for j=1:Rn_len

2319

for j=1:Rn_len

2320

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2320

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2321

end

2321

end

2322

rho_noiseEE_row=Rho_row.*alphas_row;

2322

rho_noiseEE_row=Rho_row.*alphas_row;

2323

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2323

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2324

for j=1:Rn_len

2324

for j=1:Rn_len

2325

rho_noiseEE(j,j)=(1-alpha)^2;

2325

rho_noiseEE(j,j)=(1-alpha)^2;

2326

end

2326

end

2327

rho_noiseEE(1,1)=1;

2327

rho_noiseEE(1,1)=1;

2328

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2328

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2329

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2329

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2330

% determine complete matrix

2330

% determine complete matrix

2331

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2331

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2332

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2332

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2333

%% shakiba_3dj_elec_01a_230504 slide 17

2333

%% shakiba_3dj_elec_01a_230504 slide 17

2334

j=1:Rn_len;

2334

j=1:Rn_len;

2335

DER_MLSE=[];

2335

DER_MLSE=[];

2336

DER_MLSE_CDF=0; jj=1;

2336

DER_MLSE_CDF=0; jj=1;

2337

DER_MLSE_CDFold=0;

2337

DER_MLSE_CDFold=0;

2338

DER_delta = inf;

2338

DER_delta = inf;

2339

% slight modified for PAM4 DER vs SER

2339

% slight modified for PAM4 DER vs SER

2340

while DER_delta > .0001 && jj<=Rn_len || jj==1

2340

while DER_delta > .0001 && jj<=Rn_len || jj==1

2341

last_DER_MLSE_CDF=DER_MLSE_CDF;

2341

last_DER_MLSE_CDF=DER_MLSE_CDF;

2342

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2342

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2343

DER_MLSE_CDF= ...

2343

DER_MLSE_CDF= ...

2344

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2344

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2345

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2345

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2346

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2346

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2347

jj=jj+1;

2347

jj=jj+1;

2348

end

2348

end

2349

%% shakiba_3dj_elec_01a_230504 slide 19

2349

%% shakiba_3dj_elec_01a_230504 slide 19

2350

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2350

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2351

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2351

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2352

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2352

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2353

(L-1)/main * CDF_inv_ev(...

2353

(L-1)/main * CDF_inv_ev(...

2354

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2354

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2355

,PDF, CDF ) ...

2355

,PDF, CDF ) ...

2356

)^2;

2356

)^2;

2357

%% step 5 shakiba_3dj_01_230116 slide 13

2357

%% step 5 shakiba_3dj_01_230116 slide 13

2358

delta_com=[];

2358

delta_com=[];

2359

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2359

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2360

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2360

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2361

new_com_CDF=COM_from_matlab+delta_com_CDF;

2361

new_com_CDF=COM_from_matlab+delta_com_CDF;

2362

else

2362

else

2363

warning('MLSE not applied because there is more noise than signal')

2363

warning('MLSE not applied because there is more noise than signal')

2364

DER_MLSE=[];

2364

DER_MLSE=[];

2365

DER_MLSE_CDF=[];

2365

DER_MLSE_CDF=[];

2366

SNR_DFE_eqivalent=[];

2366

SNR_DFE_eqivalent=[];

2367

SNR_DFE_eqivalent_CDF=[];

2367

SNR_DFE_eqivalent_CDF=[];

2368

new_com_CDF=COM_from_matlab;

2368

new_com_CDF=COM_from_matlab;

2369

delta_com_CDF=0;

2369

delta_com_CDF=0;

2370

delta_com=0;

2370

delta_com=0;

2371

SNR_DFE=[];

2371

SNR_DFE=[];

2372

end

2372

end

2373

SNR_DFE_eqivalent=[];

2373

SNR_DFE_eqivalent=[];

2374

%%

2374

%%

2375

MLSE_results.COM_from_matlab=COM_from_matlab;

2375

MLSE_results.COM_from_matlab=COM_from_matlab;

2376

MLSE_results.SNR_DFE=SNR_DFE;

2376

MLSE_results.SNR_DFE=SNR_DFE;

2377

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2377

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2378

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2378

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2379

MLSE_results.sigma_noise=sigma_noise;

2379

MLSE_results.sigma_noise=sigma_noise;

2380

MLSE_results.SNR_dB=SNR_dB ;

2380

MLSE_results.SNR_dB=SNR_dB ;

2381

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2381

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2382

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2382

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2383

MLSE_results.COM_Gaussian=new_com_CDF;

2383

MLSE_results.COM_Gaussian=new_com_CDF;

2384

MLSE_results.COM_CDF=new_com_CDF;

2384

MLSE_results.COM_CDF=new_com_CDF;

2385

MLSE_results.k_DER=k_DER;

2385

MLSE_results.k_DER=k_DER;

2386

MLSE_results.delta_com_CDF=delta_com_CDF;

2386

MLSE_results.delta_com_CDF=delta_com_CDF;

2387

MLSE_results.delta_com_Gaussian=delta_com;

2387

MLSE_results.delta_com_Gaussian=delta_com;

2388

2388

2389

2389

2390

2390

2391

function [MLSE_results] = MLSE_instu(param,alpha,A_s,A_ni,PDF,CDF)

2391

function [MLSE_results] = MLSE_instu(param,alpha,A_s,A_ni,PDF,CDF)

2392

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2392

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2393

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2393

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2394

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2394

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2395

2395

2396

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2396

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2397

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2397

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2398

2398

2399

%% step 0

2399

%% step 0

2400

COM_from_matlab=20*log10(A_s/A_ni);

2400

COM_from_matlab=20*log10(A_s/A_ni);

2401

L=param.levels;

2401

L=param.levels;

2402

DER0=param.specBER;

2402

DER0=param.specBER;

2403

%% step 1 from slide 6/5

2403

%% step 1 from slide 6/5

2404

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2404

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2405

main=A_peak;

2405

main=A_peak;

2406

k_DER=qfuncinv(param.specBER);

2406

k_DER=qfuncinv(param.specBER);

2407

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2407

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2408

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2408

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2409

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2409

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2410

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2410

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2411

if A_s >= A_ni

2411

if A_s >= A_ni

2412

%% step 2 slide 10/8

2412

%% step 2 slide 10/8

2413

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2413

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2414

%% step 2 slide 10/8

2414

%% step 2 slide 10/8

2415

snr_dfe = @(der,PDF,CDF) -10*log10((A_s./CDF_inv_ev(der,PDF,CDF)).^2)+10*log10((L^2-1)/3*qfuncinv(der).^2) ;

2415

snr_dfe = @(der,PDF,CDF) -10*log10((A_s./CDF_inv_ev(der,PDF,CDF)).^2)+10*log10((L^2-1)/3*qfuncinv(der).^2) ;

2416

2416

2417

%% step 3 side 11/9

2417

%% step 3 side 11/9

2418

j=1:200;

2418

j=1:200;

2419

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2419

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2420

DER_MLSE_CDF=0; jj=1;

2420

DER_MLSE_CDF=0; jj=1;

2421

DER_delta = inf;

2421

DER_delta = inf;

2422

while DER_delta > .001

2422

while DER_delta > .001

2423

last_DER_MLSE_CDF=DER_MLSE_CDF;

2423

last_DER_MLSE_CDF=DER_MLSE_CDF;

2424

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2424

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2425

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2425

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2426

jj=jj+1;

2426

jj=jj+1;

2427

end

2427

end

2428

%%

2428

%%

2429

dscale=.05;

2429

dscale=.05;

2430

scale=1;

2430

scale=1;

2431

last_scale_tune=inf;

2431

last_scale_tune=inf;

2432

scale_tune=inf;

2432

scale_tune=inf;

2433

while abs(scale_tune) >= .1

2433

while abs(scale_tune) >= .1

2434

istart=-PDF.Min+1;

2434

istart=-PDF.Min+1;

2435

scale=scale-dscale;

2435

scale=scale-dscale;

2436

PDF_SCALED = scalePDF(PDF,scale);

2436

PDF_SCALED = scalePDF(PDF,scale);

2437

cdf_scaled=pdf_to_cdf(PDF_SCALED);

2437

cdf_scaled=pdf_to_cdf(PDF_SCALED);

2438

test_snr=snr_dfe(DER_MLSE_CDF,PDF_SCALED,cdf_scaled.y);

2438

test_snr=snr_dfe(DER_MLSE_CDF,PDF_SCALED,cdf_scaled.y);

2439

test_DER=2*(L-1)/L* (CDF_ev(main/(L-1),PDF_SCALED,cdf_scaled.y) );

2439

test_DER=2*(L-1)/L* (CDF_ev(main/(L-1),PDF_SCALED,cdf_scaled.y) );

2440

scale_tune=(test_DER-DER_MLSE_CDF)/DER_MLSE_CDF;

2440

scale_tune=(test_DER-DER_MLSE_CDF)/DER_MLSE_CDF;

2441

if sign(scale_tune) ~= sign(last_scale_tune)

2441

if sign(scale_tune) ~= sign(last_scale_tune)

2442

% scale=scale+dscale % back up

2442

% scale=scale+dscale % back up

2443

dscale=-dscale/2;

2443

dscale=-dscale/2;

2444

end

2444

end

2445

last_scale_tune=scale_tune;

2445

last_scale_tune=scale_tune;

2446

end

2446

end

2447

new_com_CDF=10*log10((A_s./CDF_inv_ev(DER0,PDF_SCALED,cdf_scaled.y)).^2);

2447

new_com_CDF=10*log10((A_s./CDF_inv_ev(DER0,PDF_SCALED,cdf_scaled.y)).^2);

2448

delta_com=new_com_CDF-10*log10((A_s./CDF_inv_ev(DER0,PDF,CDF)).^2);

2448

delta_com=new_com_CDF-10*log10((A_s./CDF_inv_ev(DER0,PDF,CDF)).^2);

2449

else

2449

else

2450

warning('MLSE not applied because there is more noise than signal')

2450

warning('MLSE not applied because there is more noise than signal')

2451

DER_MLSE=[];

2451

DER_MLSE=[];

2452

DER_MLSE_CDF=[];

2452

DER_MLSE_CDF=[];

2453

SNR_DFE_eqivalent=[];

2453

SNR_DFE_eqivalent=[];

2454

SNR_DFE_eqivalent_CDF=[];

2454

SNR_DFE_eqivalent_CDF=[];

2455

new_com_CDF=COM_from_matlab;

2455

new_com_CDF=COM_from_matlab;

2456

delta_com_CDF=0;

2456

delta_com_CDF=0;

2457

delta_com=0;

2457

delta_com=0;

2458

SNR_DFE=[];

2458

SNR_DFE=[];

2459

PDF_SCALED=[];

2459

PDF_SCALED=[];

2460

cdf_scaled=[];

2460

cdf_scaled=[];

2461

end

2461

end

2462

2462

2463

%%

2463

%%

2464

MLSE_results.COM_from_matlab=COM_from_matlab;

2464

MLSE_results.COM_from_matlab=COM_from_matlab;

2465

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2465

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2466

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2466

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2467

MLSE_results.sigma_noise=sigma_noise;

2467

MLSE_results.sigma_noise=sigma_noise;

2468

MLSE_results.k_DER=k_DER;

2468

MLSE_results.k_DER=k_DER;

2469

MLSE_results.COM_CDF=new_com_CDF;

2469

MLSE_results.COM_CDF=new_com_CDF;

2470

MLSE_results.delta_com_CDF=delta_com;

2470

MLSE_results.delta_com_CDF=delta_com;

2471

MLSE_results.delta_com_Gaussian=delta_com;

2471

MLSE_results.delta_com_Gaussian=delta_com;

2472

MLSE_results.PDF=PDF_SCALED;

2472

MLSE_results.PDF=PDF_SCALED;

2473

MLSE_results.CDF=cdf_scaled.y;

2473

MLSE_results.CDF=cdf_scaled.y;

2474

MLSE_results.PDF_scale=scale;

2474

MLSE_results.PDF_scale=scale;

2475

2475

2476

2476

2477

2477

2478

2478

2479

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2479

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2480

if 1

2480

if 1

2481

num_ui=param.num_ui_RXFF_noise;

2481

num_ui=param.num_ui_RXFF_noise;

2482

M=param.samples_per_ui;

2482

M=param.samples_per_ui;

2483

L=param.levels;

2483

L=param.levels;

2484

sigma_X2=(L^2-1)/(3*(L-1)^2);

2484

sigma_X2=(L^2-1)/(3*(L-1)^2);

2485

fb=param.fb;

2485

fb=param.fb;

2486

R_LM=param.R_LM;

2486

R_LM=param.R_LM;

2487

end

2487

end

2488

% h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2488

% h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2489

% h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2489

% h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2490

% h=reshape(h,1,[]); % make row vectors

2490

% h=reshape(h,1,[]); % make row vectors

2491

% h=[ h(1:floor(length(h)/M)*M) ];

2491

% h=[ h(1:floor(length(h)/M)*M) ];

2492

% h= [h zeros(1,num_ui*M-length(h)) ];

2492

% h= [h zeros(1,num_ui*M-length(h)) ];

2493

% h=h(1:M:end);% resample

2493

% h=h(1:M:end);% resample

2494

% N=length(h);

2494

% N=length(h);

2495

% dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2495

% dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2496

% dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2496

% dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2497

2498

samp_idx = (mod(cursor_i-1,M )+1):M:length(sbr);

2497

samp_idx = (mod(cursor_i-1,M )+1):M:length(sbr);

2499

dh= find(samp_idx == cursor_i)-1;

2498

dh= find(samp_idx == cursor_i)-1;

2500

dw=param.RxFFE_cmx;

2499

dw=param.RxFFE_cmx;

2501

h = reshape(sbr(samp_idx),1,[]); % make row vector

2500

h = reshape(sbr(samp_idx),1,[]); % make row vector

2502

h(end+1:num_ui)=0;

2501

h(end+1:num_ui)=0;

2503

h = h(1:num_ui); % h needs to have num_ui points

2502

h = h(1:num_ui); % h needs to have num_ui points

2504

N=length(h); % used in subsequent expressions

2503

N=length(h); % used in subsequent expressions

2505

2506

if param.N_bg == 0

2504

if param.N_bg == 0

2507

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2505

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2508

bmax=param.bmax;

2506

bmax=param.bmax;

2509

bmin=param.bmin ;

2507

bmin=param.bmin ;

2510

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2508

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2511

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2509

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2512

idx=[];

2510

idx=[];

2513

else

2511

else

2514

Nfloating_taps=param.N_bf*param.N_bg;

2512

Nfloating_taps=param.N_bf*param.N_bg;

2515

Nmax=param.N_bmax;

2513

Nmax=param.N_bmax;

2516

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2514

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2517

Ng=param.N_bg;

2515

Ng=param.N_bg;

2518

Nf=param.N_bf;

2516

Nf=param.N_bf;

2519

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2517

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2520

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2518

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2521

% hisi=h(dh+2:((dh-dw)+Nw));

2519

% hisi=h(dh+2:((dh-dw)+Nw));

2522

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2520

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2523

% idx=sort(idx);

2521

% idx=sort(idx);

2524

bmax=param.bmax;

2522

bmax=param.bmax;

2525

bmin=param.bmin ;

2523

bmin=param.bmin ;

2526

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ones(1,Nfloating_taps)*param.bmaxg ];

2524

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ones(1,Nfloating_taps)*param.bmaxg ];

2527

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max -ones(1,Nfloating_taps)*param.bmaxg ];

2525

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max -ones(1,Nfloating_taps)*param.bmaxg ];

2528

end

2526

end

2529

Nb=param.ndfe; % DFE taps

2527

Nb=param.ndfe; % DFE taps

2530

d=dw+dh; % used for index in algorithms

2528

d=dw+dh; % used for index in algorithms

2531

indx(1:N)=(1:N)-dh-1;

2529

indx(1:N)=(1:N)-dh-1;

2532

S_n=PSD_results.S_n; % total agregate noise PSD

2530

S_n=PSD_results.S_n; % total agregate noise PSD

2533

Rn=ifft(S_n)*fb;

2531

Rn=ifft(S_n)*fb;

2534

%% HH and R

2532

%% HH and R

2535

2533

2536

%Test routine finding rxffe floating taps using best FOM for each bank

2534

%Test routine finding rxffe floating taps using best FOM for each bank

2537

isi_start = dh+2;

2535

isi_start = dh+2;

2538

isi_end = (dh-dw)+Nw;

2536

isi_end = (dh-dw)+Nw;

2539

2540

%check for num_ui too small

2541

if isi_end > length(h)

2542

error('num_ui_RXFF_noise (%d) is too small',num_ui);

2543

end

2544

2545

hc1=[ h zeros(1,Nw-1) ];

2537

hc1=[ h zeros(1,Nw-1) ];

2546

hr1=[ h(1) zeros(1,Nw-1)];

2538

hr1=[ h(1) zeros(1,Nw-1)];

2547

H=toeplitz(hc1,hr1);

2539

H=toeplitz(hc1,hr1);

2548

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2540

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2549

if param.N_bg ~= 0

2541

if param.N_bg ~= 0

2550

switch lower(OP.RXFFE_FLOAT_CTL)

2542

switch lower(OP.RXFFE_FLOAT_CTL)

2551

case 'isi'

2543

case 'isi'

2552

hisi=h(dh+2:((dh-dw)+Nw));

2544

hisi=h(dh+2:((dh-dw)+Nw));

2553

[idx]=findbankloc( hisi ,param.RxFFE_cpx+1,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2545

[idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2554

idx=sort(idx);

2546

idx=sort(idx);

2555

otherwise

2547

otherwise

2556

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2548

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2557

idx=sort(idx);

2549

idx=sort(idx);

2558

end

2550

end

2559

end

2551

end

2560

[sigma_e,FOM,w,idx] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx);

2552

[sigma_e,FOM,w,idx] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx);

2561

MMSE_results.sigma_e=sigma_e; %

2553

MMSE_results.sigma_e=sigma_e; %

2562

MMSE_results.FOM=FOM;

2554

MMSE_results.FOM=FOM;

2563

Craw=w/w(dw+1); % returned Rx FFE taps

2555

Craw=w/w(dw+1); % returned Rx FFE taps

2564

% re-align Cmod to floating tap locations

2556

% re-align Cmod to floating tap locations

2565

if param.N_bg ~= 0

2557

if param.N_bg ~= 0

2566

C=Craw;

2558

C=Craw;

2567

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2559

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2568

C(idx+param.RxFFE_cmx+1 )=Craw(Nfix+(1:Nfloating_taps));

2560

C(idx-param.N_tail_start+1+Nfix)=Craw(Nfix+(1:Nfloating_taps));

2569

else

2561

else

2570

C=Craw;

2562

C=Craw;

2571

end

2563

end

2572

MMSE_results.floating_tap_locations=idx + param.RxFFE_cmx+1;

2564

MMSE_results.floating_tap_locations=idx-param.N_tail_start+1+Nfix;

2573

MMSE_results.C=C;

2565

MMSE_results.C=C;

2574

2566

2575

2567

2576

2568

2577

2569

2578

function [sigma_e,FOM,w,idx,Nw] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2570

function [sigma_e,FOM,w,idx,Nw] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2579

if isempty(idx)

2571

if isempty(idx)

2580

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2572

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2581

bmax=param.bmax;

2573

bmax=param.bmax;

2582

bmin=param.bmin ;

2574

bmin=param.bmin ;

2583

else

2575

else

2584

Nfloating_taps=param.N_bf*param.N_bg;

2576

Nfloating_taps=param.N_bf*param.N_bg;

2585

%If using the routine that finds RXFFE floating taps bank-by-bank, the number of total floating taps can be less than the final amount

2577

%If using the routine that finds RXFFE floating taps bank-by-bank, the number of total floating taps can be less than the final amount

2586

Nfloating_taps = length(idx);

2578

Nfloating_taps = length(idx);

2587

Nmax=param.N_bmax;

2579

Nmax=param.N_bmax;

2588

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2580

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2589

Ng=param.N_bg;

2581

Ng=param.N_bg;

2590

Nf=param.N_bf;

2582

Nf=param.N_bf;

2591

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2583

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2592

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2584

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2593

end

2585

end

2594

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2586

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2595

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2587

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2596

% hc1=[ h zeros(1,Nw-1) ];

2588

% hc1=[ h zeros(1,Nw-1) ];

2597

% hr1=[ h(1) zeros(1,Nw-1)];

2589

% hr1=[ h(1) zeros(1,Nw-1)];

2598

% H=toeplitz(hc1,hr1);

2590

% H=toeplitz(hc1,hr1);

2599

2591

2600

if param.N_bg ~= 0

2592

if param.N_bg ~= 0

2601

H=H( :,[1:Nfix idx+param.RxFFE_cmx+1 ]);

2593

H=H( :,[1:Nfix idx-param.N_tail_start+1+Nfix]); % from Tobey (Pei-Rong Li 02/28/2024)

2602

end

2594

end

2603

%% HH and R

2595

%% HH and R

2604

HH= H'*H;

2596

HH= H'*H;

2605

if param.N_bg ~= 0

2597

if param.N_bg ~= 0

2606

Rnn=Rnn( [1:Nfix idx+param.RxFFE_cmx+1],[1:Nfix idx+param.RxFFE_cmx+1]);

2598

Rnn=Rnn( [1:Nfix idx-param.N_tail_start+1+Nfix],[1:Nfix idx-param.N_tail_start+1+Nfix]);

2607

end

2599

end

2608

R=HH+Rnn/sigma_X2;

2600

R=HH+Rnn/sigma_X2;

2609

%% hb and h0

2601

%% hb and h0

2610

Hb= H(d+2:d+Nb+1,:);

2602

Hb= H(d+2:d+Nb+1,:);

2611

h0=H(d+1,:);

2603

h0=H(d+1,:);

2612

% display(floor(h0));

2604

% display(floor(h0));

2613

2605

2614

%% Ib and zb (slide 10)

2606

%% Ib and zb (slide 10)

2615

ib=eye(Nb);

2607

ib=eye(Nb);

2616

zb=zeros(1,Nb);

2608

zb=zeros(1,Nb);

2617

wbl= [ R -Hb' -h0';...

2609

wbl= [ R -Hb' -h0';...

2618

-Hb ib zb'; ...

2610

-Hb ib zb'; ...

2619

h0 zb 0]\[h0'; zb' ;1];

2611

h0 zb 0]\[h0'; zb' ;1];

2620

2612

2621

%% re-adjust Nw to number of used taps

2613

%% re-adjust Nw to number of used taps

2622

if param.N_bg ~= 0

2614

if param.N_bg ~= 0

2623

Nw=Nwft;

2615

Nw=Nwft;

2624

end

2616

end

2625

%% check equalized pulse

2617

%% check equalized pulse

2626

w=wbl(1:Nw);

2618

w=wbl(1:Nw);

2627

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2619

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2628

2620

2629

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2621

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2630

blim = min(bmax(:), max(bmin(:), b));

2622

blim = min(bmax(:), max(bmin(:), b));

2631

if (Nb > 0) && ~isequal(b, blim)

2623

if (Nb > 0) && ~isequal(b, blim)

2632

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2624

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2633

w = wl(1:Nw);

2625

w = wl(1:Nw);

2634

end

2626

end

2635

2627

2636

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2628

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2637

%so need to chop off the extra indices on wmax and wmin

2629

%so need to chop off the extra indices on wmax and wmin

2638

if length(w)<length(wmax)

2630

if length(w)<length(wmax)

2639

wmax=wmax(1:length(w));

2631

wmax=wmax(1:length(w));

2640

wmin=wmin(1:length(w));

2632

wmin=wmin(1:length(w));

2641

end

2633

end

2642

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2634

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2643

if ~isequal(w, wlim)

2635

if ~isequal(w, wlim)

2644

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2636

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2645

if Nb > 0

2637

if Nb > 0

2646

b = Hb*wlim; % Update the feedback coefficients.

2638

b = Hb*wlim; % Update the feedback coefficients.

2647

blim = min(bmax(:), max(bmin(:), b));

2639

blim = min(bmax(:), max(bmin(:), b));

2648

end

2640

end

2649

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2641

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2650

% wl = wl(1:Nw);

2642

% wl = wl(1:Nw);

2651

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2643

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2652

end

2644

end

2653

% w=w(1:Nw) ;

2645

% w=w(1:Nw) ;

2654

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2646

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2655

w=wlim;

2647

w=wlim;

2656

b=blim;

2648

b=blim;

2657

sigma_e=sqrt(sigma_X2*(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b)); % Commit request 4p4_5 from healey_3dj_COM_01_240416

2649

sigma_e=sqrt(sigma_X2*(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b)); % Commit request 4p4_5 from healey_3dj_COM_01_240416

2658

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2650

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2659

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2651

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2660

2652

2661

%not all output_args are filled here but most are

2653

%not all output_args are filled here but most are

2662

2654

2663

switch lower(OP.TDECQ)

2655

switch lower(OP.TDECQ)

2664

case { false 'none' } % should be the default

2656

case { false 'none' } % should be the default

2665

output_args.VMA=[];

2657

output_args.VMA=[];

2666

case 'vma'

2658

case 'vma'

2667

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2659

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2668

output_args.VMA=est_vma.VMA;

2660

output_args.VMA=est_vma.VMA;

2669

otherwise

2661

otherwise

2670

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2662

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2671

end

2663

end

2672

2664

2673

fileset_str=str2csv({chdata.base});

2665

fileset_str=str2csv({chdata.base});

2674

output_args.file_names=sprintf('"%s"', fileset_str);

2666

output_args.file_names=sprintf('"%s"', fileset_str);

2675

% [ahealey] Echo the termination parameters in the output arguments..

2667

% [ahealey] Echo the termination parameters in the output arguments..

2676

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2668

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2677

output_args.(odt_param{:}) = param.(odt_param{:});

2669

output_args.(odt_param{:}) = param.(odt_param{:});

2678

end

2670

end

2679

% [ahealey] End of modifications.

2671

% [ahealey] End of modifications.

2680

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2672

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2681

output_args.(pkg_params{:})= param.(pkg_params{:});

2673

output_args.(pkg_params{:})= param.(pkg_params{:});

2682

end

2674

end

2683

output_args.baud_rate_GHz=param.fb/1e9;

2675

output_args.baud_rate_GHz=param.fb/1e9;

2684

output_args.f_Nyquist_GHz = param.fb/2e9;

2676

output_args.f_Nyquist_GHz = param.fb/2e9;

2685

output_args.BER=param.specBER;

2677

output_args.BER=param.specBER;

2686

output_args.FOM = fom_result.FOM;

2678

output_args.FOM = fom_result.FOM;

2687

output_args.sigma_N=Noise_Struct.sigma_N;

2679

output_args.sigma_N=Noise_Struct.sigma_N;

2688

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2680

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2689

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2681

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2690

output_args.tail_RSS=fom_result.tail_RSS;

2682

output_args.tail_RSS=fom_result.tail_RSS;

2691

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2683

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2692

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2684

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2693

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2685

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2694

try

2686

try

2695

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2687

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2696

catch

2688

catch

2697

output_args.uneq_FIR_peak_time=[];

2689

output_args.uneq_FIR_peak_time=[];

2698

end

2690

end

2699

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2691

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2700

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2692

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2701

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2693

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2702

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2694

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2703

2695

2704

if OP.RX_CALIBRATION== 1

2696

if OP.RX_CALIBRATION== 1

2705

output_args.sigma_bn=sigma_bn;

2697

output_args.sigma_bn=sigma_bn;

2706

else

2698

else

2707

output_args.sigma_bn=[];

2699

output_args.sigma_bn=[];

2708

end

2700

end

2709

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2701

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2710

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2702

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2711

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2703

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2712

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2704

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2713

2705

2714

if OP.RX_CALIBRATION == 0

2706

if OP.RX_CALIBRATION == 0

2715

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2707

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2716

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2708

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2717

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2709

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2718

else

2710

else

2719

output_args.peak_MDXTK_interference_at_BER_mV=[];

2711

output_args.peak_MDXTK_interference_at_BER_mV=[];

2720

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2712

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2721

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2713

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2722

end

2714

end

2723

%output_args.ICN_mV=ICN*1000;

2715

%output_args.ICN_mV=ICN*1000;

2724

% output_args.ICN_test_mV=ICN_test*1000;

2716

% output_args.ICN_test_mV=ICN_test*1000;

2725

xtk=param.num_next+param.num_fext;

2717

xtk=param.num_next+param.num_fext;

2726

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2718

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2727

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2719

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2728

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2720

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2729

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2721

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2730

else

2722

else

2731

output_args.MDNEXT_ICN_92_46_mV=0;

2723

output_args.MDNEXT_ICN_92_46_mV=0;

2732

output_args.MDFEXT_ICN_92_47_mV=0;

2724

output_args.MDFEXT_ICN_92_47_mV=0;

2733

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2725

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2734

end

2726

end

2735

%output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(A_s/(peak_interference_at_BER/qfuncinv(param.specBER))); modified by Yasuo Hidaka, 8/7/17

2727

%output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(A_s/(peak_interference_at_BER/qfuncinv(param.specBER))); modified by Yasuo Hidaka, 8/7/17

2736

if 1

2728

if 1

2737

output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(COM_SNR_Struct.A_s/(Noise_Struct.peak_interference_at_BER/sqrt(2)/erfcinv(2*param.specBER)));

2729

output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(COM_SNR_Struct.A_s/(Noise_Struct.peak_interference_at_BER/sqrt(2)/erfcinv(2*param.specBER)));

2738

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2730

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2739

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2731

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2740

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2732

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2741

end

2733

end

2742

2734

2743

2735

2744

switch param.CTLE_type

2736

switch param.CTLE_type

2745

case 'CL93'

2737

case 'CL93'

2746

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2738

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2747

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2739

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2748

output_args.g_DC_HP=[];

2740

output_args.g_DC_HP=[];

2749

output_args.HP_poles_zero=[];

2741

output_args.HP_poles_zero=[];

2750

case 'CL120d'

2742

case 'CL120d'

2751

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2743

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2752

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2744

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2753

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2745

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2754

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2746

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2755

case 'CL120e'

2747

case 'CL120e'

2756

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.f_HP_Z(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle) param.f_HP_P(fom_result.ctle)];

2748

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.f_HP_Z(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle) param.f_HP_P(fom_result.ctle)];

2757

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2749

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2758

output_args.g_DC_HP=[];

2750

output_args.g_DC_HP=[];

2759

output_args.HP_poles_zero=[];

2751

output_args.HP_poles_zero=[];

2760

end

2752

end

2761

output_args.TXLE_taps=fom_result.txffe;

2753

output_args.TXLE_taps=fom_result.txffe;

2762

if length(output_args.TXLE_taps) >= 3

2754

if length(output_args.TXLE_taps) >= 3

2763

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2755

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2764

else

2756

else

2765

output_args.Pre2Pmax=[];

2757

output_args.Pre2Pmax=[];

2766

end

2758

end

2767

output_args.DFE_taps=fom_result.DFE_taps;

2759

output_args.DFE_taps=fom_result.DFE_taps;

2768

if param.Floating_DFE || param.Floating_RXFFE

2760

if param.Floating_DFE || param.Floating_RXFFE

2769

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2761

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2770

else

2762

else

2771

output_args.floating_tap_locations=[];

2763

output_args.floating_tap_locations=[];

2772

end

2764

end

2773

2765

2774

if OP.RxFFE

2766

if OP.RxFFE

2775

output_args.RxFFE=fom_result.RxFFE;

2767

output_args.RxFFE=fom_result.RxFFE;

2776

output_args.RxFFEgain=param.current_ffegain;

2768

output_args.RxFFEgain=param.current_ffegain;

2777

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2769

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2778

output_args.RxFFE=[];

2770

output_args.RxFFE=[];

2779

output_args.RxFFEgain=[];

2771

output_args.RxFFEgain=[];

2780

end

2772

end

2781

2773

2782

output_args.itick=fom_result.itick;

2774

output_args.itick=fom_result.itick;

2783

2775

2784

% Calculation of error propagation and burst probability

2776

% Calculation of error propagation and burst probability

2785

if OP.nburst>0

2777

if OP.nburst>0

2786

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2778

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2787

output_args.error_propagation_probability = p_error_propagation;

2779

output_args.error_propagation_probability = p_error_propagation;

2788

output_args.burst_probabilities = p_burst;

2780

output_args.burst_probabilities = p_burst;

2789

else

2781

else

2790

output_args.error_propagation_probability = [];

2782

output_args.error_propagation_probability = [];

2791

output_args.burst_probabilities = [];

2783

output_args.burst_probabilities = [];

2792

end

2784

end

2793

2785

2794

2786

2795

%begin yasuo patch 12/11/2018

2787

%begin yasuo patch 12/11/2018

2796

% collect sigma values to report

2788

% collect sigma values to report

2797

% pdf2sgm() is a function to calculate sigma value from PDF

2789

% pdf2sgm() is a function to calculate sigma value from PDF

2798

% It is added at the end of this file code.

2790

% It is added at the end of this file code.

2799

% I am not sure if an equivalent function already exists.

2791

% I am not sure if an equivalent function already exists.

2800

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2792

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2801

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2793

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2802

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2794

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2803

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2795

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2804

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2796

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2805

output_args.sgm_G = Noise_Struct.sigma_G;

2797

output_args.sgm_G = Noise_Struct.sigma_G;

2806

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2798

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2807

output_args.sgm_N = Noise_Struct.sigma_N;

2799

output_args.sgm_N = Noise_Struct.sigma_N;

2808

output_args.sgm_TX = Noise_Struct.sigma_TX;

2800

output_args.sgm_TX = Noise_Struct.sigma_TX;

2809

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2801

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2810

if OP.RX_CALIBRATION == 0

2802

if OP.RX_CALIBRATION == 0

2811

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2803

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2812

else

2804

else

2813

output_args.sgm_xt=[];

2805

output_args.sgm_xt=[];

2814

end

2806

end

2815

% end yasuo patch

2807

% end yasuo patch

2816

2808

2817

% r259 putting COM, VEO and loss last in report

2809

% r259 putting COM, VEO and loss last in report

2818

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2810

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2819

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2811

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2820

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2812

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2821

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2813

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2822

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2814

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2823

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2815

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2824

output_args.VEO_window_mUI= param.T_O;

2816

output_args.VEO_window_mUI= param.T_O;

2825

else

2817

else

2826

output_args.EW_UI_est=[];

2818

output_args.EW_UI_est=[];

2827

output_args.eye_contour=[];

2819

output_args.eye_contour=[];

2828

output_args.VEO_window_mUI= [];

2820

output_args.VEO_window_mUI= [];

2829

end

2821

end

2830

2822

2831

if sum(param.AC_CM_RMS) ~= 0

2823

if sum(param.AC_CM_RMS) ~= 0

2832

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2824

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2833

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2825

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2834

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2826

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2835

else

2827

else

2836

output_args.sigma_ACCM_at_tp0_mV=[];

2828

output_args.sigma_ACCM_at_tp0_mV=[];

2837

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2829

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2838

end

2830

end

2839

if OP.MLSE

2831

if OP.MLSE

2840

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2832

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2841

output_args.delta_COM = COM_SNR_Struct.delta_COM;

2833

output_args.delta_COM = COM_SNR_Struct.delta_COM;

2842

output_args.DER_DFE= COM_SNR_Struct.DER_DFE;

2834

output_args.DER_DFE= COM_SNR_Struct.DER_DFE;

2843

output_args.DER_MLSE= COM_SNR_Struct.DER_MLSE;

2835

output_args.DER_MLSE= COM_SNR_Struct.DER_MLSE;

2844

if strcmpi(upper(OP.PHY),'C2M')

2836

if strcmpi(upper(OP.PHY),'C2M')

2845

output_args.VEC_dB_orig= COM_SNR_Struct.VEC_dB_orig;

2837

output_args.VEC_dB_orig= COM_SNR_Struct.VEC_dB_orig;

2846

output_args.delta_VEC = COM_SNR_Struct.delta_VEC;

2838

output_args.delta_VEC = COM_SNR_Struct.delta_VEC;

2847

output_args.VEC_dB_orig = COM_SNR_Struct.VEC_dB_orig;

2839

output_args.VEC_dB_orig = COM_SNR_Struct.VEC_dB_orig;

2848

output_args.VEC_dB= COM_SNR_Struct.VEC_dB;

2840

output_args.VEC_dB= COM_SNR_Struct.VEC_dB;

2849

end

2841

end

2850

end

2842

end

2851

%

2843

%

2852

output_args.COM_dB=COM_SNR_Struct.COM;

2844

output_args.COM_dB=COM_SNR_Struct.COM;

2853

% end yasuo patch

2845

% end yasuo patch

2854

% begin yasuo patch 3/18/2019

2846

% begin yasuo patch 3/18/2019

2855

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2847

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2856

% end yasuo patch

2848

% end yasuo patch

2857

function [ seq syms syms_nrz ] = PRBS13Q( )

2849

function [ seq syms syms_nrz ] = PRBS13Q( )

2858

%UNTITLED Summary of this function goes here

2850

%UNTITLED Summary of this function goes here

2859

% Detailed explanation goes here

2851

% Detailed explanation goes here

2860

2852

2861

2853

2862

taps = ([13 12 2 1]);

2854

taps = ([13 12 2 1]);

2863

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2855

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2864

[seq_nrz c] =LFSR(seed,taps);

2856

[seq_nrz c] =LFSR(seed,taps);

2865

seq_nrz=2*(seq_nrz-0.5);

2857

seq_nrz=2*(seq_nrz-0.5);

2866

seq=pam(seq_nrz);

2858

seq=pam(seq_nrz);

2867

% syms=round(2*(seq+1));

2859

% syms=round(2*(seq+1));

2868

syms((round(2*(seq+1))/2==2))=3;

2860

syms((round(2*(seq+1))/2==2))=3;

2869

syms((round(2*(seq+1))/2==1.5))=2;

2861

syms((round(2*(seq+1))/2==1.5))=2;

2870

syms((round(2*(seq+1))/2==.5))=1;

2862

syms((round(2*(seq+1))/2==.5))=1;

2871

syms((round(2*(seq+1))/2==0))=0;

2863

syms((round(2*(seq+1))/2==0))=0;

2872

2864

2873

% syms_nrz=((seq_nrz+1)/2);

2865

% syms_nrz=((seq_nrz+1)/2);

2874

2866

2875

syms_nrz=seq_nrz;

2867

syms_nrz=seq_nrz;

2876

2868

2877

2869

2878

function[seq c]=LFSR(s,t)

2870

function[seq c]=LFSR(s,t)

2879

%s=initial state of LFSR, you can choose any lenght of LFSR

2871

%s=initial state of LFSR, you can choose any lenght of LFSR

2880

%Instruction:==========

2872

%Instruction:==========

2881

%Save LFSR.m in your current directory and type following

2873

%Save LFSR.m in your current directory and type following

2882

%on Command window for simulating 5 bit LFSR with tap [5 2]

2874

%on Command window for simulating 5 bit LFSR with tap [5 2]

2883

%---------------------

2875

%---------------------

2884

%>>s=[1 1 0 0 1]

2876

%>>s=[1 1 0 0 1]

2885

%>>t=[5 2]

2877

%>>t=[5 2]

2886

%>>[seq c] =LFSR(s,t)

2878

%>>[seq c] =LFSR(s,t)

2887

%---------------------------

2879

%---------------------------

2888

%seq = generated sequence

2880

%seq = generated sequence

2889

%c will be matrix containing the states of LFSR raw wise

2881

%c will be matrix containing the states of LFSR raw wise

2890

%

2882

%

2891

%-----------------------------------------------------------

2883

%-----------------------------------------------------------

2892

%If any doubt, confusion or feedback please contact me

2884

%If any doubt, confusion or feedback please contact me

2893

% NIKESH BAJAJ

2885

% NIKESH BAJAJ

2894

% bajaj.nikkey@gmail.com (+91-9915522564)

2886

% bajaj.nikkey@gmail.com (+91-9915522564)

2895

% Asst. Professor at Lovely Profesional University

2887

% Asst. Professor at Lovely Profesional University

2896

% Masters from Aligarh Muslim University,INDIA

2888

% Masters from Aligarh Muslim University,INDIA

2897

%--------------------------------------------------

2889

%--------------------------------------------------

2898

n=length(s);

2890

n=length(s);

2899

c(1,:)=s;

2891

c(1,:)=s;

2900

m=length(t);

2892

m=length(t);

2901

for k=1:2^n-2;

2893

for k=1:2^n-2;

2902

b(1)=xor(s(t(1)), s(t(2)));

2894

b(1)=xor(s(t(1)), s(t(2)));

2903

if m>2;

2895

if m>2;

2904

for i=1:m-2;

2896

for i=1:m-2;

2905

b(i+1)=xor(s(t(i+2)), b(i));

2897

b(i+1)=xor(s(t(i+2)), b(i));

2906

end

2898

end

2907

end

2899

end

2908

j=1:n-1;

2900

j=1:n-1;

2909

s(n+1-j)=s(n-j);

2901

s(n+1-j)=s(n-j);

2910

s(1)=b(m-1);

2902

s(1)=b(m-1);

2911

c(k+1,:)=s;

2903

c(k+1,:)=s;

2912

end

2904

end

2913

seq=c(:,n)';

2905

seq=c(:,n)';

2914

2906

2915

function [ dataout ] = pam( data )

2907

function [ dataout ] = pam( data )

2916

% mapping data usng Grey Coding

2908

% mapping data usng Grey Coding

2917

for i=1:2:floor(length(data)/2)*2

2909

for i=1:2:floor(length(data)/2)*2

2918

if data(i:i+1)==[ -1 -1 ]

2910

if data(i:i+1)==[ -1 -1 ]

2919

dataout(ceil(i/2)) = -1;

2911

dataout(ceil(i/2)) = -1;

2920

elseif data(i:i+1)==[ -1 1 ]

2912

elseif data(i:i+1)==[ -1 1 ]

2921

dataout(ceil(i/2)) = -1/3;

2913

dataout(ceil(i/2)) = -1/3;

2922

elseif data(i:i+1)==[ 1 1 ]

2914

elseif data(i:i+1)==[ 1 1 ]

2923

dataout(ceil(i/2)) = 1/3;

2915

dataout(ceil(i/2)) = 1/3;

2924

elseif data(i:i+1)==[ 1 -1 ]

2916

elseif data(i:i+1)==[ 1 -1 ]

2925

dataout(ceil(i/2)) = 1;

2917

dataout(ceil(i/2)) = 1;

2926

end

2918

end

2927

end

2919

end

2928

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2920

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2929

db = @(x) 20*log10(abs(x));

2921

db = @(x) 20*log10(abs(x));

2930

disp('computing TD_RILN...')

2922

disp('computing TD_RILN...')

2931

sdd21=squeeze(sdd21);

2923

sdd21=squeeze(sdd21);

2932

if iscolumn(sdd21)

2924

if iscolumn(sdd21)

2933

sdd21=sdd21.';

2925

sdd21=sdd21.';

2934

end

2926

end

2935

RIL=squeeze(RIL);

2927

RIL=squeeze(RIL);

2936

if iscolumn(RIL)

2928

if iscolumn(RIL)

2937

RIL=RIL.';

2929

RIL=RIL.';

2938

end

2930

end

2939

print_for_codereview=1;

2931

print_for_codereview=1;

2940

if exist('OP','var')

2932

if exist('OP','var')

2941

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2933

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2942

2934

2943

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2935

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2944

H_bw=Butterworth_Filter(param,faxis_f2,1);

2936

H_bw=Butterworth_Filter(param,faxis_f2,1);

2945

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2937

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2946

H_tw=Tukey_Window(faxis_f2,param);

2938

H_tw=Tukey_Window(faxis_f2,param);

2947

H_tw=ones(1,length(faxis_f2) );

2939

H_tw=ones(1,length(faxis_f2) );

2948

[RILN_TD_struct.REF.FIR, ...

2940

[RILN_TD_struct.REF.FIR, ...

2949

RILN_TD_struct.REF.t, ...

2941

RILN_TD_struct.REF.t, ...

2950

RILN_TD_struct.REF.causality_correction_dB, ...

2942

RILN_TD_struct.REF.causality_correction_dB, ...

2951

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2943

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2952

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2944

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2953

[RILN_TD_struct.FIT.FIR, ...

2945

[RILN_TD_struct.FIT.FIR, ...

2954

RILN_TD_struct.FIT.t, ...

2946

RILN_TD_struct.FIT.t, ...

2955

RILN_TD_struct.FIT.causality_correction_dB, ...

2947

RILN_TD_struct.FIT.causality_correction_dB, ...

2956

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2948

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2957

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2949

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2958

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2950

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2959

NrangeUI=1000;

2951

NrangeUI=1000;

2960

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2952

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2961

range=ipeak:range_end;

2953

range=ipeak:range_end;

2962

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2954

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2963

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2955

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2964

RILN_TD_struct.FOM=-inf;

2956

RILN_TD_struct.FOM=-inf;

2965

RILN_TD_struct.FOM_PDF=-inf;

2957

RILN_TD_struct.FOM_PDF=-inf;

2966

rms_fom=-inf;

2958

rms_fom=-inf;

2967

for im=1:param.samples_per_ui

2959

for im=1:param.samples_per_ui

2968

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2960

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2969

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2961

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2970

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2962

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2971

cdf=pdf; cdf.y=cumsum(pdf.y);

2963

cdf=pdf; cdf.y=cumsum(pdf.y);

2972

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2964

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2973

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2965

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2974

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2966

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2975

if print_for_codereview % remove once all checked out

2967

if print_for_codereview % remove once all checked out

2976

h=figure(191);set(gcf,'Tag','COM');

2968

h=figure(191);set(gcf,'Tag','COM');

2977

semilogy(-cdf.x,cdf.y);

2969

semilogy(-cdf.x,cdf.y);

2978

% xlim ([0,-cdf.x(1)])

2970

% xlim ([0,-cdf.x(1)])

2979

ylim([param.specBER 1]);title ('CDF of RILN')

2971

ylim([param.specBER 1]);title ('CDF of RILN')

2980

hold on

2972

hold on

2981

end

2973

end

2982

if rms>rms_fom

2974

if rms>rms_fom

2983

rms_fom=rms;

2975

rms_fom=rms;

2984

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2976

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2985

RILN_TD_struct.PDF=pdf;

2977

RILN_TD_struct.PDF=pdf;

2986

end

2978

end

2987

end

2979

end

2988

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2980

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2989

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2981

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2990

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2982

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2991

if print_for_codereview % remove once all checked out

2983

if print_for_codereview % remove once all checked out

2992

figure(9003);set(gcf,'Tag','COM');

2984

figure(9003);set(gcf,'Tag','COM');

2993

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2985

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2994

hold on

2986

hold on

2995

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2987

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2996

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2988

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2997

hold off

2989

hold off

2998

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

2990

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

2999

figure(9004);set(gcf,'Tag','COM');

2991

figure(9004);set(gcf,'Tag','COM');

3000

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2992

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

3001

hold on

2993

hold on

3002

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2994

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

3003

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2995

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

3004

grid on

2996

grid on

3005

legend('show')

2997

legend('show')

3006

end

2998

end

3007

end

2999

end

3008

function is_illegal=RXFFE_Illegal(C,param,last_index)

3000

function is_illegal=RXFFE_Illegal(C,param,last_index)

3009

3001

3010

%check if RXFFE taps are illegal

3002

%check if RXFFE taps are illegal

3011

%C = RXFFE taps

3003

%C = RXFFE taps

3012

%param = COM param struct

3004

%param = COM param struct

3013

%last_index is used when computing illegality prior to Backoff. It will be set so taps

3005

%last_index is used when computing illegality prior to Backoff. It will be set so taps

3014

% in the Backoff region are not considered in the legality check.

3006

% in the Backoff region are not considered in the legality check.

3015

3007

3016

%If last index is omitted, set it to length(C)

3008

%If last index is omitted, set it to length(C)

3017

if nargin<3

3009

if nargin<3

3018

last_index=length(C);

3010

last_index=length(C);

3019

end

3011

end

3020

3012

3021

is_illegal=0;

3013

is_illegal=0;

3022

3014

3023

%Check cursor tap

3015

%Check cursor tap

3024

Ccur_i=param.RxFFE_cmx+1;

3016

Ccur_i=param.RxFFE_cmx+1;

3025

if C(Ccur_i) < param.ffe_main_cursor_min

3017

if C(Ccur_i) < param.ffe_main_cursor_min

3026

is_illegal=1;

3018

is_illegal=1;

3027

return;

3019

return;

3028

end

3020

end

3029

3021

3030

%Check postcursors

3022

%Check postcursors

3031

if param.ffe_post_tap_len ~=0

3023

if param.ffe_post_tap_len ~=0

3032

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

3024

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

3033

is_illegal=1;

3025

is_illegal=1;

3034

return;

3026

return;

3035

end

3027

end

3036

if (param.ffe_post_tap_len > 1)

3028

if (param.ffe_post_tap_len > 1)

3037

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

3029

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

3038

is_illegal=1;

3030

is_illegal=1;

3039

return;

3031

return;

3040

end

3032

end

3041

end

3033

end

3042

end

3034

end

3043

3035

3044

%Check precursors

3036

%Check precursors

3045

if param.ffe_pre_tap_len ~=0

3037

if param.ffe_pre_tap_len ~=0

3046

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

3038

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

3047

is_illegal=1;

3039

is_illegal=1;

3048

return;

3040

return;

3049

end

3041

end

3050

if (param.ffe_pre_tap_len > 1)

3042

if (param.ffe_pre_tap_len > 1)

3051

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

3043

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

3052

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

3044

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

3053

is_illegal=1;

3045

is_illegal=1;

3054

return;

3046

return;

3055

end % 11.22.2018 Yasou Hadaka

3047

end % 11.22.2018 Yasou Hadaka

3056

end

3048

end

3057

end

3049

end

3058

function S =R_series2(zref,f,R)

3050

function S =R_series2(zref,f,R)

3059

r=ones(1,length(f))*R;

3051

r=ones(1,length(f))*R;

3060

S.Parameters(1,1,:) = r./(r + 2*zref);

3052

S.Parameters(1,1,:) = r./(r + 2*zref);

3061

S.Parameters(2,2,:) = r./(r + 2*zref);

3053

S.Parameters(2,2,:) = r./(r + 2*zref);

3062

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

3054

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

3063

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

3055

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

3064

% Sm=sparameters(S.Parameters,f,zref);

3056

% Sm=sparameters(S.Parameters,f,zref);

3065

3057

3066

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

3058

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

3067

3059

3068

if use_RC

3060

if use_RC

3069

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

3061

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

3070

else

3062

else

3071

H_tw=ones(1,length(f));

3063

H_tw=ones(1,length(f));

3072

end

3064

end

3073

function SLD=SL(S,f,R)

3065

function SLD=SL(S,f,R)

3074

% source load impact return loss add to S21

3066

% source load impact return loss add to S21

3075

% S and SLD are the same structure

3067

% S and SLD are the same structure

3076

% S.Parameters

3068

% S.Parameters

3077

% S.Impedance

3069

% S.Impedance

3078

% S.NumPorts

3070

% S.NumPorts

3079

% S.Frequencies

3071

% S.Frequencies

3080

SLD=S; % assign the fields

3072

SLD=S; % assign the fields

3081

zref=100;

3073

zref=100;

3082

if R==0

3074

if R==0

3083

warndlg('Termination should not be set to zero');

3075

warndlg('Termination should not be set to zero');

3084

SLD=S;

3076

SLD=S;

3085

return

3077

return

3086

end

3078

end

3087

3079

3088

if R > zref

3080

if R > zref

3089

spr =R_series2(zref,f,(R-zref)); % make series sparameter

3081

spr =R_series2(zref,f,(R-zref)); % make series sparameter

3090

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

3082

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

3091

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3083

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3092

combines4p( ...

3084

combines4p( ...

3093

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3085

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3094

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3086

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3095

);

3087

);

3096

elseif R < zref

3088

elseif R < zref

3097

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

3089

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

3098

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

3090

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

3099

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3091

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3100

combines4p( ...

3092

combines4p( ...

3101

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3093

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3102

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3094

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3103

);

3095

);

3104

else

3096

else

3105

SLD=S;

3097

SLD=S;

3106

end

3098

end

3107

3099

3108

%%

3100

%%

3109

3101

3110

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

3102

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

3111

p1=param.CTLE_fp1(1);

3103

p1=param.CTLE_fp1(1);

3112

z1=param.CTLE_fz(1);

3104

z1=param.CTLE_fz(1);

3113

p2=param.CTLE_fp2(1);

3105

p2=param.CTLE_fp2(1);

3114

zlf=param.f_HP(1);

3106

zlf=param.f_HP(1);

3115

plf=param.f_HP(1);

3107

plf=param.f_HP(1);

3116

f_b=param.fb;

3108

f_b=param.fb;

3117

f_r=param.f_r;

3109

f_r=param.f_r;

3118

eta_0=param.eta_0;

3110

eta_0=param.eta_0;

3119

H_CTF = ( 10^(G_DC/20)+ 1i*f/z1 ) .*( 10^(G_DC2/20) + 1i*f/zlf )./ ( ( 1+1i*f/p1) .* ( 1+1i*f/p2) .* ( 1+1i*f/plf));

3111

H_CTF = ( 10^(G_DC/20)+ 1i*f/z1 ) .*( 10^(G_DC2/20) + 1i*f/zlf )./ ( ( 1+1i*f/p1) .* ( 1+1i*f/p2) .* ( 1+1i*f/plf));

3120

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

3112

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

3121

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

3113

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

3122

if 0

3114

if 0

3123

figure

3115

figure

3124

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

3116

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

3125

% see if it looks correct

3117

% see if it looks correct

3126

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

3118

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

3127

ylabel('dB');

3119

ylabel('dB');

3128

xlabel('GHz');

3120

xlabel('GHz');

3129

title( 'H_ctf with H_r')

3121

title( 'H_ctf with H_r')

3130

grid on

3122

grid on

3131

ylim([-30 0])

3123

ylim([-30 0])

3132

end

3124

end

3133

3125

3134

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

3126

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

3135

3127

3136

%Fill TDR data

3128

%Fill TDR data

3137

if package_testcase_i == 1

3129

if package_testcase_i == 1

3138

if OP.TDR

3130

if OP.TDR

3139

output_args.Z11est=chdata(1).TDR11.avgZport;

3131

output_args.Z11est=chdata(1).TDR11.avgZport;

3140

if ~param.FLAG.S2P

3132

if ~param.FLAG.S2P

3141

output_args.Z22est=chdata(1).TDR22.avgZport;

3133

output_args.Z22est=chdata(1).TDR22.avgZport;

3142

else

3134

else

3143

output_args.Z22est=[];

3135

output_args.Z22est=[];

3144

end

3136

end

3145

if OP.AUTO_TFX

3137

if OP.AUTO_TFX

3146

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

3138

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

3147

else

3139

else

3148

output_args.tfx_estimate=[];

3140

output_args.tfx_estimate=[];

3149

end

3141

end

3150

else

3142

else

3151

output_args.Z11est=[];

3143

output_args.Z11est=[];

3152

output_args.Z22est=[];

3144

output_args.Z22est=[];

3153

output_args.tfx_estimate=[];

3145

output_args.tfx_estimate=[];

3154

end

3146

end

3155

end

3147

end

3156

3148

3157

% Process ERL

3149

% Process ERL

3158

if package_testcase_i == 1

3150

if package_testcase_i == 1

3159

if OP.ERL

3151

if OP.ERL

3160

output_args.ERL11=chdata(1).TDR11.ERL;

3152

output_args.ERL11=chdata(1).TDR11.ERL;

3161

if ~param.FLAG.S2P

3153

if ~param.FLAG.S2P

3162

output_args.ERL22=chdata(1).TDR22.ERL;

3154

output_args.ERL22=chdata(1).TDR22.ERL;

3163

else

3155

else

3164

output_args.ERL22=[];

3156

output_args.ERL22=[];

3165

end

3157

end

3166

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

3158

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

3167

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

3159

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

3168

else

3160

else

3169

output_args.ERL11=[];

3161

output_args.ERL11=[];

3170

output_args.ERL22=[];

3162

output_args.ERL22=[];

3171

end

3163

end

3172

end

3164

end

3173

if OP.ERL

3165

if OP.ERL

3174

if OP.TDR_W_TXPKG

3166

if OP.TDR_W_TXPKG

3175

min_ERL=output_args.ERL22;

3167

min_ERL=output_args.ERL22;

3176

ERL= [ nan output_args.ERL22 ];

3168

ERL= [ nan output_args.ERL22 ];

3177

else

3169

else

3178

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

3170

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

3179

min_ERL=output_args.ERL11;

3171

min_ERL=output_args.ERL11;

3180

ERL= [ output_args.ERL11 nan ];

3172

ERL= [ output_args.ERL11 nan ];

3181

else

3173

else

3182

min_ERL=min(output_args.ERL11,output_args.ERL22);

3174

min_ERL=min(output_args.ERL11,output_args.ERL22);

3183

ERL= [ output_args.ERL11 output_args.ERL22 ];

3175

ERL= [ output_args.ERL11 output_args.ERL22 ];

3184

end

3176

end

3185

end

3177

end

3186

output_args.ERL=min_ERL;

3178

output_args.ERL=min_ERL;

3187

else

3179

else

3188

min_ERL=[];

3180

min_ERL=[];

3189

ERL= [];

3181

ERL= [];

3190

output_args.ERL=[];

3182

output_args.ERL=[];

3191

end

3183

end

3192

if OP.ERL_ONLY

3184

if OP.ERL_ONLY

3193

if OP.BREAD_CRUMBS

3185

if OP.BREAD_CRUMBS

3194

output_args.OP=OP;

3186

output_args.OP=OP;

3195

output_args.param=param;

3187

output_args.param=param;

3196

output_args.chdata=chdata;

3188

output_args.chdata=chdata;

3197

%This seems to be the intent of setting fom_result.ran=0. Add it

3189

%This seems to be the intent of setting fom_result.ran=0. Add it

3198

%to output_args so there is a fom_result field.

3190

%to output_args so there is a fom_result field.

3199

fom_result.ran=0;

3191

fom_result.ran=0;

3200

output_args.fom_result=fom_result;

3192

output_args.fom_result=fom_result;

3201

end

3193

end

3202

output_args.Z_t=param.Z_t;

3194

output_args.Z_t=param.Z_t;

3203

fileset_str=str2csv({chdata(1).base});

3195

fileset_str=str2csv({chdata(1).base});

3204

output_args.file_names=sprintf('"%s"', fileset_str);

3196

output_args.file_names=sprintf('"%s"', fileset_str);

3205

if OP.DISPLAY_WINDOW

3197

if OP.DISPLAY_WINDOW

3206

savefigs(param, OP);

3198

savefigs(param, OP);

3207

end

3199

end

3208

end

3200

end

3209

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3201

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3210

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3202

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3211

p1_ctle = -2*pi*f_p1;

3203

p1_ctle = -2*pi*f_p1;

3212

p2_ctle = -2*pi*f_p2;

3204

p2_ctle = -2*pi*f_p2;

3213

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3205

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3214

k_ctle = -p2_ctle;

3206

k_ctle = -p2_ctle;

3215

bilinear_fs = 2*fb*oversampling;

3207

bilinear_fs = 2*fb*oversampling;

3216

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3208

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3217

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3209

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3218

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3210

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3219

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3211

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3220

% allow for different pole zeros RIM 9-29-2015

3212

% allow for different pole zeros RIM 9-29-2015

3221

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3213

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3222

B_filt =k_ctle*kd*poly([zd, -1]);

3214

B_filt =k_ctle*kd*poly([zd, -1]);

3223

A_filt=poly([p1d, p2d]);

3215

A_filt=poly([p1d, p2d]);

3224

impulse_response=filter(B_filt,A_filt,ir_in);

3216

impulse_response=filter(B_filt,A_filt,ir_in);

3225

3217

3226

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3218

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3227

Over_sample=2;

3219

Over_sample=2;

3228

num_files=length(chdata);

3220

num_files=length(chdata);

3229

for i=1:num_files

3221

for i=1:num_files

3230

V=chdata(i).uneq_pulse_response;

3222

V=chdata(i).uneq_pulse_response;

3231

T=chdata(i).t;

3223

T=chdata(i).t;

3232

dt=T(2)-T(1);

3224

dt=T(2)-T(1);

3233

f=0:1/max(T):1/dt;

3225

f=0:1/max(T):1/dt;

3234

chdata(i).faxis=f;

3226

chdata(i).faxis=f;

3235

f75=find(f >= param.fb*.75,1,'first');

3227

f75=find(f >= param.fb*.75,1,'first');

3236

fnq=find(f >= param.fb*.5,1,'first');

3228

fnq=find(f >= param.fb*.5,1,'first');

3237

chdata(i).fmaxi = length(f);

3229

chdata(i).fmaxi = length(f);

3238

chdata(i).faxis = f;

3230

chdata(i).faxis = f;

3239

UI=param.ui; % unit interval

3231

UI=param.ui; % unit interval

3240

M=param.samples_per_ui; % sample per UI

3232

M=param.samples_per_ui; % sample per UI

3241

N_v=param.N_v; % number of UI for Vf determination

3233

N_v=param.N_v; % number of UI for Vf determination

3242

3234

3243

% filters

3235

% filters

3244

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3236

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3245

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3237

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3246

H_ftr=H_bw.*H_bt;

3238

H_ftr=H_bw.*H_bt;

3247

H_ftr=H_ftr(:);

3239

H_ftr=H_ftr(:);

3248

% fd of PR

3240

% fd of PR

3249

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3241

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3250

prr = prr(:);

3242

prr = prr(:);

3251

if f(1)==0, prr(1)=1; end %remove NaN

3243

if f(1)==0, prr(1)=1; end %remove NaN

3252

fd=fft(V);

3244

fd=fft(V);

3253

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3245

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3254

3246

3255

%% get Vf

3247

%% get Vf

3256

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3248

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3257

step_response=filter(V,1, shifting_vector);

3249

step_response=filter(V,1, shifting_vector);

3258

Vf=step_response(end);

3250

Vf=step_response(end);

3259

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3251

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3260

%%

3252

%%

3261

% ILest=20.*log10(abs(fd(1:f75)/Vf/M/Over_sample)) - 20.*log10(abs(prr(1:f75))) - 20*log10(abs(squeeze(H_ftr(1:f75)))) ; %removing db function to avoid using sig proc toolbox

3253

% ILest=20.*log10(abs(fd(1:f75)/Vf/M/Over_sample)) - 20.*log10(abs(prr(1:f75))) - 20*log10(abs(squeeze(H_ftr(1:f75)))) ; %removing db function to avoid using sig proc toolbox

3262

% figure

3254

% figure

3263

% plot(f(1:f75),ILest)

3255

% plot(f(1:f75),ILest)

3264

3256

3265

IL_conv=fd(1:f75)/Vf/M/Over_sample ./ prr(1:f75) ./ H_ftr(1:f75) ; %removing db function to avoid using sig proc toolbox

3257

IL_conv=fd(1:f75)/Vf/M/Over_sample ./ prr(1:f75) ./ H_ftr(1:f75) ; %removing db function to avoid using sig proc toolbox

3266

% set same variables as get_s4p_files

3258

% set same variables as get_s4p_files

3267

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3259

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3268

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3260

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3269

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3261

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3270

zero_vector=zeros(length(IL_conv),1);

3262

zero_vector=zeros(length(IL_conv),1);

3271

for j=1:length(IL_fields)

3263

for j=1:length(IL_fields)

3272

chdata(i).(IL_fields{j})=IL_conv;

3264

chdata(i).(IL_fields{j})=IL_conv;

3273

end

3265

end

3274

for j=1:length(Zero_fields)

3266

for j=1:length(Zero_fields)

3275

chdata(i).(Zero_fields{j})=zero_vector;

3267

chdata(i).(Zero_fields{j})=zero_vector;

3276

end

3268

end

3277

3269

3278

if i==1

3270

if i==1

3279

SDDch(:,1,2)=chdata.sdd12_raw;

3271

SDDch(:,1,2)=chdata.sdd12_raw;

3280

SDDch(:,2,1)=chdata.sdd21_raw;

3272

SDDch(:,2,1)=chdata.sdd21_raw;

3281

SDDch(:,1,1)=chdata.sdd11_raw;

3273

SDDch(:,1,1)=chdata.sdd11_raw;

3282

SDDch(:,2,2)=chdata.sdd22_raw;

3274

SDDch(:,2,2)=chdata.sdd22_raw;

3283

SDDp2p= zeros(length(IL_conv),1);

3275

SDDp2p= zeros(length(IL_conv),1);

3284

end

3276

end

3285

chdata(i).TX_RL=[];

3277

chdata(i).TX_RL=[];

3286

chdata(i).TDR11=[];

3278

chdata(i).TDR11=[];

3287

chdata(i).PDTR11=[];

3279

chdata(i).PDTR11=[];

3288

chdata(i).TDR22=[];

3280

chdata(i).TDR22=[];

3289

chdata(i).PDTR22=[];

3281

chdata(i).PDTR22=[];

3290

end

3282

end

3291

3283

3292

3284

3293

function H_tw=Tukey_Window(f,param,fr,fb)

3285

function H_tw=Tukey_Window(f,param,fr,fb)

3294

% RIM 05/26/2022 added optional fr and fb

3286

% RIM 05/26/2022 added optional fr and fb

3295

% fr is the start of the raised cosine window

3287

% fr is the start of the raised cosine window

3296

% fb is the end of the raised cosine window

3288

% fb is the end of the raised cosine window

3297

if ~exist('fr','var') && ~exist('fb','var')

3289

if ~exist('fr','var') && ~exist('fb','var')

3298

fb=param.fb;

3290

fb=param.fb;

3299

fr=param.f_r*param.fb;

3291

fr=param.f_r*param.fb;

3300

end

3292

end

3301

fperiod=2*(fb-fr);

3293

fperiod=2*(fb-fr);

3302

H_tw = [ ones(1,length(f(f<fr))) ...

3294

H_tw = [ ones(1,length(f(f<fr))) ...

3303

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3295

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3304

zeros(1,length(f(f>fb)) )];

3296

zeros(1,length(f(f>fb)) )];

3305

H_tw=H_tw(1:length(f));

3297

H_tw=H_tw(1:length(f));

3306

if 0

3298

if 0

3307

plot(f/1e9,H_tw)

3299

plot(f/1e9,H_tw)

3308

end

3300

end

3309

3301

3310

3302

3311

3303

3312

%% moved output control to functions

3304

%% moved output control to functions

3313

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3305

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3314

% Author: Richard Mellitz

3306

% Author: Richard Mellitz

3315

% Date: 7/29/2022

3307

% Date: 7/29/2022

3316

% generate FD tx ffe system function

3308

% generate FD tx ffe system function

3317

% varagins...

3309

% varagins...

3318

% param - stucture

3310

% param - stucture

3319

% param.fb baud rate

3311

% param.fb baud rate

3320

% param.Tx_FFE Tx FFE coef

3312

% param.Tx_FFE Tx FFE coef

3321

% f - freq array

3313

% f - freq array

3322

% Use_Tx_FFE = flag to use or not

3314

% Use_Tx_FFE = flag to use or not

3323

% H_TxFFE is system function for Tx_FFE

3315

% H_TxFFE is system function for Tx_FFE

3324

db = @(x) 20*log10(abs(x));

3316

db = @(x) 20*log10(abs(x));

3325

[param,varargin]=varargin_extractor(varargin{:});

3317

[param,varargin]=varargin_extractor(varargin{:});

3326

[f,varargin]=varargin_extractor(varargin{:});

3318

[f,varargin]=varargin_extractor(varargin{:});

3327

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3319

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3328

if isempty(Use_Tx_FFE)

3320

if isempty(Use_Tx_FFE)

3329

Use_Tx_FFE=0;

3321

Use_Tx_FFE=0;

3330

end

3322

end

3331

if isempty(param)

3323

if isempty(param)

3332

param.fb=106.25e9;

3324

param.fb=106.25e9;

3333

Tx_FFE=[1 ];

3325

Tx_FFE=[1 ];

3334

else

3326

else

3335

if ~isfield(param, 'Pkg_TXFFE_preset')

3327

if ~isfield(param, 'Pkg_TXFFE_preset')

3336

Tx_FFE=[ 1 ];

3328

Tx_FFE=[ 1 ];

3337

else

3329

else

3338

Tx_FFE=param.Pkg_TXFFE_preset;

3330

Tx_FFE=param.Pkg_TXFFE_preset;

3339

end

3331

end

3340

end

3332

end

3341

if isempty(f)

3333

if isempty(f)

3342

f=0:10e6:param.fb;

3334

f=0:10e6:param.fb;

3343

end

3335

end

3344

3336

3345

3337

3346

if Use_Tx_FFE ~=0

3338

if Use_Tx_FFE ~=0

3347

[mcur,icur] = max(Tx_FFE);

3339

[mcur,icur] = max(Tx_FFE);

3348

H_TxFFE=zeros(1,length(f));

3340

H_TxFFE=zeros(1,length(f));

3349

for ii=1:length(Tx_FFE)

3341

for ii=1:length(Tx_FFE)

3350

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3342

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3351

end

3343

end

3352

else

3344

else

3353

H_TxFFE=ones(1,length(f));

3345

H_TxFFE=ones(1,length(f));

3354

end

3346

end

3355

% figure (1102320)

3347

% figure (1102320)

3356

% plot(f/1e9,db(H_TxFFE))

3348

% plot(f/1e9,db(H_TxFFE))

3357

% hold on

3349

% hold on

3358

function C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs)

3350

function C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs)

3359

cmx=param.RxFFE_cmx;

3351

cmx=param.RxFFE_cmx;

3360

cpx=param.RxFFE_cpx;

3352

cpx=param.RxFFE_cpx;

3361

% do this early on so we can reuse the old code

3353

% do this early on so we can reuse the old code

3362

% to be replaced with MMSE function from healey...

3354

% to be replaced with MMSE function from healey...

3363

if param.N_bg ~=0 % must be floating taps

3355

if param.N_bg ~=0 % must be floating taps

3364

cpx=param.N_bmax; % N_f in spreadsheet

3356

cpx=param.N_bmax; % N_f in spreadsheet

3365

end

3357

end

3366

num_taps=cmx+cpx+1;

3358

num_taps=cmx+cpx+1;

3367

ndfe=param.ndfe;

3359

ndfe=param.ndfe;

3368

spui=param.samples_per_ui;

3360

spui=param.samples_per_ui;

3369

%% Start of WIENER-HOPF MMSE EQ code

3361

%% Start of WIENER-HOPF MMSE EQ code

3370

R_n = zeros(num_taps,num_taps);

3362

R_n = zeros(num_taps,num_taps);

3371

R_xt = zeros(num_taps,num_taps);

3363

R_xt = zeros(num_taps,num_taps);

3372

3364

3373

if OP.Do_Colored_Noise

3365

if OP.Do_Colored_Noise

3374

% Form Noise Autocorrelation matrix

3366

% Form Noise Autocorrelation matrix

3375

Noise_XC = reshape (Noise_XC,1,[]);

3367

Noise_XC = reshape (Noise_XC,1,[]);

3376

len = length(Noise_XC);

3368

len = length(Noise_XC);

3377

if len < num_taps, Noise_XC = [Noise_XC,zeros(1,num_taps-len)]; end

3369

if len < num_taps, Noise_XC = [Noise_XC,zeros(1,num_taps-len)]; end

3378

Noise_XC = Noise_XC(1:num_taps);

3370

Noise_XC = Noise_XC(1:num_taps);

3379

R_n = toeplitz (Noise_XC,Noise_XC);

3371

R_n = toeplitz (Noise_XC,Noise_XC);

3380

end

3372

end

3381

%% Calculate Cross Talk Correlation matrix at T intervals.

3373

%% Calculate Cross Talk Correlation matrix at T intervals.

3382

if OP.Do_XT_Noise

3374

if OP.Do_XT_Noise

3383

% Calculate variance of Tx signal based on +/-1 outer limits

3375

% Calculate variance of Tx signal based on +/-1 outer limits

3384

Tx_sigma = sqrt( (param.levels^2-1)/(3*(param.levels-1)^2) );

3376

Tx_sigma = sqrt( (param.levels^2-1)/(3*(param.levels-1)^2) );

3385

for jj = 2:length(chdata)

3377

for jj = 2:length(chdata)

3386

if isequal(chdata(jj).type, 'FEXT') || isequal(chdata(jj).type, 'NEXT')

3378

if isequal(chdata(jj).type, 'FEXT') || isequal(chdata(jj).type, 'NEXT')

3387

if isequal(chdata(jj).type, 'FEXT')

3379

if isequal(chdata(jj).type, 'FEXT')

3388

% len = length(chdata(jj).ctle_imp_response);

3380

% len = length(chdata(jj).ctle_imp_response);

3389

% ch_imp = ifft( fft(reshape(chdata(jj).ctle_imp_response,1,[])) .* fft(reshape(upsample(txffe, param.samples_per_ui),1,[]),len) );

3381

% ch_imp = ifft( fft(reshape(chdata(jj).ctle_imp_response,1,[])) .* fft(reshape(upsample(txffe, param.samples_per_ui),1,[]),len) );

3390

ch_imp= FFE( txffe , cmx,param.samples_per_ui, chdata(jj).ctle_imp_response).';

3382

ch_imp= FFE( txffe , cmx,param.samples_per_ui, chdata(jj).ctle_imp_response).';

3391

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3383

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3392

elseif isequal(chdata(jj).type, 'NEXT')

3384

elseif isequal(chdata(jj).type, 'NEXT')

3393

ch_imp = chdata(jj).ctle_imp_response;

3385

ch_imp = chdata(jj).ctle_imp_response;

3394

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3386

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3395

end

3387

end

3396

norms = zeros(1,spui);

3388

norms = zeros(1,spui);

3397

for ii = 1:spui

3389

for ii = 1:spui

3398

norms(ii) = norm(ch_imp(ii:spui:end));

3390

norms(ii) = norm(ch_imp(ii:spui:end));

3399

end

3391

end

3400

% Pick out sampling phase with largest noise contribution

3392

% Pick out sampling phase with largest noise contribution

3401

[~,cursor] = max(norms);

3393

[~,cursor] = max(norms);

3402

sub_sample_ch = ch_imp(cursor:spui:end);

3394

sub_sample_ch = ch_imp(cursor:spui:end);

3403

xc = xcorr(sub_sample_ch,num_taps)* Tx_sigma^2;

3395

xc = xcorr(sub_sample_ch,num_taps)* Tx_sigma^2;

3404

xc = xc(num_taps+1:end);

3396

xc = xc(num_taps+1:end);

3405

xc = xc(1:num_taps);

3397

xc = xc(1:num_taps);

3406

R = toeplitz (xc,xc);

3398

R = toeplitz (xc,xc);

3407

R_xt = R_xt + R;

3399

R_xt = R_xt + R;

3408

end

3400

end

3409

end

3401

end

3410

end

3402

end

3411

%% Noise + Cross Talk contribution to R matrix

3403

%% Noise + Cross Talk contribution to R matrix

3412

R_n_xc = zeros(num_taps+ndfe);

3404

R_n_xc = zeros(num_taps+ndfe);

3413

R_n_xc(1:num_taps,1:num_taps) = R_n + R_xt ;

3405

R_n_xc(1:num_taps,1:num_taps) = R_n + R_xt ;

3414

%% For least means squares, we want to solve

3406

%% For least means squares, we want to solve

3415

%

3407

%

3416

% ro = |Ryy Ryx| * w

3408

% ro = |Ryy Ryx| * w

3417

% |Rxy Rxx|

3409

% |Rxy Rxx|

3418

% see Cioffi chapter 3, 3.7.3

3410

% see Cioffi chapter 3, 3.7.3

3419

3411

3420

himp = vsampled;

3412

himp = vsampled;

3421

RefTap = cmx+1;

3413

RefTap = cmx+1;

3422

Signal_Variance = mean ( [-1, -1/3, 1/3, 1].^2 );

3414

Signal_Variance = mean ( [-1, -1/3, 1/3, 1].^2 );

3423

Ryy.r = [1:num_taps];

3415

Ryy.r = [1:num_taps];

3424

Ryy.c = [1:num_taps];

3416

Ryy.c = [1:num_taps];

3425

Ryx.r = 1:num_taps;

3417

Ryx.r = 1:num_taps;

3426

Ryx.c = num_taps + (1:ndfe);

3418

Ryx.c = num_taps + (1:ndfe);

3427

Rxy.r = num_taps + (1:ndfe);

3419

Rxy.r = num_taps + (1:ndfe);

3428

Rxy.c = 1:num_taps;

3420

Rxy.c = 1:num_taps;

3429

Rxx.r = num_taps+(1:ndfe);

3421

Rxx.r = num_taps+(1:ndfe);

3430

Rxx.c = num_taps+(1:ndfe);

3422

Rxx.c = num_taps+(1:ndfe);

3431

himp = reshape (himp,1,[]);

3423

himp = reshape (himp,1,[]);

3432

%% ro is simply the channel response reversed in time

3424

%% ro is simply the channel response reversed in time

3433

himp_lr = fliplr(himp); % make sure himp has enough pre/post cursors, e.g. numtaps+ndfe

3425

himp_lr = fliplr(himp); % make sure himp has enough pre/post cursors, e.g. numtaps+ndfe

3434

himp_lr = [zeros(1,num_taps+ndfe), himp_lr, zeros(1,num_taps+ndfe)];

3426

himp_lr = [zeros(1,num_taps+ndfe), himp_lr, zeros(1,num_taps+ndfe)];

3435

[~,pk] = max(himp_lr);

3427

[~,pk] = max(himp_lr);

3436

r_indx = (1:num_taps) - RefTap;

3428

r_indx = (1:num_taps) - RefTap;

3437

ro = [himp_lr(pk+r_indx), zeros(1,ndfe)].';

3429

ro = [himp_lr(pk+r_indx), zeros(1,ndfe)].';

3438

ro = ro*Signal_Variance;

3430

ro = ro*Signal_Variance;

3439

%% Setup up the covariance matrix

3431

%% Setup up the covariance matrix

3440

R = zeros(num_taps+ndfe);

3432

R = zeros(num_taps+ndfe);

3441

% Form Ryy

3433

% Form Ryy

3442

% Note: important to use whole impulse response

3434

% Note: important to use whole impulse response

3443

% not just the part that spans the FFE.

3435

% not just the part that spans the FFE.

3444

[ryy,lags] = xcorr(himp,himp, num_taps-1);

3436

[ryy,lags] = xcorr(himp,himp, num_taps-1);

3445

R(Ryy.r,Ryy.c) = toeplitz (ryy(num_taps:end));

3437

R(Ryy.r,Ryy.c) = toeplitz (ryy(num_taps:end));

3446

3438

3447

% Form Rxx

3439

% Form Rxx

3448

R(Rxx.r,Rxx.c) = diag(ones(1,ndfe));

3440

R(Rxx.r,Rxx.c) = diag(ones(1,ndfe));

3449

3441

3450

% Form Ryx columns

3442

% Form Ryx columns

3451

Ryx_indxs = (1:num_taps)-1;

3443

Ryx_indxs = (1:num_taps)-1;

3452

for jj = 0:ndfe-1

3444

for jj = 0:ndfe-1

3453

% R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk+1 + Ryx_indxs -jj ).';

3445

% R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk+1 + Ryx_indxs -jj ).';

3454

R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk-cmx-1 + Ryx_indxs -jj ).';

3446

R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk-cmx-1 + Ryx_indxs -jj ).';

3455

end

3447

end

3456

% Form Rxy rows

3448

% Form Rxy rows

3457

R(Rxy.r,Rxy.c ) = R(Ryx.r,Ryx.c )';

3449

R(Rxy.r,Rxy.c ) = R(Ryx.r,Ryx.c )';

3458

3450

3459

% add in Signal Variance

3451

% add in Signal Variance

3460

R = R*Signal_Variance;

3452

R = R*Signal_Variance;

3461

Rtmp = R;

3453

Rtmp = R;

3462

% Add in Xt and colored noise terms

3454

% Add in Xt and colored noise terms

3463

R = R + R_n_xc;

3455

R = R + R_n_xc;

3464

3456

3465

% SNR = 25 dB

3457

% SNR = 25 dB

3466

SNR = OP.FFE_SNR;

3458

SNR = OP.FFE_SNR;

3467

Noise_var = max(vsampled)^2*Signal_Variance/10^(SNR/10);

3459

Noise_var = max(vsampled)^2*Signal_Variance/10^(SNR/10);

3468

R_noise = diag(ones(1,num_taps))*Noise_var;

3460

R_noise = diag(ones(1,num_taps))*Noise_var;

3469

if ~OP.Do_Colored_Noise && ~OP.Do_XT_Noise

3461

if ~OP.Do_Colored_Noise && ~OP.Do_XT_Noise

3470

R(Ryy.r,Ryy.c) = R(Ryy.r,Ryy.c) + R_noise;

3462

R(Ryy.r,Ryy.c) = R(Ryy.r,Ryy.c) + R_noise;

3471

end

3463

end

3472

3464

3473

3465

3474

%% Solve for equalizer weights

3466

%% Solve for equalizer weights

3475

w = inv(R)*ro;

3467

w = inv(R)*ro;

3476

C = w;

3468

C = w;

3477

%% Deal with 1st post Cursor DFE weight saturation

3469

%% Deal with 1st post Cursor DFE weight saturation

3478

% ro = Rw by moving "saturated" weights over to the LHS

3470

% ro = Rw by moving "saturated" weights over to the LHS

3479

DFE_h1_indx = num_taps+1;

3471

DFE_h1_indx = num_taps+1;

3480

Indx_full = 1:length(C);

3472

Indx_full = 1:length(C);

3481

ws = C;

3473

ws = C;

3482

if ndfe>0 && abs(C(DFE_h1_indx)) > param.bmax(1)

3474

if ndfe>0 && abs(C(DFE_h1_indx)) > param.bmax(1)

3483

rtmp = reshape (ro,[],1);

3475

rtmp = reshape (ro,[],1);

3484

Rtmp = R;

3476

Rtmp = R;

3485

% Move saturated DFE weights over to left hand side of equation

3477

% Move saturated DFE weights over to left hand side of equation

3486

ws = zeros (size(C));

3478

ws = zeros (size(C));

3487

ws (DFE_h1_indx) = sign(C(DFE_h1_indx))*param.bmax(1);

3479

ws (DFE_h1_indx) = sign(C(DFE_h1_indx))*param.bmax(1);

3488

rtmp = rtmp - Rtmp*ws;

3480

rtmp = rtmp - Rtmp*ws;

3489

3481

3490

% and remove the corresponding column from R

3482

% and remove the corresponding column from R

3491

Rtmp(:,DFE_h1_indx) = [];

3483

Rtmp(:,DFE_h1_indx) = [];

3492

Indx_full (DFE_h1_indx) = [];

3484

Indx_full (DFE_h1_indx) = [];

3493

% now Rtmp isn't square so have to use the R'R trick

3485

% now Rtmp isn't square so have to use the R'R trick

3494

% Probably a little dicey "theoretically" because

3486

% Probably a little dicey "theoretically" because

3495

% w = inv(R)*ro is already the mmse solution

3487

% w = inv(R)*ro is already the mmse solution

3496

% now we at doing a R'R operation, but hey

3488

% now we at doing a R'R operation, but hey

3497

% seems to work

3489

% seems to work

3498

% Alternative, since R is now over specified, more rows than

3490

% Alternative, since R is now over specified, more rows than

3499

% columns, one could try removing one of the DFE rows from the

3491

% columns, one could try removing one of the DFE rows from the

3500

% Rxy Rxx portion of the R matrix.

3492

% Rxy Rxx portion of the R matrix.

3501

3493

3502

w_partial = inv(Rtmp'*Rtmp)*(Rtmp'*rtmp);

3494

w_partial = inv(Rtmp'*Rtmp)*(Rtmp'*rtmp);

3503

ws (Indx_full,:) = w_partial;

3495

ws (Indx_full,:) = w_partial;

3504

C = ws;

3496

C = ws;

3505

end

3497

end

3506

% From Cioffi, Chapter 3

3498

% From Cioffi, Chapter 3

3507

var_ffe_dfe = Signal_Variance-ws.'*ro;

3499

var_ffe_dfe = Signal_Variance-ws.'*ro;

3508

SNR_Eq = 10*log10(Signal_Variance/var_ffe_dfe-1);

3500

SNR_Eq = 10*log10(Signal_Variance/var_ffe_dfe-1);

3509

3501

3510

%% Scale FFE gain to target output voltage

3502

%% Scale FFE gain to target output voltage

3511

Target_ouput = vsampled(ivs)*10^(param.current_ffegain/20);

3503

Target_ouput = vsampled(ivs)*10^(param.current_ffegain/20);

3512

C = C*Target_ouput;

3504

C = C*Target_ouput;

3513

C = C(1:num_taps);

3505

C = C(1:num_taps);

3514

%% End MMSE dfe code

3506

%% End MMSE dfe code

3515

function Write_CSV(output_args,csv_file)

3507

function Write_CSV(output_args,csv_file)

3516

3508

3517

items = fieldnames(output_args);

3509

items = fieldnames(output_args);

3518

item_value_strings = cell(size(items));

3510

item_value_strings = cell(size(items));

3519

for field_id=1:length(items)

3511

for field_id=1:length(items)

3520

field_name=items{field_id};

3512

field_name=items{field_id};

3521

field_value=output_args.(field_name);

3513

field_value=output_args.(field_name);

3522

if isstruct(output_args.(field_name))

3514

if isstruct(output_args.(field_name))

3523

field_value='struct';

3515

field_value='struct';

3524

end

3516

end

3525

if ischar(field_value)

3517

if ischar(field_value)

3526

item_value_strings{field_id}=field_value;

3518

item_value_strings{field_id}=field_value;

3527

elseif isempty(field_value)

3519

elseif isempty(field_value)

3528

item_value_strings{field_id}='';

3520

item_value_strings{field_id}='';

3529

elseif numel(field_value)==1

3521

elseif numel(field_value)==1

3530

item_value_strings{field_id}=num2str(field_value);

3522

item_value_strings{field_id}=num2str(field_value);

3531

else

3523

else

3532

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3524

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3533

end

3525

end

3534

end

3526

end

3535

3527

3536

header_string = str2csv(items);

3528

header_string = str2csv(items);

3537

data_string = str2csv(item_value_strings);

3529

data_string = str2csv(item_value_strings);

3538

fid = fopen(csv_file,'w');

3530

fid = fopen(csv_file,'w');

3539

fprintf(fid,'%s\n', header_string);

3531

fprintf(fid,'%s\n', header_string);

3540

fprintf(fid,'%s\n', data_string);

3532

fprintf(fid,'%s\n', data_string);

3541

fclose(fid);

3533

fclose(fid);

3542

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3534

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3543

%% Used in Clause 92 for adding board trace between TP0 and TP2

3535

%% Used in Clause 92 for adding board trace between TP0 and TP2

3544

3536

3545

switch chdata.type

3537

switch chdata.type

3546

case 'THRU'

3538

case 'THRU'

3547

z_bp_tx = param.z_bp_tx;

3539

z_bp_tx = param.z_bp_tx;

3548

z_bp_rx = param.z_bp_rx;

3540

z_bp_rx = param.z_bp_rx;

3549

case 'NEXT'

3541

case 'NEXT'

3550

z_bp_tx = param.z_bp_rx;

3542

z_bp_tx = param.z_bp_rx;

3551

z_bp_rx = param.z_bp_next;

3543

z_bp_rx = param.z_bp_next;

3552

case 'FEXT'

3544

case 'FEXT'

3553

z_bp_tx = param.z_bp_fext;

3545

z_bp_tx = param.z_bp_fext;

3554

z_bp_rx = param.z_bp_rx;

3546

z_bp_rx = param.z_bp_rx;

3555

end

3547

end

3556

% Same cap on each tx and rx three is a data stratue for bifrucation but

3548

% Same cap on each tx and rx three is a data stratue for bifrucation but

3557

% logic no implemented here RIM 06/28/2019

3549

% logic no implemented here RIM 06/28/2019

3558

zref=param.Z0;

3550

zref=param.Z0;

3559

c1=param.C_0;

3551

c1=param.C_0;

3560

c2=param.C_1;

3552

c2=param.C_1;

3561

f=chdata.faxis;

3553

f=chdata.faxis;

3562

f(f<eps)=eps;

3554

f(f<eps)=eps;

3563

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3555

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3564

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3556

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3565

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3557

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3566

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3558

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3567

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3559

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3568

% add Tx caps

3560

% add Tx caps

3569

[s11tx, s12tx, s21tx, s22tx ]= ...

3561

[s11tx, s12tx, s21tx, s22tx ]= ...

3570

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3562

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3571

[s11tx, s12tx, s21tx, s22tx ]= ...

3563

[s11tx, s12tx, s21tx, s22tx ]= ...

3572

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3564

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3573

3565

3574

3566

3575

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3567

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3576

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3568

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3577

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3569

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3578

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3570

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3579

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_rx);

3571

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_rx);

3580

% add Rx caps

3572

% add Rx caps

3581

[s11rx, s12rx, s21rx, s22rx ]= ...

3573

[s11rx, s12rx, s21rx, s22rx ]= ...

3582

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3574

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3583

[s11rx, s12rx, s21rx, s22rx ]= ...

3575

[s11rx, s12rx, s21rx, s22rx ]= ...

3584

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3576

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3585

3577

3586

3578

3587

switch OP.include_pcb

3579

switch OP.include_pcb

3588

case 1

3580

case 1

3589

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3581

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3590

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3582

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3591

case 2

3583

case 2

3592

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3584

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3593

end

3585

end

3594

3586

3595

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3587

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3596

% Used in Clause 92 for adding board trace between TP0 and TP2

3588

% Used in Clause 92 for adding board trace between TP0 and TP2

3597

switch chdata.type

3589

switch chdata.type

3598

case 'THRU'

3590

case 'THRU'

3599

z_bp_tx = param.z_bp_tx;

3591

z_bp_tx = param.z_bp_tx;

3600

case 'NEXT'

3592

case 'NEXT'

3601

z_bp_tx = param.z_bp_next;

3593

z_bp_tx = param.z_bp_next;

3602

case 'FEXT'

3594

case 'FEXT'

3603

z_bp_tx = param.z_bp_fext;

3595

z_bp_tx = param.z_bp_fext;

3604

end

3596

end

3605

3597

3606

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3598

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3607

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, param.z_bp_rx);

3599

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, param.z_bp_rx);

3608

3600

3609

switch OP.include_pcb

3601

switch OP.include_pcb

3610

case 1

3602

case 1

3611

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3603

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3612

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3604

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3613

case 2

3605

case 2

3614

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3606

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3615

end

3607

end

3616

3608

3617

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3609

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3618

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3610

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3619

% applying a bank of DFE at desired location

3611

% applying a bank of DFE at desired location

3620

% hisi: waveform with cursor values;

3612

% hisi: waveform with cursor values;

3621

% idx: starting index of the bank;

3613

% idx: starting index of the bank;

3622

% tap_bk: number of taps in bank;

3614

% tap_bk: number of taps in bank;

3623

% bmaxg: maxmum coefficient in bank;

3615

% bmaxg: maxmum coefficient in bank;

3624

3616

3625

if nargin<6

3617

if nargin<6

3626

dfe_delta=0;

3618

dfe_delta=0;

3627

end

3619

end

3628

3620

3629

rng=idx:idx+tap_bk-1;

3621

rng=idx:idx+tap_bk-1;

3630

flt_curval=hisi(rng);

3622

flt_curval=hisi(rng);

3631

3623

3632

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3624

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3633

3625

3634

if dfe_delta~=0

3626

if dfe_delta~=0

3635

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3627

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3636

dfe_delta.*sign(flt_curval)*curval;

3628

dfe_delta.*sign(flt_curval)*curval;

3637

else

3629

else

3638

flt_curval_q=hisi(rng);

3630

flt_curval_q=hisi(rng);

3639

end

3631

end

3640

3632

3641

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3633

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3642

hisi(rng)= hisi(rng) - curval*tap_coef;

3634

hisi(rng)= hisi(rng) - curval*tap_coef;

3643

hisi_ref(rng)=0;

3635

hisi_ref(rng)=0;

3644

3636

3645

%AJG021820

3637

%AJG021820

3646

function [ a] = bessel( n )

3638

function [ a] = bessel( n )

3647

% bessel polynomial

3639

% bessel polynomial

3648

for ii= 0:n

3640

for ii= 0:n

3649

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3641

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3650

end

3642

end

3651

3643

3652

3644

3653

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3645

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3654

% History:

3646

% History:

3655

% 1. 14th October, 2021 (Intial release)

3647

% 1. 14th October, 2021 (Intial release)

3656

3648

3657

% Definition:

3649

% Definition:

3658

% This function captures the channel delay through the time domain using causality enforcement.

3650

% This function captures the channel delay through the time domain using causality enforcement.

3659

% Following are the steps being followed.

3651

% Following are the steps being followed.

3660

% Step 1. Cascade negative frequencies

3652

% Step 1. Cascade negative frequencies

3661

% Step 2. Extract magnitude

3653

% Step 2. Extract magnitude

3662

% Step 3. IFFT of the magnitude

3654

% Step 3. IFFT of the magnitude

3663

% Step 4. Multiply by the sign(t)

3655

% Step 4. Multiply by the sign(t)

3664

% Step 5. Calculate the phase of the 1j*causal_phase

3656

% Step 5. Calculate the phase of the 1j*causal_phase

3665

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3657

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3666

% Step 7. f-domain to t-domain pulse response

3658

% Step 7. f-domain to t-domain pulse response

3667

% Step 8. Calculate the delay

3659

% Step 8. Calculate the delay

3668

3660

3669

% Author:

3661

% Author:

3670

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3662

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3671

3663

3672

% Reference:

3664

% Reference:

3673

% 1] "IEEE Standard for Electrical Characterization of Printed Circuit Board and Related Interconnects at Frequencies up to 50 GHz," in IEEE Std 370-2020 , vol., no., pp.1-147, 8 Jan. 2021, doi: 10.1109/IEEESTD.2021.9316329.

3665

% 1] "IEEE Standard for Electrical Characterization of Printed Circuit Board and Related Interconnects at Frequencies up to 50 GHz," in IEEE Std 370-2020 , vol., no., pp.1-147, 8 Jan. 2021, doi: 10.1109/IEEESTD.2021.9316329.

3674

3666

3675

% Input:

3667

% Input:

3676

% freq %frequency in hertz (odd number points)

3668

% freq %frequency in hertz (odd number points)

3677

% sdd21 %insertion loss in complex (odd number points)

3669

% sdd21 %insertion loss in complex (odd number points)

3678

% param %COM native structure passed

3670

% param %COM native structure passed

3679

% OP %COM native structure passed

3671

% OP %COM native structure passed

3680

3672

3681

% Output:

3673

% Output:

3682

% delay_sec %channel delay in seconds

3674

% delay_sec %channel delay in seconds

3683

% delay_idx %channel delay index

3675

% delay_idx %channel delay index

3684

3676

3685

if iscolumn(sdd21)

3677

if iscolumn(sdd21)

3686

sdd21= sdd21.';

3678

sdd21= sdd21.';

3687

end

3679

end

3688

if iscolumn(freq)

3680

if iscolumn(freq)

3689

freq= freq.';

3681

freq= freq.';

3690

end

3682

end

3691

3683

3692

%---start. Step 1. Cascade negative frequencies

3684

%---start. Step 1. Cascade negative frequencies

3693

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3685

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3694

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3686

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3695

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3687

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3696

%---end. Step 1. Cascade negative frequencies

3688

%---end. Step 1. Cascade negative frequencies

3697

3689

3698

%---start. Step 2. Extract magnitude

3690

%---start. Step 2. Extract magnitude

3699

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3691

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3700

%---end. Step 2. Extract magnitude

3692

%---end. Step 2. Extract magnitude

3701

3693

3702

%---start. Step 3. IFFT of the magnitude

3694

%---start. Step 3. IFFT of the magnitude

3703

sdd21_mag_time = ifft(sdd21_mag_conj);

3695

sdd21_mag_time = ifft(sdd21_mag_conj);

3704

%---end. Step 3. IFFT of the magnitude

3696

%---end. Step 3. IFFT of the magnitude

3705

3697

3706

%---start. Step 4. Multiply by the sign(t)

3698

%---start. Step 4. Multiply by the sign(t)

3707

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3699

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3708

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3700

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3709

%---end. Step 4. Multiply by the sign(t)

3701

%---end. Step 4. Multiply by the sign(t)

3710

3702

3711

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3703

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3712

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3704

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3713

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3705

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3714

3706

3715

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3707

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3716

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3708

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3717

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3709

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3718

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3710

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3719

3711

3720

%---start. Step 7. f-domain to t-domain pulse response

3712

%---start. Step 7. f-domain to t-domain pulse response

3721

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3713

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3722

%--------- Extrapolation has been already done by the COM tool

3714

%--------- Extrapolation has been already done by the COM tool

3723

freq_array= freq;

3715

freq_array= freq;

3724

time_step= param.sample_dt;

3716

time_step= param.sample_dt;

3725

fmax=1/time_step/2;

3717

fmax=1/time_step/2;

3726

freq_step=(freq_array(3)-freq_array(2))/1;

3718

freq_step=(freq_array(3)-freq_array(2))/1;

3727

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3719

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3728

3720

3729

ILin=sdd21;

3721

ILin=sdd21;

3730

IL=interp_Sparam(ILin,freq_array,fout, ...

3722

IL=interp_Sparam(ILin,freq_array,fout, ...

3731

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3723

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3732

IL_nan = find(isnan(IL));

3724

IL_nan = find(isnan(IL));

3733

for in=IL_nan

3725

for in=IL_nan

3734

IL(in)=IL(in-1);

3726

IL(in)=IL(in-1);

3735

end

3727

end

3736

IL = IL(:);

3728

IL = IL(:);

3737

% add padding for time steps

3729

% add padding for time steps

3738

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3730

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3739

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3731

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3740

clear IL IL_nan IL_symmetric

3732

clear IL IL_nan IL_symmetric

3741

3733

3742

ILin=sdd21_causality_enforced;

3734

ILin=sdd21_causality_enforced;

3743

IL=interp_Sparam(ILin,freq_array,fout, ...

3735

IL=interp_Sparam(ILin,freq_array,fout, ...

3744

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3736

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3745

IL_nan = find(isnan(IL));

3737

IL_nan = find(isnan(IL));

3746

for in=IL_nan

3738

for in=IL_nan

3747

IL(in)=IL(in-1);

3739

IL(in)=IL(in-1);

3748

end

3740

end

3749

IL = IL(:);

3741

IL = IL(:);

3750

% add padding for time steps

3742

% add padding for time steps

3751

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3743

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3752

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3744

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3753

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3745

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3754

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3746

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3755

clear IL IL_nan IL_symmetric

3747

clear IL IL_nan IL_symmetric

3756

3748

3757

clear time_step fmax freq_step freq_array

3749

clear time_step fmax freq_step freq_array

3758

3750

3759

freq_step=(fout(3)-fout(2))/1;

3751

freq_step=(fout(3)-fout(2))/1;

3760

L= length(sdd21_PR);

3752

L= length(sdd21_PR);

3761

t_base = (0:L-1)/(freq_step*L);

3753

t_base = (0:L-1)/(freq_step*L);

3762

clear fout freq_step L

3754

clear fout freq_step L

3763

%---end. Step 7. f-domain to t-domain pulse response

3755

%---end. Step 7. f-domain to t-domain pulse response

3764

3756

3765

%---start. Step 8. Calculate the delay

3757

%---start. Step 8. Calculate the delay

3766

%------start. Remove the last 5% of the waveform for noise due to IFFT

3758

%------start. Remove the last 5% of the waveform for noise due to IFFT

3767

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3759

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3768

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3760

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3769

%------end. Remove the last 5% of the waveform for noise due to IFFT

3761

%------end. Remove the last 5% of the waveform for noise due to IFFT

3770

3762

3771

%---start. calculate the difference in index between the peaks

3763

%---start. calculate the difference in index between the peaks

3772

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3764

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3773

[~, peak_y_idx] = max(sdd21_PR_reduced);

3765

[~, peak_y_idx] = max(sdd21_PR_reduced);

3774

peak_idx_difference = peak_x_idx - peak_y_idx;

3766

peak_idx_difference = peak_x_idx - peak_y_idx;

3775

%---end. calculate the difference in index between the peaks

3767

%---end. calculate the difference in index between the peaks

3776

3768

3777

if peak_idx_difference~=0

3769

if peak_idx_difference~=0

3778

search_bounds = min(peak_x_idx, peak_y_idx);%<----one may fix it to 1e3; using minimum of the peaks in assuming the other signal has zero delay

3770

search_bounds = min(peak_x_idx, peak_y_idx);%<----one may fix it to 1e3; using minimum of the peaks in assuming the other signal has zero delay

3779

error_value = length(sdd21_causality_enforced_PR_reduced);

3771

error_value = length(sdd21_causality_enforced_PR_reduced);

3780

error_idx = 0;

3772

error_idx = 0;

3781

% i= 1;

3773

% i= 1;

3782

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3774

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3783

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3775

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3784

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3776

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3785

if (error_value > current_error)

3777

if (error_value > current_error)

3786

error_idx = shift_value;

3778

error_idx = shift_value;

3787

error_value = current_error;

3779

error_value = current_error;

3788

end

3780

end

3789

% error_idx_H(i)= error_idx;

3781

% error_idx_H(i)= error_idx;

3790

% i= i+ 1;

3782

% i= i+ 1;

3791

end

3783

end

3792

%plot(error_idx_H);

3784

%plot(error_idx_H);

3793

3785

3794

if error_idx==0

3786

if error_idx==0

3795

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3787

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3796

end

3788

end

3797

3789

3798

delay_idx = error_idx;

3790

delay_idx = error_idx;

3799

else

3791

else

3800

delay_idx= 1;

3792

delay_idx= 1;

3801

end

3793

end

3802

3794

3803

delay_sec= t_base(abs(delay_idx));

3795

delay_sec= t_base(abs(delay_idx));

3804

3796

3805

3797

3806

function [return_struct]= capture_RIL_RILN(chdata)

3798

function [return_struct]= capture_RIL_RILN(chdata)

3807

% History:

3799

% History:

3808

% 1. 12th April, 2019 (Intial release)

3800

% 1. 12th April, 2019 (Intial release)

3809

%

3801

%

3810

% 2. 11th October, 2021

3802

% 2. 11th October, 2021

3811

% - Details:

3803

% - Details:

3812

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3804

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3813

% 2] Revised the selection criteria for the solution of the quadratic

3805

% 2] Revised the selection criteria for the solution of the quadratic

3814

% equation in finding the reflection coefficient (rho).

3806

% equation in finding the reflection coefficient (rho).

3815

% - Impact:

3807

% - Impact:

3816

% => Zero impact in |RIL|, while impact on angle(RIL).

3808

% => Zero impact in |RIL|, while impact on angle(RIL).

3817

% - Previous:

3809

% - Previous:

3818

% %---start. For passive networks the reflection coefficient should be less than one

3810

% %---start. For passive networks the reflection coefficient should be less than one

3819

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3811

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3820

% rho_port2= solution_1;

3812

% rho_port2= solution_1;

3821

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3813

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3822

% rho_port2= solution_2;

3814

% rho_port2= solution_2;

3823

% else

3815

% else

3824

% rho_port2= solution_1;

3816

% rho_port2= solution_1;

3825

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3817

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3826

% end

3818

% end

3827

% %---end. For passive networks the reflection coefficient should be less than one

3819

% %---end. For passive networks the reflection coefficient should be less than one

3828

%

3820

%

3829

% RIL= conj((1- rho_port1).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- rho_port2).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3821

% RIL= conj((1- rho_port1).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- rho_port2).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3830

% - Change:

3822

% - Change:

3831

% %---start. Given the real part of the impedance is to be positive

3823

% %---start. Given the real part of the impedance is to be positive

3832

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3824

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3833

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3825

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3834

%

3826

%

3835

% rho_port2= zeros(length(solution_1), 1);

3827

% rho_port2= zeros(length(solution_1), 1);

3836

% for solution_idx= 1:length(solution_1)

3828

% for solution_idx= 1:length(solution_1)

3837

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3829

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3838

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3830

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3839

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3831

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3840

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3832

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3841

% else

3833

% else

3842

% error('An odd case has occured. Please contact the tool developer.');

3834

% error('An odd case has occured. Please contact the tool developer.');

3843

% end

3835

% end

3844

% end

3836

% end

3845

% %---end. Given the real part of the impedance is to be positive

3837

% %---end. Given the real part of the impedance is to be positive

3846

% RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3838

% RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3847

3839

3848

% Definition:

3840

% Definition:

3849

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3841

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3850

3842

3851

% Author:

3843

% Author:

3852

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3844

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3853

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3845

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3854

3846

3855

% This function has been shared by Hansel for others to evaluate for reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter.

3847

% This function has been shared by Hansel for others to evaluate for reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter.

3856

3848

3857

% Reference:

3849

% Reference:

3858

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3850

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3859

% 2] H. Dsilva, A. Jain, J. Sasikala and A. Kumar, "Novel Signal Integrity Application of Power Wave Scattering Matrix theory," 2019 IEEE MTT-S International Microwave and RF Conference (IMARC), 2019, pp. 1-7, doi: 10.1109/IMaRC45935.2019.9118701.

3851

% 2] H. Dsilva, A. Jain, J. Sasikala and A. Kumar, "Novel Signal Integrity Application of Power Wave Scattering Matrix theory," 2019 IEEE MTT-S International Microwave and RF Conference (IMARC), 2019, pp. 1-7, doi: 10.1109/IMaRC45935.2019.9118701.

3860

3852

3861

% Input:

3853

% Input:

3862

% 1] SCH: S-matrix structure

3854

% 1] SCH: S-matrix structure

3863

% SCH.Frequencies= faxis;

3855

% SCH.Frequencies= faxis;

3864

% SCH.Parameters(1,1,:)= sdd11;

3856

% SCH.Parameters(1,1,:)= sdd11;

3865

% SCH.Parameters(2,2,:)= sdd22;

3857

% SCH.Parameters(2,2,:)= sdd22;

3866

% SCH.Parameters(1,2,:)= sdd12;

3858

% SCH.Parameters(1,2,:)= sdd12;

3867

% SCH.Parameters(2,1,:)= sdd21;

3859

% SCH.Parameters(2,1,:)= sdd21;

3868

% SCH.NumPorts= 2;

3860

% SCH.NumPorts= 2;

3869

% SCH.Impedance= 100;

3861

% SCH.Impedance= 100;

3870

3862

3871

% Output: Struct returned has the following,

3863

% Output: Struct returned has the following,

3872

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3864

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3873

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3865

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3874

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3866

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3875

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3867

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3876

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3868

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3877

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3869

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3878

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3870

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3879

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3871

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3880

% return_struct.freq %Frequency axis

3872

% return_struct.freq %Frequency axis

3881

3873

3882

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3874

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3883

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3875

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3884

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3876

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3885

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3877

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3886

SCH.Frequencies=chdata(1).faxis;

3878

SCH.Frequencies=chdata(1).faxis;

3887

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3879

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3888

SCH.NumPorts= 2;

3880

SCH.NumPorts= 2;

3889

3881

3890

%---start. allowed is only a 2-port network having a transmitter and receiver

3882

%---start. allowed is only a 2-port network having a transmitter and receiver

3891

if size(SCH.Parameters, 1)~=2

3883

if size(SCH.Parameters, 1)~=2

3892

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3884

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3893

error('Allowed is only a 2-port network having a transmitter and receiver.');

3885

error('Allowed is only a 2-port network having a transmitter and receiver.');

3894

end

3886

end

3895

%---end. allowed is only a 2-port network having a transmitter and receiver

3887

%---end. allowed is only a 2-port network having a transmitter and receiver

3896

3888

3897

%---start. do not include the DC point given sinusoidals at DC are not

3889

%---start. do not include the DC point given sinusoidals at DC are not

3898

%defined

3890

%defined

3899

if SCH.Frequencies(1)==0

3891

if SCH.Frequencies(1)==0

3900

idx_start= 2;

3892

idx_start= 2;

3901

else

3893

else

3902

idx_start= 1;

3894

idx_start= 1;

3903

end

3895

end

3904

%---end. do not include the DC point given sinusoidals at DC are not

3896

%---end. do not include the DC point given sinusoidals at DC are not

3905

%defined

3897

%defined

3906

3898

3907

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3899

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3908

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3900

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3909

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3901

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3910

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3902

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3911

3903

3912

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3904

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3913

b= 1+ Sdd22.*conj(Sdd22)+...

3905

b= 1+ Sdd22.*conj(Sdd22)+...

3914

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3906

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3915

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3907

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3916

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3908

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3917

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3909

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3918

Sdd11.*conj(Sdd11);

3910

Sdd11.*conj(Sdd11);

3919

c= -conj(Sdd22)-...

3911

c= -conj(Sdd22)-...

3920

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3912

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3921

Sdd11.*conj(Sdd11).*conj(Sdd22);

3913

Sdd11.*conj(Sdd11).*conj(Sdd22);

3922

3914

3923

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3915

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3924

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3916

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3925

3917

3926

clear a b c

3918

clear a b c

3927

3919

3928

%---start. Given the real part of the impedance is to be positive

3920

%---start. Given the real part of the impedance is to be positive

3929

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3921

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3930

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3922

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3931

3923

3932

rho_port2= zeros(length(solution_1), 1);

3924

rho_port2= zeros(length(solution_1), 1);

3933

for solution_idx= 1:length(solution_1)

3925

for solution_idx= 1:length(solution_1)

3934

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3926

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3935

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3927

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3936

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3928

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3937

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3929

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3938

else

3930

else

3939

error('An odd case has occured. Please contact the tool developer.');

3931

error('An odd case has occured. Please contact the tool developer.');

3940

end

3932

end

3941

end

3933

end

3942

%---end. Given the real part of the impedance is to be positive

3934

%---end. Given the real part of the impedance is to be positive

3943

3935

3944

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3936

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3945

3937

3946

%---start. calculate the equivalent port impedance

3938

%---start. calculate the equivalent port impedance

3947

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3939

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3948

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3940

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3949

%---end. calculate the equivalent port impedance

3941

%---end. calculate the equivalent port impedance

3950

3942

3951

3943

3952

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3944

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3953

% %to zero reflections.

3945

% %to zero reflections.

3954

RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3946

RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3955

%---end. The reflectionless insertion loss is the insertion loss corresponding

3947

%---end. The reflectionless insertion loss is the insertion loss corresponding

3956

%to zero reflections.

3948

%to zero reflections.

3957

3949

3958

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3950

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3959

RILN= RIL- Sdd21;

3951

RILN= RIL- Sdd21;

3960

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3952

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3961

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3953

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3962

3954

3963

%---start. preparing returns struct

3955

%---start. preparing returns struct

3964

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3956

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3965

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3957

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3966

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3958

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3967

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3959

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3968

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3960

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3969

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3961

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3970

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3962

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3971

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3963

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3972

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3964

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3973

%---end. preparing returns struct

3965

%---end. preparing returns struct

3974

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3966

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3975

3967

3976

3968

3977

%For the given BER, find the top & bottom voltage level in the CDF

3969

%For the given BER, find the top & bottom voltage level in the CDF

3978

3970

3979

%for the top, just find the first index at the spec BER

3971

%for the top, just find the first index at the spec BER

3980

nidx=find(cdf.y>specBER, 1, 'first');

3972

nidx=find(cdf.y>specBER, 1, 'first');

3981

noise_bottom = cdf.x(nidx);

3973

noise_bottom = cdf.x(nidx);

3982

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3974

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3983

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3975

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3984

%the true index without flipping

3976

%the true index without flipping

3985

nidx=length(cdf.y)-nidx+1;

3977

nidx=length(cdf.y)-nidx+1;

3986

noise_top = cdf.x(nidx);

3978

noise_top = cdf.x(nidx);

3987

function p=comb_fct(p1, p2)

3979

function p=comb_fct(p1, p2)

3988

if p1.BinSize ~= p2.BinSize

3980

if p1.BinSize ~= p2.BinSize

3989

error('bin size must be equal')

3981

error('bin size must be equal')

3990

end

3982

end

3991

3983

3992

p=p1;

3984

p=p1;

3993

p.BinSize=p1.BinSize;

3985

p.BinSize=p1.BinSize;

3994

%p.Min=p1.Min+p2.Min;

3986

%p.Min=p1.Min+p2.Min;

3995

p.Min=min(p1.Min,p2.Min);

3987

p.Min=min(p1.Min,p2.Min);

3996

difsz=abs(p1.Min-p2.Min);

3988

difsz=abs(p1.Min-p2.Min);

3997

lp1=length(p1.y);

3989

lp1=length(p1.y);

3998

lp2=length(p2.y);

3990

lp2=length(p2.y);

3999

if p1.Min == p.Min

3991

if p1.Min == p.Min

4000

p2.y(difsz+1:lp2+difsz)=p2.y;

3992

p2.y(difsz+1:lp2+difsz)=p2.y;

4001

p2.y(1:difsz)=0;

3993

p2.y(1:difsz)=0;

4002

p2.y(lp2+difsz+1:lp1)=0;

3994

p2.y(lp2+difsz+1:lp1)=0;

4003

elseif p2.Min == p.Min

3995

elseif p2.Min == p.Min

4004

p1.y(difsz+1:lp1+difsz)=p1.y;

3996

p1.y(difsz+1:lp1+difsz)=p1.y;

4005

p1.y(1:difsz)=0;

3997

p1.y(1:difsz)=0;

4006

p1.y(lp1+difsz+1:lp2)=0;

3998

p1.y(lp1+difsz+1:lp2)=0;

4007

end

3999

end

4008

% p.y=conv(p1.y, p2.y);

4000

% p.y=conv(p1.y, p2.y);

4009

p.y=(p1.y+p2.y);

4001

p.y=(p1.y+p2.y);

4010

% p.y=p.y/sum(p.y);

4002

% p.y=p.y/sum(p.y);

4011

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

4003

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

4012

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

4004

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

4013

4005

4014

4006

4015

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

4007

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

4016

4008

4017

if pdf1.BinSize ~= pdf2.BinSize

4009

if pdf1.BinSize ~= pdf2.BinSize

4018

error('bin size must be equal')

4010

error('bin size must be equal')

4019

end

4011

end

4020

4012

4021

x1=pdf1.x;

4013

x1=pdf1.x;

4022

y1=pdf1.y;

4014

y1=pdf1.y;

4023

x2=pdf2.x;

4015

x2=pdf2.x;

4024

y2=pdf2.y;

4016

y2=pdf2.y;

4025

%find the pdf with a larger min, force it to have the same min, and insert

4017

%find the pdf with a larger min, force it to have the same min, and insert

4026

%probability = 0

4018

%probability = 0

4027

min1=pdf1.x(1);

4019

min1=pdf1.x(1);

4028

min2=pdf2.x(1);

4020

min2=pdf2.x(1);

4029

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

4021

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

4030

if min1<min2

4022

if min1<min2

4031

x2=[pdf1.x(1:shift_amount) pdf2.x];

4023

x2=[pdf1.x(1:shift_amount) pdf2.x];

4032

y2=[zeros(1,shift_amount) pdf2.y];

4024

y2=[zeros(1,shift_amount) pdf2.y];

4033

else

4025

else

4034

x1=[pdf2.x(1:shift_amount) pdf1.x];

4026

x1=[pdf2.x(1:shift_amount) pdf1.x];

4035

y1=[zeros(1,shift_amount) pdf1.y];

4027

y1=[zeros(1,shift_amount) pdf1.y];

4036

end

4028

end

4037

%find the pdf with smaller max, force it to have the same max, and insert

4029

%find the pdf with smaller max, force it to have the same max, and insert

4038

%probability=0

4030

%probability=0

4039

L1=length(x1);

4031

L1=length(x1);

4040

L2=length(x2);

4032

L2=length(x2);

4041

Ldiff=abs(L1-L2);

4033

Ldiff=abs(L1-L2);

4042

if L1>L2

4034

if L1>L2

4043

out_x=x1;

4035

out_x=x1;

4044

y2=[y2 zeros(1,Ldiff)];

4036

y2=[y2 zeros(1,Ldiff)];

4045

else

4037

else

4046

out_x=x2;

4038

out_x=x2;

4047

y1=[y1 zeros(1,Ldiff)];

4039

y1=[y1 zeros(1,Ldiff)];

4048

end

4040

end

4049

%now the 2 pdfs have the same voltage axis, add probabilities together

4041

%now the 2 pdfs have the same voltage axis, add probabilities together

4050

%renormalization is not handled here, so the output pdf will not have sum=1

4042

%renormalization is not handled here, so the output pdf will not have sum=1

4051

%It is the responsibility of the calling function to handle renormalization

4043

%It is the responsibility of the calling function to handle renormalization

4052

%if needed

4044

%if needed

4053

out_y=y1+y2;

4045

out_y=y1+y2;

4054

out_pdf.x=out_x;

4046

out_pdf.x=out_x;

4055

out_pdf.y=out_y;

4047

out_pdf.y=out_y;

4056

out_pdf.BinSize=pdf1.BinSize;

4048

out_pdf.BinSize=pdf1.BinSize;

4057

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

4049

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

4058

4050

4059

%original method:

4051

%original method:

4060

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

4052

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

4061

% for i=1:length(s11in1)

4053

% for i=1:length(s11in1)

4062

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

4054

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

4063

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

4055

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

4064

% end

4056

% end

4065

% t1=stot(s1);

4057

% t1=stot(s1);

4066

% t2=stot(s2);

4058

% t2=stot(s2);

4067

% for i=1:length(s11in1)

4059

% for i=1:length(s11in1)

4068

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

4060

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

4069

% end

4061

% end

4070

% s3=ttos(t3);

4062

% s3=ttos(t3);

4071

% s11out=s3(1,1,:);

4063

% s11out=s3(1,1,:);

4072

% s11out=transpose(s11out(:));

4064

% s11out=transpose(s11out(:));

4073

% s12out=s3(1,2,:);

4065

% s12out=s3(1,2,:);

4074

% s12out=transpose(s12out(:));

4066

% s12out=transpose(s12out(:));

4075

% s21out=s3(2,1,:);

4067

% s21out=s3(2,1,:);

4076

% s21out=transpose(s21out(:));

4068

% s21out=transpose(s21out(:));

4077

% s22out=s3(2,2,:);

4069

% s22out=s3(2,2,:);

4078

% s22out=transpose(s22out(:));

4070

% s22out=transpose(s22out(:));

4079

4071

4080

4072

4081

%vectorized method:

4073

%vectorized method:

4082

s1(1,1,:)=s11in1;

4074

s1(1,1,:)=s11in1;

4083

s1(1,2,:)=s12in1;

4075

s1(1,2,:)=s12in1;

4084

s1(2,1,:)=s21in1;

4076

s1(2,1,:)=s21in1;

4085

s1(2,2,:)=s22in1;

4077

s1(2,2,:)=s22in1;

4086

s2(1,1,:)=s11in2;

4078

s2(1,1,:)=s11in2;

4087

s2(1,2,:)=s12in2;

4079

s2(1,2,:)=s12in2;

4088

s2(2,1,:)=s21in2;

4080

s2(2,1,:)=s21in2;

4089

s2(2,2,:)=s22in2;

4081

s2(2,2,:)=s22in2;

4090

4082

4091

4083

4092

N = (1-s1(2,2,:).*s2(1,1,:)) ;

4084

N = (1-s1(2,2,:).*s2(1,1,:)) ;

4093

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

4085

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

4094

s12out = s1(1,2,:).*s2(1,2,:)./N ;

4086

s12out = s1(1,2,:).*s2(1,2,:)./N ;

4095

s21out = s2(2,1,:).*s1(2,1,:)./N;

4087

s21out = s2(2,1,:).*s1(2,1,:)./N;

4096

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

4088

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

4097

4089

4098

s11out=transpose(squeeze(s11out));

4090

s11out=transpose(squeeze(s11out));

4099

s12out=transpose(squeeze(s12out));

4091

s12out=transpose(squeeze(s12out));

4100

s21out=transpose(squeeze(s21out));

4092

s21out=transpose(squeeze(s21out));

4101

s22out=transpose(squeeze(s22out));

4093

s22out=transpose(squeeze(s22out));

4102

function p=conv_fct(p1, p2)

4094

function p=conv_fct(p1, p2)

4103

if p1.BinSize ~= p2.BinSize

4095

if p1.BinSize ~= p2.BinSize

4104

error('bin size must be equal')

4096

error('bin size must be equal')

4105

end

4097

end

4106

4098

4107

p=p1;

4099

p=p1;

4108

%p.BinSize=p1.BinSize;

4100

%p.BinSize=p1.BinSize;

4109

%p.Min=p1.Min+p2.Min;

4101

%p.Min=p1.Min+p2.Min;

4110

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4102

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4111

p.y=conv2(p1.y, p2.y);

4103

p.y=conv2(p1.y, p2.y);

4112

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

4104

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

4113

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

4105

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

4114

pMax=p.Min+length(p.y)-1;

4106

pMax=p.Min+length(p.y)-1;

4115

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4107

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4116

4108

4117

4109

4118

4110

4119

4111

4120

function p=conv_fct_MeanNotZero(p1, p2)

4112

function p=conv_fct_MeanNotZero(p1, p2)

4121

4113

4122

if p1.BinSize ~= p2.BinSize

4114

if p1.BinSize ~= p2.BinSize

4123

error('bin size must be equal')

4115

error('bin size must be equal')

4124

end

4116

end

4125

4117

4126

p=p1;

4118

p=p1;

4127

%p.BinSize=p1.BinSize;

4119

%p.BinSize=p1.BinSize;

4128

%p.Min=p1.Min+p2.Min;

4120

%p.Min=p1.Min+p2.Min;

4129

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4121

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4130

p.y=conv2(p1.y, p2.y);

4122

p.y=conv2(p1.y, p2.y);

4131

4123

4132

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

4124

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

4133

%But it is faster to pre-multiply BinSize instead of multiplying the entire

4125

%But it is faster to pre-multiply BinSize instead of multiplying the entire

4134

%vector by BinSize

4126

%vector by BinSize

4135

pMax=p.Min+length(p.y)-1;

4127

pMax=p.Min+length(p.y)-1;

4136

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4128

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4137

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

4129

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

4138

4130

4139

%IN:

4131

%IN:

4140

%sbr = pulse response

4132

%sbr = pulse response

4141

%param = COM "param" struct

4133

%param = COM "param" struct

4142

%OP = COM "OP" struct

4134

%OP = COM "OP" struct

4143

%peak_search_range= a limited range to search for the peak (for speed up)

4135

%peak_search_range= a limited range to search for the peak (for speed up)

4144

% it is usually +/- 20 UI

4136

% it is usually +/- 20 UI

4145

%

4137

%

4146

%OUT:

4138

%OUT:

4147

%cursor_i = sampling location

4139

%cursor_i = sampling location

4148

%no_zero_crossing = flag that reveals if sampling is not possible.

4140

%no_zero_crossing = flag that reveals if sampling is not possible.

4149

% When this function is called in optimize_fom, it signals to quit the current case

4141

% When this function is called in optimize_fom, it signals to quit the current case

4150

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

4142

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

4151

% time consuming, so saving the peak in one spot is advantageous

4143

% time consuming, so saving the peak in one spot is advantageous

4152

%zxi = zero crossing index (returned because RXFFE uses it)

4144

%zxi = zero crossing index (returned because RXFFE uses it)

4153

4145

4154

no_zero_crossing=0;

4146

no_zero_crossing=0;

4155

%need to set cursor_i to empty in case no_zero_crossing flag is set

4147

%need to set cursor_i to empty in case no_zero_crossing flag is set

4156

cursor_i=[];

4148

cursor_i=[];

4157

4149

4158

%get peak of pulse and peak index

4150

%get peak of pulse and peak index

4159

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

4151

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

4160

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

4152

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

4161

4153

4162

4154

4163

% initial guess at cursor location (t_s) - based on approximate zero crossing

4155

% initial guess at cursor location (t_s) - based on approximate zero crossing

4164

%limit search space for speed up

4156

%limit search space for speed up

4165

search_start=sbr_peak_i-4*param.samples_per_ui;

4157

search_start=sbr_peak_i-4*param.samples_per_ui;

4166

if search_start<1

4158

if search_start<1

4167

search_start=1;

4159

search_start=1;

4168

end

4160

end

4169

%Find zero crossings

4161

%Find zero crossings

4170

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

4162

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

4171

4163

4172

%Note: the original implementation of zxi:

4164

%Note: the original implementation of zxi:

4173

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

4165

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

4174

% zxi = zxi(zxi<sbr_peak_i);

4166

% zxi = zxi(zxi<sbr_peak_i);

4175

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

4167

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

4176

% The changes to limit search space and remember max(sbr) give 10x speed up

4168

% The changes to limit search space and remember max(sbr) give 10x speed up

4177

% A test case of 25k runs, reduced from 1.2s to 0.1s

4169

% A test case of 25k runs, reduced from 1.2s to 0.1s

4178

4170

4179

4171

4180

if isempty(zxi)

4172

if isempty(zxi)

4181

%if no zero crossing, the calling program must respond (since sample point will be empty)

4173

%if no zero crossing, the calling program must respond (since sample point will be empty)

4182

no_zero_crossing=1;

4174

no_zero_crossing=1;

4183

return;

4175

return;

4184

elseif length(zxi)>1

4176

elseif length(zxi)>1

4185

%only need the last zero crossing

4177

%only need the last zero crossing

4186

zxi=zxi(end);

4178

zxi=zxi(end);

4187

end

4179

end

4188

if param.ndfe==0

4180

if param.ndfe==0

4189

max_dfe1=0;

4181

max_dfe1=0;

4190

else

4182

else

4191

max_dfe1=param.bmax(1);

4183

max_dfe1=param.bmax(1);

4192

end

4184

end

4193

% adjust cursor_i to Solve equation 93A-25 %%

4185

% adjust cursor_i to Solve equation 93A-25 %%

4194

% Muller-Mueller criterion with DFE

4186

% Muller-Mueller criterion with DFE

4195

mm_range = zxi+(0:2*param.samples_per_ui);

4187

mm_range = zxi+(0:2*param.samples_per_ui);

4196

switch OP.CDR

4188

switch OP.CDR

4197

case 'Mod-MM'

4189

case 'Mod-MM'

4198

mm_metric = ...

4190

mm_metric = ...

4199

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

4191

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

4200

otherwise % MM

4192

otherwise % MM

4201

%MM is generally: first precursor = 0

4193

%MM is generally: first precursor = 0

4202

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

4194

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

4203

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

4195

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

4204

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

4196

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

4205

%first precursor = first postcursor - max_dfe

4197

%first precursor = first postcursor - max_dfe

4206

mm_metric = ...

4198

mm_metric = ...

4207

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

4199

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

4208

end

4200

end

4209

[~, mm_cursor_offset] = min(mm_metric);

4201

[~, mm_cursor_offset] = min(mm_metric);

4210

4202

4211

%cursor_i = the sample location

4203

%cursor_i = the sample location

4212

cursor_i = zxi+mm_cursor_offset-1;

4204

cursor_i = zxi+mm_cursor_offset-1;

4213

function pdf=d_cpdf( binsize, values, probs)

4205

function pdf=d_cpdf( binsize, values, probs)

4214

% p=cpdf(type, ...)

4206

% p=cpdf(type, ...)

4215

%

4207

%

4216

% CPDF is a probability mass function for discrete distributions or an

4208

% CPDF is a probability mass function for discrete distributions or an

4217

% approxmation of a PDF for continuous distributions.

4209

% approxmation of a PDF for continuous distributions.

4218

%

4210

%

4219

% cpdf is internally normalized so that the sum of probabilities is 1

4211

% cpdf is internally normalized so that the sum of probabilities is 1

4220

% (regardless of bin size).

4212

% (regardless of bin size).

4221

4213

4222

% Internal fields:

4214

% Internal fields:

4223

% Min: *bin number* of minimum value.

4215

% Min: *bin number* of minimum value.

4224

% BinSize: size of PDF bins. Bin center is the representative value.

4216

% BinSize: size of PDF bins. Bin center is the representative value.

4225

% Vec: vector of probabilities per bin.

4217

% Vec: vector of probabilities per bin.

4226

4218

4227

%speed up for initializing empty pdf

4219

%speed up for initializing empty pdf

4228

if all(values==0)

4220

if all(values==0)

4229

pdf.BinSize=binsize;

4221

pdf.BinSize=binsize;

4230

pdf.Min=0;

4222

pdf.Min=0;

4231

pdf.y=1;

4223

pdf.y=1;

4232

pdf.x=0;

4224

pdf.x=0;

4233

return;

4225

return;

4234

end

4226

end

4235

4227

4236

if ~issorted(values)

4228

if ~issorted(values)

4237

[values,si]=sort(values);

4229

[values,si]=sort(values);

4238

probs=probs(si);

4230

probs=probs(si);

4239

end

4231

end

4240

values=binsize*round(values/binsize);

4232

values=binsize*round(values/binsize);

4241

t=(values(1):binsize:values(end));

4233

t=(values(1):binsize:values(end));

4242

pdf.Min=values(1)/binsize;

4234

pdf.Min=values(1)/binsize;

4243

pdf.y=zeros(size(t));

4235

pdf.y=zeros(size(t));

4244

for k=1:length(values)

4236

for k=1:length(values)

4245

if k==1

4237

if k==1

4246

bin=1;

4238

bin=1;

4247

elseif k==length(values)

4239

elseif k==length(values)

4248

bin=length(t);

4240

bin=length(t);

4249

else

4241

else

4250

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

4242

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

4251

end

4243

end

4252

pdf.y(bin) = pdf.y(bin)+probs(k);

4244

pdf.y(bin) = pdf.y(bin)+probs(k);

4253

end

4245

end

4254

4246

4255

pdf.BinSize=binsize;

4247

pdf.BinSize=binsize;

4256

pdf.y=pdf.y/sum(pdf.y);

4248

pdf.y=pdf.y/sum(pdf.y);

4257

if any(~isreal(pdf.y)) || any(pdf.y<0)

4249

if any(~isreal(pdf.y)) || any(pdf.y<0)

4258

error('PDF must be real and nonnegative');

4250

error('PDF must be real and nonnegative');

4259

end

4251

end

4260

support=find(pdf.y);

4252

support=find(pdf.y);

4261

pdf.y=pdf.y(support(1):support(end));

4253

pdf.y=pdf.y(support(1):support(end));

4262

pdf.Min=pdf.Min+(support(1)-1);

4254

pdf.Min=pdf.Min+(support(1)-1);

4263

pdf.x=(pdf.Min:-pdf.Min)*binsize;

4255

pdf.x=(pdf.Min:-pdf.Min)*binsize;

4264

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

4256

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

4265

4257

4266

if isrow(input)

4258

if isrow(input)

4267

max_threshold=max_threshold(:).';

4259

max_threshold=max_threshold(:).';

4268

min_threshold=min_threshold(:).';

4260

min_threshold=min_threshold(:).';

4269

else

4261

else

4270

max_threshold=max_threshold(:);

4262

max_threshold=max_threshold(:);

4271

min_threshold=min_threshold(:);

4263

min_threshold=min_threshold(:);

4272

end

4264

end

4273

4265

4274

clip_output=input;

4266

clip_output=input;

4275

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

4267

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

4276

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

4268

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

4277

4269

4278

4270

4279

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

4271

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

4280

[ncases, mele]=size(param.z_p_tx_cases);

4272

[ncases, mele]=size(param.z_p_tx_cases);

4281

if mele ==2

4273

if mele ==2

4282

param.flex=2;

4274

param.flex=2;

4283

elseif mele==4

4275

elseif mele==4

4284

param.flex=4;

4276

param.flex=4;

4285

elseif mele==1

4277

elseif mele==1

4286

param.flex=1;

4278

param.flex=1;

4287

else

4279

else

4288

error(springf('config file syntax error'))

4280

error(springf('config file syntax error'))

4289

end

4281

end

4290

4282

4291

4283

4292

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

4284

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

4293

% display bathtub curves in one axis per test case.

4285

% display bathtub curves in one axis per test case.

4294

% h=findall(0, 'Name', 'COM results');

4286

% h=findall(0, 'Name', 'COM results');

4295

if ~exist('h','var')

4287

if ~exist('h','var')

4296

msgtext = cell(1, length(OP.pkg_len_select));

4288

msgtext = cell(1, length(OP.pkg_len_select));

4297

msgcolor = 'g';

4289

msgcolor = 'g';

4298

else

4290

else

4299

msgtext=get(findobj(h, 'type', 'text'), 'string');

4291

msgtext=get(findobj(h, 'type', 'text'), 'string');

4300

msgcolor = get(h, 'color');

4292

msgcolor = get(h, 'color');

4301

close(h); % will be recreated

4293

close(h); % will be recreated

4302

end

4294

end

4303

msgctr=size(msgtext,1)+1;

4295

msgctr=size(msgtext,1)+1;

4304

if ~OP.ERL_ONLY

4296

if ~OP.ERL_ONLY

4305

switch OP.PHY

4297

switch OP.PHY

4306

case 'C2M'

4298

case 'C2M'

4307

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4299

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4308

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4300

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4309

msg, VEO_mV);

4301

msg, VEO_mV);

4310

else

4302

else

4311

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4303

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4312

msg, VEO_mV);

4304

msg, VEO_mV);

4313

msgcolor = 'r';

4305

msgcolor = 'r';

4314

end

4306

end

4315

4307

4316

if VEC_dB <= param.VEC_pass_threshold

4308

if VEC_dB <= param.VEC_pass_threshold

4317

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4309

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4318

(msg), VEC_dB);

4310

(msg), VEC_dB);

4319

else

4311

else

4320

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4312

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4321

(msg), VEC_dB);

4313

(msg), VEC_dB);

4322

msgcolor = 'r';

4314

msgcolor = 'r';

4323

end

4315

end

4324

case 'C2C'

4316

case 'C2C'

4325

if COM >= param.pass_threshold

4317

if COM >= param.pass_threshold

4326

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4318

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4327

% msg, COM);

4319

% msg, COM);

4328

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4320

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4329

msg, COM);

4321

msg, COM);

4330

else

4322

else

4331

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4323

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4332

% msg, COM);

4324

% msg, COM);

4333

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4325

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4334

msg, COM);

4326

msg, COM);

4335

msgcolor = 'r';

4327

msgcolor = 'r';

4336

end

4328

end

4337

% begin yasuo patch 3/18/2019

4329

% begin yasuo patch 3/18/2019

4338

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4330

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4339

% end yasuo patch

4331

% end yasuo patch

4340

case 'C2Mcom'

4332

case 'C2Mcom'

4341

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4333

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4342

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4334

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4343

msg, VEO_mV);

4335

msg, VEO_mV);

4344

else

4336

else

4345

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4337

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4346

msg, VEO_mV);

4338

msg, VEO_mV);

4347

msgcolor = 'r';

4339

msgcolor = 'r';

4348

end

4340

end

4349

4341

4350

if VEC_dB <= param.VEC_pass_threshold

4342

if VEC_dB <= param.VEC_pass_threshold

4351

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4343

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4352

(msg), VEC_dB);

4344

(msg), VEC_dB);

4353

else

4345

else

4354

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4346

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4355

(msg), VEC_dB);

4347

(msg), VEC_dB);

4356

msgcolor = 'r';

4348

msgcolor = 'r';

4357

end

4349

end

4358

if COM >= param.pass_threshold

4350

if COM >= param.pass_threshold

4359

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4351

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4360

% msg, COM);

4352

% msg, COM);

4361

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4353

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4362

msg, COM);

4354

msg, COM);

4363

else

4355

else

4364

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4356

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4365

% msg, COM);

4357

% msg, COM);

4366

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4358

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4367

msg, COM);

4359

msg, COM);

4368

msgcolor = 'r';

4360

msgcolor = 'r';

4369

end

4361

end

4370

% begin yasuo patch 3/18/2019

4362

% begin yasuo patch 3/18/2019

4371

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4363

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4372

% end yasuo patch

4364

% end yasuo patch

4373

end

4365

end

4374

end

4366

end

4375

if OP.ERL

4367

if OP.ERL

4376

if ~isempty(ERL)

4368

if ~isempty(ERL)

4377

if min_ERL >= param.ERL_pass_threshold

4369

if min_ERL >= param.ERL_pass_threshold

4378

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4370

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4379

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4371

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4380

else

4372

else

4381

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4373

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4382

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4374

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4383

msgcolor = 'r';

4375

msgcolor = 'r';

4384

end

4376

end

4385

end

4377

end

4386

end

4378

end

4387

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4379

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4388

set(h, 'color', msgcolor, 'tag', 'COM');

4380

set(h, 'color', msgcolor, 'tag', 'COM');

4389

movegui(h, 'center');

4381

movegui(h, 'center');

4390

else % no windows

4382

else % no windows

4391

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4383

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4392

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4384

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4393

if ~OP.ERL_ONLY

4385

if ~OP.ERL_ONLY

4394

switch OP.PHY

4386

switch OP.PHY

4395

case 'C2C'

4387

case 'C2C'

4396

if COM >= param.pass_threshold

4388

if COM >= param.pass_threshold

4397

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4389

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4398

else

4390

else

4399

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4391

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4400

end

4392

end

4401

% begin yasuo patch 3/18/2019

4393

% begin yasuo patch 3/18/2019

4402

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4394

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4403

% end yasuo patch

4395

% end yasuo patch

4404

case 'C2Mcom'

4396

case 'C2Mcom'

4405

if VEC_dB <= param.VEC_pass_threshold

4397

if VEC_dB <= param.VEC_pass_threshold

4406

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4398

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4407

else

4399

else

4408

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4400

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4409

end

4401

end

4410

4402

4411

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4403

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4412

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4404

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4413

else

4405

else

4414

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4406

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4415

end

4407

end

4416

if COM >= param.pass_threshold

4408

if COM >= param.pass_threshold

4417

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4409

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4418

else

4410

else

4419

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4411

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4420

end

4412

end

4421

% begin yasuo patch 3/18/2019

4413

% begin yasuo patch 3/18/2019

4422

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4414

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4423

% end yasuo patch

4415

% end yasuo patch

4424

case 'C2M'

4416

case 'C2M'

4425

if VEC_dB <= param.VEC_pass_threshold

4417

if VEC_dB <= param.VEC_pass_threshold

4426

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4418

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4427

else

4419

else

4428

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4420

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4429

end

4421

end

4430

4422

4431

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4423

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4432

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4424

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4433

else

4425

else

4434

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4426

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4435

end

4427

end

4436

end

4428

end

4437

end

4429

end

4438

if OP.ERL

4430

if OP.ERL

4439

if ~isempty(ERL)

4431

if ~isempty(ERL)

4440

if min_ERL >= param.ERL_pass_threshold

4432

if min_ERL >= param.ERL_pass_threshold

4441

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4433

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4442

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4434

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4443

else

4435

else

4444

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4436

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4445

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4437

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4446

end

4438

end

4447

end

4439

end

4448

end

4440

end

4449

end

4441

end

4450

4442

4451

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4443

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4452

4444

4453

%Left eye Width (Top Eye)

4445

%Left eye Width (Top Eye)

4454

left_top=eye_contour(half_UI:-1:1,1);

4446

left_top=eye_contour(half_UI:-1:1,1);

4455

%vref_crossing is the first point less than vref (usually first point < 0)

4447

%vref_crossing is the first point less than vref (usually first point < 0)

4456

vref_crossing=find(left_top<vref,1,'first');

4448

vref_crossing=find(left_top<vref,1,'first');

4457

if isempty(vref_crossing)

4449

if isempty(vref_crossing)

4458

%this case handles completely open eye

4450

%this case handles completely open eye

4459

L1=half_UI;

4451

L1=half_UI;

4460

elseif vref_crossing==1

4452

elseif vref_crossing==1

4461

%this case handles completely closed eye

4453

%this case handles completely closed eye

4462

L1=0;

4454

L1=0;

4463

else

4455

else

4464

%this case handles the normal eye

4456

%this case handles the normal eye

4465

%INT is a linear interpolation between the 2 points on either side of

4457

%INT is a linear interpolation between the 2 points on either side of

4466

%vref to determine where the vref crossing occurred. In systems with

4458

%vref to determine where the vref crossing occurred. In systems with

4467

%a small number of samples_per_UI, interpolation improves accuracy over

4459

%a small number of samples_per_UI, interpolation improves accuracy over

4468

%just using the integer sample point

4460

%just using the integer sample point

4469

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4461

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4470

L1=half_UI-INT;

4462

L1=half_UI-INT;

4471

end

4463

end

4472

%Left eye Width (Bottom Eye)

4464

%Left eye Width (Bottom Eye)

4473

left_bot=eye_contour(half_UI:-1:1,2);

4465

left_bot=eye_contour(half_UI:-1:1,2);

4474

vref_crossing=find(left_bot>vref,1,'first');

4466

vref_crossing=find(left_bot>vref,1,'first');

4475

if isempty(vref_crossing)

4467

if isempty(vref_crossing)

4476

L0=half_UI;

4468

L0=half_UI;

4477

elseif vref_crossing==1

4469

elseif vref_crossing==1

4478

L0=0;

4470

L0=0;

4479

else

4471

else

4480

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4472

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4481

L0=half_UI-INT;

4473

L0=half_UI-INT;

4482

end

4474

end

4483

%Right eye Width (Top Eye)

4475

%Right eye Width (Top Eye)

4484

right_top=eye_contour(half_UI:end,1);

4476

right_top=eye_contour(half_UI:end,1);

4485

vref_crossing=find(right_top<vref,1,'first');

4477

vref_crossing=find(right_top<vref,1,'first');

4486

if isempty(vref_crossing)

4478

if isempty(vref_crossing)

4487

R1=samples_per_UI-half_UI;

4479

R1=samples_per_UI-half_UI;

4488

elseif vref_crossing==1

4480

elseif vref_crossing==1

4489

R1=0;

4481

R1=0;

4490

else

4482

else

4491

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4483

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4492

R1=INT-half_UI;

4484

R1=INT-half_UI;

4493

end

4485

end

4494

%Right eye Width (Bottom Eye)

4486

%Right eye Width (Bottom Eye)

4495

right_bot=eye_contour(half_UI:end,2);

4487

right_bot=eye_contour(half_UI:end,2);

4496

vref_crossing=find(right_bot>vref,1,'first');

4488

vref_crossing=find(right_bot>vref,1,'first');

4497

if isempty(vref_crossing)

4489

if isempty(vref_crossing)

4498

R0=samples_per_UI-half_UI;

4490

R0=samples_per_UI-half_UI;

4499

elseif vref_crossing==1

4491

elseif vref_crossing==1

4500

R0=0;

4492

R0=0;

4501

else

4493

else

4502

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4494

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4503

R0=INT-half_UI;

4495

R0=INT-half_UI;

4504

end

4496

end

4505

4497

4506

%L1 = top left eye width

4498

%L1 = top left eye width

4507

%L0 = bottom left eye width

4499

%L0 = bottom left eye width

4508

%Left eye width is the minimum

4500

%Left eye width is the minimum

4509

%R1 = top right eye width

4501

%R1 = top right eye width

4510

%R0 = bottom right eye width

4502

%R0 = bottom right eye width

4511

%Right eye width is the minimum

4503

%Right eye width is the minimum

4512

Left_EW=min([L1 L0]);

4504

Left_EW=min([L1 L0]);

4513

Right_EW=min([R1 R0]);

4505

Right_EW=min([R1 R0]);

4514

4506

4515

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4507

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4516

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4508

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4517

% find the location of the DFE bank

4509

% find the location of the DFE bank

4518

% hisi: waveform with cursor values;

4510

% hisi: waveform with cursor values;

4519

% idx_st: starting index;

4511

% idx_st: starting index;

4520

% idx_en: ending index ;

4512

% idx_en: ending index ;

4521

% tap_bk: number of taps per bank;

4513

% tap_bk: number of taps per bank;

4522

% bmaxg: maximum coefficient;

4514

% bmaxg: maximum coefficient;

4523

4515

4524

hisi=hisi(:);

4516

hisi=hisi(:);

4525

len=idx_en-idx_st+1;

4517

len=idx_en-idx_st+1;

4526

h0=abs(hisi(idx_st:idx_en));

4518

h0=abs(hisi(idx_st:idx_en));

4527

h1=max(0,h0-bmaxg*curval);

4519

h1=max(0,h0-bmaxg*curval);

4528

4520

4529

%if cursor value is negative, force h1 to all zeros

4521

%if cursor value is negative, force h1 to all zeros

4530

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4522

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4531

%this makes the weakest isi the most desirable to choose so everything breaks

4523

%this makes the weakest isi the most desirable to choose so everything breaks

4532

if curval<0

4524

if curval<0

4533

h1=zeros(size(h0));

4525

h1=zeros(size(h0));

4534

end

4526

end

4535

4527

4536

h0n=zeros(len-tap_bk+1,1);

4528

h0n=zeros(len-tap_bk+1,1);

4537

h1n=h0n;

4529

h1n=h0n;

4538

4530

4539

for ii=1:tap_bk

4531

for ii=1:tap_bk

4540

h0tmp=h0(ii:ii+len-tap_bk);

4532

h0tmp=h0(ii:ii+len-tap_bk);

4541

h0n=h0n+h0tmp.^2;

4533

h0n=h0n+h0tmp.^2;

4542

h1tmp=h1(ii:ii+len-tap_bk);

4534

h1tmp=h1(ii:ii+len-tap_bk);

4543

h1n=h1n+h1tmp.^2;

4535

h1n=h1n+h1tmp.^2;

4544

end

4536

end

4545

4537

4546

ndiff=h0n-h1n;

4538

ndiff=h0n-h1n;

4547

4539

4548

min_energy = -Inf;

4540

min_energy = -Inf;

4549

4541

4550

idx=zeros(1,tap_bk*N_bg);

4542

idx=zeros(1,tap_bk*N_bg);

4551

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4543

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4552

set_next_bank=0;

4544

set_next_bank=0;

4553

%Loop through each group

4545

%Loop through each group

4554

for k=1:N_bg

4546

for k=1:N_bg

4555

%Sort to choose the strongest

4547

%Sort to choose the strongest

4556

[~,val_sort]=sort(ndiff,'descend');

4548

[~,val_sort]=sort(ndiff,'descend');

4557

if k==1

4549

if k==1

4558

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4550

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4559

if isequal(sort(val_sort(ordered_set)),ordered_set)

4551

if isequal(sort(val_sort(ordered_set)),ordered_set)

4560

idx=1:N_bg*tap_bk;

4552

idx=1:N_bg*tap_bk;

4561

break;

4553

break;

4562

end

4554

end

4563

end

4555

end

4564

if set_next_bank>0

4556

if set_next_bank>0

4565

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4557

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4566

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4558

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4567

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4559

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4568

set_next_bank=0;

4560

set_next_bank=0;

4569

ndiff(new_bank)=min_energy;

4561

ndiff(new_bank)=min_energy;

4570

bad_start=new_bank(1)-tap_bk+1;

4562

bad_start=new_bank(1)-tap_bk+1;

4571

bad_end=new_bank(1)-1;

4563

bad_end=new_bank(1)-1;

4572

if bad_end<=0

4564

if bad_end<=0

4573

badV=[];

4565

badV=[];

4574

elseif bad_start>0

4566

elseif bad_start>0

4575

badV=bad_start:bad_end;

4567

badV=bad_start:bad_end;

4576

else

4568

else

4577

badV=1:bad_end;

4569

badV=1:bad_end;

4578

end

4570

end

4579

if ~isempty(badV)

4571

if ~isempty(badV)

4580

ndiff(badV)=min_energy;

4572

ndiff(badV)=min_energy;

4581

end

4573

end

4582

continue;

4574

continue;

4583

end

4575

end

4584

%potential bank = the strongest tap group

4576

%potential bank = the strongest tap group

4585

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4577

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4586

if k==N_bg

4578

if k==N_bg

4587

%Last group: just choose the strongest

4579

%Last group: just choose the strongest

4588

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4580

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4589

break;

4581

break;

4590

end

4582

end

4591

4583

4592

do_it_again=1;

4584

do_it_again=1;

4593

first_time=1;

4585

first_time=1;

4594

num_loops=0;

4586

num_loops=0;

4595

while do_it_again

4587

while do_it_again

4596

do_it_again=0;

4588

do_it_again=0;

4597

if num_loops>length(ndiff)

4589

if num_loops>length(ndiff)

4598

break;

4590

break;

4599

end

4591

end

4600

%note badV: taps smaller and less than 1 group away

4592

%note badV: taps smaller and less than 1 group away

4601

bad_start=new_bank(1)-tap_bk+1;

4593

bad_start=new_bank(1)-tap_bk+1;

4602

bad_end=new_bank(1)-1;

4594

bad_end=new_bank(1)-1;

4603

if bad_end<=0

4595

if bad_end<=0

4604

badV=[];

4596

badV=[];

4605

elseif bad_start>0

4597

elseif bad_start>0

4606

badV=bad_start:bad_end;

4598

badV=bad_start:bad_end;

4607

else

4599

else

4608

badV=1:bad_end;

4600

badV=1:bad_end;

4609

end

4601

end

4610

for j=length(badV):-1:1

4602

for j=length(badV):-1:1

4611

if any(badV(j)-idx==0)

4603

if any(badV(j)-idx==0)

4612

badV(j)=[];

4604

badV(j)=[];

4613

end

4605

end

4614

end

4606

end

4615

%note goodV: the tap exactly 1 tap_bk smaller

4607

%note goodV: the tap exactly 1 tap_bk smaller

4616

goodV=new_bank(1)-tap_bk;

4608

goodV=new_bank(1)-tap_bk;

4617

if ~isempty(badV)

4609

if ~isempty(badV)

4618

if ~first_time

4610

if ~first_time

4619

[~,val_sort]=sort(ndiff,'descend');

4611

[~,val_sort]=sort(ndiff,'descend');

4620

end

4612

end

4621

first_time=0;

4613

first_time=0;

4622

checkV=[badV new_bank];

4614

checkV=[badV new_bank];

4623

4615

4624

badV_pos=zeros(1,length(badV));

4616

badV_pos=zeros(1,length(badV));

4625

for j=1:length(badV)

4617

for j=1:length(badV)

4626

badV_pos(j)=find(badV(j)==val_sort);

4618

badV_pos(j)=find(badV(j)==val_sort);

4627

end

4619

end

4628

4620

4629

%loop through the sorted list to find the first tap outside the group and not a member of badV

4621

%loop through the sorted list to find the first tap outside the group and not a member of badV

4630

found_goodV=0;

4622

found_goodV=0;

4631

for ii=1:length(val_sort)

4623

for ii=1:length(val_sort)

4632

if val_sort(ii)==goodV

4624

if val_sort(ii)==goodV

4633

found_goodV=1;

4625

found_goodV=1;

4634

break;

4626

break;

4635

end

4627

end

4636

if all(val_sort(ii)-checkV~=0)

4628

if all(val_sort(ii)-checkV~=0)

4637

break;

4629

break;

4638

end

4630

end

4639

end

4631

end

4640

4632

4641

if ~found_goodV && min(badV_pos)<ii

4633

if ~found_goodV && min(badV_pos)<ii

4642

%if goodV wasn't found and bad taps occur before non group members are found

4634

%if goodV wasn't found and bad taps occur before non group members are found

4643

%throw out the strongest tap and take the next strongest

4635

%throw out the strongest tap and take the next strongest

4644

do_it_again=1;

4636

do_it_again=1;

4645

ndiff(new_bank(1))=min_energy;

4637

ndiff(new_bank(1))=min_energy;

4646

%speed up: new max_val is always val_sort(2)

4638

%speed up: new max_val is always val_sort(2)

4647

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4639

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4648

end

4640

end

4649

if found_goodV

4641

if found_goodV

4650

%if goodV was found, set the next bank to goodV

4642

%if goodV was found, set the next bank to goodV

4651

set_next_bank=goodV;

4643

set_next_bank=goodV;

4652

end

4644

end

4653

end

4645

end

4654

num_loops=num_loops+1;

4646

num_loops=num_loops+1;

4655

end

4647

end

4656

%at the end, the floating taps are set to idx

4648

%at the end, the floating taps are set to idx

4657

%and ndiff has illegal values set to zero

4649

%and ndiff has illegal values set to zero

4658

ndiff(new_bank)=min_energy;

4650

ndiff(new_bank)=min_energy;

4659

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4651

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4660

if ~isempty(badV)

4652

if ~isempty(badV)

4661

ndiff(badV)=min_energy;

4653

ndiff(badV)=min_energy;

4662

end

4654

end

4663

end

4655

end

4664

4656

4665

4657

4666

idx=idx+idx_st-1;

4658

idx=idx+idx_st-1;

4667

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4659

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4668

4660

4669

% hisi = postcursor isi

4661

% hisi = postcursor isi

4670

% N_b = number of fixed dfe taps (before floating taps begin)

4662

% N_b = number of fixed dfe taps (before floating taps begin)

4671

% N_bf = number of floating taps per group

4663

% N_bf = number of floating taps per group

4672

% N_bg = nubmber of groups

4664

% N_bg = nubmber of groups

4673

% N_bmax = max tap number that can be used for floating tap

4665

% N_bmax = max tap number that can be used for floating tap

4674

% bmaxg = max tap strength for floating taps

4666

% bmaxg = max tap strength for floating taps

4675

% curval = value of the cursor

4667

% curval = value of the cursor

4676

4668

4677

4669

4678

if nargin<8, dfe_delta=0;end

4670

if nargin<8, dfe_delta=0;end

4679

4671

4680

4672

4681

tap_coef=zeros(1,length(hisi));

4673

tap_coef=zeros(1,length(hisi));

4682

b=zeros(1,length(hisi));

4674

b=zeros(1,length(hisi));

4683

4675

4684

4676

4685

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4677

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4686

4678

4687

%Apply DFE to all taps

4679

%Apply DFE to all taps

4688

flt_curval=hisi(tap_loc);

4680

flt_curval=hisi(tap_loc);

4689

if dfe_delta~=0

4681

if dfe_delta~=0

4690

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4682

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4691

dfe_delta.*sign(flt_curval)*curval;

4683

dfe_delta.*sign(flt_curval)*curval;

4692

else

4684

else

4693

flt_curval_q=hisi(tap_loc);

4685

flt_curval_q=hisi(tap_loc);

4694

end

4686

end

4695

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4687

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4696

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4688

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4697

tap_coef(tap_loc)=applied_coef;

4689

tap_coef(tap_loc)=applied_coef;

4698

4690

4699

4691

4700

4692

4701

tap_loc=sort(tap_loc,'ascend');

4693

tap_loc=sort(tap_loc,'ascend');

4702

b(tap_loc)=bmaxg;

4694

b(tap_loc)=bmaxg;

4703

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4695

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4704

% Richard Mellitz: 04/23/2019

4696

% Richard Mellitz: 04/23/2019

4705

% hisi is the isi 1 ui/sample

4697

% hisi is the isi 1 ui/sample

4706

% N_b number of fixed dfe taps

4698

% N_b number of fixed dfe taps

4707

% N_bf number of floating taps per group

4699

% N_bf number of floating taps per group

4708

% N_bg number of floating tap groups. 1 2 or 3 right now

4700

% N_bg number of floating tap groups. 1 2 or 3 right now

4709

% N_bmax number of ui for the max reach of the floating taps

4701

% N_bmax number of ui for the max reach of the floating taps

4710

% bmaxg limit for the floating taps

4702

% bmaxg limit for the floating taps

4711

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4703

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4712

%

4704

%

4713

%

4705

%

4714

% function to remove isi or add noise above bmaxg

4706

% function to remove isi or add noise above bmaxg

4715

if ~exist('COOP','var'), COOP=0;end

4707

if ~exist('COOP','var'), COOP=0;end

4716

if iscolumn(hisi); hisi=hisi.';end

4708

if iscolumn(hisi); hisi=hisi.';end

4717

hsis_in=hisi;

4709

hsis_in=hisi;

4718

% find all the reduction group taken N_bf at a time

4710

% find all the reduction group taken N_bf at a time

4719

% we are looking for the group when when remove yield the miminim isi, h, power

4711

% we are looking for the group when when remove yield the miminim isi, h, power

4720

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4712

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4721

% add on switch and loop for each potential group

4713

% add on switch and loop for each potential group

4722

switch N_bg

4714

switch N_bg

4723

case 0

4715

case 0

4724

bmax=0;

4716

bmax=0;

4725

return

4717

return

4726

case 1

4718

case 1

4727

end1=N_bmax-N_bf;

4719

end1=N_bmax-N_bf;

4728

end2=N_b+1;

4720

end2=N_b+1;

4729

end3=N_b+1;

4721

end3=N_b+1;

4730

case 2

4722

case 2

4731

end1=N_bmax-N_bf;

4723

end1=N_bmax-N_bf;

4732

end2=N_bmax-N_bf;

4724

end2=N_bmax-N_bf;

4733

end3=N_b+1;

4725

end3=N_b+1;

4734

case 3

4726

case 3

4735

end1=N_bmax-N_bf;

4727

end1=N_bmax-N_bf;

4736

end2=N_bmax-N_bf;

4728

end2=N_bmax-N_bf;

4737

end3=N_bmax-N_bf;

4729

end3=N_bmax-N_bf;

4738

end

4730

end

4739

if COOP

4731

if COOP

4740

for ig1= N_b+1:end1 % now remove the 2nd group

4732

for ig1= N_b+1:end1 % now remove the 2nd group

4741

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4733

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4742

% loop for 2rd group

4734

% loop for 2rd group

4743

for ig2= N_b+1: end2

4735

for ig2= N_b+1: end2

4744

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4736

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4745

if N_bg < 2; hcap2 =hcap; end

4737

if N_bg < 2; hcap2 =hcap; end

4746

for ig3= N_b+1: end3

4738

for ig3= N_b+1: end3

4747

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4739

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4748

if N_bg < 3 ; hcap3=hcap2 ; end

4740

if N_bg < 3 ; hcap3=hcap2 ; end

4749

sigma=norm( hcap3 );

4741

sigma=norm( hcap3 );

4750

if sigma < best_sigma

4742

if sigma < best_sigma

4751

best_sigma=sigma;

4743

best_sigma=sigma;

4752

best_ig1=ig1;

4744

best_ig1=ig1;

4753

best_ig2=ig2;

4745

best_ig2=ig2;

4754

best_ig3=ig3;

4746

best_ig3=ig3;

4755

best_hcap=hcap3;

4747

best_hcap=hcap3;

4756

end

4748

end

4757

end

4749

end

4758

end

4750

end

4759

end

4751

end

4760

else % sequentail

4752

else % sequentail

4761

for ig1= N_b+1:end1 % now remove the 1st group

4753

for ig1= N_b+1:end1 % now remove the 1st group

4762

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4754

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4763

sigma=norm( hcap );

4755

sigma=norm( hcap );

4764

if sigma < best_sigma

4756

if sigma < best_sigma

4765

best_sigma=sigma;

4757

best_sigma=sigma;

4766

best_ig1=ig1;

4758

best_ig1=ig1;

4767

best_hcap=hcap;

4759

best_hcap=hcap;

4768

end

4760

end

4769

end

4761

end

4770

% loop for 2rd group

4762

% loop for 2rd group

4771

hisi=best_hcap;

4763

hisi=best_hcap;

4772

for ig2= N_b+1: end2

4764

for ig2= N_b+1: end2

4773

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4765

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4774

sigma=norm( hcap );

4766

sigma=norm( hcap );

4775

if sigma < best_sigma

4767

if sigma < best_sigma

4776

best_sigma=sigma;

4768

best_sigma=sigma;

4777

best_ig2=ig2;

4769

best_ig2=ig2;

4778

best_hcap=hcap;

4770

best_hcap=hcap;

4779

end

4771

end

4780

end

4772

end

4781

hisi=best_hcap;

4773

hisi=best_hcap;

4782

% loop for 3rd group

4774

% loop for 3rd group

4783

for ig3= N_b+1: end3

4775

for ig3= N_b+1: end3

4784

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4776

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4785

sigma=norm( hcap );

4777

sigma=norm( hcap );

4786

if sigma < best_sigma

4778

if sigma < best_sigma

4787

best_sigma=sigma;

4779

best_sigma=sigma;

4788

best_ig3=ig3;

4780

best_ig3=ig3;

4789

best_hcap=hcap;

4781

best_hcap=hcap;

4790

end

4782

end

4791

end

4783

end

4792

4784

4793

end

4785

end

4794

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4786

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4795

switch N_bg

4787

switch N_bg

4796

case 1

4788

case 1

4797

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4789

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4798

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4790

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4799

case 2

4791

case 2

4800

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4792

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4801

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4793

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4802

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4794

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4803

case 3

4795

case 3

4804

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4796

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4805

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4797

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4806

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4798

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4807

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4799

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4808

end

4800

end

4809

floating_tap_locations=sort(floating_tap_locations);

4801

floating_tap_locations=sort(floating_tap_locations);

4810

if 0 % for code debug

4802

if 0 % for code debug

4811

close force all

4803

close force all

4812

stem(best_hcap,'disp','hcap')

4804

stem(best_hcap,'disp','hcap')

4813

hold on

4805

hold on

4814

stem(bmax,'-k','disp','bmax')

4806

stem(bmax,'-k','disp','bmax')

4815

stem(hisi,'disp','hisi')

4807

stem(hisi,'disp','hisi')

4816

hold off

4808

hold off

4817

end

4809

end

4818

4810

4819

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4811

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4820

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4812

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4821

% Vfilter is vector forced filtered sbr

4813

% Vfilter is vector forced filtered sbr

4822

% Cmod is the ffe tap co-efficient vector

4814

% Cmod is the ffe tap co-efficient vector

4823

% if C is passed, just process V with C else compute C

4815

% if C is passed, just process V with C else compute C

4824

% cmx=param.rx_cmx; number of pre cursor taps

4816

% cmx=param.rx_cmx; number of pre cursor taps

4825

% cpx=param.rx_cps; number of post cursor taps

4817

% cpx=param.rx_cps; number of post cursor taps

4826

% V=sbr; pass pulse response

4818

% V=sbr; pass pulse response

4827

% ix the sample point in the passed pulse response

4819

% ix the sample point in the passed pulse response

4828

% the sample point is recomputed by optimize_fom

4820

% the sample point is recomputed by optimize_fom

4829

% idx - return floating tap location (RIM 9-19-2023)

4821

% idx - return floating tap location (RIM 9-19-2023)

4830

% OP not used for now

4822

% OP not used for now

4831

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4823

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4832

% this allows significant speed up in optimize_fom since FFE is time consuming

4824

% this allows significant speed up in optimize_fom since FFE is time consuming

4833

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4825

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4834

% Vfiltered to be calculated

4826

% Vfiltered to be calculated

4835

% test with load('SBR_FIR_resp.mydata','-mat')

4827

% test with load('SBR_FIR_resp.mydata','-mat')

4836

idx=[];

4828

idx=[];

4837

if nargin<4

4829

if nargin<4

4838

ix=find(V==max(V),1,'first');

4830

ix=find(V==max(V),1,'first');

4839

end

4831

end

4840

if nargin<5

4832

if nargin<5

4841

C=[];

4833

C=[];

4842

end

4834

end

4843

if nargin<6

4835

if nargin<6

4844

return_V=1;

4836

return_V=1;

4845

end

4837

end

4846

cmx=param.RxFFE_cmx;

4838

cmx=param.RxFFE_cmx;

4847

cpx=param.RxFFE_cpx;

4839

cpx=param.RxFFE_cpx;

4848

% do this early on so we can reuse the old code

4840

% do this early on so we can reuse the old code

4849

if param.N_bg ~=0 % must be floating taps

4841

if param.N_bg ~=0 % must be floating taps

4850

cpx=param.N_bmax; % N_f in spreadsheet

4842

cpx=param.N_bmax; % N_f in spreadsheet

4851

end

4843

end

4852

num_taps=cmx+cpx+1;

4844

num_taps=cmx+cpx+1;

4853

cstep=param.RxFFE_stepz;

4845

cstep=param.RxFFE_stepz;

4854

ndfe=param.ndfe;

4846

ndfe=param.ndfe;

4855

spui=param.samples_per_ui;

4847

spui=param.samples_per_ui;

4856

param.current_ffegain=0;

4848

param.current_ffegain=0;

4857

if return_V && ~isempty(C)

4849

if return_V && ~isempty(C)

4858

% RIM 2-3-23 when we just want to EQ not find EQ

4850

% RIM 2-3-23 when we just want to EQ not find EQ

4859

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4851

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4860

Cmod=C;

4852

Cmod=C;

4861

return

4853

return

4862

end

4854

end

4863

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4855

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4864

if ix < length(V)

4856

if ix < length(V)

4865

if isrow(V)

4857

if isrow(V)

4866

if mod(ix,spui) == 0

4858

if mod(ix,spui) == 0

4867

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4859

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4868

else

4860

else

4869

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4861

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4870

end

4862

end

4871

4863

4872

else

4864

else

4873

if mod(ix,spui) == 0

4865

if mod(ix,spui) == 0

4874

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4866

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4875

else

4867

else

4876

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4868

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4877

end

4869

end

4878

end

4870

end

4879

else

4871

else

4880

if isrow(V)

4872

if isrow(V)

4881

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4873

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4882

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4874

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4883

else

4875

else

4884

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4876

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4885

end

4877

end

4886

else

4878

else

4887

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4879

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4888

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4880

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4889

else

4881

else

4890

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4882

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4891

end

4883

end

4892

end

4884

end

4893

end

4885

end

4894

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4886

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4895

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4887

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4896

4888

4897

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4889

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4898

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4890

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4899

% Upen Kareti suggested fix for indexing 11/04/18

4891

% Upen Kareti suggested fix for indexing 11/04/18

4900

if ix < length(V)

4892

if ix < length(V)

4901

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4893

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4902

else

4894

else

4903

ivs=find(vsampled == max(vsampled),1,'first');

4895

ivs=find(vsampled == max(vsampled),1,'first');

4904

end

4896

end

4905

4897

4906

4898

4907

%% create VV matrix of shifted UI spaced sample of the pulse response

4899

%% create VV matrix of shifted UI spaced sample of the pulse response

4908

% only consider the VV matrix that correstonds to the FFE taps

4900

% only consider the VV matrix that correstonds to the FFE taps

4909

VV=zeros(num_taps,num_taps);

4901

VV=zeros(num_taps,num_taps);

4910

for i=1:num_taps

4902

for i=1:num_taps

4911

start_idx=ivs+i-1;

4903

start_idx=ivs+i-1;

4912

end_idx=start_idx-num_taps+1;

4904

end_idx=start_idx-num_taps+1;

4913

VV(:,i)=vsampled(start_idx:-1:end_idx);

4905

VV(:,i)=vsampled(start_idx:-1:end_idx);

4914

end

4906

end

4915

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4907

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4916

%% Apply RXFFE

4908

%% Apply RXFFE

4917

if isempty(C)

4909

if isempty(C)

4918

switch upper(OP.FFE_OPT_METHOD)

4910

switch upper(OP.FFE_OPT_METHOD)

4919

case 'WIENER-HOPF'

4911

case 'WIENER-HOPF'

4920

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4912

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4921

Cmod=C(1:num_taps);

4913

Cmod=C(1:num_taps);

4922

otherwise

4914

otherwise

4923

% cmx+1 is the cursor or sample point

4915

% cmx+1 is the cursor or sample point

4924

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4916

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4925

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4917

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4926

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4918

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4927

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4919

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4928

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4920

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4929

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4921

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4930

end

4922

end

4931

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4923

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4932

if diff(size(VV))==0

4924

if diff(size(VV))==0

4933

%For square matrix, can solve C using simple inv(VV')*FV'

4925

%For square matrix, can solve C using simple inv(VV')*FV'

4934

C=VV'\FV';

4926

C=VV'\FV';

4935

else

4927

else

4936

%otherwise use the general solution with psuedo inverse

4928

%otherwise use the general solution with psuedo inverse

4937

%note: this is the same as doing pinv(VV') but pinv is far slower

4929

%note: this is the same as doing pinv(VV') but pinv is far slower

4938

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4930

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4939

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4931

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4940

end

4932

end

4941

4933

4942

Cmod=C(1:num_taps);

4934

Cmod=C(1:num_taps);

4943

end

4935

end

4944

4936

4945

4937

4946

% added for 4.2 find floating taps with either ISI or taps

4938

% added for 4.2 find floating taps with either ISI or taps

4947

switch lower(OP.RXFFE_FLOAT_CTL)

4939

switch lower(OP.RXFFE_FLOAT_CTL)

4948

case 'taps'

4940

case 'taps'

4949

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4941

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4950

otherwise

4942

otherwise

4951

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4943

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4952

end

4944

end

4953

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4945

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4954

case 'unity cursor'

4946

case 'unity cursor'

4955

Cmod=Cmod/Cmod(cmx+1);

4947

Cmod=Cmod/Cmod(cmx+1);

4956

otherwise

4948

otherwise

4957

Cmod=C;

4949

Cmod=C;

4958

end

4950

end

4959

if cstep ~= 0

4951

if cstep ~= 0

4960

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4952

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4961

end

4953

end

4962

4954

4963

if ~isempty(idx)

4955

if ~isempty(idx)

4964

idx=sort(idx);

4956

idx=sort(idx);

4965

C1=Cmod;

4957

C1=Cmod;

4966

% C1(param.N_tail_start:end)=0;

4958

% C1(param.N_tail_start:end)=0;

4967

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4959

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4968

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4960

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4969

Cmod=C1;

4961

Cmod=C1;

4970

else

4962

else

4971

% Cmod=C;

4963

% Cmod=C;

4972

end

4964

end

4973

4965

4974

% now when ussing RxFFE floating taps need to tag stems correctly and

4966

% now when ussing RxFFE floating taps need to tag stems correctly and

4975

% make sure DFEfloating tap code does not get exectuted

4967

% make sure DFEfloating tap code does not get exectuted

4976

4968

4977

%

4969

%

4978

else

4970

else

4979

Cmod=C;%just us the FFE taps, C, passed for filtering

4971

Cmod=C;%just us the FFE taps, C, passed for filtering

4980

end

4972

end

4981

%%

4973

%%

4982

%% filter the pulse response with the solved FFE

4974

%% filter the pulse response with the solved FFE

4983

% (now option to avoid this and just return Cmod for speed up)

4975

% (now option to avoid this and just return Cmod for speed up)

4984

if return_V

4976

if return_V

4985

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4977

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4986

else

4978

else

4987

Vfiltered=[];

4979

Vfiltered=[];

4988

end

4980

end

4989

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4981

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4990

% used for FD IL fitting

4982

% used for FD IL fitting

4991

% sdd21 us a complex insertion loss

4983

% sdd21 us a complex insertion loss

4992

db = @(x) 20*log10(abs(x));

4984

db = @(x) 20*log10(abs(x));

4993

sdd21=squeeze(sdd21);

4985

sdd21=squeeze(sdd21);

4994

if iscolumn(sdd21)

4986

if iscolumn(sdd21)

4995

sdd21=sdd21.';

4987

sdd21=sdd21.';

4996

end

4988

end

4997

fmbg=[ones(length(faxis_f2),1).*transpose(abs(sdd21)) transpose(sqrt(faxis_f2)).*transpose(abs(sdd21)) transpose(faxis_f2).*transpose(abs(sdd21)) transpose(faxis_f2.^2).*transpose(abs(sdd21)) ];

4989

fmbg=[ones(length(faxis_f2),1).*transpose(abs(sdd21)) transpose(sqrt(faxis_f2)).*transpose(abs(sdd21)) transpose(faxis_f2).*transpose(abs(sdd21)) transpose(faxis_f2.^2).*transpose(abs(sdd21)) ];

4998

warning('off','MATLAB:nearlySingularMatrix');

4990

warning('off','MATLAB:nearlySingularMatrix');

4999

LGw=transpose(abs(sdd21).*db(sdd21));

4991

LGw=transpose(abs(sdd21).*db(sdd21));

5000

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4992

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5001

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4993

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5002

ILN = db(sdd21)-efit;

4994

ILN = db(sdd21)-efit;

5003

4995

5004

4996

5005

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4997

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

5006

% Complex IL fitting

4998

% Complex IL fitting

5007

% sdd21 us a complex insertion loss

4999

% sdd21 us a complex insertion loss

5008

% efit and ILN are in db

5000

% efit and ILN are in db

5009

% faxix_f2 needs to be at least to fb

5001

% faxix_f2 needs to be at least to fb

5010

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

5002

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

5011

% still need to settle on voltage scaling.

5003

% still need to settle on voltage scaling.

5012

% maybe db(peak/Rss

5004

% maybe db(peak/Rss

5013

5005

5014

OP.interp_sparam_mag= 'trend_to_DC';

5006

OP.interp_sparam_mag= 'trend_to_DC';

5015

OP.interp_sparam_phase= 'interp_to_DC';

5007

OP.interp_sparam_phase= 'interp_to_DC';

5016

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5008

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5017

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5009

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5018

5010

5019

print_for_codereview=0;

5011

print_for_codereview=0;

5020

if ~exist('A_T','var')

5012

if ~exist('A_T','var')

5021

A_T=1;

5013

A_T=1;

5022

end

5014

end

5023

5015

5024

db = @(x) 20*log10(abs(x));

5016

db = @(x) 20*log10(abs(x));

5025

sdd21=squeeze(sdd21);

5017

sdd21=squeeze(sdd21);

5026

if iscolumn(sdd21)

5018

if iscolumn(sdd21)

5027

sdd21=sdd21.';

5019

sdd21=sdd21.';

5028

end

5020

end

5029

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5021

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5030

warning('off','MATLAB:nearlySingularMatrix');

5022

warning('off','MATLAB:nearlySingularMatrix');

5031

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5023

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5032

LGw=transpose(sdd21.*unwraplog);

5024

LGw=transpose(sdd21.*unwraplog);

5033

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5025

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5034

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5026

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5035

FIT=transpose(exp(transpose(efit_C)));

5027

FIT=transpose(exp(transpose(efit_C)));

5036

efit=db(abs(FIT));

5028

efit=db(abs(FIT));

5037

ILN = db(sdd21)-efit;

5029

ILN = db(sdd21)-efit;

5038

% time domain

5030

% time domain

5039

fprintf('computing TD_ILN (dB) ...')

5031

fprintf('computing TD_ILN (dB) ...')

5040

if exist('OP','var')

5032

if exist('OP','var')

5041

% OP.fraction_of_F_range_start_extrap_from=.95;

5033

% OP.fraction_of_F_range_start_extrap_from=.95;

5042

OP.impulse_response_truncation_threshold =1e-7;

5034

OP.impulse_response_truncation_threshold =1e-7;

5043

5035

5044

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5036

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5045

H_bw=Butterworth_Filter(param,faxis_f2,1);

5037

H_bw=Butterworth_Filter(param,faxis_f2,1);

5046

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5038

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5047

H_tw=Tukey_Window(faxis_f2,param);

5039

H_tw=Tukey_Window(faxis_f2,param);

5048

H_tw=ones(1,length(faxis_f2) );

5040

H_tw=ones(1,length(faxis_f2) );

5049

5041

5050

[TD_ILN.REF.FIR, ...

5042

[TD_ILN.REF.FIR, ...

5051

TD_ILN.REF.t, ...

5043

TD_ILN.REF.t, ...

5052

TD_ILN.REF.causality_correction_dB, ...

5044

TD_ILN.REF.causality_correction_dB, ...

5053

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5045

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5054

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

5046

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

5055

5047

5056

[TD_ILN.FIT.FIR, ...

5048

[TD_ILN.FIT.FIR, ...

5057

TD_ILN.FIT.t, ...

5049

TD_ILN.FIT.t, ...

5058

TD_ILN.FIT.causality_correction_dB, ...

5050

TD_ILN.FIT.causality_correction_dB, ...

5059

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5051

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5060

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

5052

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

5061

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

5053

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

5062

% NrangeUI=1000;

5054

% NrangeUI=1000;

5063

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(TD_ILN.FIT.PR)-param.samples_per_ui ),length(TD_ILN.REF.PR)-param.samples_per_ui);

5055

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(TD_ILN.FIT.PR)-param.samples_per_ui ),length(TD_ILN.REF.PR)-param.samples_per_ui);

5064

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

5056

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

5065

range=ipeak:range_end;

5057

range=ipeak:range_end;

5066

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

5058

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

5067

TD_ILN.t=TD_ILN.FIT.t(range);

5059

TD_ILN.t=TD_ILN.FIT.t(range);

5068

TD_ILN.FOM=-inf;

5060

TD_ILN.FOM=-inf;

5069

TD_ILN.FOM_PDF=-inf;

5061

TD_ILN.FOM_PDF=-inf;

5070

rms_fom=-inf;

5062

rms_fom=-inf;

5071

for im=1:param.samples_per_ui

5063

for im=1:param.samples_per_ui

5072

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

5064

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

5073

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5065

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5074

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5066

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5075

cdf=pdf; cdf.y=cumsum(pdf.y);

5067

cdf=pdf; cdf.y=cumsum(pdf.y);

5076

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5068

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5077

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5069

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5078

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5070

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5079

if print_for_codereview % remove once all checked out

5071

if print_for_codereview % remove once all checked out

5080

h=figure(190);set(gcf,'Tag','COM');

5072

h=figure(190);set(gcf,'Tag','COM');

5081

semilogy(-cdf.x,cdf.y);

5073

semilogy(-cdf.x,cdf.y);

5082

% xlim ([0,-cdf.x(1)])

5074

% xlim ([0,-cdf.x(1)])

5083

ylim([param.specBER 1]);title ('CDF of ILN')

5075

ylim([param.specBER 1]);title ('CDF of ILN')

5084

hold on

5076

hold on

5085

end

5077

end

5086

if rms>rms_fom

5078

if rms>rms_fom

5087

rms_fom=rms;

5079

rms_fom=rms;

5088

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5080

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5089

TD_ILN.PDF=pdf;

5081

TD_ILN.PDF=pdf;

5090

end

5082

end

5091

end

5083

end

5092

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

5084

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

5093

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

5085

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

5094

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

5086

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

5095

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

5087

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

5096

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

5088

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

5097

if print_for_codereview % remove once all checked out

5089

if print_for_codereview % remove once all checked out

5098

figure(9000);set(gcf,'Tag','COM');

5090

figure(9000);set(gcf,'Tag','COM');

5099

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

5091

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

5100

hold on

5092

hold on

5101

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

5093

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

5102

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

5094

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

5103

hold off

5095

hold off

5104

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',TD_ILN.SNR_ISI_FOM,TD_ILN.SNR_ISI_FOM_PDF)

5096

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',TD_ILN.SNR_ISI_FOM,TD_ILN.SNR_ISI_FOM_PDF)

5105

figure(9002);set(gcf,'Tag','COM');

5097

figure(9002);set(gcf,'Tag','COM');

5106

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

5098

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

5107

hold on

5099

hold on

5108

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5100

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5109

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5101

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5110

grid on

5102

grid on

5111

legend('show')

5103

legend('show')

5112

end

5104

end

5113

end

5105

end

5114

% display('got to end of get_ILN_cmp_td')

5106

% display('got to end of get_ILN_cmp_td')

5115

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

5107

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

5116

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

5108

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

5117

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

5109

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

5118

if 1 % force indent for doc

5110

if 1 % force indent for doc

5119

num_ui=param.num_ui_RXFF_noise;

5111

num_ui=param.num_ui_RXFF_noise;

5120

M=param.samples_per_ui;

5112

M=param.samples_per_ui;

5121

L=param.levels;

5113

L=param.levels;

5122

f_b=param.fb;

5114

f_b=param.fb;

5123

SNR_TX=param.SNR_TX;

5115

SNR_TX=param.SNR_TX;

5124

dw=param.RxFFE_cmx;

5116

dw=param.RxFFE_cmx;

5125

bmax=param.bmax;

5117

bmax=param.bmax;

5126

bmin=param.bmin ;

5118

bmin=param.bmin ;

5127

Nb=param.ndfe;

5119

Nb=param.ndfe;

5128

sigma_X2=(L^2-1)/(3*(L-1)^2);

5120

sigma_X2=(L^2-1)/(3*(L-1)^2);

5129

eta_0=param.eta_0; %V^2/GHz

5121

eta_0=param.eta_0; %V^2/GHz

5130

T_b=1/f_b;

5122

T_b=1/f_b;

5131

delta_f = f_b/num_ui; % Units are Hz.

5123

delta_f = f_b/num_ui; % Units are Hz.

5132

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

5124

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

5133

result.fvec=fvec;

5125

result.fvec=fvec;

5134

end

5126

end

5135

if OP.COMPUTE_COM

5127

if OP.COMPUTE_COM

5136

%% H_rxffe eq 178A-28 d1.0

5128

%% H_rxffe eq 178A-28 d1.0

5137

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

5129

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

5138

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

5130

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

5139

H_rxffe=0;

5131

H_rxffe=0;

5140

for nn=1:length(result.w)

5132

for nn=1:length(result.w)

5141

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

5133

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

5142

end

5134

end

5143

H_rxffe_2_of_f=abs(H_rxffe).^2;

5135

H_rxffe_2_of_f=abs(H_rxffe).^2;

5144

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

5136

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

5145

H_rxffe_2= [real( H_rxffe_2(1)), H_rxffe_2(2:end-1), real( H_rxffe_2(end)), conj( H_rxffe_2(end-1:-1:2))];

5137

H_rxffe_2= [real( H_rxffe_2(1)), H_rxffe_2(2:end-1), real( H_rxffe_2(end)), conj( H_rxffe_2(end-1:-1:2))];

5146

else

5138

else

5147

H_rxffe_2=1;

5139

H_rxffe_2=1;

5148

end

5140

end

5149

5141

5150

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

5142

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

5151

% --->this is the point in the code may fork where we add extra rx noise

5143

% --->this is the point in the code may fork where we add extra rx noise

5152

%% compute S_rn ( eq 178A-15 d0.2 )

5144

%% compute S_rn ( eq 178A-15 d0.2 )

5153

if ~OP.COMPUTE_COM

5145

if ~OP.COMPUTE_COM

5154

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

5146

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

5155

rxn_psd=[real(S_RN_of_f(1)), S_RN_of_f(2:end-1), real(S_RN_of_f(end)), conj(S_RN_of_f(end-1:-1:2))]; % Convert single-sided frequency response to conjugate-symmetric

5147

rxn_psd=[real(S_RN_of_f(1)), S_RN_of_f(2:end-1), real(S_RN_of_f(end)), conj(S_RN_of_f(end-1:-1:2))]; % Convert single-sided frequency response to conjugate-symmetric

5156

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

5148

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

5157

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

5149

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

5158

S_rn = sum(reshape(rxn_psd, num_ui, M).');

5150

S_rn = sum(reshape(rxn_psd, num_ui, M).');

5159

S_rn=S_rn(1:num_ui/2+1);

5151

S_rn=S_rn(1:num_ui/2+1);

5160

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

5152

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

5161

result.S_rn=S_rn;

5153

result.S_rn=S_rn;

5162

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5154

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5163

else

5155

else

5164

result.S_rn=result.S_rn.*H_rxffe_2;

5156

result.S_rn=result.S_rn.*H_rxffe_2;

5165

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5157

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5166

end

5158

end

5167

5159

5168

else % find noise for item that set have tx ffe for each loop

5160

else % find noise for item that set have tx ffe for each loop

5169

%% S_xn from eq 178A-16

5161

%% S_xn from eq 178A-16

5170

%% Crosstalk power spectral density

5162

%% Crosstalk power spectral density

5171

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

5163

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

5172

result.S_xn=0;

5164

result.S_xn=0;

5173

if length(chdata)~=1

5165

if length(chdata)~=1

5174

for xchan=2:length(chdata)

5166

for xchan=2:length(chdata)

5175

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

5167

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

5176

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

5168

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

5177

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

5169

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

5178

% enable less UI for computation speed improvement

5170

% enable less UI for computation speed improvement

5179

%%

5171

%%

5180

if num_ui*M > length(pulse_ctle)

5172

if num_ui*M > length(pulse_ctle)

5181

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

5173

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

5182

else

5174

else

5183

hk(xchan).k=hk(xchan).k(1:num_ui*M);

5175

hk(xchan).k=hk(xchan).k(1:num_ui*M);

5184

end

5176

end

5185

for i1=1:M

5177

for i1=1:M

5186

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

5178

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

5187

end

5179

end

5188

iphase(xchan)=find(hxn==max(hxn));

5180

iphase(xchan)=find(hxn==max(hxn));

5189

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

5181

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

5190

result.hk(xchan).hrn= hk(xchan).hrn;

5182

result.hk(xchan).hrn= hk(xchan).hrn;

5191

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

5183

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

5192

result.S_xn=hk(xchan).S_xn+result.S_xn;

5184

result.S_xn=hk(xchan).S_xn+result.S_xn;

5193

end

5185

end

5194

result.S_xn=result.S_xn;

5186

result.S_xn=result.S_xn;

5195

result.hk=hk;

5187

result.hk=hk;

5196

result.iphase=iphase;

5188

result.iphase=iphase;

5197

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5189

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5198

else % if no crosstalk, perserve structure and return 0 for S_xn

5190

else % if no crosstalk, perserve structure and return 0 for S_xn

5199

result.S_xn=0;

5191

result.S_xn=0;

5200

result.hk=[];

5192

result.hk=[];

5201

result.iphase=1;

5193

result.iphase=1;

5202

result.S_xn_rms = 0;

5194

result.S_xn_rms = 0;

5203

end

5195

end

5204

else % adjust for H_rxffe when computing COM

5196

else % adjust for H_rxffe when computing COM

5205

result.S_xn=result.S_xn.*H_rxffe_2;

5197

result.S_xn=result.S_xn.*H_rxffe_2;

5206

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5198

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5207

end

5199

end

5208

%% S_tn from eq 178A-17

5200

%% S_tn from eq 178A-17

5209

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

5201

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

5210

%% Transmitter noise power spectral density

5202

%% Transmitter noise power spectral density

5211

if ~OP.COMPUTE_COM

5203

if ~OP.COMPUTE_COM

5212

if ~OP.TDMODE

5204

if ~OP.TDMODE

5213

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

5205

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

5214

else % only use when the input was a pulse response not s-parameters

5206

else % only use when the input was a pulse response not s-parameters

5215

if isfield(chdata(1),'ctle_pulse_response')

5207

if isfield(chdata(1),'ctle_pulse_response')

5216

htn=chdata(1).ctle_pulse_response;

5208

htn=chdata(1).ctle_pulse_response;

5217

else

5209

else

5218

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

5210

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

5219

end

5211

end

5220

end

5212

end

5221

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

5213

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

5222

htn=reshape(htn,1,[]); % make row vectors

5214

htn=reshape(htn,1,[]); % make row vectors

5223

htn=[ htn(1:floor(length(htn)/M)*M) ];

5215

htn=[ htn(1:floor(length(htn)/M)*M) ];

5224

htn= [htn zeros(1,num_ui*M-length(htn)) ];

5216

htn= [htn zeros(1,num_ui*M-length(htn)) ];

5225

htn=htn(1:M:end);% resample

5217

htn=htn(1:M:end);% resample

5226

if num_ui>length(htn)

5218

if num_ui>length(htn)

5227

hext=[htn zeros(1,num_ui-length(htn))];

5219

hext=[htn zeros(1,num_ui-length(htn))];

5228

else

5220

else

5229

hext=htn(1:num_ui);

5221

hext=htn(1:num_ui);

5230

end

5222

end

5231

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

5223

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

5232

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5224

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5233

else

5225

else

5234

result.S_tn=result.S_tn.*H_rxffe_2;

5226

result.S_tn=result.S_tn.*H_rxffe_2;

5235

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5227

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5236

end

5228

end

5237

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

5229

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

5238

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

5230

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

5239

%% Power spectral density of noise due to jitter

5231

%% Power spectral density of noise due to jitter

5240

%% Eq. 93A-28 %%

5232

%% Eq. 93A-28 %%

5241

if ~OP.COMPUTE_COM

5233

if ~OP.COMPUTE_COM

5242

sampling_offset = mod(cursor_i, M);

5234

sampling_offset = mod(cursor_i, M);

5243

%ensure we can take early sample

5235

%ensure we can take early sample

5244

if sampling_offset<=1

5236

if sampling_offset<=1

5245

sampling_offset=sampling_offset+M;

5237

sampling_offset=sampling_offset+M;

5246

end

5238

end

5247

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

5239

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

5248

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

5240

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

5249

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

5241

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

5250

else

5242

else

5251

cursors_early_sample = h(sampling_offset-1:M:end);

5243

cursors_early_sample = h(sampling_offset-1:M:end);

5252

cursors_late_sample = h(sampling_offset+1:M:end);

5244

cursors_late_sample = h(sampling_offset+1:M:end);

5253

end

5245

end

5254

% ensure lengths are equal

5246

% ensure lengths are equal

5255

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

5247

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

5256

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

5248

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

5257

h_J=reshape(h_J,1,[]); % make row vectors

5249

h_J=reshape(h_J,1,[]); % make row vectors

5258

if num_ui>length(h_J)

5250

if num_ui>length(h_J)

5259

h_J=[h_J zeros(1,num_ui-length(h_J))];

5251

h_J=[h_J zeros(1,num_ui-length(h_J))];

5260

else

5252

else

5261

h_J=h_J(1:num_ui);

5253

h_J=h_J(1:num_ui);

5262

end

5254

end

5263

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5255

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5264

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5256

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5265

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5257

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5266

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5258

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5267

else

5259

else

5268

result.S_jn=result.S_jn.*H_rxffe_2;

5260

result.S_jn=result.S_jn.*H_rxffe_2;

5269

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5261

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5270

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

5262

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

5271

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5263

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5272

end

5264

end

5273

% result.S_jn

5265

% result.S_jn

5274

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn;

5266

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn;

5275

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

5267

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

5276

5268

5277

%%

5269

%%

5278

%% Hisi to be included in MLSE rho eq 178a-28

5270

%% Hisi to be included in MLSE rho eq 178a-28

5279

if OP.COMPUTE_COM

5271

if OP.COMPUTE_COM

5280

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

5272

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

5281

% sampling_offset = mod(cursor_i-1, M)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

5273

% sampling_offset = mod(cursor_i-1, M)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

5282

% hisi=h(sampling_offset:M:end);

5274

% hisi=h(sampling_offset:M:end);

5283

% hisi=hisi(:).';

5275

% hisi=hisi(:).';

5284

% if num_ui>length(hisi)

5276

% if num_ui>length(hisi)

5285

% hisi=[hisi zeros(1,num_ui-length(hisi))];

5277

% hisi=[hisi zeros(1,num_ui-length(hisi))];

5286

% else

5278

% else

5287

% hisi=hisi(1:num_ui);% sometime cable channels need a bigger num_ui. prehap compare to the tripple transit time and compute num_ui

5279

% hisi=hisi(1:num_ui);% sometime cable channels need a bigger num_ui. prehap compare to the tripple transit time and compute num_ui

5288

% end

5280

% end

5289

% cursor_n=find(hisi==max(hisi),1','first');

5281

% cursor_n=find(hisi==max(hisi),1','first');

5290

samp_idx = (mod(cursor_i-1,M)+1):M:length(h);% Commit request 4p5_2, healey_3dj_COM_01_240521.pdf

5282

samp_idx = (mod(cursor_i-1,M)+1):M:length(h);% Commit request 4p5_2, healey_3dj_COM_01_240521.pdf

5291

cursor_n=find(samp_idx == cursor_i);

5283

cursor_n=find(samp_idx == cursor_i);

5292

hisi=h(samp_idx);

5284

hisi=h(samp_idx);

5293

hisi(end+1:num_ui)=0;

5285

hisi(end+1:num_ui)=0;

5294

hisi=reshape(hisi(1:num_ui),1,[]);

5286

hisi=reshape(hisi(1:num_ui),1,[]);

5295

%% Eq 178a-29

5287

%% Eq 178a-29

5296

for ii=1:length(hisi)

5288

for ii=1:length(hisi)

5297

if ii==cursor_n % cursor

5289

if ii==cursor_n % cursor

5298

cursor=hisi(ii);

5290

cursor=hisi(ii);

5299

hisi(ii)= 0;

5291

hisi(ii)= 0;

5300

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

5292

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

5301

ib_indx=ii-cursor_n;

5293

ib_indx=ii-cursor_n;

5302

if hisi(ii) >= bmax(ib_indx)*cursor

5294

if hisi(ii) >= bmax(ib_indx)*cursor

5303

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

5295

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

5304

elseif hisi(ii) <= bmin(ib_indx)*cursor

5296

elseif hisi(ii) <= bmin(ib_indx)*cursor

5305

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

5297

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

5306

else

5298

else

5307

hisi(ii)=0;

5299

hisi(ii)=0;

5308

end

5300

end

5309

end

5301

end

5310

end

5302

end

5311

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

5303

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

5312

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

5304

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

5313

%%

5305

%%

5314

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

5306

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

5315

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

5307

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

5316

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

5308

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

5317

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

5309

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

5318

end

5310

end

5319

end

5311

end

5320

function result=get_PulseR(ir,param,cb_step,ZT)

5312

function result=get_PulseR(ir,param,cb_step,ZT)

5321

%ir = impulse response

5313

%ir = impulse response

5322

%t_base=time array with equal time steps

5314

%t_base=time array with equal time steps

5323

%samp_UI = number of samples per UI for ir

5315

%samp_UI = number of samples per UI for ir

5324

5316

5325

% t for debug

5317

% t for debug

5326

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5318

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5327

5319

5328

if cb_step

5320

if cb_step

5329

Ag=1;

5321

Ag=1;

5330

dt=1/param.fb/param.samples_per_ui;

5322

dt=1/param.fb/param.samples_per_ui;

5331

edge_time=param.TR_TDR*1e-9;

5323

edge_time=param.TR_TDR*1e-9;

5332

fedge=1/edge_time;

5324

fedge=1/edge_time;

5333

tedge=0:dt:edge_time*2;

5325

tedge=0:dt:edge_time*2;

5334

%

5326

%

5335

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5327

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5336

drive_pulse=[edge ones(1,param.samples_per_ui)];

5328

drive_pulse=[edge ones(1,param.samples_per_ui)];

5337

%pulse=filter(UI_ones,1,ir);

5329

%pulse=filter(UI_ones,1,ir);

5338

% t for debug

5330

% t for debug

5339

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5331

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5340

5332

5341

pulse=filter(drive_pulse,1,ir);

5333

pulse=filter(drive_pulse,1,ir);

5342

else

5334

else

5343

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5335

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5344

end

5336

end

5345

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5337

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5346

result.PDR=PDR_response;

5338

result.PDR=PDR_response;

5347

result.pulse=pulse;

5339

result.pulse=pulse;

5348

5340

5349

5341

5350

5342

5351

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5343

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5352

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

5344

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

5353

if ~iscolumn(H), H=H.';end

5345

if ~iscolumn(H), H=H.';end

5354

if ~iscolumn(H_r), H_r=H_r.';end

5346

if ~iscolumn(H_r), H_r=H_r.';end

5355

H=H(:).*H_r;

5347

H=H(:).*H_r;

5356

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5348

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5357

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5349

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5358

5350

5359

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5351

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5360

% Complex reflection and re-reflection noise using the concept of zero'ing

5352

% Complex reflection and re-reflection noise using the concept of zero'ing

5361

% out of reflections

5353

% out of reflections

5362

% sdd21 us a complex insertion loss

5354

% sdd21 us a complex insertion loss

5363

% RIL_struct is the output of capture_RIL_RILN()

5355

% RIL_struct is the output of capture_RIL_RILN()

5364

% faxix_f2 needs to be at least to fb

5356

% faxix_f2 needs to be at least to fb

5365

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5357

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5366

% still need to settle on voltage scaling.

5358

% still need to settle on voltage scaling.

5367

% maybe db(peak/Rss

5359

% maybe db(peak/Rss

5368

db = @(x) 20*log10(abs(x));

5360

db = @(x) 20*log10(abs(x));

5369

fprintf('computing TD_RILN (dB) ...');

5361

fprintf('computing TD_RILN (dB) ...');

5370

5362

5371

OP.interp_sparam_mag= 'trend_to_DC';

5363

OP.interp_sparam_mag= 'trend_to_DC';

5372

OP.interp_sparam_phase= 'interp_to_DC';

5364

OP.interp_sparam_phase= 'interp_to_DC';

5373

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5365

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5374

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5366

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5375

5367

5376

sdd21=squeeze(sdd21);

5368

sdd21=squeeze(sdd21);

5377

if iscolumn(sdd21)

5369

if iscolumn(sdd21)

5378

sdd21=sdd21.';

5370

sdd21=sdd21.';

5379

end

5371

end

5380

RIL=squeeze(RIL_struct.RIL);

5372

RIL=squeeze(RIL_struct.RIL);

5381

if iscolumn(RIL)

5373

if iscolumn(RIL)

5382

RIL=RIL.';

5374

RIL=RIL.';

5383

end

5375

end

5384

rho_port1=squeeze(RIL_struct.rho_port1);

5376

rho_port1=squeeze(RIL_struct.rho_port1);

5385

if iscolumn(rho_port1)

5377

if iscolumn(rho_port1)

5386

rho_port1=rho_port1.';

5378

rho_port1=rho_port1.';

5387

end

5379

end

5388

rho_port2=squeeze(RIL_struct.rho_port2);

5380

rho_port2=squeeze(RIL_struct.rho_port2);

5389

if iscolumn(rho_port2)

5381

if iscolumn(rho_port2)

5390

rho_port2=rho_port2.';

5382

rho_port2=rho_port2.';

5391

end

5383

end

5392

RIL_f=squeeze(RIL_struct.freq);

5384

RIL_f=squeeze(RIL_struct.freq);

5393

if iscolumn(RIL_f)

5385

if iscolumn(RIL_f)

5394

RIL_f=RIL_f.';

5386

RIL_f=RIL_f.';

5395

end

5387

end

5396

5388

5397

%---start. Calculate the reflection and re-reflection noise

5389

%---start. Calculate the reflection and re-reflection noise

5398

number_of_echos= 1e3;

5390

number_of_echos= 1e3;

5399

fmin= 1e9;%<-------------

5391

fmin= 1e9;%<-------------

5400

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5392

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5401

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5393

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5402

for m= 1:number_of_echos

5394

for m= 1:number_of_echos

5403

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m)).*(rho_port1.^m).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port2);

5395

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m)).*(rho_port1.^m).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port2);

5404

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m-1)).*(rho_port1.^(m-1)).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port1);

5396

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m-1)).*(rho_port1.^(m-1)).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port1);

5405

end

5397

end

5406

5398

5407

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5399

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5408

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5400

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5409

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5401

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5410

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5402

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5411

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5403

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5412

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5404

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5413

5405

5414

% clear RIL RIL_f rho_port1 rho_port2

5406

% clear RIL RIL_f rho_port1 rho_port2

5415

% clear fmin m

5407

% clear fmin m

5416

%---end. Calculate the reflection and re-reflection noise

5408

%---end. Calculate the reflection and re-reflection noise

5417

5409

5418

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5410

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5419

warning('off','MATLAB:nearlySingularMatrix');

5411

warning('off','MATLAB:nearlySingularMatrix');

5420

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5412

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5421

LGw=transpose(sdd21.*unwraplog);

5413

LGw=transpose(sdd21.*unwraplog);

5422

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5414

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5423

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5415

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5424

FIT=transpose(exp(transpose(efit_C)));

5416

FIT=transpose(exp(transpose(efit_C)));

5425

efit=db(abs(FIT));

5417

efit=db(abs(FIT));

5426

ILN = db(sdd21)-efit;

5418

ILN = db(sdd21)-efit;

5427

5419

5428

5420

5429

OP.impulse_response_truncation_threshold =1e-7;

5421

OP.impulse_response_truncation_threshold =1e-7;

5430

5422

5431

print_for_codereview=0;

5423

print_for_codereview=0;

5432

if exist('OP','var')

5424

if exist('OP','var')

5433

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5425

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5434

H_bw=Butterworth_Filter(param,faxis_f2,1);

5426

H_bw=Butterworth_Filter(param,faxis_f2,1);

5435

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5427

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5436

H_tw=Tukey_Window(faxis_f2,param);

5428

H_tw=Tukey_Window(faxis_f2,param);

5437

H_tw=ones(1,length(faxis_f2) );

5429

H_tw=ones(1,length(faxis_f2) );

5438

[RILN_TD_struct.REF.FIR, ...

5430

[RILN_TD_struct.REF.FIR, ...

5439

RILN_TD_struct.REF.t, ...

5431

RILN_TD_struct.REF.t, ...

5440

RILN_TD_struct.REF.causality_correction_dB, ...

5432

RILN_TD_struct.REF.causality_correction_dB, ...

5441

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5433

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5442

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5434

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5443

5435

5444

5436

5445

[RILN_TD_struct.FIT.FIR, ...

5437

[RILN_TD_struct.FIT.FIR, ...

5446

RILN_TD_struct.FIT.t, ...

5438

RILN_TD_struct.FIT.t, ...

5447

RILN_TD_struct.FIT.causality_correction_dB, ...

5439

RILN_TD_struct.FIT.causality_correction_dB, ...

5448

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5440

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5449

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5441

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5450

5442

5451

5443

5452

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5444

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5453

H_bw=Butterworth_Filter(param,RIL_f,1);

5445

H_bw=Butterworth_Filter(param,RIL_f,1);

5454

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5446

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5455

H_tw=Tukey_Window(RIL_f,param);

5447

H_tw=Tukey_Window(RIL_f,param);

5456

H_tw=ones(1,length(RIL_f) );

5448

H_tw=ones(1,length(RIL_f) );

5457

[RILN_TD_struct.RIL.FIR, ...

5449

[RILN_TD_struct.RIL.FIR, ...

5458

RILN_TD_struct.RIL.t, ...

5450

RILN_TD_struct.RIL.t, ...

5459

RILN_TD_struct.RIL.causality_correction_dB, ...

5451

RILN_TD_struct.RIL.causality_correction_dB, ...

5460

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5452

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5461

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5453

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5462

5454

5463

5455

5464

%---start. Calculate the channel delay

5456

%---start. Calculate the channel delay

5465

try

5457

try

5466

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5458

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5467

catch

5459

catch

5468

end

5460

end

5469

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5461

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5470

clear delay_sec delay_idx

5462

clear delay_sec delay_idx

5471

%---end. Calculate the channel delay

5463

%---end. Calculate the channel delay

5472

5464

5473

5465

5474

5466

5475

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5467

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5476

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5468

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5477

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5469

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5478

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5470

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5479

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5471

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5480

[RILN_TD_struct.REF_noise.FIR, ...

5472

[RILN_TD_struct.REF_noise.FIR, ...

5481

RILN_TD_struct.REF_noise.t, ...

5473

RILN_TD_struct.REF_noise.t, ...

5482

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5474

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5483

RILN_TD_struct.REF_noise.truncation_dB] = s21_to_impulse_DC(port2_reflection_rereflection_noise.*H_bw.*H_t.*H_tw ,f_reflection_rereflection_noise, param.sample_dt, OP) ;

5475

RILN_TD_struct.REF_noise.truncation_dB] = s21_to_impulse_DC(port2_reflection_rereflection_noise.*H_bw.*H_t.*H_tw ,f_reflection_rereflection_noise, param.sample_dt, OP) ;

5484

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5476

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5485

5477

5486

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5478

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5487

% NrangeUI=1000;

5479

% NrangeUI=1000;

5488

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(RILN_TD_struct.FIT.PR)-param.samples_per_ui ),length(RILN_TD_struct.REF.PR)-param.samples_per_ui);

5480

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(RILN_TD_struct.FIT.PR)-param.samples_per_ui ),length(RILN_TD_struct.REF.PR)-param.samples_per_ui);

5489

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5481

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5490

range=ipeak:range_end;

5482

range=ipeak:range_end;

5491

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5483

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5492

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5484

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5493

RILN_TD_struct.FOM=-inf;

5485

RILN_TD_struct.FOM=-inf;

5494

RILN_TD_struct.FOM_PDF=-inf;

5486

RILN_TD_struct.FOM_PDF=-inf;

5495

rms_fom=-inf;

5487

rms_fom=-inf;

5496

for im=1:param.samples_per_ui

5488

for im=1:param.samples_per_ui

5497

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5489

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5498

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5490

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5499

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5491

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5500

cdf=pdf; cdf.y=cumsum(pdf.y);

5492

cdf=pdf; cdf.y=cumsum(pdf.y);

5501

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5493

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5502

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5494

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5503

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5495

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5504

if print_for_codereview % remove once all checked out

5496

if print_for_codereview % remove once all checked out

5505

h=figure(190);set(gcf,'Tag','COM');

5497

h=figure(190);set(gcf,'Tag','COM');

5506

semilogy(-cdf.x,cdf.y);

5498

semilogy(-cdf.x,cdf.y);

5507

% xlim ([0,-cdf.x(1)])

5499

% xlim ([0,-cdf.x(1)])

5508

ylim([param.specBER 1]);title ('CDF of ILN')

5500

ylim([param.specBER 1]);title ('CDF of ILN')

5509

hold on

5501

hold on

5510

end

5502

end

5511

if rms>rms_fom

5503

if rms>rms_fom

5512

rms_fom=rms;

5504

rms_fom=rms;

5513

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5505

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5514

RILN_TD_struct.PDF=pdf;

5506

RILN_TD_struct.PDF=pdf;

5515

end

5507

end

5516

end

5508

end

5517

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5509

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5518

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5510

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5519

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5511

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5520

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5512

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5521

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5513

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5522

if print_for_codereview % remove once all checked out

5514

if print_for_codereview % remove once all checked out

5523

figure(9000);set(gcf,'Tag','COM');

5515

figure(9000);set(gcf,'Tag','COM');

5524

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5516

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5525

hold on

5517

hold on

5526

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5518

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5527

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5519

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5528

yyaxis right

5520

yyaxis right

5529

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5521

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5530

hold off

5522

hold off

5531

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

5523

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

5532

figure(9002);set(gcf,'Tag','COM');

5524

figure(9002);set(gcf,'Tag','COM');

5533

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5525

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5534

hold on

5526

hold on

5535

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5527

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5536

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5528

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5537

grid on

5529

grid on

5538

legend('show')

5530

legend('show')

5539

end

5531

end

5540

end

5532

end

5541

function result=get_StepR(ir,param,cb_step,ZT)

5533

function result=get_StepR(ir,param,cb_step,ZT)

5542

%ir = impulse response

5534

%ir = impulse response

5543

%t_base=time array with equal time steps

5535

%t_base=time array with equal time steps

5544

%samp_UI = number of samples per UI for ir

5536

%samp_UI = number of samples per UI for ir

5545

% result.SBR

5537

% result.SBR

5546

% t for debug

5538

% t for debug

5547

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5539

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5548

5540

5549

if cb_step

5541

if cb_step

5550

Ag=1;

5542

Ag=1;

5551

dt=1/param.fb/param.samples_per_ui;

5543

dt=1/param.fb/param.samples_per_ui;

5552

edge_time=param.TR_TDR*1e-9;

5544

edge_time=param.TR_TDR*1e-9;

5553

fedge=1/edge_time;

5545

fedge=1/edge_time;

5554

tedge=0:dt:edge_time*2;

5546

tedge=0:dt:edge_time*2;

5555

%

5547

%

5556

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5548

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5557

drive_pulse=[edge ones(1,param.samples_per_ui)];

5549

drive_pulse=[edge ones(1,param.samples_per_ui)];

5558

%pulse=filter(UI_ones,1,ir);

5550

%pulse=filter(UI_ones,1,ir);

5559

5551

5560

pulse=filter(drive_pulse,1,ir);

5552

pulse=filter(drive_pulse,1,ir);

5561

else

5553

else

5562

pulse=cumsum(ir);

5554

pulse=cumsum(ir);

5563

end

5555

end

5564

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5556

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5565

result.ZSR=TDR_response;

5557

result.ZSR=TDR_response;

5566

result.pulse=pulse;

5558

result.pulse=pulse;

5567

5559

5568

5560

5569

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5561

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5570

% sdd is differential s-parameters structure (2 port assumed)

5562

% sdd is differential s-parameters structure (2 port assumed)

5571

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5563

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5572

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5564

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5573

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5565

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5574

% TDR_results.t starting at t=0

5566

% TDR_results.t starting at t=0

5575

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5567

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5576

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5568

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5577

% TDR_results.f frequency for filter and s parameters

5569

% TDR_results.f frequency for filter and s parameters

5578

% TDR_results.ptdr_RL reflection waveform from the pulse

5570

% TDR_results.ptdr_RL reflection waveform from the pulse

5579

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5571

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5580

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5572

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5581

% TDR_results.ERL reported effective return loss

5573

% TDR_results.ERL reported effective return loss

5582

%

5574

%

5583

db = @(x) 20*log10(abs(x));

5575

db = @(x) 20*log10(abs(x));

5584

rms =@(x) norm(x)/sqrt(length(x));

5576

rms =@(x) norm(x)/sqrt(length(x));

5585

if isfield(OP,'TDR_duration')

5577

if isfield(OP,'TDR_duration')

5586

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5578

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5587

else

5579

else

5588

TDR_duration=5;

5580

TDR_duration=5;

5589

end

5581

end

5590

if ~isfield(OP,'DISPLAY_WINDOW')

5582

if ~isfield(OP,'DISPLAY_WINDOW')

5591

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5583

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5592

end

5584

end

5593

f=sdd.Frequencies;

5585

f=sdd.Frequencies;

5594

TDR_results.f=f;

5586

TDR_results.f=f;

5595

% OP.Zt_adj=2;

5587

% OP.Zt_adj=2;

5596

if param.FLAG.S2P == 0

5588

if param.FLAG.S2P == 0

5597

5589

5598

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5590

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5599

TDR_RL =@(Zin,Zout,s11,s12,s21,s22)(Zin.^2.*s11+Zin.^2.*s22+Zout.^2.*s11+Zout.^2.*s22+Zin.^2-Zout.^2+Zin.*Zout.*s11.*2.0-Zin.*Zout.*s22.*2.0+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21-Zout.^2.*s11.*s22+Zout.^2.*s12.*s21)./(Zin.*Zout.*2.0+Zin.^2.*s11+Zin.^2.*s22-Zout.^2.*s11-Zout.^2.*s22+Zin.^2+Zout.^2+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21+Zout.^2.*s11.*s22-Zout.^2.*s12.*s21-Zin.*Zout.*s11.*s22.*2.0+Zin.*Zout.*s12.*s21.*2.0);

5591

TDR_RL =@(Zin,Zout,s11,s12,s21,s22)(Zin.^2.*s11+Zin.^2.*s22+Zout.^2.*s11+Zout.^2.*s22+Zin.^2-Zout.^2+Zin.*Zout.*s11.*2.0-Zin.*Zout.*s22.*2.0+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21-Zout.^2.*s11.*s22+Zout.^2.*s12.*s21)./(Zin.*Zout.*2.0+Zin.^2.*s11+Zin.^2.*s22-Zout.^2.*s11-Zout.^2.*s22+Zin.^2+Zout.^2+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21+Zout.^2.*s11.*s22-Zout.^2.*s12.*s21-Zin.*Zout.*s11.*s22.*2.0+Zin.*Zout.*s12.*s21.*2.0);

5600

5592

5601

if param.RL_sel==1, other_port=2;end

5593

if param.RL_sel==1, other_port=2;end

5602

if param.RL_sel==2, other_port=1;end

5594

if param.RL_sel==2, other_port=1;end

5603

for i = 1:length(sdd.Frequencies)

5595

for i = 1:length(sdd.Frequencies)

5604

if size(sdd.Parameters,2) ==1 % for s2p files

5596

if size(sdd.Parameters,2) ==1 % for s2p files

5605

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,1, 1 ,sdd.Parameters(param.RL_sel,param.RL_sel,i) );

5597

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,1, 1 ,sdd.Parameters(param.RL_sel,param.RL_sel,i) );

5606

else

5598

else

5607

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,sdd.Parameters( 1,2 ,i), sdd.Parameters( 2,1 ,i),sdd.Parameters( other_port,other_port ,i) );

5599

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,sdd.Parameters( 1,2 ,i), sdd.Parameters( 2,1 ,i),sdd.Parameters( other_port,other_port ,i) );

5608

end

5600

end

5609

end

5601

end

5610

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5602

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5611

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5603

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5612

% Z_t=ZT;

5604

% Z_t=ZT;

5613

% zref=sdd.Impedance/2;

5605

% zref=sdd.Impedance/2;

5614

% if Z_t > zref

5606

% if Z_t > zref

5615

% radjust= (zref-Z_t);

5607

% radjust= (zref-Z_t);

5616

% S11adjust= radjust./(radjust + 2*zref);

5608

% S11adjust= radjust./(radjust + 2*zref);

5617

% RL=RL +S11adjust;

5609

% RL=RL +S11adjust;

5618

% elseif Z_t < zref

5610

% elseif Z_t < zref

5619

% rpad=-Z_t*zref/(Z_t-zref);

5611

% rpad=-Z_t*zref/(Z_t-zref);

5620

% S11adjust=zref/(rpad*(zref/rpad + 2));

5612

% S11adjust=zref/(rpad*(zref/rpad + 2));

5621

% RL=RL + S11adjust;

5613

% RL=RL + S11adjust;

5622

% else

5614

% else

5623

% RL=RL;

5615

% RL=RL;

5624

% end

5616

% end

5625

else

5617

else

5626

for i = 1:length(sdd.Frequencies)

5618

for i = 1:length(sdd.Frequencies)

5627

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5619

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5628

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5620

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5629

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5621

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5630

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5622

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5631

end

5623

end

5632

end

5624

end

5633

5625

5634

% end

5626

% end

5635

RL=squeeze(RL);

5627

RL=squeeze(RL);

5636

f9=f/1e9;

5628

f9=f/1e9;

5637

tr=param.TR_TDR;

5629

tr=param.TR_TDR;

5638

TDR_results.delay=500e-12 ;

5630

TDR_results.delay=500e-12 ;

5639

% determine max time from thue

5631

% determine max time from thue

5640

% if sdd.NumPorts==1

5632

% if sdd.NumPorts==1

5641

% try

5633

% try

5642

% maxtime=OP.N*param.ui;

5634

% maxtime=OP.N*param.ui;

5643

% catch

5635

% catch

5644

% maxtime=2e-9;

5636

% maxtime=2e-9;

5645

% end

5637

% end

5646

% pix=1;

5638

% pix=1;

5647

% else

5639

% else

5648

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5640

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5649

% pix=find(fir4del==max(fir4del),1);

5641

% pix=find(fir4del==max(fir4del),1);

5650

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5642

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5651

% if maxtime > tu(end); maxtime=tu(end);end

5643

% if maxtime > tu(end); maxtime=tu(end);end

5652

% endS

5644

% endS

5653

5645

5654

try

5646

try

5655

maxtime=OP.N*param.ui;

5647

maxtime=OP.N*param.ui;

5656

catch

5648

catch

5657

maxtime=2e-9;

5649

maxtime=2e-9;

5658

end

5650

end

5659

if OP.N==0

5651

if OP.N==0

5660

if sdd.NumPorts==1

5652

if sdd.NumPorts==1

5661

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5653

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5662

else

5654

else

5663

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5655

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5664

pix=find(fir4del==max(fir4del),1);

5656

pix=find(fir4del==max(fir4del),1);

5665

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5657

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5666

if maxtime > tu(end); maxtime=tu(end);end

5658

if maxtime > tu(end); maxtime=tu(end);end

5667

end

5659

end

5668

end

5660

end

5669

5661

5670

5662

5671

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5663

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5672

% (makes gausian edge somewhat causal)

5664

% (makes gausian edge somewhat causal)

5673

H_t = exp( -2*(pi*f9*(tr)/1.6832).^2 ).*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9).*exp(-1j*2*pi*f9*tr*3);

5665

H_t = exp( -2*(pi*f9*(tr)/1.6832).^2 ).*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9).*exp(-1j*2*pi*f9*tr*3);

5674

if ~isfield(OP,'cb_Guassian')

5666

if ~isfield(OP,'cb_Guassian')

5675

Use_gaussian=1;

5667

Use_gaussian=1;

5676

else

5668

else

5677

Use_gaussian=OP.cb_Guassian;

5669

Use_gaussian=OP.cb_Guassian;

5678

end

5670

end

5679

if Use_gaussian

5671

if Use_gaussian

5680

if iscolumn(H_t), H_t=H_t.'; end

5672

if iscolumn(H_t), H_t=H_t.'; end

5681

RLf=RL(:).'.*H_t;

5673

RLf=RL(:).'.*H_t;

5682

else % add extra 3x tr delay for causality

5674

else % add extra 3x tr delay for causality

5683

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5675

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5684

end

5676

end

5685

5677

5686

%Bessesl-Thomson turned off here (3rd input=0)

5678

%Bessesl-Thomson turned off here (3rd input=0)

5687

H_bt=Bessel_Thomson_Filter(param,f,0);

5679

H_bt=Bessel_Thomson_Filter(param,f,0);

5688

5680

5689

if isfield(OP,'TDR_Butterworth')

5681

if isfield(OP,'TDR_Butterworth')

5690

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5682

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5691

else

5683

else

5692

H_bw=ones(1,length(f));

5684

H_bw=ones(1,length(f));

5693

end

5685

end

5694

5686

5695

5687

5696

if param.Tukey_Window ~= 0

5688

if param.Tukey_Window ~= 0

5697

H_tw= Tukey_Window(f,param);

5689

H_tw= Tukey_Window(f,param);

5698

else

5690

else

5699

H_tw=ones(1,length(f));

5691

H_tw=ones(1,length(f));

5700

end

5692

end

5701

5693

5702

5694

5703

if iscolumn(H_tw), H_tw=H_tw.';end

5695

if iscolumn(H_tw), H_tw=H_tw.';end

5704

if iscolumn(H_bt), H_bt=H_bt.';end

5696

if iscolumn(H_bt), H_bt=H_bt.';end

5705

if iscolumn(H_bw), H_bw=H_bw.';end

5697

if iscolumn(H_bw), H_bw=H_bw.';end

5706

if iscolumn(RLf), RLf=RLf.';end

5698

if iscolumn(RLf), RLf=RLf.';end

5707

5699

5708

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5700

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5709

RLf=RLf.*TDR_results.Rx_filter;

5701

RLf=RLf.*TDR_results.Rx_filter;

5710

TDR_results.tx_filter=H_t;

5702

TDR_results.tx_filter=H_t;

5711

5703

5712

5704

5713

[IR, t, causality_correction_dB, truncation_dB] = ...

5705

[IR, t, causality_correction_dB, truncation_dB] = ...

5714

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5706

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5715

5707

5716

5708

5717

%

5709

%

5718

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5710

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5719

tfx=param.tfx(np); % use fixture delay for port (np)

5711

tfx=param.tfx(np); % use fixture delay for port (np)

5720

5712

5721

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5713

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5722

5714

5723

t = t-TDR_results.delay;

5715

t = t-TDR_results.delay;

5724

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5716

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5725

if isempty(tend), tend=length(t); end

5717

if isempty(tend), tend=length(t); end

5726

IR=IR(1:tend);

5718

IR=IR(1:tend);

5727

t=t(1:tend);

5719

t=t(1:tend);

5728

if isempty(tend), tend=length(t); end

5720

if isempty(tend), tend=length(t); end

5729

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5721

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5730

if isempty(tstart), tstart=1;end

5722

if isempty(tstart), tstart=1;end

5731

if isempty(tend) || tstart >= tend

5723

if isempty(tend) || tstart >= tend

5732

if isempty(tend) || tstart >= tend

5724

if isempty(tend) || tstart >= tend

5733

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5725

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5734

end

5726

end

5735

tend=length(t);

5727

tend=length(t);

5736

tstart=1;

5728

tstart=1;

5737

end

5729

end

5738

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5730

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5739

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5731

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5740

TDR_results.tdr= ch.ZSR;

5732

TDR_results.tdr= ch.ZSR;

5741

TDR_results.t = t(tstart:tend);

5733

TDR_results.t = t(tstart:tend);

5742

5734

5743

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5735

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5744

if OP.TDR || OP.PTDR % determin average impededance with

5736

if OP.TDR || OP.PTDR % determin average impededance with

5745

try

5737

try

5746

tfstart=find(t>=3*tr*1e-9,1);

5738

tfstart=find(t>=3*tr*1e-9,1);

5747

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5739

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5748

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5740

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5749

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5741

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5750

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5742

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5751

catch

5743

catch

5752

TDR_results.avgZport=0;

5744

TDR_results.avgZport=0;

5753

fit=zeros(1,1);

5745

fit=zeros(1,1);

5754

p=[0 0 0 0 ];

5746

p=[0 0 0 0 ];

5755

end

5747

end

5756

TDR_results.RL=RL;

5748

TDR_results.RL=RL;

5757

end

5749

end

5758

if OP.PTDR

5750

if OP.PTDR

5759

% param.N_bx=param.ndfe;

5751

% param.N_bx=param.ndfe;

5760

RL_equiv=-inf;

5752

RL_equiv=-inf;

5761

L=param.levels;

5753

L=param.levels;

5762

BinSize=OP.BinSize;

5754

BinSize=OP.BinSize;

5763

% param.specBER=1e-5;

5755

% param.specBER=1e-5;

5764

if OP.DISPLAY_WINDOW

5756

if OP.DISPLAY_WINDOW

5765

hwaitbar=waitbar(0);

5757

hwaitbar=waitbar(0);

5766

else

5758

else

5767

fprintf('Worst ERL searching');

5759

fprintf('Worst ERL searching');

5768

end

5760

end

5769

% adjust PTDR for NDFE

5761

% adjust PTDR for NDFE

5770

% ---------------------- 2.7 code

5762

% ---------------------- 2.7 code

5771

% ntx=find(TDR_results.t >= tfx,1,'first');

5763

% ntx=find(TDR_results.t >= tfx,1,'first');

5772

% % gatestartt=TDR_results.t(ntx);

5764

% % gatestartt=TDR_results.t(ntx);

5773

% % gatestartV=PTDR.pulse(ntx);

5765

% % gatestartV=PTDR.pulse(ntx);

5774

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5766

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5775

% tk=param.ui*1*(param.N_bx+1)+tfx;

5767

% tk=param.ui*1*(param.N_bx+1)+tfx;

5776

% -------------------

5768

% -------------------

5777

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5769

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5778

% time filter.

5770

% time filter.

5779

% ntx=find(TDR_results.t >= tfx,1,'first');

5771

% ntx=find(TDR_results.t >= tfx,1,'first');

5780

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5772

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5781

% gatestartt=TDR_results.t(ntx);

5773

% gatestartt=TDR_results.t(ntx);

5782

% gatestartV=PTDR.pulse(ntx);

5774

% gatestartV=PTDR.pulse(ntx);

5783

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5775

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5784

% tk=param.ui*1*(param.N_bx+1)+tfx;

5776

% tk=param.ui*1*(param.N_bx+1)+tfx;

5785

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5777

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5786

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5778

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5787

% [ahealey] End of modifications.

5779

% [ahealey] End of modifications.

5788

if isempty(ndfex), ndfex=length(TDR_results.t); end

5780

if isempty(ndfex), ndfex=length(TDR_results.t); end

5789

PTDR.pulse_orig=PTDR.pulse;

5781

PTDR.pulse_orig=PTDR.pulse;

5790

5782

5791

switch param.Grr

5783

switch param.Grr

5792

case 0 % pre .3cd release

5784

case 0 % pre .3cd release

5793

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5785

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5794

case 1 % .3cd release

5786

case 1 % .3cd release

5795

fctrx(1:length(PTDR.pulse_orig))=1;

5787

fctrx(1:length(PTDR.pulse_orig))=1;

5796

case 2 % .3ck working

5788

case 2 % .3ck working

5797

fctrx(1:length(PTDR.pulse_orig))=1;

5789

fctrx(1:length(PTDR.pulse_orig))=1;

5798

end

5790

end

5799

Gloss(1:length(TDR_results.t))=1;

5791

Gloss(1:length(TDR_results.t))=1;

5800

Grr(1:length(TDR_results.t))=1;

5792

Grr(1:length(TDR_results.t))=1;

5801

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5793

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5802

5794

5803

for ii=ntx:ndfex

5795

for ii=ntx:ndfex

5804

% adjust for near end loss

5796

% adjust for near end loss

5805

if param.N_bx>0 && param.beta_x~=0;

5797

if param.N_bx>0 && param.beta_x~=0;

5806

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5798

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5807

else

5799

else

5808

Gloss(ii)=1;

5800

Gloss(ii)=1;

5809

end

5801

end

5810

% ---------------------- 2.7 code

5802

% ---------------------- 2.7 code

5811

% x=(TDR_results.t(ii)-tfx)/param.ui;

5803

% x=(TDR_results.t(ii)-tfx)/param.ui;

5812

% ----------------------

5804

% ----------------------

5813

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5805

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5814

% rise time filter.

5806

% rise time filter.

5815

% x=(TDR_results.t(ii)-tfx)/param.ui;

5807

% x=(TDR_results.t(ii)-tfx)/param.ui;

5816

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5808

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5817

% determine how much of the return loss to use base on expected

5809

% determine how much of the return loss to use base on expected

5818

% missing reflections

5810

% missing reflections

5819

switch param.Grr

5811

switch param.Grr

5820

case 0 % pre .3cd release

5812

case 0 % pre .3cd release

5821

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5813

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5822

case 1 % .3cd release

5814

case 1 % .3cd release

5823

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5815

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5824

case 2 % .3ck working

5816

case 2 % .3ck working

5825

Grr(ii)= param.rho_x ;

5817

Grr(ii)= param.rho_x ;

5826

end

5818

end

5827

fctrx(ii)=Gloss(ii).*Grr(ii);

5819

fctrx(ii)=Gloss(ii).*Grr(ii);

5828

end

5820

end

5829

5821

5830

if isrow(fctrx), fctrx=fctrx(:);end

5822

if isrow(fctrx), fctrx=fctrx(:);end

5831

PTDR.pulse=PTDR.pulse.*fctrx;

5823

PTDR.pulse=PTDR.pulse.*fctrx;

5832

if 0

5824

if 0

5833

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5825

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5834

s1=subplot(2,1,1);

5826

s1=subplot(2,1,1);

5835

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5827

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5836

hold on

5828

hold on

5837

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5829

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5838

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5830

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5839

grid on

5831

grid on

5840

ylim([ 0 1.2])

5832

ylim([ 0 1.2])

5841

s2=subplot(2,1,2);

5833

s2=subplot(2,1,2);

5842

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5834

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5843

grid on

5835

grid on

5844

linkaxes([s1,s2],'x')

5836

linkaxes([s1,s2],'x')

5845

xlabel 'UI'

5837

xlabel 'UI'

5846

xlim ([ 1 200])

5838

xlim ([ 1 200])

5847

end

5839

end

5848

5840

5849

FAST_NOISE_CONV=0;

5841

FAST_NOISE_CONV=0;

5850

ERLRMS=rms(PTDR.pulse);

5842

ERLRMS=rms(PTDR.pulse);

5851

for ki=1:param.samples_per_ui

5843

for ki=1:param.samples_per_ui

5852

progress = ki/param.samples_per_ui;

5844

progress = ki/param.samples_per_ui;

5853

if OP.DISPLAY_WINDOW

5845

if OP.DISPLAY_WINDOW

5854

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5846

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5855

else

5847

else

5856

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5848

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5857

end

5849

end

5858

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5850

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5859

if OP.RL_norm_test

5851

if OP.RL_norm_test

5860

rl_fom=(norm(tps));

5852

rl_fom=(norm(tps));

5861

else

5853

else

5862

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5854

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5863

cdf_test=cumsum(testpdf.y);

5855

cdf_test=cumsum(testpdf.y);

5864

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5856

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5865

rl_fom=rl_test;

5857

rl_fom=rl_test;

5866

end

5858

end

5867

if rl_fom > RL_equiv

5859

if rl_fom > RL_equiv

5868

RL_equiv=rl_fom;

5860

RL_equiv=rl_fom;

5869

best_ki=ki;

5861

best_ki=ki;

5870

end

5862

end

5871

if ~OP.RL_norm_test

5863

if ~OP.RL_norm_test

5872

best_erl=rl_test;

5864

best_erl=rl_test;

5873

best_pdf=testpdf;

5865

best_pdf=testpdf;

5874

best_cdf=cdf_test;

5866

best_cdf=cdf_test;

5875

end

5867

end

5876

5868

5877

end

5869

end

5878

if OP.RL_norm_test

5870

if OP.RL_norm_test

5879

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5871

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5880

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5872

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5881

cdf_test=cumsum(testpdf.y);

5873

cdf_test=cumsum(testpdf.y);

5882

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5874

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5883

end

5875

end

5884

5876

5885

fprintf('\n');

5877

fprintf('\n');

5886

try

5878

try

5887

close(hwaitbar)

5879

close(hwaitbar)

5888

catch

5880

catch

5889

end

5881

end

5890

if ~exist('best_ki','var'),best_ki=1;end

5882

if ~exist('best_ki','var'),best_ki=1;end

5891

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5883

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5892

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5884

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5893

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5885

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5894

TDR_results.ERL=-db(best_erl);

5886

TDR_results.ERL=-db(best_erl);

5895

TDR_results.ERLRMS=-db(ERLRMS);

5887

TDR_results.ERLRMS=-db(ERLRMS);

5896

5888

5897

end

5889

end

5898

5890

5899

5891

5900

% end get TDR

5892

% end get TDR

5901

%%

5893

%%

5902

5894

5903

5895

5904

5896

5905

5897

5906

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5898

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5907

% filename parsing and acquisition

5899

% filename parsing and acquisition

5908

%------------------------------------------------------------------

5900

%------------------------------------------------------------------

5909

%----------put files names into chdata structure ---------

5901

%----------put files names into chdata structure ---------

5910

% The thru file has the index of 1

5902

% The thru file has the index of 1

5911

% crosstalk file are indexed from 2

5903

% crosstalk file are indexed from 2

5912

% nxi is incremented each time a file is read in so that nxi will end

5904

% nxi is incremented each time a file is read in so that nxi will end

5913

filepath=[]; % path name for file

5905

filepath=[]; % path name for file

5914

nxi=0; % file index

5906

nxi=0; % file index

5915

% get the THRU file

5907

% get the THRU file

5916

if size(file_list,2) ~= 0

5908

if size(file_list,2) ~= 0

5917

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5909

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5918

[filepath, basename, fileext]=fileparts(file_list{1});

5910

[filepath, basename, fileext]=fileparts(file_list{1});

5919

5911

5920

else

5912

else

5921

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5913

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5922

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5914

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5923

movegui(h,'northeast')

5915

movegui(h,'northeast')

5924

end

5916

end

5925

dir=fullfile(filepath, '*.csv');

5917

dir=fullfile(filepath, '*.csv');

5926

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5918

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5927

if filepath == 0

5919

if filepath == 0

5928

error('No Thru file')

5920

error('No Thru file')

5929

end

5921

end

5930

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5922

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5931

end

5923

end

5932

nxi=nxi+1;

5924

nxi=nxi+1;

5933

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5925

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5934

chdata(nxi).ext = fileext;

5926

chdata(nxi).ext = fileext;

5935

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5927

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5936

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5928

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5937

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5929

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5938

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5930

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5939

chdata(nxi).type='THRU';

5931

chdata(nxi).type='THRU';

5940

chdata(nxi).ftr=param.fb*param.f_v;

5932

chdata(nxi).ftr=param.fb*param.f_v;

5941

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5933

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5942

5934

5943

% now get FEXT file names into chdata structure

5935

% now get FEXT file names into chdata structure

5944

kxi=nxi;

5936

kxi=nxi;

5945

for nxi=kxi+1:num_fext+kxi

5937

for nxi=kxi+1:num_fext+kxi

5946

lastfilepath=filepath;

5938

lastfilepath=filepath;

5947

if size(file_list,2) ~= 0

5939

if size(file_list,2) ~= 0

5948

[filepath, basename, fileext]=fileparts(file_list{nxi});

5940

[filepath, basename, fileext]=fileparts(file_list{nxi});

5949

else

5941

else

5950

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5942

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5951

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5943

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5952

movegui(h,'northeast')

5944

movegui(h,'northeast')

5953

end

5945

end

5954

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5946

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5955

dir=fullfile(filepath, '*.csv');

5947

dir=fullfile(filepath, '*.csv');

5956

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5948

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5957

if filepath==0

5949

if filepath==0

5958

error('Not enough NEXT files')

5950

error('Not enough NEXT files')

5959

end

5951

end

5960

else

5952

else

5961

dir=fullfile(filepath, '*.csv');

5953

dir=fullfile(filepath, '*.csv');

5962

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5954

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5963

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5955

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5964

else

5956

else

5965

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5957

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5966

end

5958

end

5967

if filepath==0

5959

if filepath==0

5968

error('Not enough NEXT files')

5960

error('Not enough NEXT files')

5969

end

5961

end

5970

end

5962

end

5971

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5963

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5972

end

5964

end

5973

if isempty( filepath), filepath=lastfilepath; end

5965

if isempty( filepath), filepath=lastfilepath; end

5974

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5966

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5975

chdata(nxi).ext = fileext;

5967

chdata(nxi).ext = fileext;

5976

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5968

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5977

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5969

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5978

% chdata(nxi).A=param.a_fext;

5970

% chdata(nxi).A=param.a_fext;

5979

chdata(nxi).ftr=param.fb*param.f_f;

5971

chdata(nxi).ftr=param.fb*param.f_f;

5980

chdata(nxi).type='FEXT';

5972

chdata(nxi).type='FEXT';

5981

end

5973

end

5982

% now get NEXT file names into chdata structure

5974

% now get NEXT file names into chdata structure

5983

kxi=num_fext+kxi;

5975

kxi=num_fext+kxi;

5984

for nxi=kxi+1:num_next+kxi

5976

for nxi=kxi+1:num_next+kxi

5985

lastfilepath=filepath;

5977

lastfilepath=filepath;

5986

if size(file_list,2) ~= 0

5978

if size(file_list,2) ~= 0

5987

[filepath, basename, fileext]=fileparts(file_list{nxi});

5979

[filepath, basename, fileext]=fileparts(file_list{nxi});

5988

else

5980

else

5989

dir=fullfile(filepath, '*.csv');

5981

dir=fullfile(filepath, '*.csv');

5990

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5982

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5991

if filepath==0

5983

if filepath==0

5992

error('Not enough NEXT files')

5984

error('Not enough NEXT files')

5993

end

5985

end

5994

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5986

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5995

end

5987

end

5996

if isempty( filepath), filepath=lastfilepath; end

5988

if isempty( filepath), filepath=lastfilepath; end

5997

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5989

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5998

chdata(nxi).ext = fileext;

5990

chdata(nxi).ext = fileext;

5999

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5991

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6000

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5992

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6001

% chdata(nxi).A=param.A_next;

5993

% chdata(nxi).A=param.A_next;

6002

chdata(nxi).ftr=param.fb*param.f_n;

5994

chdata(nxi).ftr=param.fb*param.f_n;

6003

chdata(nxi).type='NEXT';

5995

chdata(nxi).type='NEXT';

6004

end

5996

end

6005

function half_UI=get_center_of_UI(samples_per_UI)

5997

function half_UI=get_center_of_UI(samples_per_UI)

6006

5998

6007

%half_UI reveals which value to use for the center of the UI. For eye

5999

%half_UI reveals which value to use for the center of the UI. For eye

6008

%width calculations, it is necessary to place the cursor in the center of the

6000

%width calculations, it is necessary to place the cursor in the center of the

6009

%UI window to ensure a 0 crossing on both left/right inside the window.

6001

%UI window to ensure a 0 crossing on both left/right inside the window.

6010

%This function was written in order to support even and odd samples_per_UI

6002

%This function was written in order to support even and odd samples_per_UI

6011

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

6003

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

6012

6004

6013

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

6005

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

6014

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

6006

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

6015

%the center of the UI is sample closest to 0.5

6007

%the center of the UI is sample closest to 0.5

6016

[temp_diff,half_UI]=min(abs(UI_window-0.5));

6008

[temp_diff,half_UI]=min(abs(UI_window-0.5));

6017

function results= get_cm_noise(M,PR,L,BER,OP)

6009

function results= get_cm_noise(M,PR,L,BER,OP)

6018

6010

6019

if ~exist('OP')

6011

if ~exist('OP')

6020

OP.DC_norm_test=0;

6012

OP.DC_norm_test=0;

6021

OP.DISPLAY_WINDOW=1;

6013

OP.DISPLAY_WINDOW=1;

6022

end

6014

end

6023

param.BinSize=1e-5;

6015

param.BinSize=1e-5;

6024

PR_test=-inf;

6016

PR_test=-inf;

6025

PR_fom_best=-inf;

6017

PR_fom_best=-inf;

6026

% hwaitbar=waitbar(0);

6018

% hwaitbar=waitbar(0);

6027

for ki=1:M

6019

for ki=1:M

6028

progress = ki/M;

6020

progress = ki/M;

6029

% if OP.DISPLAY_WINDOW

6021

% if OP.DISPLAY_WINDOW

6030

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

6022

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

6031

% else

6023

% else

6032

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

6024

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

6033

% end

6025

% end

6034

tps=PR(ki:M:end);

6026

tps=PR(ki:M:end);

6035

if OP.DC_norm_test

6027

if OP.DC_norm_test

6036

PR_fom=(norm(tps));

6028

PR_fom=(norm(tps));

6037

else

6029

else

6038

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

6030

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

6039

cdf_test=cumsum(testpdf.y);

6031

cdf_test=cumsum(testpdf.y);

6040

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

6032

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

6041

PR_fom=PRn_test;

6033

PR_fom=PRn_test;

6042

end

6034

end

6043

if PR_fom > PR_fom_best

6035

if PR_fom > PR_fom_best

6044

PR_fom_best=PR_fom;

6036

PR_fom_best=PR_fom;

6045

best_ki=ki;

6037

best_ki=ki;

6046

end

6038

end

6047

if ~OP.DC_norm_test

6039

if ~OP.DC_norm_test

6048

results.DCn=PR_fom_best;

6040

results.DCn=PR_fom_best;

6049

results.DCn_pdf=testpdf;

6041

results.DCn_pdf=testpdf;

6050

results.DCn_cdf=cdf_test;

6042

results.DCn_cdf=cdf_test;

6051

else

6043

else

6052

results.DCn=PR_fom_best;

6044

results.DCn=PR_fom_best;

6053

end

6045

end

6054

results.DCn_p2p=max(PR)-min(PR);

6046

results.DCn_p2p=max(PR)-min(PR);

6055

end

6047

end

6056

6048

6057

6049

6058

6050

6059

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

6051

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

6060

SBR=chdata.eq_pulse_response(:)'; % row vector

6052

SBR=chdata.eq_pulse_response(:)'; % row vector

6061

type=chdata.type;

6053

type=chdata.type;

6062

samp_UI=param.samples_per_ui;

6054

samp_UI=param.samples_per_ui;

6063

residual_response = SBR;

6055

residual_response = SBR;

6064

6056

6065

if isequal(type, 'THRU')

6057

if isequal(type, 'THRU')

6066

% for thru pulse response:

6058

% for thru pulse response:

6067

% remove the cursor and the DFE postcursors (up to their limit), since

6059

% remove the cursor and the DFE postcursors (up to their limit), since

6068

% we only care about the residuals.

6060

% we only care about the residuals.

6069

6061

6070

if ~param.Floating_DFE

6062

if ~param.Floating_DFE

6071

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

6063

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

6072

else

6064

else

6073

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

6065

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

6074

end

6066

end

6075

if param.dfe_delta ~= 0

6067

if param.dfe_delta ~= 0

6076

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

6068

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

6077

else

6069

else

6078

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

6070

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

6079

end

6071

end

6080

6072

6081

%AJG021820

6073

%AJG021820

6082

if ~param.Floating_DFE

6074

if ~param.Floating_DFE

6083

bmax_vec=residual_response(t_s)*[1,param.bmax];

6075

bmax_vec=residual_response(t_s)*[1,param.bmax];

6084

bmin_vec=residual_response(t_s)*[1,param.bmin];

6076

bmin_vec=residual_response(t_s)*[1,param.bmin];

6085

else

6077

else

6086

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

6078

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

6087

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

6079

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

6088

end

6080

end

6089

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6081

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6090

6082

6091

6083

6092

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

6084

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

6093

dfetaps=effective_cancelled_cursors/SBR(t_s);

6085

dfetaps=effective_cancelled_cursors/SBR(t_s);

6094

6086

6095

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6087

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6096

% really needed for COM, but helps debugging. May be factored out in future revisions.

6088

% really needed for COM, but helps debugging. May be factored out in future revisions.

6097

start_cancel = t_s-param.samples_per_ui/2;

6089

start_cancel = t_s-param.samples_per_ui/2;

6098

if ~param.Floating_DFE

6090

if ~param.Floating_DFE

6099

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

6091

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

6100

else

6092

else

6101

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

6093

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

6102

end

6094

end

6103

residual_response(start_cancel:end_cancel) = ...

6095

residual_response(start_cancel:end_cancel) = ...

6104

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6096

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6105

%else

6097

%else

6106

% for crosstalk pulse responses, nothing is cancelled, and all phases

6098

% for crosstalk pulse responses, nothing is cancelled, and all phases

6107

% are equally important.

6099

% are equally important.

6108

end

6100

end

6109

6101

6110

nui=round(length(residual_response)/param.samples_per_ui);

6102

nui=round(length(residual_response)/param.samples_per_ui);

6111

6103

6112

vs=zeros(nui-2, param.samples_per_ui);

6104

vs=zeros(nui-2, param.samples_per_ui);

6113

for i=1:param.samples_per_ui

6105

for i=1:param.samples_per_ui

6114

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

6106

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

6115

end

6107

end

6116

6108

6117

if OP.DISPLAY_WINDOW,

6109

if OP.DISPLAY_WINDOW,

6118

hwaitbar=waitbar(0);

6110

hwaitbar=waitbar(0);

6119

end

6111

end

6120

6112

6121

% determine which pdf to use

6113

% determine which pdf to use

6122

if isequal(type, 'THRU')

6114

if isequal(type, 'THRU')

6123

% one phase is interesting for thru

6115

% one phase is interesting for thru

6124

phases = mod(t_s,param.samples_per_ui);

6116

phases = mod(t_s,param.samples_per_ui);

6125

if phases==0, phases = param.samples_per_ui; end

6117

if phases==0, phases = param.samples_per_ui; end

6126

else

6118

else

6127

phases=1:samp_UI;

6119

phases=1:samp_UI;

6128

end

6120

end

6129

6121

6130

mxV = zeros(size(phases));

6122

mxV = zeros(size(phases));

6131

% we already found the phase in the PSD process for MMSE

6123

% we already found the phase in the PSD process for MMSE

6132

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

6124

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

6133

if isequal(type, 'THRU')

6125

if isequal(type, 'THRU')

6134

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

6126

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

6135

else

6127

else

6136

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

6128

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

6137

end

6129

end

6138

else

6130

else

6139

for k=phases

6131

for k=phases

6140

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

6132

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

6141

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6133

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6142

progress = k/length(phases);

6134

progress = k/length(phases);

6143

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6135

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6144

end

6136

end

6145

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

6137

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

6146

pdf=pdf_samples(pxi);

6138

pdf=pdf_samples(pxi);

6147

end

6139

end

6148

6140

6149

6141

6150

6142

6151

if OP.DISPLAY_WINDOW

6143

if OP.DISPLAY_WINDOW

6152

close(hwaitbar);

6144

close(hwaitbar);

6153

end

6145

end

6154

6146

6155

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

6147

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

6156

% Create PDF from interference vector using successive delta-set convolutions.

6148

% Create PDF from interference vector using successive delta-set convolutions.

6157

% input_vector = list of values of samples

6149

% input_vector = list of values of samples

6158

% return

6150

% return

6159

% pdf.x

6151

% pdf.x

6160

% pdf.y

6152

% pdf.y

6161

% pdf.vec

6153

% pdf.vec

6162

% pdf.bin

6154

% pdf.bin

6163

if ~exist('FAST_NOISE_CONV','var')

6155

if ~exist('FAST_NOISE_CONV','var')

6164

FAST_NOISE_CONV=0;

6156

FAST_NOISE_CONV=0;

6165

end

6157

end

6166

if max(input_vector) > BinSize

6158

if max(input_vector) > BinSize

6167

input_vector=input_vector(abs(input_vector)>BinSize);

6159

input_vector=input_vector(abs(input_vector)>BinSize);

6168

end

6160

end

6169

% for i = 1:length(input_vector)

6161

% for i = 1:length(input_vector)

6170

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

6162

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

6171

%end

6163

%end

6172

6164

6173

input_vector(abs(input_vector)<BinSize) = 0;

6165

input_vector(abs(input_vector)<BinSize) = 0;

6174

b=sign(input_vector);

6166

b=sign(input_vector);

6175

[input_vector,index]=sort(abs(input_vector),'descend');

6167

[input_vector,index]=sort(abs(input_vector),'descend');

6176

input_vector=input_vector.*b(index);

6168

input_vector=input_vector.*b(index);

6177

if FAST_NOISE_CONV

6169

if FAST_NOISE_CONV

6178

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

6170

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

6179

res_pdf= normal_dist(sig_res,5,BinSize);

6171

res_pdf= normal_dist(sig_res,5,BinSize);

6180

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

6172

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

6181

end

6173

end

6182

%% Equation 93A-39 %%

6174

%% Equation 93A-39 %%

6183

values = 2*(0:L-1)/(L-1)-1;

6175

values = 2*(0:L-1)/(L-1)-1;

6184

prob = ones(1,L)/L;

6176

prob = ones(1,L)/L;

6185

6177

6186

%% Initialize pdf to delta at 0

6178

%% Initialize pdf to delta at 0

6187

pdf=d_cpdf(BinSize, 0, 1);

6179

pdf=d_cpdf(BinSize, 0, 1);

6188

empty_pdf=pdf;

6180

empty_pdf=pdf;

6189

for k = 1:length(input_vector)

6181

for k = 1:length(input_vector)

6190

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

6182

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

6191

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

6183

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

6192

pdf=conv_fct(pdf, pdfn);

6184

pdf=conv_fct(pdf, pdfn);

6193

end

6185

end

6194

if FAST_NOISE_CONV

6186

if FAST_NOISE_CONV

6195

% pdf=conv_fct(pdf,res_pdf);

6187

% pdf=conv_fct(pdf,res_pdf);

6196

pdf=conv_fct_TEST(pdf,res_pdf);

6188

pdf=conv_fct_TEST(pdf,res_pdf);

6197

end

6189

end

6198

6190

6199

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

6191

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

6200

t_s_orig=t_s;

6192

t_s_orig=t_s;

6201

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

6193

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

6202

type=chdata.type;

6194

type=chdata.type;

6203

6195

6204

pulse_orig=chdata.eq_pulse_response(:)';

6196

pulse_orig=chdata.eq_pulse_response(:)';

6205

%build arbitrary time axis with step size = 1/samples per ui

6197

%build arbitrary time axis with step size = 1/samples per ui

6206

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

6198

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

6207

%force t_s at time =0 (makes the other things below easy)

6199

%force t_s at time =0 (makes the other things below easy)

6208

original_sample_time=old_time(t_s_orig);

6200

original_sample_time=old_time(t_s_orig);

6209

old_time=old_time-original_sample_time;

6201

old_time=old_time-original_sample_time;

6210

%build new time axis that forces time=0 to be in the axis

6202

%build new time axis that forces time=0 to be in the axis

6211

%unless the new/old samples per UI are integer ratios, time 0 will not be

6203

%unless the new/old samples per UI are integer ratios, time 0 will not be

6212

%there by default

6204

%there by default

6213

samp_UI=param.samples_for_C2M;

6205

samp_UI=param.samples_for_C2M;

6214

new_timea=[0:-1/samp_UI:min(old_time)];

6206

new_timea=[0:-1/samp_UI:min(old_time)];

6215

new_timeb=[0:1/samp_UI:max(old_time)];

6207

new_timeb=[0:1/samp_UI:max(old_time)];

6216

new_time=[fliplr(new_timea) new_timeb(2:end)];

6208

new_time=[fliplr(new_timea) new_timeb(2:end)];

6217

SBR=interp1(old_time,pulse_orig,new_time);

6209

SBR=interp1(old_time,pulse_orig,new_time);

6218

%new sample time is simply the point where new_time = 0

6210

%new sample time is simply the point where new_time = 0

6219

[tmp,t_s]=min(abs(new_time));

6211

[tmp,t_s]=min(abs(new_time));

6220

6212

6221

residual_response = SBR;

6213

residual_response = SBR;

6222

6214

6223

half_UI=get_center_of_UI(samp_UI);

6215

half_UI=get_center_of_UI(samp_UI);

6224

6216

6225

if isequal(type, 'THRU')

6217

if isequal(type, 'THRU')

6226

% for thru pulse response:

6218

% for thru pulse response:

6227

% remove the cursor and the DFE postcursors (up to their limit), since

6219

% remove the cursor and the DFE postcursors (up to their limit), since

6228

% we only care about the residuals.

6220

% we only care about the residuals.

6229

6221

6230

%AJG021820

6222

%AJG021820

6231

if ~param.Floating_DFE

6223

if ~param.Floating_DFE

6232

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

6224

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

6233

else

6225

else

6234

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

6226

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

6235

end

6227

end

6236

if param.dfe_delta ~= 0

6228

if param.dfe_delta ~= 0

6237

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

6229

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

6238

else

6230

else

6239

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

6231

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

6240

end

6232

end

6241

6233

6242

if ~param.Floating_DFE

6234

if ~param.Floating_DFE

6243

bmax_vec=residual_response(t_s)*[param.bmax];

6235

bmax_vec=residual_response(t_s)*[param.bmax];

6244

bmin_vec=residual_response(t_s)*[param.bmin];

6236

bmin_vec=residual_response(t_s)*[param.bmin];

6245

else

6237

else

6246

bmax_vec=residual_response(t_s)*[param.use_bmax];

6238

bmax_vec=residual_response(t_s)*[param.use_bmax];

6247

bmin_vec=residual_response(t_s)*[param.use_bmin];

6239

bmin_vec=residual_response(t_s)*[param.use_bmin];

6248

end

6240

end

6249

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6241

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6250

6242

6251

6243

6252

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

6244

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

6253

dfetaps=effective_cancelled_cursors/SBR(t_s);

6245

dfetaps=effective_cancelled_cursors/SBR(t_s);

6254

6246

6255

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6247

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6256

% really needed for COM, but helps debugging. May be factored out in future revisions.

6248

% really needed for COM, but helps debugging. May be factored out in future revisions.

6257

6249

6258

%avoid dividing samp_UI by 2 in case it is not even

6250

%avoid dividing samp_UI by 2 in case it is not even

6259

start_cancel=t_s-half_UI+1+samp_UI;

6251

start_cancel=t_s-half_UI+1+samp_UI;

6260

%AJG021820

6252

%AJG021820

6261

if ~param.Floating_DFE

6253

if ~param.Floating_DFE

6262

end_cancel=start_cancel+param.ndfe*samp_UI-1;

6254

end_cancel=start_cancel+param.ndfe*samp_UI-1;

6263

else

6255

else

6264

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

6256

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

6265

end

6257

end

6266

residual_response(start_cancel:end_cancel) = ...

6258

residual_response(start_cancel:end_cancel) = ...

6267

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6259

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6268

%else

6260

%else

6269

% for crosstalk pulse responses, nothing is cancelled, and all phases

6261

% for crosstalk pulse responses, nothing is cancelled, and all phases

6270

% are equally important.

6262

% are equally important.

6271

6263

6272

%remove entire cursor UI

6264

%remove entire cursor UI

6273

uiv_start=start_cancel-samp_UI;

6265

uiv_start=start_cancel-samp_UI;

6274

uiv_end=uiv_start+samp_UI-1;

6266

uiv_end=uiv_start+samp_UI-1;

6275

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

6267

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

6276

residual_response(uiv_start:uiv_end)=0;

6268

residual_response(uiv_start:uiv_end)=0;

6277

end

6269

end

6278

6270

6279

nui=round(length(residual_response)/samp_UI);

6271

nui=round(length(residual_response)/samp_UI);

6280

6272

6281

6273

6282

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6274

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6283

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

6275

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

6284

%response without DFE included. (Can't include DFE for jitter calc)

6276

%response without DFE included. (Can't include DFE for jitter calc)

6285

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6277

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6286

6278

6287

% if OP.DISPLAY_WINDOW,

6279

% if OP.DISPLAY_WINDOW,

6288

% hwaitbar=waitbar(0);

6280

% hwaitbar=waitbar(0);

6289

% end

6281

% end

6290

6282

6291

% determine which pdf to use

6283

% determine which pdf to use

6292

if isequal(type, 'THRU')

6284

if isequal(type, 'THRU')

6293

% one phase is interesting for thru

6285

% one phase is interesting for thru

6294

phases = mod(t_s,samp_UI);

6286

phases = mod(t_s,samp_UI);

6295

if phases==0, phases = samp_UI; end

6287

if phases==0, phases = samp_UI; end

6296

else

6288

else

6297

phases=1:samp_UI;

6289

phases=1:samp_UI;

6298

end

6290

end

6299

6291

6300

mxV = zeros(size(phases));

6292

mxV = zeros(size(phases));

6301

6293

6302

%phases reveals the raw position in the UI window of the cursor.

6294

%phases reveals the raw position in the UI window of the cursor.

6303

%shift_amount is the amount to shift so that it aligns with half_UI

6295

%shift_amount is the amount to shift so that it aligns with half_UI

6304

shift_amount=half_UI-phases;

6296

shift_amount=half_UI-phases;

6305

%vs_shift puts the cursor at the center

6297

%vs_shift puts the cursor at the center

6306

vs_shift=circshift(vs,[0 shift_amount]);

6298

vs_shift=circshift(vs,[0 shift_amount]);

6307

L=size(vs_raw,1);

6299

L=size(vs_raw,1);

6308

%allow partial UI computation through pdf_range

6300

%allow partial UI computation through pdf_range

6309

%if pdf_range is empty, do full UI

6301

%if pdf_range is empty, do full UI

6310

if isempty(pdf_range)

6302

if isempty(pdf_range)

6311

pdf_range=1:samp_UI;

6303

pdf_range=1:samp_UI;

6312

else

6304

else

6313

pdf_range=min(pdf_range):max(pdf_range);

6305

pdf_range=min(pdf_range):max(pdf_range);

6314

end

6306

end

6315

h_j_full=zeros(L,samp_UI);

6307

h_j_full=zeros(L,samp_UI);

6316

for k=pdf_range

6308

for k=pdf_range

6317

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6309

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6318

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6310

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6319

%progress = k/length(phases);

6311

%progress = k/length(phases);

6320

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6312

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6321

6313

6322

%build the circshift of h_j_full into the loop to support a reduced

6314

%build the circshift of h_j_full into the loop to support a reduced

6323

%range of sampling points. circshift at the end only works if doing the

6315

%range of sampling points. circshift at the end only works if doing the

6324

%full range of sampling points. And shifting before the loop will

6316

%full range of sampling points. And shifting before the loop will

6325

%yield the wrong answer at the edges of the UI

6317

%yield the wrong answer at the edges of the UI

6326

hk=k-shift_amount;

6318

hk=k-shift_amount;

6327

if hk<1

6319

if hk<1

6328

hk=hk+samp_UI;

6320

hk=hk+samp_UI;

6329

elseif hk>samp_UI

6321

elseif hk>samp_UI

6330

hk=hk-samp_UI;

6322

hk=hk-samp_UI;

6331

end

6323

end

6332

if hk==1

6324

if hk==1

6333

%when hk=1, the early UI is the last column

6325

%when hk=1, the early UI is the last column

6334

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6326

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6335

elseif hk==samp_UI

6327

elseif hk==samp_UI

6336

%when hk=samp_UI, the late UI is the first column

6328

%when hk=samp_UI, the late UI is the first column

6337

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6329

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6338

else

6330

else

6339

%for all other cases, do the normal late=+1, early = -1

6331

%for all other cases, do the normal late=+1, early = -1

6340

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6332

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6341

end

6333

end

6342

end

6334

end

6343

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6335

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6344

% filename parsing and acquisition

6336

% filename parsing and acquisition

6345

%------------------------------------------------------------------

6337

%------------------------------------------------------------------

6346

%----------put files names into chdata structure ---------

6338

%----------put files names into chdata structure ---------

6347

% The thru file has the index of 1

6339

% The thru file has the index of 1

6348

% crosstalk file are indexed from 2

6340

% crosstalk file are indexed from 2

6349

% nxi is incremented each time a file is read in so that nxi will end

6341

% nxi is incremented each time a file is read in so that nxi will end

6350

filepath=[]; % path name for file

6342

filepath=[]; % path name for file

6351

nxi=0; % file index

6343

nxi=0; % file index

6352

% get the THRU file

6344

% get the THRU file

6353

if size(file_list,2) ~= 0

6345

if size(file_list,2) ~= 0

6354

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6346

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6355

[filepath, basename, fileext]=fileparts(file_list{1});

6347

[filepath, basename, fileext]=fileparts(file_list{1});

6356

6348

6357

else

6349

else

6358

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6350

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6359

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6351

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6360

movegui(h,'northeast')

6352

movegui(h,'northeast')

6361

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6353

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6362

end

6354

end

6363

if OP.ERL == 2

6355

if OP.ERL == 2

6364

dir=fullfile(filepath, '*.s2p');

6356

dir=fullfile(filepath, '*.s2p');

6365

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6357

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6366

if filepath == 0

6358

if filepath == 0

6367

error('No RL measurement file')

6359

error('No RL measurement file')

6368

end

6360

end

6369

else

6361

else

6370

dir=fullfile(filepath, '*.s4p');

6362

dir=fullfile(filepath, '*.s4p');

6371

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6363

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6372

if filepath == 0

6364

if filepath == 0

6373

error('No Thru file')

6365

error('No Thru file')

6374

end

6366

end

6375

end

6367

end

6376

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6368

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6377

end

6369

end

6378

nxi=nxi+1;

6370

nxi=nxi+1;

6379

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6371

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6380

chdata(nxi).ext = fileext;

6372

chdata(nxi).ext = fileext;

6381

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6373

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6382

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6374

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6383

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6375

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6384

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6376

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6385

chdata(nxi).type='THRU';

6377

chdata(nxi).type='THRU';

6386

chdata(nxi).ftr=param.fb*param.f_v;

6378

chdata(nxi).ftr=param.fb*param.f_v;

6387

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6379

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6388

6380

6389

% now get FEXT file names into chdata structure

6381

% now get FEXT file names into chdata structure

6390

kxi=nxi;

6382

kxi=nxi;

6391

for nxi=kxi+1:num_fext+kxi

6383

for nxi=kxi+1:num_fext+kxi

6392

lastfilepath=filepath;

6384

lastfilepath=filepath;

6393

if size(file_list,2) ~= 0

6385

if size(file_list,2) ~= 0

6394

[filepath, basename, fileext]=fileparts(file_list{nxi});

6386

[filepath, basename, fileext]=fileparts(file_list{nxi});

6395

else

6387

else

6396

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6388

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6397

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6389

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6398

movegui(h,'northeast')

6390

movegui(h,'northeast')

6399

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6391

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6400

end

6392

end

6401

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6393

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6402

dir=fullfile(filepath, '*.s4p');

6394

dir=fullfile(filepath, '*.s4p');

6403

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6395

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6404

if filepath==0

6396

if filepath==0

6405

error('Not enough NEXT files')

6397

error('Not enough NEXT files')

6406

end

6398

end

6407

else

6399

else

6408

dir=fullfile(filepath, '*.s4p');

6400

dir=fullfile(filepath, '*.s4p');

6409

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6401

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6410

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6402

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6411

else

6403

else

6412

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6404

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6413

end

6405

end

6414

if filepath==0

6406

if filepath==0

6415

error('Not enough NEXT files')

6407

error('Not enough NEXT files')

6416

end

6408

end

6417

end

6409

end

6418

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6410

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6419

end

6411

end

6420

if isempty( filepath), filepath=lastfilepath; end

6412

if isempty( filepath), filepath=lastfilepath; end

6421

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6413

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6422

chdata(nxi).ext = fileext;

6414

chdata(nxi).ext = fileext;

6423

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6415

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6424

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6416

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6425

% chdata(nxi).A=param.a_fext;

6417

% chdata(nxi).A=param.a_fext;

6426

chdata(nxi).ftr=param.fb*param.f_f;

6418

chdata(nxi).ftr=param.fb*param.f_f;

6427

chdata(nxi).type='FEXT';

6419

chdata(nxi).type='FEXT';

6428

end

6420

end

6429

% now get NEXT file names into chdata structure

6421

% now get NEXT file names into chdata structure

6430

kxi=num_fext+kxi;

6422

kxi=num_fext+kxi;

6431

for nxi=kxi+1:num_next+kxi

6423

for nxi=kxi+1:num_next+kxi

6432

lastfilepath=filepath;

6424

lastfilepath=filepath;

6433

if size(file_list,2) ~= 0

6425

if size(file_list,2) ~= 0

6434

[filepath, basename, fileext]=fileparts(file_list{nxi});

6426

[filepath, basename, fileext]=fileparts(file_list{nxi});

6435

else

6427

else

6436

dir=fullfile(filepath, '*.s4p');

6428

dir=fullfile(filepath, '*.s4p');

6437

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6429

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6438

if filepath==0

6430

if filepath==0

6439

error('Not enough NEXT files')

6431

error('Not enough NEXT files')

6440

end

6432

end

6441

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6433

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6442

end

6434

end

6443

if isempty( filepath), filepath=lastfilepath; end

6435

if isempty( filepath), filepath=lastfilepath; end

6444

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6436

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6445

chdata(nxi).ext = fileext;

6437

chdata(nxi).ext = fileext;

6446

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6438

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6447

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6439

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6448

% chdata(nxi).A=param.A_next;

6440

% chdata(nxi).A=param.A_next;

6449

chdata(nxi).ftr=param.fb*param.f_n;

6441

chdata(nxi).ftr=param.fb*param.f_n;

6450

chdata(nxi).type='NEXT';

6442

chdata(nxi).type='NEXT';

6451

end

6443

end

6452

6444

6453

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6445

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6454

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6446

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6455

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6447

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6456

% H_r - receiver filter, Butterworth

6448

% H_r - receiver filter, Butterworth

6457

% H_ctf - total gain of CTLE and low freq filtering

6449

% H_ctf - total gain of CTLE and low freq filtering

6458

% H_dc - the common mode channel gain

6450

% H_dc - the common mode channel gain

6459

% param.eta_0 -input referred Rx noise

6451

% param.eta_0 -input referred Rx noise

6460

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6452

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6461

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6453

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6462

%% Equation 93A-35 - independent of FFE setting %%

6454

%% Equation 93A-35 - independent of FFE setting %%

6463

sigma_N1 = sqrt(param.eta_0*sum( abs(H_sy(2:end) .* H_r(2:end) .* H_ctf(2:end) ).^2 .* diff(chdata(1).faxis)/1e9));% eta_0 is V^2/Ghz i.e. /1

6455

sigma_N1 = sqrt(param.eta_0*sum( abs(H_sy(2:end) .* H_r(2:end) .* H_ctf(2:end) ).^2 .* diff(chdata(1).faxis)/1e9));% eta_0 is V^2/Ghz i.e. /1

6464

if sum(param.AC_CM_RMS) ~= 0

6456

if sum(param.AC_CM_RMS) ~= 0

6465

sigma_ACCM=0;

6457

sigma_ACCM=0;

6466

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6458

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6467

for i=1:length(chdata)

6459

for i=1:length(chdata)

6468

H_dc=abs(squeeze(chdata(i).sdc21));

6460

H_dc=abs(squeeze(chdata(i).sdc21));

6469

sigma_ACCM_acc= sqrt( 2*param.AC_CM_RMS_TX^2.*sum( abs(H_sy(2:length(f_int)) .* H_r(2:length(f_int)) .* H_ctf(2:length(f_int)).*H_dc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end) );

6461

sigma_ACCM_acc= sqrt( 2*param.AC_CM_RMS_TX^2.*sum( abs(H_sy(2:length(f_int)) .* H_r(2:length(f_int)) .* H_ctf(2:length(f_int)).*H_dc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end) );

6470

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6462

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6471

end

6463

end

6472

sigma_N=norm([sigma_N1,sigma_ACCM]);

6464

sigma_N=norm([sigma_N1,sigma_ACCM]);

6473

else

6465

else

6474

sigma_N=sigma_N1;

6466

sigma_N=sigma_N1;

6475

end

6467

end

6476

%%

6468

%%

6477

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6469

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6478

% for Rx calibratrion only

6470

% for Rx calibratrion only

6479

% the FEXT channel for calibration basically a DC connection unlike normal

6471

% the FEXT channel for calibration basically a DC connection unlike normal

6480

% FEXT channels which are nearly open at DC channels

6472

% FEXT channels which are nearly open at DC channels

6481

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6473

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6482

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6474

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6483

if size(chdata,2) >= 2

6475

if size(chdata,2) >= 2

6484

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6476

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6485

else

6477

else

6486

Hnoise_channel=1;

6478

Hnoise_channel=1;

6487

end

6479

end

6488

f=chdata(2).faxis;

6480

f=chdata(2).faxis;

6489

f_hp=param.f_hp;

6481

f_hp=param.f_hp;

6490

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6482

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6491

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6483

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6492

else

6484

else

6493

H_hp=ones(1,length(f));

6485

H_hp=ones(1,length(f));

6494

end

6486

end

6495

%% Equation 93A-47 or 162-12

6487

%% Equation 93A-47 or 162-12

6496

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6488

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6497

6489

6498

%% Equation 93A-48 or 162-14%%

6490

%% Equation 93A-48 or 162-14%%

6499

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6491

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6500

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6492

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6501

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6493

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6502

% Modified not to double count crosstalk: John Ewen 13/12/2018

6494

% Modified not to double count crosstalk: John Ewen 13/12/2018

6503

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6495

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6504

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6496

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6505

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6497

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6506

f=chdata(1).faxis;

6498

f=chdata(1).faxis;

6507

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6499

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6508

if(f(1)==0)

6500

if(f(1)==0)

6509

temp_angle(1)=1e-20;% we don't want to divide by zero

6501

temp_angle(1)=1e-20;% we don't want to divide by zero

6510

end

6502

end

6511

PWF_tx=ones(1,length(f));

6503

PWF_tx=ones(1,length(f));

6512

if max(upsampled_txffe) > 0

6504

if max(upsampled_txffe) > 0

6513

PWF_tx=zeros(1,length(f));

6505

PWF_tx=zeros(1,length(f));

6514

[mcur,icur] = max(upsampled_txffe);

6506

[mcur,icur] = max(upsampled_txffe);

6515

if exist('phase_memory','var') && ~isempty(phase_memory)

6507

if exist('phase_memory','var') && ~isempty(phase_memory)

6516

pre_calc=1;

6508

pre_calc=1;

6517

else

6509

else

6518

pre_calc=0;

6510

pre_calc=0;

6519

end

6511

end

6520

for ii=1:length(upsampled_txffe)

6512

for ii=1:length(upsampled_txffe)

6521

if upsampled_txffe(ii)==0

6513

if upsampled_txffe(ii)==0

6522

%speed up: skip cases when txffe=0

6514

%speed up: skip cases when txffe=0

6523

continue;

6515

continue;

6524

end

6516

end

6525

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6517

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6526

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6518

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6527

% that is needed

6519

% that is needed

6528

if ii==icur

6520

if ii==icur

6529

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6521

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6530

PWF_tx = PWF_tx + upsampled_txffe(ii);

6522

PWF_tx = PWF_tx + upsampled_txffe(ii);

6531

else

6523

else

6532

if pre_calc

6524

if pre_calc

6533

%speed up: avoid vector exp calculation by externally pre-calculating it

6525

%speed up: avoid vector exp calculation by externally pre-calculating it

6534

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6526

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6535

else

6527

else

6536

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6528

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6537

end

6529

end

6538

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6530

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6539

PWF_tx = PWF_tx + transpose(term_ii(:));

6531

PWF_tx = PWF_tx + transpose(term_ii(:));

6540

end

6532

end

6541

% /Adee

6533

% /Adee

6542

end

6534

end

6543

end

6535

end

6544

PWF_rx=ones(1,length(f));

6536

PWF_rx=ones(1,length(f));

6545

if exist('C','var')

6537

if exist('C','var')

6546

PWF_rx=zeros(1,length(f));

6538

PWF_rx=zeros(1,length(f));

6547

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6539

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6548

if C(ii+param.RxFFE_cmx+1)==0

6540

if C(ii+param.RxFFE_cmx+1)==0

6549

%speed up: skip cases when rxffe=0

6541

%speed up: skip cases when rxffe=0

6550

continue;

6542

continue;

6551

end

6543

end

6552

if ii+1==0

6544

if ii+1==0

6553

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6545

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6554

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6546

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6555

else

6547

else

6556

if pre_calc

6548

if pre_calc

6557

%speed up: avoid vector exp calculation by externally pre-calculating it

6549

%speed up: avoid vector exp calculation by externally pre-calculating it

6558

%The latter columns of phase_memory hold RXFFE shift vectors

6550

%The latter columns of phase_memory hold RXFFE shift vectors

6559

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6551

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6560

term_ii=transpose(term_ii);

6552

term_ii=transpose(term_ii);

6561

else

6553

else

6562

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6554

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6563

end

6555

end

6564

PWF_rx=PWF_rx+term_ii;

6556

PWF_rx=PWF_rx+term_ii;

6565

end

6557

end

6566

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6558

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6567

end

6559

end

6568

end

6560

end

6569

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6561

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6570

for ii=2:size(chdata,2)

6562

for ii=2:size(chdata,2)

6571

SINC = sin(temp_angle)./temp_angle;

6563

SINC = sin(temp_angle)./temp_angle;

6572

PWF_data=SINC.^2;

6564

PWF_data=SINC.^2;

6573

PWF=PWF_data.*PWF_rx; % power weight function

6565

PWF=PWF_data.*PWF_rx; % power weight function

6574

PWFnext=abs(PWF);

6566

PWFnext=abs(PWF);

6575

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6567

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6576

PWFfext=abs(PWF);

6568

PWFfext=abs(PWF);

6577

if isequal(chdata(ii).type, 'FEXT')

6569

if isequal(chdata(ii).type, 'FEXT')

6578

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6570

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6579

MDFEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFfext(1:index_f2).*abs(MDFEXT(1:index_f2)).^2)); %eq 46

6571

MDFEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFfext(1:index_f2).*abs(MDFEXT(1:index_f2)).^2)); %eq 46

6580

elseif isequal(chdata(ii).type, 'NEXT')

6572

elseif isequal(chdata(ii).type, 'NEXT')

6581

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6573

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6582

MDNEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFnext(1:index_f2).*abs(MDNEXT(1:index_f2)).^2)); %eq 47

6574

MDNEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFnext(1:index_f2).*abs(MDNEXT(1:index_f2)).^2)); %eq 47

6583

end

6575

end

6584

end

6576

end

6585

if nargout == 1 && isequal(type,'NEXT')

6577

if nargout == 1 && isequal(type,'NEXT')

6586

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6578

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6587

elseif nargout == 1 && isequal(type,'FEXT')

6579

elseif nargout == 1 && isequal(type,'FEXT')

6588

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6580

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6589

elseif nargout == 3

6581

elseif nargout == 3

6590

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6582

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6591

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6583

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6592

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6584

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6593

end

6585

end

6594

6586

6595

function out=hrem(h,index,N_bf,bmaxg)

6587

function out=hrem(h,index,N_bf,bmaxg)

6596

6588

6597

out=[ h(1:index-1) h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) h(index+N_bf:end) ];

6589

out=[ h(1:index-1) h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) h(index+N_bf:end) ];

6598

% faster than single line function

6590

% faster than single line function

6599

% hrem =@(h,index,N_bf,bmaxg) ...

6591

% hrem =@(h,index,N_bf,bmaxg) ...

6600

% [ h(1:index-1) ...

6592

% [ h(1:index-1) ...

6601

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6593

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6602

% h(index+N_bf:end) ]...

6594

% h(index+N_bf:end) ]...

6603

% ;

6595

% ;

6604

6596

6605

%% floating DFE taps

6597

%% floating DFE taps

6606

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6598

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6607

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6599

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6608

% Sout = interp_Sparam(Sin,fin,fout)

6600

% Sout = interp_Sparam(Sin,fin,fout)

6609

%

6601

%

6610

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6602

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6611

% fout.

6603

% fout.

6612

6604

6613

if ( fin(end)<fout(end) )

6605

if ( fin(end)<fout(end) )

6614

% warning('Channel high frequencies extrapolation might be inaccurate!');

6606

% warning('Channel high frequencies extrapolation might be inaccurate!');

6615

end

6607

end

6616

6608

6617

H_mag = abs(Sin);

6609

H_mag = abs(Sin);

6618

H_mag(H_mag<eps)=eps; % handle ill cases...

6610

H_mag(H_mag<eps)=eps; % handle ill cases...

6619

H_ph = unwrap(angle(Sin));

6611

H_ph = unwrap(angle(Sin));

6620

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6612

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6621

% user ignore that.

6613

% user ignore that.

6622

if mean(diff(H_ph))>0

6614

if mean(diff(H_ph))>0

6623

if OP.DEBUG

6615

if OP.DEBUG

6624

warning('Anti-causal response found. Finer frequency step is required for this channel');

6616

warning('Anti-causal response found. Finer frequency step is required for this channel');

6625

else

6617

else

6626

error('Anti-causal response found. Finer frequency step is required for this channel');

6618

error('Anti-causal response found. Finer frequency step is required for this channel');

6627

end

6619

end

6628

end

6620

end

6629

6621

6630

%opt_interp_Sparam_mag='linear_trend_to_DC';

6622

%opt_interp_Sparam_mag='linear_trend_to_DC';

6631

switch opt_interp_Sparam_mag

6623

switch opt_interp_Sparam_mag

6632

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6624

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6633

if -iscolumn(H_mag), H_mag=H_mag.';end

6625

if -iscolumn(H_mag), H_mag=H_mag.';end

6634

if -iscolumn(fin), fin=fin.';end

6626

if -iscolumn(fin), fin=fin.';end

6635

fin_x=fin;

6627

fin_x=fin;

6636

H_mag_x=H_mag(:);

6628

H_mag_x=H_mag(:);

6637

if fin(1)>0

6629

if fin(1)>0

6638

p=polyfit(fin(1:10), H_mag(1:10), 1);

6630

p=polyfit(fin(1:10), H_mag(1:10), 1);

6639

dc_trend_val=polyval(p, 0);

6631

dc_trend_val=polyval(p, 0);

6640

fin_x=[0, fin_x];

6632

fin_x=[0, fin_x];

6641

H_mag_x = [dc_trend_val; H_mag_x];

6633

H_mag_x = [dc_trend_val; H_mag_x];

6642

end

6634

end

6643

if fin(end)<fout(end)

6635

if fin(end)<fout(end)

6644

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6636

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6645

mid_freq_ind=round(length(fin)/2);

6637

mid_freq_ind=round(length(fin)/2);

6646

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6638

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6647

warning(warn_state);

6639

warning(warn_state);

6648

hf_trend_val=polyval(p, fout(end));

6640

hf_trend_val=polyval(p, fout(end));

6649

if hf_trend_val>H_mag(end)

6641

if hf_trend_val>H_mag(end)

6650

hf_trend_val=H_mag(end);

6642

hf_trend_val=H_mag(end);

6651

hf_logtrend_val = H_mag(end);

6643

hf_logtrend_val = H_mag(end);

6652

elseif hf_trend_val<eps

6644

elseif hf_trend_val<eps

6653

hf_trend_val=eps;

6645

hf_trend_val=eps;

6654

hf_logtrend_val = realmin;

6646

hf_logtrend_val = realmin;

6655

end

6647

end

6656

fin_x=[fin_x, fout(end)];

6648

fin_x=[fin_x, fout(end)];

6657

H_mag_x = [H_mag_x; hf_trend_val];

6649

H_mag_x = [H_mag_x; hf_trend_val];

6658

end

6650

end

6659

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6651

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6660

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6652

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6661

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6653

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6662

indx = find(fout > fin(end),1,'first');

6654

indx = find(fout > fin(end),1,'first');

6663

H_mag_i(indx:end) = H_logmag_i(indx:end);

6655

H_mag_i(indx:end) = H_logmag_i(indx:end);

6664

end

6656

end

6665

case 'trend_to_DC'

6657

case 'trend_to_DC'

6666

% extrapolate to trend value at DC.

6658

% extrapolate to trend value at DC.

6667

if -iscolumn(H_mag), H_mag=H_mag.';end

6659

if -iscolumn(H_mag), H_mag=H_mag.';end

6668

if -iscolumn(fin), fin=fin.';end

6660

if -iscolumn(fin), fin=fin.';end

6669

fin_x=fin;

6661

fin_x=fin;

6670

H_mag_x=H_mag;

6662

H_mag_x=H_mag;

6671

if fin(1)>0

6663

if fin(1)>0

6672

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6664

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6673

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6665

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6674

dc_trend_val=10^polyval(p, 0);

6666

dc_trend_val=10^polyval(p, 0);

6675

fin_x=[0, fin_x];

6667

fin_x=[0, fin_x];

6676

H_mag_x = [dc_trend_val H_mag_x];

6668

H_mag_x = [dc_trend_val H_mag_x];

6677

end

6669

end

6678

if fin(end)<fout(end)

6670

if fin(end)<fout(end)

6679

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6671

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6680

mid_freq_ind=round(length(fin)/2);

6672

mid_freq_ind=round(length(fin)/2);

6681

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6673

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6682

warning(warn_state);

6674

warning(warn_state);

6683

hf_trend_val=10^polyval(p, fout(end));

6675

hf_trend_val=10^polyval(p, fout(end));

6684

if hf_trend_val>H_mag(end)

6676

if hf_trend_val>H_mag(end)

6685

hf_trend_val=H_mag(end);

6677

hf_trend_val=H_mag(end);

6686

end

6678

end

6687

fin_x=[fin_x, fout(end)];

6679

fin_x=[fin_x, fout(end)];

6688

H_mag_x = [H_mag_x hf_trend_val];

6680

H_mag_x = [H_mag_x hf_trend_val];

6689

end

6681

end

6690

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6682

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6691

case 'extrap_to_DC_or_zero'

6683

case 'extrap_to_DC_or_zero'

6692

% same as extrap_to_DC but detect AC-coupled channels and

6684

% same as extrap_to_DC but detect AC-coupled channels and

6693

% extrapolate them to 0.

6685

% extrapolate them to 0.

6694

if fin(1)>0 && 20*log10(H_mag(1))<-20

6686

if fin(1)>0 && 20*log10(H_mag(1))<-20

6695

% assume AC coupling, with 0 at DC

6687

% assume AC coupling, with 0 at DC

6696

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6688

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6697

else

6689

else

6698

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6690

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6699

end

6691

end

6700

H_mag_i(fout>fin(end)) = H_mag(end);

6692

H_mag_i(fout>fin(end)) = H_mag(end);

6701

case 'extrap_to_DC'

6693

case 'extrap_to_DC'

6702

% first extrapolate down to DC, then use highest available frequency

6694

% first extrapolate down to DC, then use highest available frequency

6703

% for higher frequencies

6695

% for higher frequencies

6704

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6696

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6705

H_mag_i(fout>fin(end)) = H_mag(end);

6697

H_mag_i(fout>fin(end)) = H_mag(end);

6706

case 'old'

6698

case 'old'

6707

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6699

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6708

otherwise

6700

otherwise

6709

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6701

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6710

end

6702

end

6711

6703

6712

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6704

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6713

6705

6714

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6706

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6715

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6707

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6716

switch opt_interp_Sparam_phase

6708

switch opt_interp_Sparam_phase

6717

case 'old'

6709

case 'old'

6718

H_ph_i = H_ph_i-H_ph_i(1);

6710

H_ph_i = H_ph_i-H_ph_i(1);

6719

case 'zero_DC'

6711

case 'zero_DC'

6720

H_ph_i(1) = 0;

6712

H_ph_i(1) = 0;

6721

case 'interp_to_DC'

6713

case 'interp_to_DC'

6722

if fin(1) ~= 0

6714

if fin(1) ~= 0

6723

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6715

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6724

end

6716

end

6725

case 'extrap_cubic_to_dc_linear_to_inf'

6717

case 'extrap_cubic_to_dc_linear_to_inf'

6726

if fin(1) ~= 0

6718

if fin(1) ~= 0

6727

% estimate low frequency group delay

6719

% estimate low frequency group delay

6728

group_delay = -diff(H_ph(:))./diff(fin(:));

6720

group_delay = -diff(H_ph(:))./diff(fin(:));

6729

low_freq_gd = group_delay(1:50);

6721

low_freq_gd = group_delay(1:50);

6730

% calculate trend, throwing away outliers

6722

% calculate trend, throwing away outliers

6731

m = median(low_freq_gd); sigma = std(low_freq_gd);

6723

m = median(low_freq_gd); sigma = std(low_freq_gd);

6732

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6724

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6733

% correct outliers in first 10 phase samples

6725

% correct outliers in first 10 phase samples

6734

for k=10:-1:1

6726

for k=10:-1:1

6735

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6727

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6736

end

6728

end

6737

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6729

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6738

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6730

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6739

% modification - trend to inf

6731

% modification - trend to inf

6740

if (1)

6732

if (1)

6741

high_freq_gd = group_delay(end-50:end);

6733

high_freq_gd = group_delay(end-50:end);

6742

% calculate trend, throwing away outliers

6734

% calculate trend, throwing away outliers

6743

m = median(high_freq_gd); sigma = std(high_freq_gd);

6735

m = median(high_freq_gd); sigma = std(high_freq_gd);

6744

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6736

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6745

hf_extrap_range = find(fout>fin(end));

6737

hf_extrap_range = find(fout>fin(end));

6746

last_data_sample = hf_extrap_range(1)-1;

6738

last_data_sample = hf_extrap_range(1)-1;

6747

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6739

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6748

% for k=hf_range

6740

% for k=hf_range

6749

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6741

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6750

% end

6742

% end

6751

end

6743

end

6752

6744

6753

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6745

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6754

H_ph_i=H_ph_cubic;

6746

H_ph_i=H_ph_cubic;

6755

H_ph_i(indx:end) = H_ph_linear(indx:end);

6747

H_ph_i(indx:end) = H_ph_linear(indx:end);

6756

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6748

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6757

end

6749

end

6758

case 'interp_and_shift_to_DC'

6750

case 'interp_and_shift_to_DC'

6759

if fin(1) ~= 0

6751

if fin(1) ~= 0

6760

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6752

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6761

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6753

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6762

end

6754

end

6763

case 'trend_and_shift_to_DC'

6755

case 'trend_and_shift_to_DC'

6764

% estimate low frequency group delay

6756

% estimate low frequency group delay

6765

group_delay = -diff(H_ph(:))./diff(fin(:));

6757

group_delay = -diff(H_ph(:))./diff(fin(:));

6766

low_freq_gd = group_delay(1:50);

6758

low_freq_gd = group_delay(1:50);

6767

% calculate trend, throwing away outliers

6759

% calculate trend, throwing away outliers

6768

m = median(low_freq_gd); sigma = std(low_freq_gd);

6760

m = median(low_freq_gd); sigma = std(low_freq_gd);

6769

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6761

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6770

fin_x=fin;

6762

fin_x=fin;

6771

H_ph_x=H_ph(:);

6763

H_ph_x=H_ph(:);

6772

if fin(1) ~= 0

6764

if fin(1) ~= 0

6773

% correct outliers in first 10 phase samples

6765

% correct outliers in first 10 phase samples

6774

for k=10:-1:1

6766

for k=10:-1:1

6775

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6767

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6776

end

6768

end

6777

6769

6778

% shift all phase data so that DC extrapolation to 0 follows trend

6770

% shift all phase data so that DC extrapolation to 0 follows trend

6779

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6771

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6780

fin_x=[0, fin_x];

6772

fin_x=[0, fin_x];

6781

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6773

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6782

end

6774

end

6783

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6775

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6784

% the last two samples, so noise can create an inverted slope and

6776

% the last two samples, so noise can create an inverted slope and

6785

% non-causal response).

6777

% non-causal response).

6786

if fout(end)>fin(end)

6778

if fout(end)>fin(end)

6787

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6779

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6788

% p=polyfit(fin_x', H_ph_x, 1);

6780

% p=polyfit(fin_x', H_ph_x, 1);

6789

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6781

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6790

% hf_phase_trend=polyval(p,max(fout));

6782

% hf_phase_trend=polyval(p,max(fout));

6791

fin_x=[fin_x, fout(end)];

6783

fin_x=[fin_x, fout(end)];

6792

H_ph_x=[H_ph_x; hf_phase_trend];

6784

H_ph_x=[H_ph_x; hf_phase_trend];

6793

end

6785

end

6794

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6786

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6795

6787

6796

otherwise

6788

otherwise

6797

error('COM:Extrap:InvalidOption', ...

6789

error('COM:Extrap:InvalidOption', ...

6798

'debug_interp_Sparam valid values are "old", "zero_DC", "interp_to_DC", "interp_and_shift_to_DC", "trend_and_shift_to_DC", "interp_cubic_to_dc_linear_to_inf"');

6790

'debug_interp_Sparam valid values are "old", "zero_DC", "interp_to_DC", "interp_and_shift_to_DC", "trend_and_shift_to_DC", "interp_cubic_to_dc_linear_to_inf"');

6799

end

6791

end

6800

H_i = H_mag_i.*exp(1j*H_ph_i);

6792

H_i = H_mag_i.*exp(1j*H_ph_i);

6801

Sout=H_i;

6793

Sout=H_i;

6802

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6794

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6803

6795

6804

%This function makes the TX or RX package. The type input must be

6796

%This function makes the TX or RX package. The type input must be

6805

%'TX' or 'RX'

6797

%'TX' or 'RX'

6806

%If the mode argument is omitted, mode='dd' is assumed. Currently

6798

%If the mode argument is omitted, mode='dd' is assumed. Currently

6807

%mode='dc' is only used when making the TX package for AC CM noise

6799

%mode='dc' is only used when making the TX package for AC CM noise

6808

%inclusion. The Rx package for 'dc' mode is still generated using

6800

%inclusion. The Rx package for 'dc' mode is still generated using

6809

%the same parameters as 'dd' mode

6801

%the same parameters as 'dd' mode

6810

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6802

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6811

%

6803

%

6812

%One instance of package block looks like this (if no elements are set to 0):

6804

%One instance of package block looks like this (if no elements are set to 0):

6813

%-------------Lcomp----------Tline---------------

6805

%-------------Lcomp----------Tline---------------

6814

% | | |

6806

% | | |

6815

% Cpad Cbump Cball

6807

% Cpad Cbump Cball

6816

% | | |

6808

% | | |

6817

%------------------------------------------------

6809

%------------------------------------------------

6818

6810

6819

if nargin<6

6811

if nargin<6

6820

%optional input "include_die"=0 allows die parameters to be forced to 0

6812

%optional input "include_die"=0 allows die parameters to be forced to 0

6821

%this includes Cpad, Lcomp, and Cbump

6813

%this includes Cpad, Lcomp, and Cbump

6822

include_die=1;

6814

include_die=1;

6823

end

6815

end

6824

if nargin<5

6816

if nargin<5

6825

mode='dd';

6817

mode='dd';

6826

end

6818

end

6827

6819

6828

6820

6829

if ~isempty(param.PKG_NAME)

6821

if ~isempty(param.PKG_NAME)

6830

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6822

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6831

%so they are swapped in depending on if Tx or Rx is set for type

6823

%so they are swapped in depending on if Tx or Rx is set for type

6832

%Note that param is not returned from this function, so the swap does not persist

6824

%Note that param is not returned from this function, so the swap does not persist

6833

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6825

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6834

if strcmpi(type,'tx')

6826

if strcmpi(type,'tx')

6835

pkg_name = param.PKG_NAME{1};

6827

pkg_name = param.PKG_NAME{1};

6836

elseif strcmpi(type,'rx')

6828

elseif strcmpi(type,'rx')

6837

pkg_name = param.PKG_NAME{2};

6829

pkg_name = param.PKG_NAME{2};

6838

else

6830

else

6839

error('Pkg type must be Tx or Rx');

6831

error('Pkg type must be Tx or Rx');

6840

end

6832

end

6841

pkg_parameter_struct = param.PKG.(pkg_name);

6833

pkg_parameter_struct = param.PKG.(pkg_name);

6842

6834

6843

6835

6844

for j=1:length(swap_fields)

6836

for j=1:length(swap_fields)

6845

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6837

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6846

end

6838

end

6847

6839

6848

end

6840

end

6849

6841

6850

C_diepad = param.C_diepad;

6842

C_diepad = param.C_diepad;

6851

C_pkg_board = param.C_pkg_board;

6843

C_pkg_board = param.C_pkg_board;

6852

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6844

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6853

L_comp = param.L_comp;

6845

L_comp = param.L_comp;

6854

C_bump = param.C_bump;

6846

C_bump = param.C_bump;

6855

if ~include_die

6847

if ~include_die

6856

%best to multiply by 0. that way vectors maintain original size

6848

%best to multiply by 0. that way vectors maintain original size

6857

C_diepad=C_diepad*0;

6849

C_diepad=C_diepad*0;

6858

L_comp=L_comp*0;

6850

L_comp=L_comp*0;

6859

C_bump=C_bump*0;

6851

C_bump=C_bump*0;

6860

end

6852

end

6861

% [ahealey] End of modifications.

6853

% [ahealey] End of modifications.

6862

% generate TX package according to channel type.

6854

% generate TX package according to channel type.

6863

[ncases, mele]=size(param.z_p_next_cases);

6855

[ncases, mele]=size(param.z_p_next_cases);

6864

6856

6865

%Syntax update for C_diepad and L_comp

6857

%Syntax update for C_diepad and L_comp

6866

%Allow a chain of values to be entered as a matrix:

6858

%Allow a chain of values to be entered as a matrix:

6867

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6859

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6868

if isvector(C_diepad)

6860

if isvector(C_diepad)

6869

Cd_Tx=C_diepad(1);

6861

Cd_Tx=C_diepad(1);

6870

Cd_Rx=C_diepad(2);

6862

Cd_Rx=C_diepad(2);

6871

L_comp_Tx=L_comp(1);

6863

L_comp_Tx=L_comp(1);

6872

L_comp_Rx=L_comp(2);

6864

L_comp_Rx=L_comp(2);

6873

num_blocks=mele;

6865

num_blocks=mele;

6874

else

6866

else

6875

Cd_Tx=C_diepad(1,:);

6867

Cd_Tx=C_diepad(1,:);

6876

Cd_Rx=C_diepad(2,:);

6868

Cd_Rx=C_diepad(2,:);

6877

L_comp_Tx=L_comp(1,:);

6869

L_comp_Tx=L_comp(1,:);

6878

L_comp_Rx=L_comp(2,:);

6870

L_comp_Rx=L_comp(2,:);

6879

num_blocks=mele+length(Cd_Tx)-1;

6871

num_blocks=mele+length(Cd_Tx)-1;

6880

end

6872

end

6881

extra_LC=length(Cd_Tx)-1;

6873

extra_LC=length(Cd_Tx)-1;

6882

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6874

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6883

insert_zeros=zeros([1 extra_LC]);

6875

insert_zeros=zeros([1 extra_LC]);

6884

6876

6885

%Updated technique of building Tx/Rx packages

6877

%Updated technique of building Tx/Rx packages

6886

%each index corresponds to the package segment

6878

%each index corresponds to the package segment

6887

switch type

6879

switch type

6888

case 'TX'

6880

case 'TX'

6889

switch mele

6881

switch mele

6890

case 1

6882

case 1

6891

Cpad=Cd_Tx;

6883

Cpad=Cd_Tx;

6892

Lcomp=L_comp_Tx;

6884

Lcomp=L_comp_Tx;

6893

Cbump=C_bump(1);

6885

Cbump=C_bump(1);

6894

Cball=C_pkg_board(1);

6886

Cball=C_pkg_board(1);

6895

Zpkg=param.pkg_Z_c(1);

6887

Zpkg=param.pkg_Z_c(1);

6896

case 4

6888

case 4

6897

Cpad=[Cd_Tx 0 0 0];

6889

Cpad=[Cd_Tx 0 0 0];

6898

Lcomp=[L_comp_Tx 0 0 0];

6890

Lcomp=[L_comp_Tx 0 0 0];

6899

Cbump=[C_bump(1) 0 0 0];

6891

Cbump=[C_bump(1) 0 0 0];

6900

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6892

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6901

Zpkg=param.pkg_Z_c(1,:);

6893

Zpkg=param.pkg_Z_c(1,:);

6902

otherwise

6894

otherwise

6903

error('package syntax error')

6895

error('package syntax error')

6904

end

6896

end

6905

switch upper(channel_type)

6897

switch upper(channel_type)

6906

case 'THRU'

6898

case 'THRU'

6907

Len=param.Pkg_len_TX;

6899

Len=param.Pkg_len_TX;

6908

case 'NEXT'

6900

case 'NEXT'

6909

Len=param.Pkg_len_NEXT;

6901

Len=param.Pkg_len_NEXT;

6910

case 'FEXT'

6902

case 'FEXT'

6911

Len=param.Pkg_len_FEXT;

6903

Len=param.Pkg_len_FEXT;

6912

end

6904

end

6913

case 'RX'

6905

case 'RX'

6914

switch mele

6906

switch mele

6915

case 1

6907

case 1

6916

Cpad=Cd_Rx;

6908

Cpad=Cd_Rx;

6917

Lcomp=L_comp_Rx;

6909

Lcomp=L_comp_Rx;

6918

Cbump=C_bump(2);

6910

Cbump=C_bump(2);

6919

Cball=C_pkg_board(2);

6911

Cball=C_pkg_board(2);

6920

Zpkg=param.pkg_Z_c(2);

6912

Zpkg=param.pkg_Z_c(2);

6921

case 4

6913

case 4

6922

Cpad=[Cd_Rx 0 0 0];

6914

Cpad=[Cd_Rx 0 0 0];

6923

Lcomp=[L_comp_Rx 0 0 0];

6915

Lcomp=[L_comp_Rx 0 0 0];

6924

Cbump=[C_bump(2) 0 0 0];

6916

Cbump=[C_bump(2) 0 0 0];

6925

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6917

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6926

Zpkg=param.pkg_Z_c(2,:);

6918

Zpkg=param.pkg_Z_c(2,:);

6927

otherwise

6919

otherwise

6928

error('package syntax error')

6920

error('package syntax error')

6929

end

6921

end

6930

switch upper(channel_type)

6922

switch upper(channel_type)

6931

case 'THRU'

6923

case 'THRU'

6932

Len=param.Pkg_len_RX;

6924

Len=param.Pkg_len_RX;

6933

case 'NEXT'

6925

case 'NEXT'

6934

Len=param.Pkg_len_RX;

6926

Len=param.Pkg_len_RX;

6935

case 'FEXT'

6927

case 'FEXT'

6936

Len=param.Pkg_len_RX;

6928

Len=param.Pkg_len_RX;

6937

end

6929

end

6938

end

6930

end

6939

6931

6940

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6932

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6941

Cball=[insert_zeros Cball];

6933

Cball=[insert_zeros Cball];

6942

Cbump=[insert_zeros Cbump];

6934

Cbump=[insert_zeros Cbump];

6943

Len=[insert_zeros Len];

6935

Len=[insert_zeros Len];

6944

Zpkg=[insert_zeros Zpkg];

6936

Zpkg=[insert_zeros Zpkg];

6945

6937

6946

% debug_string='';

6938

% debug_string='';

6947

% for j=1:length(Zpkg)

6939

% for j=1:length(Zpkg)

6948

% if Cpad(j)~=0

6940

% if Cpad(j)~=0

6949

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6941

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6950

% end

6942

% end

6951

% if Lcomp(j)~=0

6943

% if Lcomp(j)~=0

6952

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6944

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6953

% end

6945

% end

6954

% if Cbump(j)~=0

6946

% if Cbump(j)~=0

6955

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6947

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6956

% end

6948

% end

6957

% if Len(j)~=0

6949

% if Len(j)~=0

6958

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6950

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6959

% end

6951

% end

6960

% if Cball(j)~=0

6952

% if Cball(j)~=0

6961

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6953

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6962

% end

6954

% end

6963

% end

6955

% end

6964

% if length(debug_string)>2

6956

% if length(debug_string)>2

6965

% debug_string=debug_string(3:end);

6957

% debug_string=debug_string(3:end);

6966

% end

6958

% end

6967

6959

6968

% tx package

6960

% tx package

6969

pkg_param=param;

6961

pkg_param=param;

6970

if strcmpi(mode,'dc')

6962

if strcmpi(mode,'dc')

6971

% change tx package to CC mode

6963

% change tx package to CC mode

6972

pkg_param.Z0=pkg_param.Z0/2;

6964

pkg_param.Z0=pkg_param.Z0/2;

6973

Cpad=Cpad*2;

6965

Cpad=Cpad*2;

6974

Cball=Cball*2;

6966

Cball=Cball*2;

6975

Zpkg=Zpkg*2;

6967

Zpkg=Zpkg*2;

6976

Lcomp=Lcomp/2;

6968

Lcomp=Lcomp/2;

6977

Cbump=Cbump*2;

6969

Cbump=Cbump*2;

6978

end

6970

end

6979

switch num_blocks

6971

switch num_blocks

6980

case 1

6972

case 1

6981

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6973

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6982

otherwise

6974

otherwise

6983

for j=1:num_blocks

6975

for j=1:num_blocks

6984

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6976

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6985

if j==1

6977

if j==1

6986

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6978

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6987

else

6979

else

6988

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6980

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6989

end

6981

end

6990

end

6982

end

6991

end

6983

end

6992

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6984

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6993

f(f<eps)=eps;

6985

f(f<eps)=eps;

6994

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6986

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6995

%% Equation 93A-8

6987

%% Equation 93A-8

6996

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6988

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6997

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6989

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6998

6990

6999

% [ahealey] Add compensating L and shunt C (bump) when requested.

6991

% [ahealey] Add compensating L and shunt C (bump) when requested.

7000

s12pad = s21pad;

6992

s12pad = s21pad;

7001

s22pad = s11pad;

6993

s22pad = s11pad;

7002

if nargin > 6

6994

if nargin > 6

7003

lcomp = varargin{1};

6995

lcomp = varargin{1};

7004

if lcomp>0

6996

if lcomp>0

7005

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6997

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

7006

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6998

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

7007

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6999

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

7008

s11pad, s12pad, s21pad, s22pad, ...

7000

s11pad, s12pad, s21pad, s22pad, ...

7009

s11comp, s21comp, s21comp, s11comp);

7001

s11comp, s21comp, s21comp, s11comp);

7010

end

7002

end

7011

end

7003

end

7012

if nargin > 7

7004

if nargin > 7

7013

cbump = varargin{2};

7005

cbump = varargin{2};

7014

if cbump>0

7006

if cbump>0

7015

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

7007

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

7016

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

7008

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

7017

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

7009

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

7018

s11pad, s12pad, s21pad, s22pad, ...

7010

s11pad, s12pad, s21pad, s22pad, ...

7019

s11bump, s21bump, s21bump, s11bump);

7011

s11bump, s21bump, s21bump, s11bump);

7020

end

7012

end

7021

end

7013

end

7022

% [ahealey] End of modifications.

7014

% [ahealey] End of modifications.

7023

7015

7024

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

7016

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

7025

% [ahealey] Symmetry cannot be assumed with more complex termination models.

7017

% [ahealey] Symmetry cannot be assumed with more complex termination models.

7026

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

7018

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

7027

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

7019

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

7028

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

7020

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

7029

s11pad, s12pad, s21pad, s22pad, ...

7021

s11pad, s12pad, s21pad, s22pad, ...

7030

S11, S21, S21, S11);

7022

S11, S21, S21, S11);

7031

% [ahealey] End of modifications.

7023

% [ahealey] End of modifications.

7032

7024

7033

%% Equation 93A-8

7025

%% Equation 93A-8

7034

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

7026

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

7035

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

7027

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

7036

[ s11out, s12out, s21out, s22out ]= ...

7028

[ s11out, s12out, s21out, s22out ]= ...

7037

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

7029

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

7038

7030

7039

function missingParameter (parameterName)

7031

function missingParameter (parameterName)

7040

error( 'error:badParameterInformation', ...

7032

error( 'error:badParameterInformation', ...

7041

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

7033

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

7042

7034

7043

function pdf = normal_dist(sigma,nsigma,binsize)

7035

function pdf = normal_dist(sigma,nsigma,binsize)

7044

pdf.BinSize=binsize;

7036

pdf.BinSize=binsize;

7045

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

7037

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

7046

pdf.x=(pdf.Min:-pdf.Min)*binsize;

7038

pdf.x=(pdf.Min:-pdf.Min)*binsize;

7047

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

7039

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

7048

pdf.y=pdf.y/sum(pdf.y);

7040

pdf.y=pdf.y/sum(pdf.y);

7049

7041

7050

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

7042

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

7051

%% input

7043

%% input

7052

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

7044

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

7053

% baud_rate - baud rate in seconds

7045

% baud_rate - baud rate in seconds

7054

% param.samples_per_ui = samples per UI of IR

7046

% param.samples_per_ui = samples per UI of IR

7055

% param.max_ctle - maximum ac to dc gain in dB

7047

% param.max_ctle - maximum ac to dc gain in dB

7056

% param.tx_ffe(1) - maximum pre cursor (positive value)

7048

% param.tx_ffe(1) - maximum pre cursor (positive value)

7057

% param.tx_ffe(2) - maximum post cursor (positive value)

7049

% param.tx_ffe(2) - maximum post cursor (positive value)

7058

% param.tx_ffe_step - sweep step size for tx pre and post taps

7050

% param.tx_ffe_step - sweep step size for tx pre and post taps

7059

% param.ndfe - number of reference dfe taps

7051

% param.ndfe - number of reference dfe taps

7060

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

7052

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

7061

% output

7053

% output

7062

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

7054

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

7063

% result.eq.ctle - index of CTLE parameters in table

7055

% result.eq.ctle - index of CTLE parameters in table

7064

% result.IR - impulse response

7056

% result.IR - impulse response

7065

% result.avail_signal - maximum signal after equalization

7057

% result.avail_signal - maximum signal after equalization

7066

% result.avail_sig_index - index in result.IR of max signal

7058

% result.avail_sig_index - index in result.IR of max signal

7067

% result.best_FOM - best raw ISI

7059

% result.best_FOM - best raw ISI

7068

7060

7069

min_number_of_UI_in_response=40;

7061

min_number_of_UI_in_response=40;

7070

baud_rate=1/param.ui;

7062

baud_rate=1/param.ui;

7071

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

7063

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

7072

f=chdata(1).faxis;

7064

f=chdata(1).faxis;

7073

7065

7074

%Read user input of ts_sample_adj_range

7066

%Read user input of ts_sample_adj_range

7075

%if one value was entered, go from 0 to that value

7067

%if one value was entered, go from 0 to that value

7076

%if 2 values were entered, go from the 1st value to the 2nd value

7068

%if 2 values were entered, go from the 1st value to the 2nd value

7077

if length(param.ts_sample_adj_range)==1

7069

if length(param.ts_sample_adj_range)==1

7078

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

7070

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

7079

param.ts_sample_adj_range(1)=0;

7071

param.ts_sample_adj_range(1)=0;

7080

end

7072

end

7081

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

7073

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

7082

7074

7083

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

7075

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

7084

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

7076

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

7085

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7077

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7086

% need to include H_RCos in noise and when computing the system ir for thru

7078

% need to include H_RCos in noise and when computing the system ir for thru

7087

% and crosstalk

7079

% and crosstalk

7088

H_r=H_bw.*H_bt.*H_RCos;

7080

H_r=H_bw.*H_bt.*H_RCos;

7089

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

7081

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

7090

% Get f vector from 0 to Fs/2-delta_f.

7082

% Get f vector from 0 to Fs/2-delta_f.

7091

N_fft_by2 = 512;

7083

N_fft_by2 = 512;

7092

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

7084

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

7093

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

7085

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

7094

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

7086

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

7095

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

7087

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

7096

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

7088

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

7097

%%

7089

%%

7098

7090

7099

% system noise H_sy PSD

7091

% system noise H_sy PSD

7100

if OP.USE_ETA0_PSD

7092

if OP.USE_ETA0_PSD

7101

fspike=1e9;

7093

fspike=1e9;

7102

% requires communication tool box if used

7094

% requires communication tool box if used

7103

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

7095

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

7104

else

7096

else

7105

H_sy=ones(1,length(chdata(1).faxis));

7097

H_sy=ones(1,length(chdata(1).faxis));

7106

end

7098

end

7107

7099

7108

%Build txffe values dynamically

7100

%Build txffe values dynamically

7109

%any param field that is "tx_ffe_cm<X>_values" is a precursor

7101

%any param field that is "tx_ffe_cm<X>_values" is a precursor

7110

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

7102

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

7111

%where <X> is any integer

7103

%where <X> is any integer

7112

param_fields=fieldnames(param);

7104

param_fields=fieldnames(param);

7113

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

7105

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

7114

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

7106

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

7115

num_taps=num_pre+num_post;

7107

num_taps=num_pre+num_post;

7116

cur=num_pre+1;

7108

cur=num_pre+1;

7117

%txffe_cell combines all the txffe values into a single cell array

7109

%txffe_cell combines all the txffe values into a single cell array

7118

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

7110

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

7119

txffe_cell=cell(1,num_taps);

7111

txffe_cell=cell(1,num_taps);

7120

for k=num_pre:-1:1

7112

for k=num_pre:-1:1

7121

idx=num_pre-k+1;

7113

idx=num_pre-k+1;

7122

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

7114

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

7123

txffe_cell{idx}=param.(this_tx_field);

7115

txffe_cell{idx}=param.(this_tx_field);

7124

end

7116

end

7125

for k=1:num_post

7117

for k=1:num_post

7126

idx=k+num_pre;

7118

idx=k+num_pre;

7127

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

7119

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

7128

txffe_cell{idx}=param.(this_tx_field);

7120

txffe_cell{idx}=param.(this_tx_field);

7129

end

7121

end

7130

%total number of txffe runs is the product of the lengths of each tap

7122

%total number of txffe runs is the product of the lengths of each tap

7131

txffe_lengths=cellfun('length',txffe_cell);

7123

txffe_lengths=cellfun('length',txffe_cell);

7132

if isempty(txffe_cell)

7124

if isempty(txffe_cell)

7133

num_txffe_runs=1;

7125

num_txffe_runs=1;

7134

else

7126

else

7135

num_txffe_runs=prod(txffe_lengths);

7127

num_txffe_runs=prod(txffe_lengths);

7136

end

7128

end

7137

%txffe_sweep_indices are used in the LOCAL_SEARCH block

7129

%txffe_sweep_indices are used in the LOCAL_SEARCH block

7138

%any tap with length=1 can be ignored

7130

%any tap with length=1 can be ignored

7139

%Also is statistically likely that taps with greater number of values

7131

%Also is statistically likely that taps with greater number of values

7140

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

7132

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

7141

txffe_sweep_indices=find(txffe_lengths>1);

7133

txffe_sweep_indices=find(txffe_lengths>1);

7142

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

7134

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

7143

txffe_sweep_indices=txffe_sweep_indices(length_sort);

7135

txffe_sweep_indices=txffe_sweep_indices(length_sort);

7144

num_txffe_sweep_indices=length(txffe_sweep_indices);

7136

num_txffe_sweep_indices=length(txffe_sweep_indices);

7145

7137

7146

gdc_values = param.ctle_gdc_values;

7138

gdc_values = param.ctle_gdc_values;

7147

Gffe_values = param.cursor_gain;

7139

Gffe_values = param.cursor_gain;

7148

switch param.CTLE_type

7140

switch param.CTLE_type

7149

case 'CL93'

7141

case 'CL93'

7150

case 'CL120d'

7142

case 'CL120d'

7151

g_DC_HP_values =param.g_DC_HP_values;

7143

g_DC_HP_values =param.g_DC_HP_values;

7152

case 'CL120e'

7144

case 'CL120e'

7153

f_HP_Z=param.f_HP_Z;

7145

f_HP_Z=param.f_HP_Z;

7154

f_HP_P=param.f_HP_P;

7146

f_HP_P=param.f_HP_P;

7155

7147

7156

end

7148

end

7157

best_ctle = [];

7149

best_ctle = [];

7158

best_FOM = -inf;

7150

best_FOM = -inf;

7159

best_txffe = [];

7151

best_txffe = [];

7160

delta_sbr = [];

7152

delta_sbr = [];

7161

PSD_results=[];

7153

PSD_results=[];

7162

MMSE_results=[];

7154

MMSE_results=[];

7163

best_bmax=param.bmax;

7155

best_bmax=param.bmax;

7164

%AJG021820

7156

%AJG021820

7165

best_bmin=param.bmin;

7157

best_bmin=param.bmin;

7166

h_J=[];

7158

h_J=[];

7167

pxi=0;

7159

pxi=0;

7168

if OP.DISPLAY_WINDOW

7160

if OP.DISPLAY_WINDOW

7169

hwaitbar=waitbar(0);

7161

hwaitbar=waitbar(0);

7170

else

7162

else

7171

fprintf('FOM search ');

7163

fprintf('FOM search ');

7172

end

7164

end

7173

FOM=0;

7165

FOM=0;

7174

if ~OP.RxFFE

7166

if ~OP.RxFFE

7175

Gffe_values=0;

7167

Gffe_values=0;

7176

end

7168

end

7177

param.ndfe_passed=param.ndfe;

7169

param.ndfe_passed=param.ndfe;

7178

old_loops=0;

7170

old_loops=0;

7179

new_loops=0;

7171

new_loops=0;

7180

7172

7181

%GDC Qual construction

7173

%GDC Qual construction

7182

gqual= param.gqual;

7174

gqual= param.gqual;

7183

g2qual=param.g2qual;

7175

g2qual=param.g2qual;

7184

if ~strcmp(param.CTLE_type,'CL120d')

7176

if ~strcmp(param.CTLE_type,'CL120d')

7185

qual=ones(1,length(gdc_values));

7177

qual=ones(1,length(gdc_values));

7186

else

7178

else

7187

if isempty(gqual) && isempty(g2qual)

7179

if isempty(gqual) && isempty(g2qual)

7188

qual=ones(length(g_DC_HP_values),length(gdc_values));

7180

qual=ones(length(g_DC_HP_values),length(gdc_values));

7189

else

7181

else

7190

qual=zeros(length(g_DC_HP_values),length(gdc_values));

7182

qual=zeros(length(g_DC_HP_values),length(gdc_values));

7191

7183

7192

%prepare gqual and g2qual

7184

%prepare gqual and g2qual

7193

[g2qual,si]=sort(g2qual,'descend');

7185

[g2qual,si]=sort(g2qual,'descend');

7194

gqual=gqual(si,:);

7186

gqual=gqual(si,:);

7195

tmp=g2qual;

7187

tmp=g2qual;

7196

g2qual=zeros(length(tmp),2);

7188

g2qual=zeros(length(tmp),2);

7197

for kk=1:length(tmp)

7189

for kk=1:length(tmp)

7198

if kk==1

7190

if kk==1

7199

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

7191

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

7200

else

7192

else

7201

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

7193

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

7202

end

7194

end

7203

gqual(kk,:)=sort(gqual(kk,:),'descend');

7195

gqual(kk,:)=sort(gqual(kk,:),'descend');

7204

end

7196

end

7205

7197

7206

%Qual Construction

7198

%Qual Construction

7207

for jj=1:length(g_DC_HP_values)

7199

for jj=1:length(g_DC_HP_values)

7208

for ii=1:length(gdc_values)

7200

for ii=1:length(gdc_values)

7209

for kk=1:size(gqual,1)

7201

for kk=1:size(gqual,1)

7210

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

7202

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

7211

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

7203

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

7212

qual(jj,ii)=1;

7204

qual(jj,ii)=1;

7213

break;

7205

break;

7214

end

7206

end

7215

end

7207

end

7216

end

7208

end

7217

end

7209

end

7218

end

7210

end

7219

end

7211

end

7220

end

7212

end

7221

7213

7222

progress_interval=0.025;

7214

progress_interval=0.025;

7223

if do_C2M

7215

if do_C2M

7224

loop_count=[1 2];

7216

loop_count=[1 2];

7225

T_O=floor((param.T_O/1000)*param.samples_per_ui);

7217

T_O=floor((param.T_O/1000)*param.samples_per_ui);

7226

T_O=max(0,T_O);

7218

T_O=max(0,T_O);

7227

else

7219

else

7228

loop_count=1;

7220

loop_count=1;

7229

T_O=0;

7221

T_O=0;

7230

end

7222

end

7231

switch param.CTLE_type

7223

switch param.CTLE_type

7232

case 'CL93'

7224

case 'CL93'

7233

lf_indx=1;

7225

lf_indx=1;

7234

case 'CL120d'

7226

case 'CL120d'

7235

lf_indx=length(g_DC_HP_values);

7227

lf_indx=length(g_DC_HP_values);

7236

case 'CL120e'

7228

case 'CL120e'

7237

lf_indx=1;

7229

lf_indx=1;

7238

end

7230

end

7239

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

7231

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

7240

if OP.Optimize_loop_speed_up == 1

7232

if OP.Optimize_loop_speed_up == 1

7241

OP.BinSize = 1e-4;

7233

OP.BinSize = 1e-4;

7242

OP.impulse_response_truncation_threshold = 1e-3;

7234

OP.impulse_response_truncation_threshold = 1e-3;

7243

end

7235

end

7244

7236

7245

%Used to speed up FFE by only performing circshift when necessary

7237

%Used to speed up FFE by only performing circshift when necessary

7246

pulse_struc(1).pulse_ctle_circshift=[];

7238

pulse_struc(1).pulse_ctle_circshift=[];

7247

ctle_response_updated=1;

7239

ctle_response_updated=1;

7248

7240

7249

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

7241

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

7250

calc_exp_phase=0;

7242

calc_exp_phase=0;

7251

7243

7252

%calculate cur index and pre/post indices outside of the loop

7244

%calculate cur index and pre/post indices outside of the loop

7253

cur_start=cur;

7245

cur_start=cur;

7254

precursor_indices=[];

7246

precursor_indices=[];

7255

postcursor_indices=[];

7247

postcursor_indices=[];

7256

auto_count_trigger=0;

7248

auto_count_trigger=0;

7257

for kv=1:num_taps

7249

for kv=1:num_taps

7258

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

7250

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

7259

%precursor values fill the beginning of the vector. Any empty precursor means

7251

%precursor values fill the beginning of the vector. Any empty precursor means

7260

%cursor position must be subtracted by 1

7252

%cursor position must be subtracted by 1

7261

if kv<cur_start

7253

if kv<cur_start

7262

cur=cur-1;

7254

cur=cur-1;

7263

end

7255

end

7264

else

7256

else

7265

%non empty value: add to precursor or postcursor indices depending on position

7257

%non empty value: add to precursor or postcursor indices depending on position

7266

%in the vector

7258

%in the vector

7267

if kv<cur_start

7259

if kv<cur_start

7268

auto_count_trigger=1;

7260

auto_count_trigger=1;

7269

precursor_indices=[precursor_indices kv];

7261

precursor_indices=[precursor_indices kv];

7270

else

7262

else

7271

auto_count_trigger=0;

7263

auto_count_trigger=0;

7272

postcursor_indices=[postcursor_indices kv];

7264

postcursor_indices=[postcursor_indices kv];

7273

end

7265

end

7274

end

7266

end

7275

end

7267

end

7276

if ~isempty(postcursor_indices)

7268

if ~isempty(postcursor_indices)

7277

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

7269

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

7278

end

7270

end

7279

7271

7280

%Calculate the full grid matrix of all txffe combinations

7272

%Calculate the full grid matrix of all txffe combinations

7281

if isempty(txffe_cell)

7273

if isempty(txffe_cell)

7282

TXFFE_grid=0;

7274

TXFFE_grid=0;

7283

FULL_tx_index_vector=1;

7275

FULL_tx_index_vector=1;

7284

else

7276

else

7285

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

7277

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

7286

%Also calculate the full grid matrix for the index used in each txffe combination

7278

%Also calculate the full grid matrix for the index used in each txffe combination

7287

%(the index is used in the LOCAL SEARCH block)

7279

%(the index is used in the LOCAL SEARCH block)

7288

for k=1:num_taps

7280

for k=1:num_taps

7289

txffe_index_cell{k}=1:txffe_lengths(k);

7281

txffe_index_cell{k}=1:txffe_lengths(k);

7290

end

7282

end

7291

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

7283

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

7292

end

7284

end

7293

7285

7294

%pre-calculate cursor to save time

7286

%pre-calculate cursor to save time

7295

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

7287

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

7296

7288

7297

%pre-calculate full txffe for each iteration to save time

7289

%pre-calculate full txffe for each iteration to save time

7298

precursor_matrix=TXFFE_grid(:,precursor_indices);

7290

precursor_matrix=TXFFE_grid(:,precursor_indices);

7299

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7291

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7300

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7292

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7301

7293

7302

if OP.TDMODE

7294

if OP.TDMODE

7303

uneq_field='uneq_pulse_response';

7295

uneq_field='uneq_pulse_response';

7304

ctle_field='ctle_pulse_response';

7296

ctle_field='ctle_pulse_response';

7305

else

7297

else

7306

uneq_field='uneq_imp_response';

7298

uneq_field='uneq_imp_response';

7307

ctle_field='ctle_imp_response';

7299

ctle_field='ctle_imp_response';

7308

end

7300

end

7309

7301

7310

%Speed up search for max(sbr)

7302

%Speed up search for max(sbr)

7311

if OP.TDMODE

7303

if OP.TDMODE

7312

[~,init_max]=max(chdata(1).uneq_pulse_response);

7304

[~,init_max]=max(chdata(1).uneq_pulse_response);

7313

else

7305

else

7314

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7306

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7315

end

7307

end

7316

UI_max_window=20;

7308

UI_max_window=20;

7317

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7309

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7318

if start_max_idx<1

7310

if start_max_idx<1

7319

start_max_idx=1;

7311

start_max_idx=1;

7320

end

7312

end

7321

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7313

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7322

if end_max_idx>length(chdata(1).(uneq_field))

7314

if end_max_idx>length(chdata(1).(uneq_field))

7323

end_max_idx=length(chdata(1).(uneq_field));

7315

end_max_idx=length(chdata(1).(uneq_field));

7324

end

7316

end

7325

7317

7326

itick_skips=0;

7318

itick_skips=0;

7327

itick_cases=0;

7319

itick_cases=0;

7328

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7320

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7329

for i=loop_count

7321

for i=loop_count

7330

7322

7331

for Gffe_index=1:length(Gffe_values)

7323

for Gffe_index=1:length(Gffe_values)

7332

param.current_ffegain=Gffe_values(Gffe_index);

7324

param.current_ffegain=Gffe_values(Gffe_index);

7333

for ctle_index=1:length(gdc_values)

7325

for ctle_index=1:length(gdc_values)

7334

g_dc = gdc_values(ctle_index);

7326

g_dc = gdc_values(ctle_index);

7335

kacdc = 10^(g_dc/20);

7327

kacdc = 10^(g_dc/20);

7336

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7328

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7337

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7329

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7338

CTLE_fz = param.CTLE_fz(ctle_index);

7330

CTLE_fz = param.CTLE_fz(ctle_index);

7339

switch param.CTLE_type

7331

switch param.CTLE_type

7340

case 'CL93'

7332

case 'CL93'

7341

%

7333

%

7342

case 'CL120d'

7334

case 'CL120d'

7343

%

7335

%

7344

case 'CL120e'

7336

case 'CL120e'

7345

HP_Z = param.f_HP_Z(ctle_index);

7337

HP_Z = param.f_HP_Z(ctle_index);

7346

HP_P = param.f_HP_P(ctle_index);

7338

HP_P = param.f_HP_P(ctle_index);

7347

end

7339

end

7348

%% HF Boost

7340

%% HF Boost

7349

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7341

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7350

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7342

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7351

%% Mid Frequency Boost

7343

%% Mid Frequency Boost

7352

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7344

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7353

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7345

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7354

for g_LP_index=1:lf_indx

7346

for g_LP_index=1:lf_indx

7355

7347

7356

%GDC Qual Check

7348

%GDC Qual Check

7357

if qual(g_LP_index,ctle_index)==0

7349

if qual(g_LP_index,ctle_index)==0

7358

pxi=pxi+num_txffe_runs;

7350

pxi=pxi+num_txffe_runs;

7359

continue;

7351

continue;

7360

end

7352

end

7361

7353

7362

switch param.CTLE_type

7354

switch param.CTLE_type

7363

case 'CL93'

7355

case 'CL93'

7364

H_low=1;

7356

H_low=1;

7365

kacde_DC_low=1;

7357

kacde_DC_low=1;

7366

case 'CL120d'

7358

case 'CL120d'

7367

g_DC_low = g_DC_HP_values(g_LP_index);

7359

g_DC_low = g_DC_HP_values(g_LP_index);

7368

f_HP=param.f_HP(g_LP_index);

7360

f_HP=param.f_HP(g_LP_index);

7369

kacde_DC_low = 10^(g_DC_low/20);

7361

kacde_DC_low = 10^(g_DC_low/20);

7370

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7362

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7371

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7363

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7372

case 'CL120e' % z1 has been adusted on read in

7364

case 'CL120e' % z1 has been adusted on read in

7373

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7365

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7374

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7366

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7375

end

7367

end

7376

H_ctf=H_low.*ctle_gain;

7368

H_ctf=H_low.*ctle_gain;

7377

switch upper(OP.FFE_OPT_METHOD)

7369

switch upper(OP.FFE_OPT_METHOD)

7378

case 'WIENER-HOPF'

7370

case 'WIENER-HOPF'

7379

%% Bill Kirkland

7371

%% Bill Kirkland

7380

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7372

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7381

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7373

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7382

% use Fourier Transform pair for correlation as we have to

7374

% use Fourier Transform pair for correlation as we have to

7383

% take ifft of H_r anyways.

7375

% take ifft of H_r anyways.

7384

% onesided and two sided responses - tricky, tricky, tricky

7376

% onesided and two sided responses - tricky, tricky, tricky

7385

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7377

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7386

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7378

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7387

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7379

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7388

7380

7389

if OP.Do_White_Noise

7381

if OP.Do_White_Noise

7390

Noise_XC = Noise_XC(1);

7382

Noise_XC = Noise_XC(1);

7391

end

7383

end

7392

otherwise

7384

otherwise

7393

Noise_XC=[];

7385

Noise_XC=[];

7394

end

7386

end

7395

7387

7396

7388

7397

7389

7398

if OP.INCLUDE_CTLE==1

7390

if OP.INCLUDE_CTLE==1

7399

for k=1:param.num_s4p_files

7391

for k=1:param.num_s4p_files

7400

ir_peak = max(abs(chdata(k).(uneq_field)));

7392

ir_peak = max(abs(chdata(k).(uneq_field)));

7401

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7393

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7402

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7394

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7403

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7395

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7404

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7396

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7405

switch param.CTLE_type

7397

switch param.CTLE_type

7406

case 'CL93'

7398

case 'CL93'

7407

case 'CL120d'

7399

case 'CL120d'

7408

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7400

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7409

case 'CL120e' % z1 has been adusted on read in

7401

case 'CL120e' % z1 has been adusted on read in

7410

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7402

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7411

end

7403

end

7412

end

7404

end

7413

%set the flag to show ctle response was updated

7405

%set the flag to show ctle response was updated

7414

ctle_response_updated=1;

7406

ctle_response_updated=1;

7415

else

7407

else

7416

for k=1:param.num_s4p_files

7408

for k=1:param.num_s4p_files

7417

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7409

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7418

end

7410

end

7419

end

7411

end

7420

for k=1:param.num_s4p_files

7412

for k=1:param.num_s4p_files

7421

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7413

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7422

end

7414

end

7423

%% Equation 93A-22 %%

7415

%% Equation 93A-22 %%

7424

% figure(1000)

7416

% figure(1000)

7425

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7417

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7426

% hold on

7418

% hold on

7427

if OP.RX_CALIBRATION

7419

if OP.RX_CALIBRATION

7428

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7420

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7429

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7421

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7430

switch param.CTLE_type

7422

switch param.CTLE_type

7431

case 'CL93'

7423

case 'CL93'

7432

H_low2=1;

7424

H_low2=1;

7433

case 'CL120d'

7425

case 'CL120d'

7434

g_DC_low = g_DC_HP_values(g_LP_index);

7426

g_DC_low = g_DC_HP_values(g_LP_index);

7435

f_HP=param.f_HP(g_LP_index);

7427

f_HP=param.f_HP(g_LP_index);

7436

kacde_DC_low = 10^(g_DC_low/20);

7428

kacde_DC_low = 10^(g_DC_low/20);

7437

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7429

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7438

case 'CL120e' % z1 has been adusted on read in

7430

case 'CL120e' % z1 has been adusted on read in

7439

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7431

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7440

end

7432

end

7441

H_ctf2=H_low2.*ctle_gain2;

7433

H_ctf2=H_low2.*ctle_gain2;

7442

end

7434

end

7443

% RIM 11-30-2020 moved to a subfunction

7435

% RIM 11-30-2020 moved to a subfunction

7444

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7436

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7445

if OP.RX_CALIBRATION

7437

if OP.RX_CALIBRATION

7446

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7438

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7447

sigma_NEXT=sqrt(param.eta_0*sum( abs(H_sy(2:end).^2 .* H_r(2:end).*2 .* H_ctf(2:end).^2 ) .* diff(chdata(1).faxis)/1e9));% changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7439

sigma_NEXT=sqrt(param.eta_0*sum( abs(H_sy(2:end).^2 .* H_r(2:end).*2 .* H_ctf(2:end).^2 ) .* diff(chdata(1).faxis)/1e9));% changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7448

else

7440

else

7449

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7441

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7450

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7442

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7451

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7443

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7452

sigma_ne=0;

7444

sigma_ne=0;

7453

end

7445

end

7454

7446

7455

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7447

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7456

pxi=pxi+num_txffe_runs;

7448

pxi=pxi+num_txffe_runs;

7457

continue; % change per 0.3k draft 2.3

7449

continue; % change per 0.3k draft 2.3

7458

end

7450

end

7459

%%

7451

%%

7460

PSD_results=[];

7452

PSD_results=[];

7461

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7453

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7462

OP.WO_TXFFE=1;

7454

OP.WO_TXFFE=1;

7463

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7455

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7464

end

7456

end

7465

%TXFFE Loop

7457

%TXFFE Loop

7466

%Originally this was a separate for loop for each tap, but it is now all contained in the TXFFE_grid matrix to use a single modular loop

7458

%Originally this was a separate for loop for each tap, but it is now all contained in the TXFFE_grid matrix to use a single modular loop

7467

for TK=1:size(TXFFE_grid,1)

7459

for TK=1:size(TXFFE_grid,1)

7468

7460

7469

pxi=pxi+1;

7461

pxi=pxi+1;

7470

progress = pxi/runs;

7462

progress = pxi/runs;

7471

if OP.DISPLAY_WINDOW

7463

if OP.DISPLAY_WINDOW

7472

if ~mod(pxi,floor(runs*progress_interval))

7464

if ~mod(pxi,floor(runs*progress_interval))

7473

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7465

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7474

end

7466

end

7475

else

7467

else

7476

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7468

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7477

end

7469

end

7478

7470

7479

%get the cursor for this iteration

7471

%get the cursor for this iteration

7480

txffe_cur=txffe_cursor_vector(TK);

7472

txffe_cur=txffe_cursor_vector(TK);

7481

7473

7482

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7474

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7483

if txffe_cur<param.tx_ffe_c0_min

7475

if txffe_cur<param.tx_ffe_c0_min

7484

continue;

7476

continue;

7485

end

7477

end

7486

old_loops=old_loops+1;

7478

old_loops=old_loops+1;

7487

7479

7488

%get the index used for each tap on this iteration

7480

%get the index used for each tap on this iteration

7489

%this is needed for the LOCAL SEARCH block

7481

%this is needed for the LOCAL SEARCH block

7490

tx_index_vector=FULL_tx_index_vector(TK,:);

7482

tx_index_vector=FULL_tx_index_vector(TK,:);

7491

7483

7492

%Original LOCAL SEARCH Block:

7484

%Original LOCAL SEARCH Block:

7493

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7485

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7494

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7486

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7495

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7487

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7496

% % skip configurations more than

7488

% % skip configurations more than

7497

% % 2 steps away from current "best" point on any grid direction

7489

% % 2 steps away from current "best" point on any grid direction

7498

% % Matt Brown 11/19/2021 for cp2 and cp3

7490

% % Matt Brown 11/19/2021 for cp2 and cp3

7499

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7491

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7500

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7492

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7501

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7493

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7502

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7494

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7503

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7495

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7504

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7496

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7505

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7497

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7506

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7498

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7507

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7499

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7508

%

7500

%

7509

% continue;

7501

% continue;

7510

% end

7502

% end

7511

7503

7512

%Modular LOCAL_SEARCH block:

7504

%Modular LOCAL_SEARCH block:

7513

% speedup "local search" heuristic - Adee Ran 03-17-2020

7505

% speedup "local search" heuristic - Adee Ran 03-17-2020

7514

% skip configurations more than 2 steps away from current "best" point on any grid direction

7506

% skip configurations more than 2 steps away from current "best" point on any grid direction

7515

skip_it=0;

7507

skip_it=0;

7516

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7508

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7517

%instead of looping across all taps, only loop across

7509

%instead of looping across all taps, only loop across

7518

%those with length>1 (txffe_sweep_indices).

7510

%those with length>1 (txffe_sweep_indices).

7519

%It saves time since this block is encountered so often

7511

%It saves time since this block is encountered so often

7520

for kj=1:num_txffe_sweep_indices

7512

for kj=1:num_txffe_sweep_indices

7521

kv=txffe_sweep_indices(kj);

7513

kv=txffe_sweep_indices(kj);

7522

if kv==1

7514

if kv==1

7523

previous_loop_val=g_LP_index;

7515

previous_loop_val=g_LP_index;

7524

else

7516

else

7525

previous_loop_val=tx_index_vector(kv-1);

7517

previous_loop_val=tx_index_vector(kv-1);

7526

end

7518

end

7527

if previous_loop_val>1

7519

if previous_loop_val>1

7528

best_index_this_tap=best_txffe_index(kv);

7520

best_index_this_tap=best_txffe_index(kv);

7529

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7521

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7530

skip_it=1;

7522

skip_it=1;

7531

break;

7523

break;

7532

end

7524

end

7533

end

7525

end

7534

end

7526

end

7535

7527

7536

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7528

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7537

skip_it=1;

7529

skip_it=1;

7538

end

7530

end

7539

end

7531

end

7540

if skip_it

7532

if skip_it

7541

continue;

7533

continue;

7542

end

7534

end

7543

%End Modular LOCAL SEARCH block

7535

%End Modular LOCAL SEARCH block

7544

7536

7545

new_loops=new_loops+1;

7537

new_loops=new_loops+1;

7546

7538

7547

%fetch txffe for this iteration

7539

%fetch txffe for this iteration

7548

txffe=txffe_matrix(TK,:);

7540

txffe=txffe_matrix(TK,:);

7549

7541

7550

%The phase shift exponentials used in get_xtlk_noise are independent of

7542

%The phase shift exponentials used in get_xtlk_noise are independent of

7551

%everything except number of taps and cursor position

7543

%everything except number of taps and cursor position

7552

%So it can be calculated 1 time here to avoid thousands of re-calcs

7544

%So it can be calculated 1 time here to avoid thousands of re-calcs

7553

if ~calc_exp_phase

7545

if ~calc_exp_phase

7554

calc_exp_phase=1;

7546

calc_exp_phase=1;

7555

for k=1:length(txffe)

7547

for k=1:length(txffe)

7556

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7548

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7557

end

7549

end

7558

if OP.RxFFE

7550

if OP.RxFFE

7559

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7551

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7560

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7552

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7561

end

7553

end

7562

phase_memory=[phase_memory phase_memoryRXFFE];

7554

phase_memory=[phase_memory phase_memoryRXFFE];

7563

end

7555

end

7564

end

7556

end

7565

7557

7566

%% Unequalized Pulse Reponse & circshift for FFE

7558

%% Unequalized Pulse Reponse & circshift for FFE

7567

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7559

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7568

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7560

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7569

if ctle_response_updated

7561

if ctle_response_updated

7570

ctle_response_updated=0;

7562

ctle_response_updated=0;

7571

num_pre=cur-1;

7563

num_pre=cur-1;

7572

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7564

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7573

%Calculating here reduces number of convolutions by thousands

7565

%Calculating here reduces number of convolutions by thousands

7574

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7566

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7575

ich=1;

7567

ich=1;

7576

else

7568

else

7577

ich=param.num_s4p_files;

7569

ich=param.num_s4p_files;

7578

end

7570

end

7579

for ii=1:ich

7571

for ii=1:ich

7580

if OP.TDMODE

7572

if OP.TDMODE

7581

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7573

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7582

else

7574

else

7583

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7575

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7584

%"conv2" is faster than filter. Just need to chop off extra points at the end

7576

%"conv2" is faster than filter. Just need to chop off extra points at the end

7585

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7577

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7586

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7578

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7587

end

7579

end

7588

for k=1:length(txffe)

7580

for k=1:length(txffe)

7589

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7581

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7590

end

7582

end

7591

end

7583

end

7592

end

7584

end

7593

7585

7594

%% Apply TXFFE to pre-shifted pulse response

7586

%% Apply TXFFE to pre-shifted pulse response

7595

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7587

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7596

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7588

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7597

sbr_from_txffe=sbr;

7589

sbr_from_txffe=sbr;

7598

for ii=1:ich

7590

for ii=1:ich

7599

% this is sbr when ii=1; to be used in get_PSDs

7591

% this is sbr when ii=1; to be used in get_PSDs

7600

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7592

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7601

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7593

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7602

else

7594

else

7603

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7595

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7604

end

7596

end

7605

end

7597

end

7606

7598

7607

%% Find Sample Location

7599

%% Find Sample Location

7608

% If RXFFE is included, the sample location will be found again below

7600

% If RXFFE is included, the sample location will be found again below

7609

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7601

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7610

if param.ts_anchor==0

7602

if param.ts_anchor==0

7611

%keep MM

7603

%keep MM

7612

elseif param.ts_anchor==1

7604

elseif param.ts_anchor==1

7613

%peak sample

7605

%peak sample

7614

cursor_i=sbr_peak_i;

7606

cursor_i=sbr_peak_i;

7615

no_zero_crossing=0;

7607

no_zero_crossing=0;

7616

elseif param.ts_anchor==2

7608

elseif param.ts_anchor==2

7617

%max DV

7609

%max DV

7618

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7610

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7619

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7611

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7620

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7612

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7621

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7613

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7622

no_zero_crossing=0;

7614

no_zero_crossing=0;

7623

else

7615

else

7624

error('ts_anchor parameter must be 0, 1, or 2');

7616

error('ts_anchor parameter must be 0, 1, or 2');

7625

end

7617

end

7626

if no_zero_crossing

7618

if no_zero_crossing

7627

continue;

7619

continue;

7628

end

7620

end

7629

raw_cursor_i=cursor_i;

7621

raw_cursor_i=cursor_i;

7630

7622

7631

%%%%%%%%%%

7623

%%%%%%%%%%

7632

%%%%%%%%%%

7624

%%%%%%%%%%

7633

%%%%%%%%%%

7625

%%%%%%%%%%

7634

%NEW ITICK LOOP (not indenting everything yet)

7626

%NEW ITICK LOOP (not indenting everything yet)

7635

[~,si]=sort(abs(full_sample_range));

7627

[~,si]=sort(abs(full_sample_range));

7636

best_positive_itick_FOM=-inf;

7628

best_positive_itick_FOM=-inf;

7637

best_negative_itick_FOM=-inf;

7629

best_negative_itick_FOM=-inf;

7638

best_positive_itick_in_loop=[];

7630

best_positive_itick_in_loop=[];

7639

best_negative_itick_in_loop=[];

7631

best_negative_itick_in_loop=[];

7640

best_itick_FOM=-inf;

7632

best_itick_FOM=-inf;

7641

best_itick_in_cluster=[];

7633

best_itick_in_cluster=[];

7642

best_cluster=[];

7634

best_cluster=[];

7643

7635

7644

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7636

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7645

%middle_search: start from itick=0 and work outwards in negative and positive direction. stop searching when FOM starts to go down (using LOCAL SEARCH)

7637

%middle_search: start from itick=0 and work outwards in negative and positive direction. stop searching when FOM starts to go down (using LOCAL SEARCH)

7646

% Commit request4p4_7 healey_3dj_COM_01_240416

7638

% Commit request4p4_7 healey_3dj_COM_01_240416

7647

%box_search=0;

7639

%box_search=0;

7648

%middle_search=1;% should set 0 so all Ts sample points are used

7640

%middle_search=1;% should set 0 so all Ts sample points are used

7649

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7641

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7650

case 'full-sweep'

7642

case 'full-sweep'

7651

box_search=0;

7643

box_search=0;

7652

middle_search=0;

7644

middle_search=0;

7653

case 'middle'

7645

case 'middle'

7654

box_search=0;

7646

box_search=0;

7655

middle_search=1;

7647

middle_search=1;

7656

otherwise

7648

otherwise

7657

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7649

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7658

end

7650

end

7659

if box_search

7651

if box_search

7660

box_size=5;

7652

box_size=5;

7661

box_mid=floor(box_size/2);

7653

box_mid=floor(box_size/2);

7662

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7654

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7663

CL=length(cluster);

7655

CL=length(cluster);

7664

loop_range=1:CL+box_mid*2;

7656

loop_range=1:CL+box_mid*2;

7665

elseif middle_search

7657

elseif middle_search

7666

loop_range=si;

7658

loop_range=si;

7667

else

7659

else

7668

loop_range=1:length(full_sample_range);

7660

loop_range=1:length(full_sample_range);

7669

end

7661

end

7670

7662

7671

for itickn=loop_range

7663

for itickn=loop_range

7672

if box_search

7664

if box_search

7673

if itickn<=CL

7665

if itickn<=CL

7674

itick=cluster(itickn);

7666

itick=cluster(itickn);

7675

else

7667

else

7676

if itickn==CL+1

7668

if itickn==CL+1

7677

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7669

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7678

end

7670

end

7679

if isempty(best_cluster)

7671

if isempty(best_cluster)

7680

continue;

7672

continue;

7681

end

7673

end

7682

itick=best_cluster(itickn-CL);

7674

itick=best_cluster(itickn-CL);

7683

end

7675

end

7684

else

7676

else

7685

itick=full_sample_range(itickn);

7677

itick=full_sample_range(itickn);

7686

end

7678

end

7687

7679

7688

itick_cases=itick_cases+1;

7680

itick_cases=itick_cases+1;

7689

7681

7690

sbr=sbr_from_txffe;

7682

sbr=sbr_from_txffe;

7691

cursor_i = raw_cursor_i+itick;

7683

cursor_i = raw_cursor_i+itick;

7692

7684

7693

%Local Search for +/- itick sweep

7685

%Local Search for +/- itick sweep

7694

if middle_search && param.LOCAL_SEARCH>0

7686

if middle_search && param.LOCAL_SEARCH>0

7695

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7687

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7696

itick_skips=itick_skips+1;

7688

itick_skips=itick_skips+1;

7697

continue;

7689

continue;

7698

end

7690

end

7699

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7691

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7700

itick_skips=itick_skips+1;

7692

itick_skips=itick_skips+1;

7701

continue;

7693

continue;

7702

end

7694

end

7703

end

7695

end

7704

7696

7705

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7697

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7706

if min_number_of_UI_in_response < triple_transit_time

7698

if min_number_of_UI_in_response < triple_transit_time

7707

min_number_of_UI_in_response = triple_transit_time;

7699

min_number_of_UI_in_response = triple_transit_time;

7708

end

7700

end

7709

7701

7710

cursor = sbr(cursor_i);

7702

cursor = sbr(cursor_i);

7711

7703

7712

%% RXFFE

7704

%% RXFFE

7713

if OP.RxFFE

7705

if OP.RxFFE

7714

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7706

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7715

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7707

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7716

%if isrow(sbr), sbr=sbr';end

7708

%if isrow(sbr), sbr=sbr';end

7717

7709

7718

%AJG: do not return sbr here (run time improvement)

7710

%AJG: do not return sbr here (run time improvement)

7719

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7711

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7720

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7712

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7721

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7713

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7722

% sbr at this point include the current setting

7714

% sbr at this point include the current setting

7723

% under consideration of txffe h21 ctf and fr

7715

% under consideration of txffe h21 ctf and fr

7724

switch upper(OP.FFE_OPT_METHOD)

7716

switch upper(OP.FFE_OPT_METHOD)

7725

case 'MMSE'

7717

case 'MMSE'

7726

OP.WO_TXFFE=0;

7718

OP.WO_TXFFE=0;

7727

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7719

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7728

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn;

7720

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn;

7729

if 0 % for debug

7721

if 0 % for debug

7730

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7722

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7731

hold on

7723

hold on

7732

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7724

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7733

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7725

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7734

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7726

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7735

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7727

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7736

xlim([0 0.5])

7728

xlim([0 0.5])

7737

% ylim([-190 -160])

7729

% ylim([-190 -160])

7738

set(gcf,'defaulttextinterpreter','none')

7730

set(gcf,'defaulttextinterpreter','none')

7739

xlabel('Normalized Frequency')

7731

xlabel('Normalized Frequency')

7740

ylabel('PSD dBm/Hz')

7732

ylabel('PSD dBm/Hz')

7741

hold on

7733

hold on

7742

grid on

7734

grid on

7743

legend show

7735

legend show

7744

title('PSD')

7736

title('PSD')

7745

end

7737

end

7746

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7738

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7747

% floating_tap_locations=MMSE_results.MLSE_results;

7739

% floating_tap_locations=MMSE_results.MLSE_results;

7748

C=MMSE_results.C;

7740

C=MMSE_results.C;

7749

FOM=MMSE_results.FOM;

7741

FOM=MMSE_results.FOM;

7750

floating_tap_locations=MMSE_results.floating_tap_locations;

7742

floating_tap_locations=MMSE_results.floating_tap_locations;

7751

otherwise

7743

otherwise

7752

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7744

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7753

end

7745

end

7754

%Now there is a stand alone function for determining if RXFFE taps are illegal

7746

%Now there is a stand alone function for determining if RXFFE taps are illegal

7755

%This is because the "force" function will also do a legality check when "backoff" is enabled

7747

%This is because the "force" function will also do a legality check when "backoff" is enabled

7756

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7748

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7757

if RXFFE_Illegal(C,param)

7749

if RXFFE_Illegal(C,param)

7758

continue;

7750

continue;

7759

end

7751

end

7760

end

7752

end

7761

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7753

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7762

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7754

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7763

if isrow(sbr), sbr=sbr';end

7755

if isrow(sbr), sbr=sbr';end

7764

7756

7765

%% second guess at cursor location (t_s) - based on approximate zero crossing

7757

%% second guess at cursor location (t_s) - based on approximate zero crossing

7766

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7758

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7767

%UPDATE: NOT RESAMPLING AFTER RXFFE

7759

%UPDATE: NOT RESAMPLING AFTER RXFFE

7768

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7760

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7769

% if no_zero_crossing

7761

% if no_zero_crossing

7770

% continue;

7762

% continue;

7771

% end

7763

% end

7772

7764

7773

cursor = sbr(cursor_i);

7765

cursor = sbr(cursor_i);

7774

end

7766

end

7775

A_p=sbr(sbr_peak_i);

7767

A_p=sbr(sbr_peak_i);

7776

%% 93A.1.6 step c defines A_s %%

7768

%% 93A.1.6 step c defines A_s %%

7777

A_s = param.R_LM*cursor/(param.levels-1);

7769

A_s = param.R_LM*cursor/(param.levels-1);

7778

if isempty(delta_sbr)

7770

if isempty(delta_sbr)

7779

delta_sbr = sbr;

7771

delta_sbr = sbr;

7780

end

7772

end

7781

sbr=sbr(:);

7773

sbr=sbr(:);

7782

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7774

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7783

7775

7784

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7776

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7785

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7777

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7786

t=((cursor_i+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:length(sbr))-(cursor_i+param.samples_per_ui*(param.ndfe+1)))*...

7778

t=((cursor_i+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:length(sbr))-(cursor_i+param.samples_per_ui*(param.ndfe+1)))*...

7787

param.ui/param.samples_per_ui;

7779

param.ui/param.samples_per_ui;

7788

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7780

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7789

precursors = precursors(end:-1:1);

7781

precursors = precursors(end:-1:1);

7790

7782

7791

% % Error message if the sbr is not long enough for the specified range of Nb

7783

% % Error message if the sbr is not long enough for the specified range of Nb

7792

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7784

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7793

% close(hwaitbar);

7785

% close(hwaitbar);

7794

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7786

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7795

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7787

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7796

% end

7788

% end

7797

7789

7798

7790

7799

7791

7800

%% skip this case if FOM has no chance of beating old FOM

7792

%% skip this case if FOM has no chance of beating old FOM

7801

%this is also done below but with excess_dfe_cursors included.

7793

%this is also done below but with excess_dfe_cursors included.

7802

%excess_dfe_cursors requires the floating DFE computation which is

7794

%excess_dfe_cursors requires the floating DFE computation which is

7803

%time consuming, so checking here can have significant run time improvements

7795

%time consuming, so checking here can have significant run time improvements

7804

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7796

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7805

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7797

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7806

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7798

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7807

continue

7799

continue

7808

end

7800

end

7809

end

7801

end

7810

7802

7811

%% Equation 93A-27, when 1<=n<=N_b

7803

%% Equation 93A-27, when 1<=n<=N_b

7812

%required length = cursor + all DFE UI + 1 additional UI

7804

%required length = cursor + all DFE UI + 1 additional UI

7813

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7805

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7814

if length(sbr)<sbr_required_length

7806

if length(sbr)<sbr_required_length

7815

sbr(end+1:sbr_required_length)=0;

7807

sbr(end+1:sbr_required_length)=0;

7816

end

7808

end

7817

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7809

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7818

if param.dfe_delta ~= 0

7810

if param.dfe_delta ~= 0

7819

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7811

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7820

7812

7821

else

7813

else

7822

dfecursors_q=dfecursors;

7814

dfecursors_q=dfecursors;

7823

end

7815

end

7824

if param.Floating_DFE

7816

if param.Floating_DFE

7825

%% floating taps

7817

%% floating taps

7826

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7818

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7827

7819

7828

[floating_tap_locations, floating_tap_coef, hisi, bmax]= floatingDFE( postcurors ,param.ndfe_passed,param.N_bf,param.N_bg,param.N_bmax, param.bmaxg, sbr(cursor_i), param.dfe_delta );

7820

[floating_tap_locations, floating_tap_coef, hisi, bmax]= floatingDFE( postcurors ,param.ndfe_passed,param.N_bf,param.N_bg,param.N_bmax, param.bmaxg, sbr(cursor_i), param.dfe_delta );

7829

7821

7830

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7822

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7831

param.use_bmax=newbmax;

7823

param.use_bmax=newbmax;

7832

%AJG021820

7824

%AJG021820

7833

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7825

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7834

else

7826

else

7835

param.use_bmax=param.bmax;

7827

param.use_bmax=param.bmax;

7836

%AJG021820

7828

%AJG021820

7837

param.use_bmin=param.bmin;

7829

param.use_bmin=param.bmin;

7838

end

7830

end

7839

7831

7840

%AJG021820

7832

%AJG021820

7841

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7833

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7842

if do_C2M

7834

if do_C2M

7843

dfecursors_windowed=sbr(cursor_i-T_O+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe)-T_O);

7835

dfecursors_windowed=sbr(cursor_i-T_O+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe)-T_O);

7844

% readjust SBR

7836

% readjust SBR

7845

if 0

7837

if 0

7846

%PR_DFE_center not currently used, so this is in "if 0" statement

7838

%PR_DFE_center not currently used, so this is in "if 0" statement

7847

PR_DFE_center=sbr;

7839

PR_DFE_center=sbr;

7848

for n=1:param.ndfe

7840

for n=1:param.ndfe

7849

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7841

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7850

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7842

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7851

% dper=sbr(i_sample)- actual_dfecursors(n);

7843

% dper=sbr(i_sample)- actual_dfecursors(n);

7852

% PR_DFE_center(i_sample)=dper;

7844

% PR_DFE_center(i_sample)=dper;

7853

% end

7845

% end

7854

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7846

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7855

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7847

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7856

end

7848

end

7857

end

7849

end

7858

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7850

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7859

else

7851

else

7860

excess_dfe_cursors=dfecursors-actual_dfecursors;

7852

excess_dfe_cursors=dfecursors-actual_dfecursors;

7861

end

7853

end

7862

dfetaps=actual_dfecursors/sbr(cursor_i);

7854

dfetaps=actual_dfecursors/sbr(cursor_i);

7863

7855

7864

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7856

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7865

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7857

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7866

if tail_RSS ~= 0

7858

if tail_RSS ~= 0

7867

if tail_RSS >= param.B_float_RSS_MAX

7859

if tail_RSS >= param.B_float_RSS_MAX

7868

param.use_bmax(param.N_tail_start:end)= ...

7860

param.use_bmax(param.N_tail_start:end)= ...

7869

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7861

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7870

%AJG021820

7862

%AJG021820

7871

param.use_bmin(param.N_tail_start:end)= ...

7863

param.use_bmin(param.N_tail_start:end)= ...

7872

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7864

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7873

end

7865

end

7874

end

7866

end

7875

7867

7876

%AJG021820

7868

%AJG021820

7877

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7869

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7878

if do_C2M

7870

if do_C2M

7879

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7871

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7880

else

7872

else

7881

excess_dfe_cursors=dfecursors-actual_dfecursors;

7873

excess_dfe_cursors=dfecursors-actual_dfecursors;

7882

end

7874

end

7883

dfetaps=actual_dfecursors/sbr(cursor_i);

7875

dfetaps=actual_dfecursors/sbr(cursor_i);

7884

7876

7885

else

7877

else

7886

tail_RSS=0;

7878

tail_RSS=0;

7887

end

7879

end

7888

%% Eq. 93A-28 %%

7880

%% Eq. 93A-28 %%

7889

sampling_offset = mod(cursor_i, param.samples_per_ui);

7881

sampling_offset = mod(cursor_i, param.samples_per_ui);

7890

%ensure we can take early sample

7882

%ensure we can take early sample

7891

if sampling_offset<=1

7883

if sampling_offset<=1

7892

sampling_offset=sampling_offset+param.samples_per_ui;

7884

sampling_offset=sampling_offset+param.samples_per_ui;

7893

end

7885

end

7894

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7886

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7895

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7887

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7896

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7888

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7897

else

7889

else

7898

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7890

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7899

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7891

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7900

end

7892

end

7901

% ensure lengths are equal

7893

% ensure lengths are equal

7902

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7894

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7903

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7895

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7904

if ~OP.SNR_TXwC0

7896

if ~OP.SNR_TXwC0

7905

%% Equation 93A-30 %%

7897

%% Equation 93A-30 %%

7906

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7898

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7907

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7899

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7908

else

7900

else

7909

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7901

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7910

end

7902

end

7911

%% Equation 93A-31 %%

7903

%% Equation 93A-31 %%

7912

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7904

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7913

ISI_N=param.sigma_X*norm( far_cursors);

7905

ISI_N=param.sigma_X*norm( far_cursors);

7914

%% break if FOM has no chance of beating old e

7906

%% break if FOM has no chance of beating old e

7915

OP.exe_mode=1;

7907

OP.exe_mode=1;

7916

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7908

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7917

switch OP.EXE_MODE

7909

switch OP.EXE_MODE

7918

case 0

7910

case 0

7919

case 1

7911

case 1

7920

if (20*log10(A_s/sigma_ISI) < best_FOM)

7912

if (20*log10(A_s/sigma_ISI) < best_FOM)

7921

continue

7913

continue

7922

end

7914

end

7923

case 2

7915

case 2

7924

if (20*log10(A_s/sigma_ISI) < best_FOM)

7916

if (20*log10(A_s/sigma_ISI) < best_FOM)

7925

break

7917

break

7926

end

7918

end

7927

end

7919

end

7928

end

7920

end

7929

%% Equation 93A-32 %%

7921

%% Equation 93A-32 %%

7930

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7922

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7931

7923

7932

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7924

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7933

if OP.RX_CALIBRATION

7925

if OP.RX_CALIBRATION

7934

sigma_XT=0;

7926

sigma_XT=0;

7935

else

7927

else

7936

if ~OP.RxFFE

7928

if ~OP.RxFFE

7937

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata,phase_memory); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7929

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata,phase_memory); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7938

%% Equation 93A-36 denominator (actually its sqrt)

7930

%% Equation 93A-36 denominator (actually its sqrt)

7939

else % John Ewen: 13/12/20018

7931

else % John Ewen: 13/12/20018

7940

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7932

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7941

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata, phase_memory,C); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7933

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata, phase_memory,C); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7942

else % use results from get_PSDs RIM 3/28/2024

7934

else % use results from get_PSDs RIM 3/28/2024

7943

sigma_XT=PSD_results.S_xn_rms;

7935

sigma_XT=PSD_results.S_xn_rms;

7944

end

7936

end

7945

end

7937

end

7946

end

7938

end

7947

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7939

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7948

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7940

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7949

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7941

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7950

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7942

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7951

f=chdata(1).faxis;

7943

f=chdata(1).faxis;

7952

H_Rx_FFE=zeros(1,length(f));

7944

H_Rx_FFE=zeros(1,length(f));

7953

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7945

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7954

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7946

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7955

if C(ii+param.RxFFE_cmx+1)==0

7947

if C(ii+param.RxFFE_cmx+1)==0

7956

%speed up: skip cases when rxffe=0

7948

%speed up: skip cases when rxffe=0

7957

continue;

7949

continue;

7958

end

7950

end

7959

if ii+1==0

7951

if ii+1==0

7960

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7952

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7961

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7953

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7962

else

7954

else

7963

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7955

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7964

end

7956

end

7965

end

7957

end

7966

sigma_N =sqrt(param.eta_0*sum(H_sy(2:end) .* abs(H_r(2:end) .* H_ctf(2:end) .*H_Rx_FFE(2:end)).^2 .* diff(chdata(1).faxis)/1e9)); % changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7958

sigma_N =sqrt(param.eta_0*sum(H_sy(2:end) .* abs(H_r(2:end) .* H_ctf(2:end) .*H_Rx_FFE(2:end)).^2 .* diff(chdata(1).faxis)/1e9)); % changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7967

end

7959

end

7968

end

7960

end

7969

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7961

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7970

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7962

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7971

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7963

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7972

else

7964

else

7973

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7965

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7974

end

7966

end

7975

if do_C2M

7967

if do_C2M

7976

if param.Noise_Crest_Factor == 0

7968

if param.Noise_Crest_Factor == 0

7977

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7969

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7978

else

7970

else

7979

ber_q=param.Noise_Crest_Factor;

7971

ber_q=param.Noise_Crest_Factor;

7980

end

7972

end

7981

if OP.force_pdf_bin_size

7973

if OP.force_pdf_bin_size

7982

delta_y = OP.BinSize;

7974

delta_y = OP.BinSize;

7983

else

7975

else

7984

delta_y = min(A_s/1000, OP.BinSize);

7976

delta_y = min(A_s/1000, OP.BinSize);

7985

end

7977

end

7986

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7978

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7987

cci_pdf = normal_dist(0, ber_q, delta_y);

7979

cci_pdf = normal_dist(0, ber_q, delta_y);

7988

chdata(1).eq_pulse_response=sbr;

7980

chdata(1).eq_pulse_response=sbr;

7989

tmp_result.t_s= cursor_i;

7981

tmp_result.t_s= cursor_i;

7990

tmp_result.A_s=A_s;

7982

tmp_result.A_s=A_s;

7991

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7983

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7992

if EH_1st <= param.Min_VEO_Test/1000 -.001

7984

if EH_1st <= param.Min_VEO_Test/1000 -.001

7993

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7985

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7994

continue

7986

continue

7995

else

7987

else

7996

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7988

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7997

end

7989

end

7998

Struct_Noise.sigma_N=sigma_N;

7990

Struct_Noise.sigma_N=sigma_N;

7999

Struct_Noise.sigma_TX=sigma_TX;

7991

Struct_Noise.sigma_TX=sigma_TX;

8000

Struct_Noise.cci_pdf=cci_pdf;

7992

Struct_Noise.cci_pdf=cci_pdf;

8001

Struct_Noise.ber_q=ber_q;

7993

Struct_Noise.ber_q=ber_q;

8002

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7994

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

8003

[Left_EW,Right_EW,eye_contour,EH_T_C2M,EH_B_C2M]=COM_eye_width(chdata,delta_y,tmp_result,param,OP,Struct_Noise,1);

7995

[Left_EW,Right_EW,eye_contour,EH_T_C2M,EH_B_C2M]=COM_eye_width(chdata,delta_y,tmp_result,param,OP,Struct_Noise,1);

8004

EH=EH_T_C2M-EH_B_C2M;

7996

EH=EH_T_C2M-EH_B_C2M;

8005

N_i=(A_s*2-EH)/2;

7997

N_i=(A_s*2-EH)/2;

8006

if EH <= param.Min_VEO_Test/1000

7998

if EH <= param.Min_VEO_Test/1000

8007

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7999

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

8008

continue

8000

continue

8009

else

8001

else

8010

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

8002

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

8011

end

8003

end

8012

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

8004

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

8013

FOM =20*log10(A_s/N_i);

8005

FOM =20*log10(A_s/N_i);

8014

end

8006

end

8015

else

8007

else

8016

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

8008

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

8017

FOM = 20*log10(A_s/total_noise_rms);

8009

FOM = 20*log10(A_s/total_noise_rms);

8018

end

8010

end

8019

% if strfind(param.CTLE_type,'CL120e')

8011

% if strfind(param.CTLE_type,'CL120e')

8020

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

8012

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

8021

end

8013

end

8022

if 0 % for loop analysis

8014

if 0 % for loop analysis

8023

result.FOM_array(new_loops)=FOM;

8015

result.FOM_array(new_loops)=FOM;

8024

end

8016

end

8025

8017

8026

if FOM>best_itick_FOM

8018

if FOM>best_itick_FOM

8027

best_itick_FOM=FOM;

8019

best_itick_FOM=FOM;

8028

best_itick_in_cluster=itick;

8020

best_itick_in_cluster=itick;

8029

end

8021

end

8030

8022

8031

if itick>=0 && FOM>best_positive_itick_FOM

8023

if itick>=0 && FOM>best_positive_itick_FOM

8032

best_positive_itick_FOM=FOM;

8024

best_positive_itick_FOM=FOM;

8033

best_positive_itick_in_loop=itick;

8025

best_positive_itick_in_loop=itick;

8034

end

8026

end

8035

if itick<=0 && FOM>best_negative_itick_FOM

8027

if itick<=0 && FOM>best_negative_itick_FOM

8036

best_negative_itick_FOM=FOM;

8028

best_negative_itick_FOM=FOM;

8037

best_negative_itick_in_loop=itick;

8029

best_negative_itick_in_loop=itick;

8038

end

8030

end

8039

8031

8040

itick_index=find(itick==full_sample_range);

8032

itick_index=find(itick==full_sample_range);

8041

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

8033

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

8042

8034

8043

if (FOM > best_FOM)

8035

if (FOM > best_FOM)

8044

best_current_ffegain=param.current_ffegain;

8036

best_current_ffegain=param.current_ffegain;

8045

best_txffe = txffe;

8037

best_txffe = txffe;

8046

%along with best_txffe, save the indices of the best_txffe

8038

%along with best_txffe, save the indices of the best_txffe

8047

%(saves time in LOCAL SEARCH block)

8039

%(saves time in LOCAL SEARCH block)

8048

best_txffe_index=tx_index_vector;

8040

best_txffe_index=tx_index_vector;

8049

best_sbr = sbr;

8041

best_sbr = sbr;

8050

best_ctle = ctle_index;

8042

best_ctle = ctle_index;

8051

best_G_high_pass =g_LP_index;

8043

best_G_high_pass =g_LP_index;

8052

best_FOM = FOM;

8044

best_FOM = FOM;

8053

best_cursor_i = cursor_i;

8045

best_cursor_i = cursor_i;

8054

best_itick = itick;

8046

best_itick = itick;

8055

if ~OP.TDMODE

8047

if ~OP.TDMODE

8056

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

8048

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

8057

best_IR=effective_channel;

8049

best_IR=effective_channel;

8058

end

8050

end

8059

best_sigma_N = sigma_N;

8051

best_sigma_N = sigma_N;

8060

best_h_J = h_J;

8052

best_h_J = h_J;

8061

best_A_s=A_s;

8053

best_A_s=A_s;

8062

best_A_p=A_p;

8054

best_A_p=A_p;

8063

best_ISI=ISI_N;

8055

best_ISI=ISI_N;

8064

best_bmax=param.use_bmax;

8056

best_bmax=param.use_bmax;

8065

%AJG021820

8057

%AJG021820

8066

best_bmin=param.use_bmin;

8058

best_bmin=param.use_bmin;

8067

best_tail_RSS=tail_RSS;

8059

best_tail_RSS=tail_RSS;

8068

best_dfetaps=dfetaps;

8060

best_dfetaps=dfetaps;

8069

if param.Floating_DFE

8061

if param.Floating_DFE

8070

best_floating_tap_locations=floating_tap_locations;

8062

best_floating_tap_locations=floating_tap_locations;

8071

best_floating_tap_coef=floating_tap_coef;

8063

best_floating_tap_coef=floating_tap_coef;

8072

end

8064

end

8073

if param.Floating_RXFFE

8065

if param.Floating_RXFFE

8074

best_floating_tap_locations=floating_tap_locations;

8066

best_floating_tap_locations=floating_tap_locations;

8075

% best_floating_tap_coef=floating_tap_coef;

8067

% best_floating_tap_coef=floating_tap_coef;

8076

end

8068

end

8077

if OP.RxFFE

8069

if OP.RxFFE

8078

best_RxFFE=C;

8070

best_RxFFE=C;

8079

best_PSD_results=PSD_results;

8071

best_PSD_results=PSD_results;

8080

best_MMSE_results=MMSE_results;

8072

best_MMSE_results=MMSE_results;

8081

end

8073

end

8082

end

8074

end

8083

end

8075

end

8084

end

8076

end

8085

8077

8086

end

8078

end

8087

end

8079

end

8088

end

8080

end

8089

if do_C2M

8081

if do_C2M

8090

if best_FOM == -inf

8082

if best_FOM == -inf

8091

param.Min_VEO_Test=0;

8083

param.Min_VEO_Test=0;

8092

else

8084

else

8093

break

8085

break

8094

end

8086

end

8095

end

8087

end

8096

end

8088

end

8097

if 0

8089

if 0

8098

fprintf('old loops = %d\n',old_loops);

8090

fprintf('old loops = %d\n',old_loops);

8099

fprintf('new loops = %d\n',new_loops);

8091

fprintf('new loops = %d\n',new_loops);

8100

display(sprintf('\n :loops = %g',pxi))

8092

display(sprintf('\n :loops = %g',pxi))

8101

end

8093

end

8102

8094

8103

%turn this on to review if FOM changes sign more than once in an itick loop

8095

%turn this on to review if FOM changes sign more than once in an itick loop

8104

if 0

8096

if 0

8105

DIR_CHANGE={};

8097

DIR_CHANGE={};

8106

for m=1:length(Gffe_values)

8098

for m=1:length(Gffe_values)

8107

for n=1:length(gdc_values)

8099

for n=1:length(gdc_values)

8108

for k=1:lf_indx

8100

for k=1:lf_indx

8109

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

8101

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

8110

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

8102

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

8111

%1 = goes up, -1=goes down

8103

%1 = goes up, -1=goes down

8112

x=sign(diff(FOM_this_mat')');

8104

x=sign(diff(FOM_this_mat')');

8113

%y = change in sign on x. the location of a "2" is where FOM changes direction

8105

%y = change in sign on x. the location of a "2" is where FOM changes direction

8114

y=abs(diff(x'))';

8106

y=abs(diff(x'))';

8115

%the goal is the FOM only changes direction once. so count the occurences of the 2

8107

%the goal is the FOM only changes direction once. so count the occurences of the 2

8116

for j=1:size(FOM_this_mat,1)

8108

for j=1:size(FOM_this_mat,1)

8117

z{j}=find(y(j,:)==2);

8109

z{j}=find(y(j,:)==2);

8118

end

8110

end

8119

zL=cellfun('length',z);

8111

zL=cellfun('length',z);

8120

%return any row where FOM changed direction more than once

8112

%return any row where FOM changed direction more than once

8121

DIR_CHANGE{j,k}=find(zL>1);

8113

DIR_CHANGE{j,k}=find(zL>1);

8122

end

8114

end

8123

end

8115

end

8124

end

8116

end

8125

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

8117

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

8126

end

8118

end

8127

8119

8128

if ~exist('best_cursor_i', 'var')% take last setting

8120

if ~exist('best_cursor_i', 'var')% take last setting

8129

result.eq_failed=true;

8121

result.eq_failed=true;

8130

display('equalization failed')

8122

display('equalization failed')

8131

best_bmax=param.bmax;

8123

best_bmax=param.bmax;

8132

%AJG021820

8124

%AJG021820

8133

best_bmin=param.bmin;

8125

best_bmin=param.bmin;

8134

best_tail_RSS=0;

8126

best_tail_RSS=0;

8135

best_current_ffegain=0;

8127

best_current_ffegain=0;

8136

best_txffe = txffe;

8128

best_txffe = txffe;

8137

best_sbr = sbr;

8129

best_sbr = sbr;

8138

best_ctle = ctle_index;

8130

best_ctle = ctle_index;

8139

if OP.RxFFE

8131

if OP.RxFFE

8140

best_PSD_results=PSD_results;

8132

best_PSD_results=PSD_results;

8141

best_MMSE_results=MMSE_results;

8133

best_MMSE_results=MMSE_results;

8142

best_RxFFE=C;

8134

best_RxFFE=C;

8143

end

8135

end

8144

best_G_high_pass =g_LP_index;

8136

best_G_high_pass =g_LP_index;

8145

best_FOM = FOM;

8137

best_FOM = FOM;

8146

%if this block is reached, the last encountered EQ parameters are used

8138

%if this block is reached, the last encountered EQ parameters are used

8147

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

8139

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

8148

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

8140

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

8149

if isempty(cursor_i)

8141

if isempty(cursor_i)

8150

[~,cursor_i]=max(sbr);

8142

[~,cursor_i]=max(sbr);

8151

end

8143

end

8152

best_cursor_i = cursor_i;

8144

best_cursor_i = cursor_i;

8153

best_itick = itick;

8145

best_itick = itick;

8154

if ~OP.TDMODE

8146

if ~OP.TDMODE

8155

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

8147

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

8156

best_IR=effective_channel;

8148

best_IR=effective_channel;

8157

end

8149

end

8158

best_sigma_N = sigma_N;

8150

best_sigma_N = sigma_N;

8159

best_h_J = h_J;

8151

best_h_J = h_J;

8160

best_A_p=max(sbr);

8152

best_A_p=max(sbr);

8161

best_ISI=1;

8153

best_ISI=1;

8162

best_dfetaps= sbr( cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe))/sbr(cursor_i) ;

8154

best_dfetaps= sbr( cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe))/sbr(cursor_i) ;

8163

best_A_s= sbr( cursor_i);

8155

best_A_s= sbr( cursor_i);

8164

if param.Floating_DFE

8156

if param.Floating_DFE

8165

best_floating_tap_locations=[];

8157

best_floating_tap_locations=[];

8166

best_floating_tap_coef=[];

8158

best_floating_tap_coef=[];

8167

end

8159

end

8168

if do_C2M

8160

if do_C2M

8169

return

8161

return

8170

end

8162

end

8171

% return

8163

% return

8172

else

8164

else

8173

result.eq_failed=false; % RIM 12/30/2023

8165

result.eq_failed=false; % RIM 12/30/2023

8174

end

8166

end

8175

8167

8176

best_cursor = best_sbr(best_cursor_i);

8168

best_cursor = best_sbr(best_cursor_i);

8177

% report during debug

8169

% report during debug

8178

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

8170

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

8179

%If sbr was zero padded, then PRin needs to do so as well)

8171

%If sbr was zero padded, then PRin needs to do so as well)

8180

if length(PRin)<length(best_sbr)

8172

if length(PRin)<length(best_sbr)

8181

PRin(end+1:length(best_sbr))=0;

8173

PRin(end+1:length(best_sbr))=0;

8182

end

8174

end

8183

f=1e8:1e8:100e9;

8175

f=1e8:1e8:100e9;

8184

8176

8185

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

8177

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

8186

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

8178

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

8187

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

8179

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

8188

% need to include H_RCos in noise and when computing the system ir for thru

8180

% need to include H_RCos in noise and when computing the system ir for thru

8189

% and crosstalk

8181

% and crosstalk

8190

H_r=H_bw.*H_bt.*H_RCos;

8182

H_r=H_bw.*H_bt.*H_RCos;

8191

8183

8192

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

8184

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

8193

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

8185

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

8194

8186

8195

switch param.CTLE_type

8187

switch param.CTLE_type

8196

case 'CL93'

8188

case 'CL93'

8197

H_low=1;

8189

H_low=1;

8198

case 'CL120d'

8190

case 'CL120d'

8199

H_low=(10^(param.g_DC_HP_values(best_G_high_pass)/20) + 1i*f/param.f_HP(best_G_high_pass))./(1 + 1i*f/param.f_HP(best_G_high_pass));

8191

H_low=(10^(param.g_DC_HP_values(best_G_high_pass)/20) + 1i*f/param.f_HP(best_G_high_pass))./(1 + 1i*f/param.f_HP(best_G_high_pass));

8200

case 'CL120e'

8192

case 'CL120e'

8201

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

8193

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

8202

end

8194

end

8203

ctle_gain=H_low.*ctle_gain1.*H_r;

8195

ctle_gain=H_low.*ctle_gain1.*H_r;

8204

8196

8205

8197

8206

8198

8207

%lsbr=length(sbr);

8199

%lsbr=length(sbr);

8208

%use length of best_sbr in case zero padding was performed

8200

%use length of best_sbr in case zero padding was performed

8209

%check "sbr_required_length" variable

8201

%check "sbr_required_length" variable

8210

lsbr=length(best_sbr);

8202

lsbr=length(best_sbr);

8211

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

8203

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

8212

8204

8213

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

8205

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

8214

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

8206

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

8215

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

8207

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

8216

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

8208

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

8217

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

8209

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

8218

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

8210

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

8219

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

8211

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

8220

if param.Floating_DFE

8212

if param.Floating_DFE

8221

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

8213

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

8222

end

8214

end

8223

% apply max tap value constraint

8215

% apply max tap value constraint

8224

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

8216

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

8225

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

8217

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

8226

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

8218

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

8227

8219

8228

%AJG021820

8220

%AJG021820

8229

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

8221

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

8230

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

8222

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

8231

if param.Floating_DFE

8223

if param.Floating_DFE

8232

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

8224

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

8233

end

8225

end

8234

8226

8235

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

8227

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

8236

Symbol_Adj = (param.levels-1);% 3A.1.6

8228

Symbol_Adj = (param.levels-1);% 3A.1.6

8237

if OP.DEBUG ~=0

8229

if OP.DEBUG ~=0

8238

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

8230

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

8239

% display pulse responses in one axis per test case.

8231

% display pulse responses in one axis per test case.

8240

switch upper(OP.TIME_AXIS)

8232

switch upper(OP.TIME_AXIS)

8241

case 'S' % RIM 11-13-2023 added user selectable xaxis

8233

case 'S' % RIM 11-13-2023 added user selectable xaxis

8242

xnorm=1;

8234

xnorm=1;

8243

xaxis_label='seconds';

8235

xaxis_label='seconds';

8244

offset=0;

8236

offset=0;

8245

case 'UI'

8237

case 'UI'

8246

xnorm=param.ui;

8238

xnorm=param.ui;

8247

xaxis_label='UI';

8239

xaxis_label='UI';

8248

offset=t(best_cursor_i)/xnorm;

8240

offset=t(best_cursor_i)/xnorm;

8249

otherwise

8241

otherwise

8250

xnorm=1;

8242

xnorm=1;

8251

xaxis_label='seconds';

8243

xaxis_label='seconds';

8252

offset=0;

8244

offset=0;

8253

end

8245

end

8254

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

8246

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

8255

fig=findobj('Name', figure_name);

8247

fig=findobj('Name', figure_name);

8256

if isempty(fig), fig=figure('Name', figure_name); end

8248

if isempty(fig), fig=figure('Name', figure_name); end

8257

figure(fig);set(gcf,'Tag','COM');

8249

figure(fig);set(gcf,'Tag','COM');

8258

movegui(fig,'north')

8250

movegui(fig,'north')

8259

%figure(fig.Number);

8251

%figure(fig.Number);

8260

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

8252

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

8261

if OP.RxFFE

8253

if OP.RxFFE

8262

ax1=subplot(2,1,1);

8254

ax1=subplot(2,1,1);

8263

end

8255

end

8264

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

8256

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

8265

hold on

8257

hold on

8266

8258

8267

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

8259

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

8268

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

8260

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

8269

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

8261

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

8270

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

8262

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

8271

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

8263

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

8272

ylabel('volts')

8264

ylabel('volts')

8273

xlabel(xaxis_label)

8265

xlabel(xaxis_label)

8274

grid on

8266

grid on

8275

legend show

8267

legend show

8276

legend( 'Location', 'best')

8268

legend( 'Location', 'best')

8277

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

8269

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

8278

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

8270

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

8279

if param.ndfe_passed ~=0

8271

if param.ndfe_passed ~=0

8280

stem((sampled_best_sbr_dfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,DFE_taps_mV(1:param.ndfe_passed)/Symbol_Adj','m', 'LineWidth',2,'disp','DFE-canceled cursors');

8272

stem((sampled_best_sbr_dfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,DFE_taps_mV(1:param.ndfe_passed)/Symbol_Adj','m', 'LineWidth',2,'disp','DFE-canceled cursors');

8281

end

8273

end

8282

if param.Floating_DFE

8274

if param.Floating_DFE

8283

stem((sampled_best_sbr_fdfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,FDFE_taps_mV/Symbol_Adj, 'MarkerFaceColor','red','MarkerEdgeColor','m','LineWidth',1,'disp','FDFE-canceled cursors');

8275

stem((sampled_best_sbr_fdfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,FDFE_taps_mV/Symbol_Adj, 'MarkerFaceColor','red','MarkerEdgeColor','m','LineWidth',1,'disp','FDFE-canceled cursors');

8284

end

8276

end

8285

if OP.RxFFE

8277

if OP.RxFFE

8286

ax2=subplot(2,1,2);

8278

ax2=subplot(2,1,2);

8287

if param.Floating_RXFFE

8279

if param.Floating_RXFFE

8288

%AJG: floating tap x-axis location needs offset by -(RxFFE_cmx+1) because the floating tap indices include precursor indices

8289

stem((t(best_cursor_i+(best_floating_tap_locations-param.RxFFE_cmx-1)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

8280

stem((t(best_cursor_i+(best_floating_tap_locations)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

8290

,'filled','disp','RxFFE floating FFE taps')

8281

,'filled','disp','RxFFE floating FFE taps')

8291

hold on

8282

hold on

8292

end

8283

end

8293

stem((t(best_cursor_i+param.samples_per_ui*(-param.RxFFE_cmx:param.RxFFE_cpx)))/xnorm-offset,best_RxFFE(1:param.RxFFE_cmx+param.RxFFE_cpx+1)...

8284

stem((t(best_cursor_i+param.samples_per_ui*(-param.RxFFE_cmx:param.RxFFE_cpx)))/xnorm-offset,best_RxFFE(1:param.RxFFE_cmx+param.RxFFE_cpx+1)...

8294

,'filled','disp','RxFFE fixted FFE taps')

8285

,'filled','disp','RxFFE fixted FFE taps')

8295

legend show

8286

legend show

8296

zoom xon

8287

zoom xon

8297

linkaxes([ax1 ax2],'x')

8288

linkaxes([ax1 ax2],'x')

8298

end

8289

end

8299

8290

8300

8291

8301

grid on

8292

grid on

8302

legend show

8293

legend show

8303

legend( 'Location', 'best')

8294

legend( 'Location', 'best')

8304

zoom xon

8295

zoom xon

8305

% set(hax, 'tag', 'EQE');

8296

% set(hax, 'tag', 'EQE');

8306

%

8297

%

8307

figure(110);set(gcf,'Tag','COM');

8298

figure(110);set(gcf,'Tag','COM');

8308

set(gcf, 'Name', 'CTLE selection');

8299

set(gcf, 'Name', 'CTLE selection');

8309

movegui(gcf, 'southeast');

8300

movegui(gcf, 'southeast');

8310

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8301

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8311

hold on

8302

hold on

8312

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8303

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8313

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8304

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8314

fbaud_tick=find(f >= baud_rate, 1);

8305

fbaud_tick=find(f >= baud_rate, 1);

8315

fnq_tick=find(f >= baud_rate/2, 1);

8306

fnq_tick=find(f >= baud_rate/2, 1);

8316

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8307

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8317

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8308

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8318

recolor_plots(gca);

8309

recolor_plots(gca);

8319

title('CTF/w Rx Filter Response')

8310

title('CTF/w Rx Filter Response')

8320

ylabel('dB')

8311

ylabel('dB')

8321

xlabel('Hz')

8312

xlabel('Hz')

8322

legend show

8313

legend show

8323

end

8314

end

8324

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8315

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8325

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8316

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8326

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8317

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8327

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8318

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8328

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8319

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8329

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8320

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8330

end

8321

end

8331

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

8322

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

8332

eqe_axes = findobj('tag', 'EQE');

8323

eqe_axes = findobj('tag', 'EQE');

8333

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8324

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8334

end

8325

end

8335

if OP.DISPLAY_WINDOW

8326

if OP.DISPLAY_WINDOW

8336

close(hwaitbar);

8327

close(hwaitbar);

8337

else

8328

else

8338

fprintf('\n');

8329

fprintf('\n');

8339

end

8330

end

8340

8331

8341

% % eq_data

8332

% % eq_data

8342

result.cur=cur;

8333

result.cur=cur;

8343

result.txffe = best_txffe;

8334

result.txffe = best_txffe;

8344

result.ctle = best_ctle;

8335

result.ctle = best_ctle;

8345

result.best_G_high_pass=best_G_high_pass;

8336

result.best_G_high_pass=best_G_high_pass;

8346

result.DFE_taps = best_dfetaps; %relative

8337

result.DFE_taps = best_dfetaps; %relative

8347

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8338

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8348

if param.Floating_DFE

8339

if param.Floating_DFE

8349

result.floating_tap_locations=best_floating_tap_locations;

8340

result.floating_tap_locations=best_floating_tap_locations;

8350

result.floating_tap_coef=best_floating_tap_coef;

8341

result.floating_tap_coef=best_floating_tap_coef;

8351

end

8342

end

8352

if param.Floating_RXFFE

8343

if param.Floating_RXFFE

8353

result.floating_tap_locations=best_floating_tap_locations;

8344

result.floating_tap_locations=best_floating_tap_locations;

8354

end

8345

end

8355

result.A_s = best_A_s;

8346

result.A_s = best_A_s;

8356

result.t_s = best_cursor_i;

8347

result.t_s = best_cursor_i;

8357

result.itick = best_itick;

8348

result.itick = best_itick;

8358

result.sigma_N = best_sigma_N;

8349

result.sigma_N = best_sigma_N;

8359

result.h_J = best_h_J;

8350

result.h_J = best_h_J;

8360

result.FOM = best_FOM;

8351

result.FOM = best_FOM;

8361

if ~OP.TDMODE

8352

if ~OP.TDMODE

8362

%If sbr was zero padded, then best_IR needs to do so as well)

8353

%If sbr was zero padded, then best_IR needs to do so as well)

8363

if length(best_IR)<length(best_sbr)

8354

if length(best_IR)<length(best_sbr)

8364

best_IR(end+1:length(best_sbr))=0;

8355

best_IR(end+1:length(best_sbr))=0;

8365

end

8356

end

8366

result.IR = best_IR;

8357

result.IR = best_IR;

8367

end

8358

end

8368

result.t=t;

8359

result.t=t;

8369

result.sbr=best_sbr;

8360

result.sbr=best_sbr;

8370

if OP.RxFFE

8361

if OP.RxFFE

8371

result.RxFFE=best_RxFFE;

8362

result.RxFFE=best_RxFFE;

8372

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8363

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8373

result.PSD_results=best_PSD_results;

8364

result.PSD_results=best_PSD_results;

8374

result.MMSE_results=best_MMSE_results;

8365

result.MMSE_results=best_MMSE_results;

8375

end

8366

end

8376

end

8367

end

8377

8368

8378

8369

8379

8370

8380

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8371

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8381

% updated RIM 12/17/2021

8372

% updated RIM 12/17/2021

8382

result.A_p = max(chdata(1).uneq_pulse_response);

8373

result.A_p = max(chdata(1).uneq_pulse_response);

8383

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8374

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8384

PR=chdata(1).uneq_pulse_response;

8375

PR=chdata(1).uneq_pulse_response;

8385

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8376

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8386

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8377

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8387

if iend >= length(PR)

8378

if iend >= length(PR)

8388

iend = length (PR);

8379

iend = length (PR);

8389

end

8380

end

8390

if ibeg < 1

8381

if ibeg < 1

8391

ibeg = 1;

8382

ibeg = 1;

8392

end

8383

end

8393

PR=PR(ibeg:iend);

8384

PR=PR(ibeg:iend);

8394

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8385

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8395

SRn=PR;

8386

SRn=PR;

8396

for ik=1:floor(length(PR)/param.samples_per_ui)

8387

for ik=1:floor(length(PR)/param.samples_per_ui)

8397

SPR=circshift(PR,param.samples_per_ui*ik);

8388

SPR=circshift(PR,param.samples_per_ui*ik);

8398

SPR(1:ik*param.samples_per_ui)=0;

8389

SPR(1:ik*param.samples_per_ui)=0;

8399

SRn=SRn+ SPR;

8390

SRn=SRn+ SPR;

8400

end

8391

end

8401

codedebug=0;

8392

codedebug=0;

8402

if codedebug

8393

if codedebug

8403

fig=figure('Name', 'step and pulse response for code debug');

8394

fig=figure('Name', 'step and pulse response for code debug');

8404

figure(fig);set(gcf,'Tag','COM');

8395

figure(fig);set(gcf,'Tag','COM');

8405

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8396

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8406

plot(UI,SRn)

8397

plot(UI,SRn)

8407

hold on

8398

hold on

8408

plot(UI,PR)

8399

plot(UI,PR)

8409

xlim([-param.D_p param.N_v])

8400

xlim([-param.D_p param.N_v])

8410

grid on;hold off;

8401

grid on;hold off;

8411

result.step=SRn;

8402

result.step=SRn;

8412

end

8403

end

8413

i20=find(SRn>=0.20*result.A_f,1,'first');

8404

i20=find(SRn>=0.20*result.A_f,1,'first');

8414

i80=find(SRn>=0.80*result.A_f,1,'first');

8405

i80=find(SRn>=0.80*result.A_f,1,'first');

8415

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8406

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8416

result.Pmax_by_Vf=result.A_p/result.A_f;

8407

result.Pmax_by_Vf=result.A_p/result.A_f;

8417

result.ISI =best_ISI;

8408

result.ISI =best_ISI;

8418

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8409

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8419

result.best_current_ffegain=best_current_ffegain;

8410

result.best_current_ffegain=best_current_ffegain;

8420

result.best_bmax=best_bmax;

8411

result.best_bmax=best_bmax;

8421

%AJG021820

8412

%AJG021820

8422

result.best_bmin=best_bmin;

8413

result.best_bmin=best_bmin;

8423

result.tail_RSS=best_tail_RSS;

8414

result.tail_RSS=best_tail_RSS;

8424

function param=parameter_size_adjustment(param,OP)

8415

function param=parameter_size_adjustment(param,OP)

8425

8416

8426

make_length2={'C_pkg_board' 'C_diepad' 'L_comp' 'C_bump' 'tfx' 'C_v' 'C_0' 'C_1' 'pkg_Z_c' 'brd_Z_c' 'R_diepad'};

8417

make_length2={'C_pkg_board' 'C_diepad' 'L_comp' 'C_bump' 'tfx' 'C_v' 'C_0' 'C_1' 'pkg_Z_c' 'brd_Z_c' 'R_diepad'};

8427

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8418

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8428

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8419

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8429

make_length_DCHP={'f_HP'};

8420

make_length_DCHP={'f_HP'};

8430

make_length_ncases={'AC_CM_RMS'};

8421

make_length_ncases={'AC_CM_RMS'};

8431

8422

8432

%ncases used by make_length_ncases fields

8423

%ncases used by make_length_ncases fields

8433

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8424

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8434

8425

8435

%PORTZ_mult used by make_length_WCPORTZ fields

8426

%PORTZ_mult used by make_length_WCPORTZ fields

8436

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8427

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8437

if OP.WC_PORTZ

8428

if OP.WC_PORTZ

8438

PORTZ_mult=[1 1];

8429

PORTZ_mult=[1 1];

8439

else

8430

else

8440

PORTZ_mult=pkg_sel_vec;

8431

PORTZ_mult=pkg_sel_vec;

8441

end

8432

end

8442

8433

8443

%Parameters that have length = 2

8434

%Parameters that have length = 2

8444

for j=1:length(make_length2)

8435

for j=1:length(make_length2)

8445

if numel(param.(make_length2{j}))==1

8436

if numel(param.(make_length2{j}))==1

8446

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8437

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8447

end

8438

end

8448

end

8439

end

8449

8440

8450

%Parameters that have length = ncases

8441

%Parameters that have length = ncases

8451

for j=1:length(make_length_ncases)

8442

for j=1:length(make_length_ncases)

8452

if numel(param.(make_length_ncases{j}))==1

8443

if numel(param.(make_length_ncases{j}))==1

8453

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8444

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8454

end

8445

end

8455

end

8446

end

8456

8447

8457

%Parameters that have length = length(ctle_gdc_values)

8448

%Parameters that have length = length(ctle_gdc_values)

8458

for j=1:length(make_length_GDC)

8449

for j=1:length(make_length_GDC)

8459

if numel(param.(make_length_GDC{j}))==1

8450

if numel(param.(make_length_GDC{j}))==1

8460

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8451

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8461

end

8452

end

8462

end

8453

end

8463

8454

8464

%Parameters that have length = length(g_DC_HP_values)

8455

%Parameters that have length = length(g_DC_HP_values)

8465

for j=1:length(make_length_DCHP)

8456

for j=1:length(make_length_DCHP)

8466

if numel(param.(make_length_DCHP{j}))==1

8457

if numel(param.(make_length_DCHP{j}))==1

8467

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8458

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8468

end

8459

end

8469

end

8460

end

8470

8461

8471

%Parameters that have length associated with PORTZ_mult

8462

%Parameters that have length associated with PORTZ_mult

8472

for j=1:length(make_length_WCPORTZ)

8463

for j=1:length(make_length_WCPORTZ)

8473

if numel(param.(make_length_WCPORTZ{j}))==1

8464

if numel(param.(make_length_WCPORTZ{j}))==1

8474

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8465

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8475

end

8466

end

8476

end

8467

end

8477

function sgm = pdf2sgm(pdf)

8468

function sgm = pdf2sgm(pdf)

8478

avg = sum(pdf.x .* pdf.y);

8469

avg = sum(pdf.x .* pdf.y);

8479

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8470

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8480

% end yasuo patch

8471

% end yasuo patch

8481

8472

8482

8473

8483

%% adding tx packgage

8474

%% adding tx packgage

8484

function cdf=pdf_to_cdf(pdf)

8475

function cdf=pdf_to_cdf(pdf)

8485

8476

8486

%Transform PDF to CDF

8477

%Transform PDF to CDF

8487

%The CDF is natively calculated from negative-to-positive voltage.

8478

%The CDF is natively calculated from negative-to-positive voltage.

8488

%This only gives BER calculation for bottom eye. Need to also

8479

%This only gives BER calculation for bottom eye. Need to also

8489

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8480

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8490

%min of top and bottom CDF values.

8481

%min of top and bottom CDF values.

8491

%If only interested in one side, a simple cumsum on y is all that is needed.

8482

%If only interested in one side, a simple cumsum on y is all that is needed.

8492

8483

8493

cdf.yB=cumsum(pdf.y);

8484

cdf.yB=cumsum(pdf.y);

8494

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8485

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8495

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8486

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8496

cdf.x=pdf.x;

8487

cdf.x=pdf.x;

8497

function plot_bathtub_curves(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf,jitt_pdf, combined_interference_and_noise_pdf, bin_size)

8488

function plot_bathtub_curves(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf,jitt_pdf, combined_interference_and_noise_pdf, bin_size)

8498

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8489

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8499

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8490

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8500

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8491

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8501

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8492

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8502

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8493

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8503

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8494

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8504

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8495

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8505

%% Added by Bill Kirkland, June 14, 2017

8496

%% Added by Bill Kirkland, June 14, 2017

8506

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8497

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8507

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8498

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8508

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8499

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8509

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8500

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8510

8501

8511

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8502

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8512

hold on

8503

hold on

8513

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8504

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8514

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8505

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8515

semilogy(signal_and_system_noise_pdf.x, abs(cumsum(signal_and_system_noise_pdf.y)-0.5) ,'m','Disp','Jitter, SNR_TX,RL_M, eta_0 noise', 'parent', hax)

8506

semilogy(signal_and_system_noise_pdf.x, abs(cumsum(signal_and_system_noise_pdf.y)-0.5) ,'m','Disp','Jitter, SNR_TX,RL_M, eta_0 noise', 'parent', hax)

8516

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8507

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8517

8508

8518

%% Added by Bill Kirkland, June 14, 2017

8509

%% Added by Bill Kirkland, June 14, 2017

8519

% modification allows bathtub curves to cross over and hence one can

8510

% modification allows bathtub curves to cross over and hence one can

8520

% directly read the noise component.

8511

% directly read the noise component.

8521

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8512

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8522

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8513

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8523

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8514

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8524

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8515

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8525

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8516

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8526

8517

8527

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8518

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8528

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8519

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8529

8520

8530

ylabel(hax, 'Probability')

8521

ylabel(hax, 'Probability')

8531

xlabel(hax, 'volts')

8522

xlabel(hax, 'volts')

8532

legend(hax, 'show')

8523

legend(hax, 'show')

8533

% testing code

8524

% testing code

8534

if 0

8525

if 0

8535

figure_name = 'COM curves';

8526

figure_name = 'COM curves';

8536

fig=findobj('Name', figure_name);

8527

fig=findobj('Name', figure_name);

8537

if isempty(fig), fig=figure('Name', figure_name); end

8528

if isempty(fig), fig=figure('Name', figure_name); end

8538

figure(fig);set(gcf,'Tag','COM');

8529

figure(fig);set(gcf,'Tag','COM');

8539

grid on

8530

grid on

8540

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8531

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8541

hold on

8532

hold on

8542

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8533

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8543

ylim([ 1e-6 0.25])

8534

ylim([ 1e-6 0.25])

8544

xlim([0 30])

8535

xlim([0 30])

8545

grid on

8536

grid on

8546

end

8537

end

8547

function plot_pie_com(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf, combined_interference_and_noise_pdf, bin_size,param)

8538

function plot_pie_com(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf, combined_interference_and_noise_pdf, bin_size,param)

8548

BER=param.specBER;

8539

BER=param.specBER;

8549

delta_dB=param.delta_IL;

8540

delta_dB=param.delta_IL;

8550

8541

8551

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8542

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8552

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8543

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8553

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8544

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8554

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8545

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8555

8546

8556

8547

8557

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8548

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8558

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8549

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8559

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8550

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8560

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8551

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8561

8552

8562

COM=20*log10(max_signal/maxn_tot);

8553

COM=20*log10(max_signal/maxn_tot);

8563

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8554

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8564

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8555

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8565

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8556

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8566

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8557

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8567

8558

8568

pfctr=exp(-0.09054*delta_dB);% less loss

8559

pfctr=exp(-0.09054*delta_dB);% less loss

8569

mfctr=exp(0.09054*delta_dB); % more loss

8560

mfctr=exp(0.09054*delta_dB); % more loss

8570

8561

8571

%less loss

8562

%less loss

8572

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8563

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8573

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8564

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8574

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8565

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8575

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8566

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8576

plus_maxn_tot=norm(plus_maxn);

8567

plus_maxn_tot=norm(plus_maxn);

8577

8568

8578

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8569

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8579

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8570

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8580

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8571

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8581

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8572

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8582

minus_maxn_tot=norm(minus_maxn);

8573

minus_maxn_tot=norm(minus_maxn);

8583

8574

8584

% more loss

8575

% more loss

8585

COMp=20*log10(max_signal*pfctr/maxn_tot);

8576

COMp=20*log10(max_signal*pfctr/maxn_tot);

8586

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8577

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8587

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8578

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8588

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8579

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8589

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8580

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8590

% less loss

8581

% less loss

8591

COMm=20*log10(max_signal*mfctr/maxn_tot);

8582

COMm=20*log10(max_signal*mfctr/maxn_tot);

8592

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8583

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8593

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8584

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8594

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8585

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8595

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8586

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8596

8587

8597

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8588

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8598

8589

8599

8590

8600

if(COM<0)

8591

if(COM<0)

8601

return

8592

return

8602

end

8593

end

8603

8594

8604

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8595

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8605

8596

8606

% pie(COM_per_noise,labels)

8597

% pie(COM_per_noise,labels)

8607

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8598

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8608

% legend('show','Location','bestoutside')

8599

% legend('show','Location','bestoutside')

8609

nullbar= [ 0 0 0 ];

8600

nullbar= [ 0 0 0 ];

8610

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8601

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8611

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8602

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8612

hold on

8603

hold on

8613

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8604

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8614

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8605

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8615

8606

8616

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8607

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8617

% ax=gca;

8608

% ax=gca;

8618

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8609

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8619

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8610

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8620

grid on

8611

grid on

8621

legend(labels,'Location','north')

8612

legend(labels,'Location','north')

8622

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8613

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8623

ylabel('COM (dB)')

8614

ylabel('COM (dB)')

8624

hold off

8615

hold off

8625

8616

8626

8617

8627

8618

8628

8619

8629

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8620

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8630

num_files=length(chdata);

8621

num_files=length(chdata);

8631

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8622

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8632

for i=1:num_files

8623

for i=1:num_files

8633

if param.package_testcase_i==1 && i==1

8624

if param.package_testcase_i==1 && i==1

8634

if OP.TDR && i==1

8625

if OP.TDR && i==1

8635

S.Frequencies=chdata(i).faxis;

8626

S.Frequencies=chdata(i).faxis;

8636

S.Impedance=100;

8627

S.Impedance=100;

8637

if ~OP.SHOW_BRD

8628

if ~OP.SHOW_BRD

8638

Sfield='_orig';

8629

Sfield='_orig';

8639

else

8630

else

8640

Sfield='_raw';

8631

Sfield='_raw';

8641

end

8632

end

8642

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8633

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8643

if ~param.FLAG.S2P

8634

if ~param.FLAG.S2P

8644

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8635

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8645

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8636

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8646

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8637

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8647

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8638

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8648

else

8639

else

8649

S.NumPorts=1;

8640

S.NumPorts=1;

8650

end

8641

end

8651

if OP.TDR_W_TXPKG

8642

if OP.TDR_W_TXPKG

8652

if OP.ERL == 2

8643

if OP.ERL == 2

8653

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8644

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8654

end

8645

end

8655

R_diepad = param.R_diepad;

8646

R_diepad = param.R_diepad;

8656

% RX package length is assumed to be the same for all

8647

% RX package length is assumed to be the same for all

8657

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8648

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8658

% for Rx pkg

8649

% for Rx pkg

8659

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8650

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8660

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8651

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8661

combines4p( s11in, s12in, s21in, s22in, ...

8652

combines4p( s11in, s12in, s21in, s22in, ...

8662

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8653

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8663

% S=sparameters(S.Parameters,S.Frequencies,100);

8654

% S=sparameters(S.Parameters,S.Frequencies,100);

8664

S=SL(S,S.Frequencies,R_diepad(1)*2);

8655

S=SL(S,S.Frequencies,R_diepad(1)*2);

8665

chdata(i).TX_RL=S.Parameters(2,2,:);

8656

chdata(i).TX_RL=S.Parameters(2,2,:);

8666

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8657

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8667

end

8658

end

8668

8659

8669

% need to combine S wiht is page and channel

8660

% need to combine S wiht is page and channel

8670

if param.FLAG.S2P

8661

if param.FLAG.S2P

8671

port_sel=1;

8662

port_sel=1;

8672

else

8663

else

8673

port_sel=[1 2];

8664

port_sel=[1 2];

8674

if OP.AUTO_TFX

8665

if OP.AUTO_TFX

8675

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8666

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8676

pix=find(fir4del==max(fir4del),1);

8667

pix=find(fir4del==max(fir4del),1);

8677

param.tfx(2)=2*tu(pix);

8668

param.tfx(2)=2*tu(pix);

8678

end

8669

end

8679

end

8670

end

8680

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8671

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8681

for ipsl=1:length(port_sel) % do for both port if s4p

8672

for ipsl=1:length(port_sel) % do for both port if s4p

8682

for izt=1:length(param.Z_t) % do for all tdr impedances

8673

for izt=1:length(param.Z_t) % do for all tdr impedances

8683

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8674

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8684

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8675

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8685

% OP.interp_sparam_mag='trend_to_DC';

8676

% OP.interp_sparam_mag='trend_to_DC';

8686

OP.interp_sparam_mag='linear_trend_to_DC';

8677

OP.interp_sparam_mag='linear_trend_to_DC';

8687

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8678

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8688

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8679

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8689

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8680

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8690

if ipsl ==1

8681

if ipsl ==1

8691

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8682

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8692

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8683

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8693

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8684

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8694

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8685

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8695

else

8686

else

8696

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8687

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8697

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8688

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8698

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8689

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8699

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8690

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8700

end

8691

end

8701

if OP.PTDR && i==1

8692

if OP.PTDR && i==1

8702

if ipsl ==1

8693

if ipsl ==1

8703

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8694

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8704

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8695

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8705

else

8696

else

8706

if ~param.FLAG.S2P

8697

if ~param.FLAG.S2P

8707

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8698

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8708

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8699

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8709

else

8700

else

8710

chdata(i).TDR22(izt).ERL=[];

8701

chdata(i).TDR22(izt).ERL=[];

8711

chdata(i).TDR22(izt).ERLRMS=[];

8702

chdata(i).TDR22(izt).ERLRMS=[];

8712

end

8703

end

8713

end

8704

end

8714

else

8705

else

8715

chdata(i).TDR11(izt).ERL=[];

8706

chdata(i).TDR11(izt).ERL=[];

8716

chdata(i).TDR22(izt).ERL=[];

8707

chdata(i).TDR22(izt).ERL=[];

8717

chdata(i).TDR11(izt).ERLRMS=[];

8708

chdata(i).TDR11(izt).ERLRMS=[];

8718

chdata(i).TDR22(izt).ERLRMS=[];

8709

chdata(i).TDR22(izt).ERLRMS=[];

8719

end

8710

end

8720

end

8711

end

8721

end

8712

end

8722

end

8713

end

8723

8714

8724

end

8715

end

8725

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8716

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8726

h=figure(180);set(gcf,'Tag','COM');

8717

h=figure(180);set(gcf,'Tag','COM');

8727

if param.package_testcase_i==1 && i == 1

8718

if param.package_testcase_i==1 && i == 1

8728

if i==1

8719

if i==1

8729

htabgroup = uitabgroup(h);

8720

htabgroup = uitabgroup(h);

8730

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8721

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8731

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8722

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8732

hax1 = axes('Parent', htab1);

8723

hax1 = axes('Parent', htab1);

8733

hax3 = axes('Parent', htab3);

8724

hax3 = axes('Parent', htab3);

8734

if ~param.FLAG.S2P

8725

if ~param.FLAG.S2P

8735

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8726

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8736

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8727

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8737

hax2 = axes('Parent', htab2);

8728

hax2 = axes('Parent', htab2);

8738

hax4 = axes('Parent', htab4);

8729

hax4 = axes('Parent', htab4);

8739

end

8730

end

8740

end

8731

end

8741

set(h,'CurrentAxes',hax1)

8732

set(h,'CurrentAxes',hax1)

8742

hold on

8733

hold on

8743

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8734

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8744

hold off

8735

hold off

8745

legend (hax1, 'off');grid on;zoom xon;

8736

legend (hax1, 'off');grid on;zoom xon;

8746

set(legend (hax1, 'show'), 'interp', 'none');

8737

set(legend (hax1, 'show'), 'interp', 'none');

8747

8738

8748

if ~param.FLAG.S2P

8739

if ~param.FLAG.S2P

8749

set(h,'CurrentAxes',hax2)

8740

set(h,'CurrentAxes',hax2)

8750

hold on

8741

hold on

8751

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8742

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8752

hold off

8743

hold off

8753

legend (hax2, 'off');grid on;zoom xon;

8744

legend (hax2, 'off');grid on;zoom xon;

8754

set(legend (hax2, 'show'), 'interp', 'none');

8745

set(legend (hax2, 'show'), 'interp', 'none');

8755

end

8746

end

8756

8747

8757

set(h,'CurrentAxes',hax3)

8748

set(h,'CurrentAxes',hax3)

8758

hold on

8749

hold on

8759

if OP.PTDR

8750

if OP.PTDR

8760

for izt=1:length(param.Z_t)

8751

for izt=1:length(param.Z_t)

8761

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8752

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8762

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8753

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8763

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8754

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8764

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8755

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8765

end

8756

end

8766

end

8757

end

8767

hold off

8758

hold off

8768

legend (hax3, 'off');grid on;zoom xon;

8759

legend (hax3, 'off');grid on;zoom xon;

8769

set(legend (hax3, 'show'), 'interp', 'none');

8760

set(legend (hax3, 'show'), 'interp', 'none');

8770

if ~param.FLAG.S2P

8761

if ~param.FLAG.S2P

8771

set(h,'CurrentAxes',hax4)

8762

set(h,'CurrentAxes',hax4)

8772

hold on

8763

hold on

8773

if OP.PTDR

8764

if OP.PTDR

8774

for izt=1:length(param.Z_t)

8765

for izt=1:length(param.Z_t)

8775

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8766

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8776

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8767

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8777

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8768

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8778

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8769

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8779

end

8770

end

8780

end

8771

end

8781

hold off

8772

hold off

8782

legend (hax4, 'off');grid on;zoom xon;

8773

legend (hax4, 'off');grid on;zoom xon;

8783

set(legend (hax4, 'show'), 'interp', 'none');

8774

set(legend (hax4, 'show'), 'interp', 'none');

8784

end

8775

end

8785

end

8776

end

8786

end

8777

end

8787

if param.FLAG.S2P, return; end

8778

if param.FLAG.S2P, return; end

8788

end

8779

end

8789

function S =r_parrelell2(zref,f,rpad)

8780

function S =r_parrelell2(zref,f,rpad)

8790

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8781

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8791

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8782

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8792

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8783

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8793

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8784

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8794

% Sm=sparameters(S.Parameters,f,zref);

8785

% Sm=sparameters(S.Parameters,f,zref);

8795

8786

8796

8787

8797

8788

8798

8789

8799

8790

8800

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8791

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8801

8792

8802

%touchstone_file: .sNp touchstone file to read

8793

%touchstone_file: .sNp touchstone file to read

8803

%port_order: port reorder vector

8794

%port_order: port reorder vector

8804

%

8795

%

8805

%sch: sparameter matrix

8796

%sch: sparameter matrix

8806

%schFreqAxis: frequency axis

8797

%schFreqAxis: frequency axis

8807

8798

8808

[file_path,root_name,extension]=fileparts(touchstone_file);

8799

[file_path,root_name,extension]=fileparts(touchstone_file);

8809

fid=fopen(touchstone_file);

8800

fid=fopen(touchstone_file);

8810

8801

8811

%fetch number of ports from extension

8802

%fetch number of ports from extension

8812

num_ports=str2num(char(regexp(extension,'\d*','match')));

8803

num_ports=str2num(char(regexp(extension,'\d*','match')));

8813

8804

8814

%Get option line

8805

%Get option line

8815

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8806

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8816

optcell=textscan(optstr{1}{1},'%s');

8807

optcell=textscan(optstr{1}{1},'%s');

8817

optcell=optcell{1};

8808

optcell=optcell{1};

8818

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8809

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8819

%Some touchstone files need this. can't remember why now. maybe lines

8810

%Some touchstone files need this. can't remember why now. maybe lines

8820

%with whitespace but not empty but not commented

8811

%with whitespace but not empty but not commented

8821

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8812

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8822

optcell=textscan(optstr{1}{1},'%s');

8813

optcell=textscan(optstr{1}{1},'%s');

8823

optcell=optcell{1};

8814

optcell=optcell{1};

8824

end

8815

end

8825

8816

8826

%read the entire file

8817

%read the entire file

8827

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8818

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8828

raw_column_data=raw_read_data{1};

8819

raw_column_data=raw_read_data{1};

8829

fclose(fid);

8820

fclose(fid);

8830

8821

8831

%number of columns for 2D matrix

8822

%number of columns for 2D matrix

8832

columns=num_ports*num_ports*2+1;

8823

columns=num_ports*num_ports*2+1;

8833

8824

8834

%find the frequency lines by searching for the right number of NaN

8825

%find the frequency lines by searching for the right number of NaN

8835

a=sum(isnan(raw_column_data),2);

8826

a=sum(isnan(raw_column_data),2);

8836

if num_ports==3

8827

if num_ports==3

8837

b=find(a==2);

8828

b=find(a==2);

8838

elseif num_ports==1

8829

elseif num_ports==1

8839

b=find(a==6);

8830

b=find(a==6);

8840

else

8831

else

8841

b=find(a==0);

8832

b=find(a==0);

8842

end

8833

end

8843

8834

8844

num_freq=length(b);

8835

num_freq=length(b);

8845

8836

8846

%toss out the NaN and reshape into a 2D matrix

8837

%toss out the NaN and reshape into a 2D matrix

8847

raw_input = raw_column_data.';

8838

raw_input = raw_column_data.';

8848

raw_input = raw_input(~isnan(raw_input));

8839

raw_input = raw_input(~isnan(raw_input));

8849

raw_input = reshape(raw_input,columns,num_freq).';

8840

raw_input = reshape(raw_input,columns,num_freq).';

8850

8841

8851

%get the frequency mult

8842

%get the frequency mult

8852

frequency_mult_text=optcell{2};

8843

frequency_mult_text=optcell{2};

8853

if(strcmpi(frequency_mult_text,'hz'))

8844

if(strcmpi(frequency_mult_text,'hz'))

8854

frequency_mult=1;

8845

frequency_mult=1;

8855

elseif(strcmpi(frequency_mult_text,'khz'))

8846

elseif(strcmpi(frequency_mult_text,'khz'))

8856

frequency_mult=1e3;

8847

frequency_mult=1e3;

8857

elseif(strcmpi(frequency_mult_text,'mhz'))

8848

elseif(strcmpi(frequency_mult_text,'mhz'))

8858

frequency_mult=1e6;

8849

frequency_mult=1e6;

8859

elseif(strcmpi(frequency_mult_text,'ghz'))

8850

elseif(strcmpi(frequency_mult_text,'ghz'))

8860

frequency_mult=1e9;

8851

frequency_mult=1e9;

8861

else

8852

else

8862

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8853

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8863

end

8854

end

8864

8855

8865

%get the RI/MA/DB format

8856

%get the RI/MA/DB format

8866

format=optcell{4};

8857

format=optcell{4};

8867

%get Z0

8858

%get Z0

8868

port_impedance=str2double(optcell(6:end))';

8859

port_impedance=str2double(optcell(6:end))';

8869

8860

8870

8861

8871

%grab frequency

8862

%grab frequency

8872

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8863

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8873

Spar.F=raw_input(:,1);

8864

Spar.F=raw_input(:,1);

8874

Spar.F=transpose(Spar.F(:));

8865

Spar.F=transpose(Spar.F(:));

8875

8866

8876

8867

8877

%transform data to real imaginary

8868

%transform data to real imaginary

8878

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8869

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8879

if(strcmpi(format,'ri'))

8870

if(strcmpi(format,'ri'))

8880

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8871

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8881

elseif(strcmpi(format,'ma'))

8872

elseif(strcmpi(format,'ma'))

8882

mag_data=raw_input(:,2:2:end);

8873

mag_data=raw_input(:,2:2:end);

8883

rad_data=raw_input(:,3:2:end)*pi/180;

8874

rad_data=raw_input(:,3:2:end)*pi/180;

8884

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8875

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8885

elseif(strcmpi(format,'db'))

8876

elseif(strcmpi(format,'db'))

8886

mag_data=10.^(raw_input(:,2:2:end)/20);

8877

mag_data=10.^(raw_input(:,2:2:end)/20);

8887

rad_data=raw_input(:,3:2:end)*pi/180;

8878

rad_data=raw_input(:,3:2:end)*pi/180;

8888

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8879

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8889

else

8880

else

8890

error('Format %s is not supported. Use RI MA or DB',format);

8881

error('Format %s is not supported. Use RI MA or DB',format);

8891

end

8882

end

8892

8883

8893

8884

8894

8885

8895

%transform to 3D

8886

%transform to 3D

8896

%allow for upper/lower matrix specification for touchstone 2.0 support

8887

%allow for upper/lower matrix specification for touchstone 2.0 support

8897

matrix_format=0;

8888

matrix_format=0;

8898

if(matrix_format==0)

8889

if(matrix_format==0)

8899

%full

8890

%full

8900

for j=1:num_ports

8891

for j=1:num_ports

8901

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8892

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8902

end

8893

end

8903

elseif(matrix_format==1)

8894

elseif(matrix_format==1)

8904

%upper

8895

%upper

8905

used_ports=0;

8896

used_ports=0;

8906

for j=1:num_ports

8897

for j=1:num_ports

8907

stated_ports=num_ports-j+1;

8898

stated_ports=num_ports-j+1;

8908

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8899

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8909

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8900

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8910

used_ports=used_ports+stated_ports;

8901

used_ports=used_ports+stated_ports;

8911

end

8902

end

8912

elseif(matrix_format==2)

8903

elseif(matrix_format==2)

8913

%lower

8904

%lower

8914

used_ports=0;

8905

used_ports=0;

8915

for j=1:num_ports

8906

for j=1:num_ports

8916

stated_ports=j;

8907

stated_ports=j;

8917

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8908

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8918

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8909

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8919

used_ports=used_ports+stated_ports;

8910

used_ports=used_ports+stated_ports;

8920

end

8911

end

8921

else

8912

else

8922

error('Matrix format is not supported. Use Full, Lower, or Upper');

8913

error('Matrix format is not supported. Use Full, Lower, or Upper');

8923

end

8914

end

8924

8915

8925

8916

8926

%check for swapping the 2 port matrix (required on 1.x spec)

8917

%check for swapping the 2 port matrix (required on 1.x spec)

8927

two_port_swap=1;

8918

two_port_swap=1;

8928

if(num_ports==2 && two_port_swap==1)

8919

if(num_ports==2 && two_port_swap==1)

8929

temp=pre_out.sp(1,2,:);

8920

temp=pre_out.sp(1,2,:);

8930

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8921

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8931

pre_out.sp(2,1,:)=temp;

8922

pre_out.sp(2,1,:)=temp;

8932

end

8923

end

8933

8924

8934

Spar.S=pre_out.sp;

8925

Spar.S=pre_out.sp;

8935

Spar.Z0=transpose(port_impedance(:));

8926

Spar.Z0=transpose(port_impedance(:));

8936

8927

8937

if length(Spar.Z0)>1

8928

if length(Spar.Z0)>1

8938

error('Each port must have the same reference impedance');

8929

error('Each port must have the same reference impedance');

8939

end

8930

end

8940

if ~isequal(Spar.Z0,50)

8931

if ~isequal(Spar.Z0,50)

8941

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8932

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8942

%Renormalize to 50 ohms

8933

%Renormalize to 50 ohms

8943

rho=(50-Spar.Z0)/(50+Spar.Z0);

8934

rho=(50-Spar.Z0)/(50+Spar.Z0);

8944

p=num_ports;

8935

p=num_ports;

8945

s_old=Spar.S;

8936

s_old=Spar.S;

8946

for k=1:num_freq

8937

for k=1:num_freq

8947

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8938

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8948

end

8939

end

8949

end

8940

end

8950

8941

8951

%These operations sync up with COM style Spar matrix

8942

%These operations sync up with COM style Spar matrix

8952

%1: put frequency as first dimension

8943

%1: put frequency as first dimension

8953

sch=shiftdim(Spar.S,2);

8944

sch=shiftdim(Spar.S,2);

8954

%2: reorder ports according to "ports" input

8945

%2: reorder ports according to "ports" input

8955

sch=sch(:,port_order,port_order);

8946

sch=sch(:,port_order,port_order);

8956

schFreqAxis=Spar.F;

8947

schFreqAxis=Spar.F;

8957

function [chdata, param] = read_PR_files(param, OP, chdata)

8948

function [chdata, param] = read_PR_files(param, OP, chdata)

8958

%% Read in pulse response

8949

%% Read in pulse response

8959

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8950

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8960

num_files=length(chdata);

8951

num_files=length(chdata);

8961

M=param.samples_per_ui;

8952

M=param.samples_per_ui;

8962

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8953

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8963

for i=1:num_files

8954

for i=1:num_files

8964

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8955

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8965

progress = i/num_files;

8956

progress = i/num_files;

8966

if OP.DISPLAY_WINDOW

8957

if OP.DISPLAY_WINDOW

8967

[~,a]=fileparts(chdata(i).filename);

8958

[~,a]=fileparts(chdata(i).filename);

8968

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8959

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8969

else

8960

else

8970

fprintf('%i ',i);

8961

fprintf('%i ',i);

8971

end

8962

end

8972

switch chdata(i).ext

8963

switch chdata(i).ext

8973

case '.csv'

8964

case '.csv'

8974

vt=load(chdata(i).filename);

8965

vt=load(chdata(i).filename);

8975

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8966

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8976

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8967

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8977

dt=vt(2,1)-vt(1,1);

8968

dt=vt(2,1)-vt(1,1);

8978

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8969

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8979

8970

8980

8971

8981

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8972

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8982

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8973

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8983

Vf=step_response(end);

8974

Vf=step_response(end);

8984

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8975

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8985

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8976

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8986

8977

8987

end

8978

end

8988

end

8979

end

8989

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8980

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8990

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8981

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8991

[filepath,name,ext] = fileparts(paramFile);

8982

[filepath,name,ext] = fileparts(paramFile);

8992

if ~isempty(filepath)

8983

if ~isempty(filepath)

8993

filepath=[filepath '\'];

8984

filepath=[filepath '\'];

8994

end

8985

end

8995

matcongfile=[filepath name '.mat'];

8986

matcongfile=[filepath name '.mat'];

8996

try

8987

try

8997

switch upper(ext)

8988

switch upper(ext)

8998

case upper('.mat')

8989

case upper('.mat')

8999

load(matcongfile)

8990

load(matcongfile)

9000

case upper('.csv')

8991

case upper('.csv')

9001

[na1, na2, parameter] = xlsread(paramFile);

8992

[na1, na2, parameter] = xlsread(paramFile);

9002

otherwise

8993

otherwise

9003

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8994

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

9004

end

8995

end

9005

8996

9006

catch ME %#ok<NASGU>

8997

catch ME %#ok<NASGU>

9007

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8998

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

9008

switch upper(ext)

8999

switch upper(ext)

9009

case upper('.mat')

9000

case upper('.mat')

9010

load(matcongfile)

9001

load(matcongfile)

9011

case upper('.csv')

9002

case upper('.csv')

9012

[na1, na2, parameter] = xlsread(paramFile);

9003

[na1, na2, parameter] = xlsread(paramFile);

9013

otherwise

9004

otherwise

9014

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

9005

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

9015

end

9006

end

9016

end

9007

end

9017

9008

9018

%% New section to parse .START package data

9009

%% New section to parse .START package data

9019

first_column_data = parameter(:,1);

9010

first_column_data = parameter(:,1);

9020

start_data_rows = find(strcmp(first_column_data,'.START'));

9011

start_data_rows = find(strcmp(first_column_data,'.START'));

9021

if ~isempty(start_data_rows)

9012

if ~isempty(start_data_rows)

9022

end_data_rows = find(strcmp(first_column_data,'.END'));

9013

end_data_rows = find(strcmp(first_column_data,'.END'));

9023

if length(start_data_rows) ~= length(end_data_rows)

9014

if length(start_data_rows) ~= length(end_data_rows)

9024

error('Number of .START and .END must be the same');

9015

error('Number of .START and .END must be the same');

9025

end

9016

end

9026

first_start_row = start_data_rows(1);

9017

first_start_row = start_data_rows(1);

9027

special_parameter = parameter;

9018

special_parameter = parameter;

9028

parameter = parameter(1:first_start_row-1,:);

9019

parameter = parameter(1:first_start_row-1,:);

9029

for j=1:length(start_data_rows)

9020

for j=1:length(start_data_rows)

9030

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

9021

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

9031

pkg_name = special_parameter{start_data_rows(j),2};

9022

pkg_name = special_parameter{start_data_rows(j),2};

9032

9023

9033

%Read all the parameters that make up a package

9024

%Read all the parameters that make up a package

9034

PKG_param = read_package_parameters(this_block);

9025

PKG_param = read_package_parameters(this_block);

9035

9026

9036

%save the data in a field revealed by pkg_name

9027

%save the data in a field revealed by pkg_name

9037

param.PKG.(pkg_name) = PKG_param;

9028

param.PKG.(pkg_name) = PKG_param;

9038

9029

9039

9030

9040

end

9031

end

9041

end

9032

end

9042

%Allow specification of TX and RX package section through PKG_NAME keyword

9033

%Allow specification of TX and RX package section through PKG_NAME keyword

9043

%the values must match package blocks specified in .START sections

9034

%the values must match package blocks specified in .START sections

9044

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

9035

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

9045

if isnan(param.PKG_NAME)

9036

if isnan(param.PKG_NAME)

9046

param.PKG_NAME = '';

9037

param.PKG_NAME = '';

9047

end

9038

end

9048

if isempty(param.PKG_NAME)

9039

if isempty(param.PKG_NAME)

9049

param.PKG_NAME = {};

9040

param.PKG_NAME = {};

9050

else

9041

else

9051

param.PKG_NAME = strsplit(param.PKG_NAME);

9042

param.PKG_NAME = strsplit(param.PKG_NAME);

9052

end

9043

end

9053

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

9044

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

9054

error('PKG_NAME can only be used if .START blocks for package parameters are used');

9045

error('PKG_NAME can only be used if .START blocks for package parameters are used');

9055

end

9046

end

9056

for j=1:length(param.PKG_NAME)

9047

for j=1:length(param.PKG_NAME)

9057

if ~isfield(param.PKG,param.PKG_NAME{j})

9048

if ~isfield(param.PKG,param.PKG_NAME{j})

9058

error('Package Block "%s" not found',param.PKG_NAME{j});

9049

error('Package Block "%s" not found',param.PKG_NAME{j});

9059

end

9050

end

9060

end

9051

end

9061

9052

9062

%%

9053

%%

9063

% just need to define so we can pass

9054

% just need to define so we can pass

9064

param.c=[.4e-12 .4e-12];

9055

param.c=[.4e-12 .4e-12];

9065

param.alen=[ 20 30 550 ];

9056

param.alen=[ 20 30 550 ];

9066

param.az=[100 120 100];

9057

param.az=[100 120 100];

9067

9058

9068

% make control for package/channel reflection control

9059

% make control for package/channel reflection control

9069

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

9060

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

9070

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

9061

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

9071

9062

9072

9063

9073

% make compatible with presentation of kappa

9064

% make compatible with presentation of kappa

9074

9065

9075

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

9066

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

9076

9067

9077

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

9068

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

9078

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

9069

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

9079

9070

9080

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

9071

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

9081

param.f2 = xls_parameter(parameter, 'f_2', true, param.fb/1e9 )*1e9; % frequency in GHz for intergration compuation of ICN or FOM_Ild in GHz

9072

param.f2 = xls_parameter(parameter, 'f_2', true, param.fb/1e9 )*1e9; % frequency in GHz for intergration compuation of ICN or FOM_Ild in GHz

9082

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

9073

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

9083

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

9074

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

9084

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

9075

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

9085

param.tx_ffe_c0_min = xls_parameter(parameter, 'c(0)', false); % TX equalizer cursor minimum value (actual value is calculated as 1-sum(abs(tap)), Grid seat ingored for when C(0) is below this value

9076

param.tx_ffe_c0_min = xls_parameter(parameter, 'c(0)', false); % TX equalizer cursor minimum value (actual value is calculated as 1-sum(abs(tap)), Grid seat ingored for when C(0) is below this value

9086

9077

9087

if OP.dynamic_txffe

9078

if OP.dynamic_txffe

9088

found_pre=1;

9079

found_pre=1;

9089

pre_count=1;

9080

pre_count=1;

9090

while found_pre

9081

while found_pre

9091

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

9082

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

9092

if found_pre

9083

if found_pre

9093

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

9084

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

9094

param.(field_name)=p;

9085

param.(field_name)=p;

9095

pre_count=pre_count+1;

9086

pre_count=pre_count+1;

9096

end

9087

end

9097

end

9088

end

9098

found_post=1;

9089

found_post=1;

9099

post_count=1;

9090

post_count=1;

9100

while found_post

9091

while found_post

9101

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

9092

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

9102

if found_post

9093

if found_post

9103

field_name=sprintf('tx_ffe_cp%d_values',post_count);

9094

field_name=sprintf('tx_ffe_cp%d_values',post_count);

9104

param.(field_name)=p;

9095

param.(field_name)=p;

9105

post_count=post_count+1;

9096

post_count=post_count+1;

9106

end

9097

end

9107

end

9098

end

9108

else

9099

else

9109

param.tx_ffe_cm4_values = xls_parameter(parameter, 'c(-4)', true,0); % TX equalizer pre cursor tap -4 individual settings or range. If not present ignored

9100

param.tx_ffe_cm4_values = xls_parameter(parameter, 'c(-4)', true,0); % TX equalizer pre cursor tap -4 individual settings or range. If not present ignored

9110

param.tx_ffe_cm3_values = xls_parameter(parameter, 'c(-3)', true,0); % TX equalizer pre cursor tap -3 individual settings or range. If not present ignored

9101

param.tx_ffe_cm3_values = xls_parameter(parameter, 'c(-3)', true,0); % TX equalizer pre cursor tap -3 individual settings or range. If not present ignored

9111

param.tx_ffe_cm2_values = xls_parameter(parameter, 'c(-2)', true,0); % TX equalizer pre cursor tap -2 individual settings or range. If not present ignored

9102

param.tx_ffe_cm2_values = xls_parameter(parameter, 'c(-2)', true,0); % TX equalizer pre cursor tap -2 individual settings or range. If not present ignored

9112

param.tx_ffe_cm1_values = xls_parameter(parameter, 'c(-1)', true,0); % TX equalizer pre cursor tap -1 individual settings or range. If not present ignored

9103

param.tx_ffe_cm1_values = xls_parameter(parameter, 'c(-1)', true,0); % TX equalizer pre cursor tap -1 individual settings or range. If not present ignored

9113

param.tx_ffe_cp1_values = xls_parameter(parameter, 'c(1)', true,0); % TX equalizer post cursor tap 1 individual settings or range. If not present ignored

9104

param.tx_ffe_cp1_values = xls_parameter(parameter, 'c(1)', true,0); % TX equalizer post cursor tap 1 individual settings or range. If not present ignored

9114

param.tx_ffe_cp2_values = xls_parameter(parameter, 'c(2)', true,0); % TX equalizer post cursor tap 2 individual settings or range. If not present ignored

9105

param.tx_ffe_cp2_values = xls_parameter(parameter, 'c(2)', true,0); % TX equalizer post cursor tap 2 individual settings or range. If not present ignored

9115

param.tx_ffe_cp3_values = xls_parameter(parameter, 'c(3)', true,0); % TX equalizer post cursor tap 3 individual settings or range. If not present ignored

9106

param.tx_ffe_cp3_values = xls_parameter(parameter, 'c(3)', true,0); % TX equalizer post cursor tap 3 individual settings or range. If not present ignored

9116

end

9107

end

9117

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

9108

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

9118

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

9109

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

9119

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

9110

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

9120

param.N_bx = xls_parameter(parameter, 'N_bx', true, param.ndfe ); % Used for ERL to Compensate for a number of Ui assoicated with the DFE

9111

param.N_bx = xls_parameter(parameter, 'N_bx', true, param.ndfe ); % Used for ERL to Compensate for a number of Ui assoicated with the DFE

9121

% support for floating taps

9112

% support for floating taps

9122

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

9113

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

9123

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

9114

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

9124

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

9115

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

9125

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

9116

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

9126

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

9117

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

9127

if param.N_bg == 0, param.N_bmax=param.ndfe; end

9118

if param.N_bg == 0, param.N_bmax=param.ndfe; end

9128

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

9119

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

9129

9120

9130

% support for tail tap power limitations

9121

% support for tail tap power limitations

9131

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

9122

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

9132

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

9123

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

9133

%

9124

%

9134

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

9125

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

9135

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

9126

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

9136

param.RxFFE_cmx=param.ffe_pre_tap_len;

9127

param.RxFFE_cmx=param.ffe_pre_tap_len;

9137

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

9128

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

9138

param.RxFFE_cpx=param.ffe_post_tap_len;

9129

param.RxFFE_cpx=param.ffe_post_tap_len;

9139

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

9130

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

9140

param.RxFFE_stepz=param.ffe_tap_step_size;

9131

param.RxFFE_stepz=param.ffe_tap_step_size;

9141

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

9132

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

9142

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

9133

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

9143

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

9134

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

9144

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

9135

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

9145

param.ffe_backoff=xls_parameter(parameter, 'ffe_backoff', true,0); % see if better zero foreced solution is better by backing off the number specified FFE taps one at at time

9136

param.ffe_backoff=xls_parameter(parameter, 'ffe_backoff', true,0); % see if better zero foreced solution is better by backing off the number specified FFE taps one at at time

9146

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

9137

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

9147

OP.RxFFE= true;

9138

OP.RxFFE= true;

9148

else

9139

else

9149

OP.RxFFE=false;

9140

OP.RxFFE=false;

9150

end

9141

end

9151

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

9142

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

9152

9143

9153

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

9144

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

9154

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

9145

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

9155

param.f_HP_Z = 1e9*xls_parameter(parameter, 'f_HP_Z', true, []); % CFT zero fz1 is in GHz. Normally a list for 120e. Not normally use elsewise

9146

param.f_HP_Z = 1e9*xls_parameter(parameter, 'f_HP_Z', true, []); % CFT zero fz1 is in GHz. Normally a list for 120e. Not normally use elsewise

9156

param.f_HP_P = 1e9*xls_parameter(parameter, 'f_HP_P', true, []); % CFT pole fp2 is in GHz. Normally a list for 120e. Not normally use elsewise

9147

param.f_HP_P = 1e9*xls_parameter(parameter, 'f_HP_P', true, []); % CFT pole fp2 is in GHz. Normally a list for 120e. Not normally use elsewise

9157

9148

9158

9149

9159

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

9150

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

9160

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

9151

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

9161

param.Min_VEO_Test= xls_parameter(parameter, 'EH_min_test', true,0); % Older syntax. Used when PMD_type is C2M. This allow EH to go below EH_min. If set to zero it is ignored (same as Min_VEO_test)

9152

param.Min_VEO_Test= xls_parameter(parameter, 'EH_min_test', true,0); % Older syntax. Used when PMD_type is C2M. This allow EH to go below EH_min. If set to zero it is ignored (same as Min_VEO_test)

9162

param.Min_VEO_Test= xls_parameter(parameter, 'Min_VEO_Test', true,param.Min_VEO_Test); % used when PMD_type is C2M. This allow EH to go blow EH_min. If set to Zero it is ignored

9153

param.Min_VEO_Test= xls_parameter(parameter, 'Min_VEO_Test', true,param.Min_VEO_Test); % used when PMD_type is C2M. This allow EH to go blow EH_min. If set to Zero it is ignored

9163

9154

9164

param.CTLE_type= xls_parameter(parameter, 'CTLE_type', false,'CL93'); % Sets the CTLE type default is poles and zeros (i.e. not a list of poles as in 120e)

9155

param.CTLE_type= xls_parameter(parameter, 'CTLE_type', false,'CL93'); % Sets the CTLE type default is poles and zeros (i.e. not a list of poles as in 120e)

9165

if ~isempty(param.g_DC_HP_values) ; param.CTLE_type='CL120d';end % overrides CL93 if g_DC_HP_values are a spreadsheet entry. Mostly used when baud rare is >= 50Gbps

9156

if ~isempty(param.g_DC_HP_values) ; param.CTLE_type='CL120d';end % overrides CL93 if g_DC_HP_values are a spreadsheet entry. Mostly used when baud rare is >= 50Gbps

9166

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

9157

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

9167

% always read in main ctle values. They would be interpreted different baseed

9158

% always read in main ctle values. They would be interpreted different baseed

9168

% on the clause they apply because of different CTF equations

9159

% on the clause they apply because of different CTF equations

9169

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

9160

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

9170

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9161

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9171

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9162

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9172

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9163

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9173

% the contex of the poles an zeros are determined by the clause

9164

% the contex of the poles an zeros are determined by the clause

9174

switch param.CTLE_type

9165

switch param.CTLE_type

9175

case 'CL93'

9166

case 'CL93'

9176

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % Continuous time filter DC gain settings (G_DC) or range as specified in Annex 93A

9167

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % Continuous time filter DC gain settings (G_DC) or range as specified in Annex 93A

9177

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9168

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9178

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9169

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9179

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9170

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9180

case 'CL120d'

9171

case 'CL120d'

9181

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

9172

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

9182

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

9173

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

9183

case 'CL120e'

9174

case 'CL120e'

9184

% re adjust to get TD_CTLE to work with C:120e equation without

9175

% re adjust to get TD_CTLE to work with C:120e equation without

9185

% changing TD_CTLE code

9176

% changing TD_CTLE code

9186

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

9177

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

9187

end

9178

end

9188

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

9179

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

9189

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

9180

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

9190

param.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9181

param.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9191

param.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9182

param.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9192

param.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9183

param.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9193

param.a_icn_fext = xls_parameter(parameter, 'A_ft', true, param.a_fext); % FEXT aggressor amplitude for ICN. Defaults to A_fe if not specified

9184

param.a_icn_fext = xls_parameter(parameter, 'A_ft', true, param.a_fext); % FEXT aggressor amplitude for ICN. Defaults to A_fe if not specified

9194

param.a_icn_next = xls_parameter(parameter, 'A_nt', true, param.a_next );% NEXT aggressor amplitude for ICN. Defaults to A_ne if not specified

9185

param.a_icn_next = xls_parameter(parameter, 'A_nt', true, param.a_next );% NEXT aggressor amplitude for ICN. Defaults to A_ne if not specified

9195

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

9186

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

9196

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

9187

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

9197

param.DER_CDR = xls_parameter(parameter, 'DER_CDR',true,1e-2); % min DER required for a CDR

9188

param.DER_CDR = xls_parameter(parameter, 'DER_CDR',true,1e-2); % min DER required for a CDR

9198

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

9189

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

9199

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

9190

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

9200

param.VEC_pass_threshold = xls_parameter(parameter, 'VEC Pass threshold',false,0);% the pass fail threshold for VEC in dB only used when PMD_type is C2M

9191

param.VEC_pass_threshold = xls_parameter(parameter, 'VEC Pass threshold',false,0);% the pass fail threshold for VEC in dB only used when PMD_type is C2M

9201

9192

9202

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

9193

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

9203

param.A_DD = xls_parameter(parameter, 'A_DD'); % Normalized peak dual-Dirac noise, this is half of the total bound uncorrelated jitter (BUJ) in UI

9194

param.A_DD = xls_parameter(parameter, 'A_DD'); % Normalized peak dual-Dirac noise, this is half of the total bound uncorrelated jitter (BUJ) in UI

9204

param.eta_0 = xls_parameter(parameter, 'eta_0'); % One-sided noise spectral density (V^2/GHz).Input refered noise at TP5. Input referred noise at TP5

9195

param.eta_0 = xls_parameter(parameter, 'eta_0'); % One-sided noise spectral density (V^2/GHz).Input refered noise at TP5. Input referred noise at TP5

9205

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

9196

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

9206

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

9197

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

9207

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

9198

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

9208

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

9199

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

9209

param.ts_anchor = xls_parameter(parameter, 'ts_anchor', true, 0); %choice of sampling routine. 0=MM, 1=Peak, 2=max DV (max cursor minus precursor)

9200

param.ts_anchor = xls_parameter(parameter, 'ts_anchor', true, 0); %choice of sampling routine. 0=MM, 1=Peak, 2=max DV (max cursor minus precursor)

9210

% This will keep bmax length 0 if Nb=0

9201

% This will keep bmax length 0 if Nb=0

9211

9202

9212

%AJG021820

9203

%AJG021820

9213

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

9204

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

9214

if isempty(param.bmax)

9205

if isempty(param.bmax)

9215

param.bmin=param.bmax;

9206

param.bmin=param.bmax;

9216

else

9207

else

9217

param.bmin(1:param.ndfe) =xls_parameter(parameter, 'b_min(1)', true,-param.bmax(1) ); % DFE negative magnitude limit. If not specified it defaults to -bmax.

9208

param.bmin(1:param.ndfe) =xls_parameter(parameter, 'b_min(1)', true,-param.bmax(1) ); % DFE negative magnitude limit. If not specified it defaults to -bmax.

9218

9209

9219

end

9210

end

9220

if param.ndfe >= 2

9211

if param.ndfe >= 2

9221

param.bmax(2:param.ndfe) = xls_parameter(parameter, 'b_max(2..N_b)', true, .2); % DFE magnitude limit, second coefficient and on (ignored if Nb<2). Can be a regualar expression

9212

param.bmax(2:param.ndfe) = xls_parameter(parameter, 'b_max(2..N_b)', true, .2); % DFE magnitude limit, second coefficient and on (ignored if Nb<2). Can be a regualar expression

9222

param.bmin(2:param.ndfe) = xls_parameter(parameter, 'b_min(2..N_b)', true, -1*param.bmax(2:param.ndfe) ); % DFE negative magnitude limit, if not specified it defaults to -b_max(2..N_b)

9213

param.bmin(2:param.ndfe) = xls_parameter(parameter, 'b_min(2..N_b)', true, -1*param.bmax(2:param.ndfe) ); % DFE negative magnitude limit, if not specified it defaults to -b_max(2..N_b)

9223

end

9214

end

9224

9215

9225

param.gqual=xls_parameter(parameter, 'G_Qual', true,[]);% G_Qual are the dB ranges of g_DC g DC )which correspond tog_DC_HP (g DC2)

9216

param.gqual=xls_parameter(parameter, 'G_Qual', true,[]);% G_Qual are the dB ranges of g_DC g DC )which correspond tog_DC_HP (g DC2)

9226

param.g2qual=xls_parameter(parameter, 'G2_Qual', true,[]); % G2_Qual limit values of g_DC_HP (g DC2 ) which corresponds to ranges of g_DC g DC specified with G_QUAL

9217

param.g2qual=xls_parameter(parameter, 'G2_Qual', true,[]); % G2_Qual limit values of g_DC_HP (g DC2 ) which corresponds to ranges of g_DC g DC specified with G_QUAL

9227

%verify gqual and gqual2 input

9218

%verify gqual and gqual2 input

9228

if ~isempty(param.gqual) || ~isempty(param.g2qual)

9219

if ~isempty(param.gqual) || ~isempty(param.g2qual)

9229

if size(param.gqual,1)~=length(param.g2qual)

9220

if size(param.gqual,1)~=length(param.g2qual)

9230

error('gqual and g2qual size mismatch');

9221

error('gqual and g2qual size mismatch');

9231

end

9222

end

9232

if size(param.gqual,2)~=2

9223

if size(param.gqual,2)~=2

9233

error('gqual must be Nx2 matrix');

9224

error('gqual must be Nx2 matrix');

9234

end

9225

end

9235

end

9226

end

9236

9227

9237

9228

9238

% eval if string for all three - can use different for TX and RX

9229

% eval if string for all three - can use different for TX and RX

9239

param.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9230

param.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9240

param.C_diepad = xls_parameter(parameter, 'C_d', true)*1e-9; % C_d in nF (single sided)

9231

param.C_diepad = xls_parameter(parameter, 'C_d', true)*1e-9; % C_d in nF (single sided)

9241

% [ahealey] Read values for optional compensating L and "bump" C

9232

% [ahealey] Read values for optional compensating L and "bump" C

9242

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

9233

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

9243

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

9234

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

9244

% [ahealey] End of modifications.

9235

% [ahealey] End of modifications.

9245

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

9236

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

9246

param.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9237

param.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9247

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

9238

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

9248

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

9239

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

9249

9240

9250

9241

9251

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

9242

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

9252

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9243

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9253

[ncases, mele]=size(param.z_p_tx_cases);

9244

[ncases, mele]=size(param.z_p_tx_cases);

9254

if mele ==2

9245

if mele ==2

9255

param.flex=2;

9246

param.flex=2;

9256

elseif mele==4

9247

elseif mele==4

9257

param.flex=4;

9248

param.flex=4;

9258

elseif mele==1

9249

elseif mele==1

9259

param.flex=1;

9250

param.flex=1;

9260

else

9251

else

9261

error(sprintf('config file syntax error'))

9252

error(sprintf('config file syntax error'))

9262

end

9253

end

9263

9254

9264

% board parameters

9255

% board parameters

9265

param.C_0 = xls_parameter(parameter, 'C_0', true,0)*1e-9; % If Include PCB is set to 1, near device single ended capacitance C0 in nF is added

9256

param.C_0 = xls_parameter(parameter, 'C_0', true,0)*1e-9; % If Include PCB is set to 1, near device single ended capacitance C0 in nF is added

9266

param.C_1 = xls_parameter(parameter, 'C_1', true,0)*1e-9; % if Include PCB is set to 1, connector side single ended capacitance C1 in nF is added

9257

param.C_1 = xls_parameter(parameter, 'C_1', true,0)*1e-9; % if Include PCB is set to 1, connector side single ended capacitance C1 in nF is added

9267

%

9258

%

9268

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9259

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9269

[ncases1, mele1]=size(param.z_p_next_cases);

9260

[ncases1, mele1]=size(param.z_p_next_cases);

9270

if ncases ~= ncases1 || mele ~= mele1

9261

if ncases ~= ncases1 || mele ~= mele1

9271

error('All TX, NEXT, FEXT, Rx cases must agree');

9262

error('All TX, NEXT, FEXT, Rx cases must agree');

9272

else

9263

else

9273

end

9264

end

9274

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9265

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9275

[ncases1, mele1]=size(param.z_p_fext_cases);

9266

[ncases1, mele1]=size(param.z_p_fext_cases);

9276

if ncases ~= ncases1 || mele ~= mele1

9267

if ncases ~= ncases1 || mele ~= mele1

9277

error('All TX, NEXT, FEXT, Rx cases must agree');

9268

error('All TX, NEXT, FEXT, Rx cases must agree');

9278

else

9269

else

9279

end

9270

end

9280

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9271

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9281

[ncases1, mele1]=size(param.z_p_rx_cases);

9272

[ncases1, mele1]=size(param.z_p_rx_cases);

9282

if ncases ~= ncases1 || mele ~= mele1

9273

if ncases ~= ncases1 || mele ~= mele1

9283

error('All TX, NEXT, FEXT, Rx cases must agree');

9274

error('All TX, NEXT, FEXT, Rx cases must agree');

9284

else

9275

else

9285

end

9276

end

9286

% Table 93A-3 parameters

9277

% Table 93A-3 parameters

9287

param.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9278

param.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9288

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9279

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9289

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9280

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9290

[ ncases1, mele1]=size(param.pkg_Z_c);%

9281

[ ncases1, mele1]=size(param.pkg_Z_c);%

9291

if mele ~= mele1

9282

if mele ~= mele1

9292

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9283

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9293

else

9284

else

9294

end

9285

end

9295

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9286

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9296

for ii=1:ncases

9287

for ii=1:ncases

9297

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9288

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9298

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9289

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9299

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9290

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9300

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9291

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9301

end

9292

end

9302

param.z_p_fext_cases = param.z_p_fext_casesx;

9293

param.z_p_fext_cases = param.z_p_fext_casesx;

9303

param.z_p_next_cases= param.z_p_next_casesx;

9294

param.z_p_next_cases= param.z_p_next_casesx;

9304

param.z_p_tx_cases= param.z_p_tx_casesx;

9295

param.z_p_tx_cases= param.z_p_tx_casesx;

9305

param.z_p_rx_cases= param.z_p_rx_casesx;

9296

param.z_p_rx_cases= param.z_p_rx_casesx;

9306

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9297

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9307

end

9298

end

9308

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9299

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9309

9300

9310

% Table 92-12 parameters

9301

% Table 92-12 parameters

9311

param.brd_gamma0_a1_a2 = xls_parameter(parameter, 'board_tl_gamma0_a1_a2', true, [0 4.114e-4 2.547e-4]); % Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9302

param.brd_gamma0_a1_a2 = xls_parameter(parameter, 'board_tl_gamma0_a1_a2', true, [0 4.114e-4 2.547e-4]); % Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9312

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9303

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9313

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9304

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9314

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9305

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9315

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9306

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9316

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9307

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9317

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9308

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9318

9309

9319

% Unofficial parameters

9310

% Unofficial parameters

9320

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9311

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9321

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9312

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9322

% Deprecated parameters - affect only frequency domain analysis.

9313

% Deprecated parameters - affect only frequency domain analysis.

9323

param.f_v = xls_parameter(parameter, 'f_v', true, 4); % For FOM_ILD: Transiton rate cut off frequency for ICN/ILD calc in terms of fb

9314

param.f_v = xls_parameter(parameter, 'f_v', true, 4); % For FOM_ILD: Transiton rate cut off frequency for ICN/ILD calc in terms of fb

9324

param.f_f = xls_parameter(parameter, 'f_f', true, 4); % For ICN: Fext transiton rate cut off frequency for ICN calc in terms of fb

9315

param.f_f = xls_parameter(parameter, 'f_f', true, 4); % For ICN: Fext transiton rate cut off frequency for ICN calc in terms of fb

9325

param.f_n = xls_parameter(parameter, 'f_n', true, 4); % For ICN: Next transiton rate cut off frequency for ICN calc in terms of fb

9316

param.f_n = xls_parameter(parameter, 'f_n', true, 4); % For ICN: Next transiton rate cut off frequency for ICN calc in terms of fb

9326

param.f_r = xls_parameter(parameter, 'f_r', true, 4); % reference receive filter in COM and in ICN/FOM_ILD calcs in terms of fb

9317

param.f_r = xls_parameter(parameter, 'f_r', true, 4); % reference receive filter in COM and in ICN/FOM_ILD calcs in terms of fb

9327

param.fb_BT_cutoff= xls_parameter(parameter, 'TDR_f_BT_3db', true, 0.4730); % Bessel-Thomson 3 dB cut off freqeuncy in terms of fb

9318

param.fb_BT_cutoff= xls_parameter(parameter, 'TDR_f_BT_3db', true, 0.4730); % Bessel-Thomson 3 dB cut off freqeuncy in terms of fb

9328

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9319

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9329

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9320

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9330

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9321

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9331

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9322

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9332

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9323

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9333

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9324

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9334

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9325

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9335

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9326

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9336

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9327

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9337

switch param.Gx

9328

switch param.Gx

9338

case 0

9329

case 0

9339

param.Grr=param.Grr; % just use older Grr ir gx not specified

9330

param.Grr=param.Grr; % just use older Grr ir gx not specified

9340

case 1

9331

case 1

9341

param.Grr=2; % use newer Grr

9332

param.Grr=2; % use newer Grr

9342

end

9333

end

9343

9334

9344

param.LOCAL_SEARCH=xls_parameter(parameter,'Local Search',true,0); % Decreases COM compute time. Aetting to 2 seems ok ,if 0 search is full grid

9335

param.LOCAL_SEARCH=xls_parameter(parameter,'Local Search',true,0); % Decreases COM compute time. Aetting to 2 seems ok ,if 0 search is full grid

9345

% Operational control variables

9336

% Operational control variables

9346

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9337

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9347

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9338

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9348

param.Noise_Crest_Factor= xls_parameter(parameter, 'Noise_Crest_Factor', true, 0); % Normally not used. If set this is q factor used for quantized Gaussian PDFs

9339

param.Noise_Crest_Factor= xls_parameter(parameter, 'Noise_Crest_Factor', true, 0); % Normally not used. If set this is q factor used for quantized Gaussian PDFs

9349

param.AC_CM_RMS = xls_parameter(parameter, 'AC_CM_RMS', true, 0); % AC_CM_RMS is the CM BBN AWGN RMS at COM source point. Default is 0. Adds common mode noise source to the COM signal path for the through channel

9340

param.AC_CM_RMS = xls_parameter(parameter, 'AC_CM_RMS', true, 0); % AC_CM_RMS is the CM BBN AWGN RMS at COM source point. Default is 0. Adds common mode noise source to the COM signal path for the through channel

9350

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9341

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9351

param.T_O = xls_parameter(parameter, 'T_O', true, 0 ); % Units are mUI. Histogram for VEC and VEO are computed over T_s +/- T_O.

9342

param.T_O = xls_parameter(parameter, 'T_O', true, 0 ); % Units are mUI. Histogram for VEC and VEO are computed over T_s +/- T_O.

9352

param.T_O = xls_parameter(parameter, 'T_h', true, param.T_O ); % superceded with T_O but is the internal values that is used. Do not use.

9343

param.T_O = xls_parameter(parameter, 'T_h', true, param.T_O ); % superceded with T_O but is the internal values that is used. Do not use.

9353

9344

9354

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9345

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9355

9346

9356

OP.Histogram_Window_Weight=xls_parameter(parameter, 'Histogram_Window_Weight', false, 'rectangle' ); %Weighting for VEC and VEO are histogram processing. Type are Gaussian,Dual Rayleigh,Triangle, and Rectangle (default)

9347

OP.Histogram_Window_Weight=xls_parameter(parameter, 'Histogram_Window_Weight', false, 'rectangle' ); %Weighting for VEC and VEO are histogram processing. Type are Gaussian,Dual Rayleigh,Triangle, and Rectangle (default)

9357

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9348

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9358

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9349

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9359

param.QL=xls_parameter(parameter, 'QL', true, param.T_O/param.Qr/1000 ); % superceded with sigma_r but is the internal values that is used

9350

param.QL=xls_parameter(parameter, 'QL', true, param.T_O/param.Qr/1000 ); % superceded with sigma_r but is the internal values that is used

9360

9351

9361

%%

9352

%%

9362

9353

9363

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9354

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9364

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9355

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9365

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9356

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9366

param.awgn_mv=param.AC_CM_RMS;

9357

param.awgn_mv=param.AC_CM_RMS;

9367

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9358

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9368

param.f_hp=xls_parameter(parameter, 'f_hp', true, 0 ); % for rx testing for eq 162-12 if 0 (default) then rx test using rx bbn

9359

param.f_hp=xls_parameter(parameter, 'f_hp', true, 0 ); % for rx testing for eq 162-12 if 0 (default) then rx test using rx bbn

9369

param.Q=xls_parameter(parameter, 'Q', true, 0 ); % Implementation penalty for MLSE in EQ 178a-36

9360

param.Q=xls_parameter(parameter, 'Q', true, 0 ); % Implementation penalty for MLSE in EQ 178a-36

9370

9361

9371

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9362

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9372

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9363

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9373

param.Floating_RXFFE=false;

9364

param.Floating_RXFFE=false;

9374

param.Floating_DFE=false;

9365

param.Floating_DFE=false;

9375

if param.N_bg > 0

9366

if param.N_bg > 0

9376

param.Floating_DFE=true;

9367

param.Floating_DFE=true;

9377

end

9368

end

9378

if OP.RxFFE

9369

if OP.RxFFE

9379

param.Floating_DFE=false;

9370

param.Floating_DFE=false;

9380

if param.N_bg > 0

9371

if param.N_bg > 0

9381

param.Floating_RXFFE=true;

9372

param.Floating_RXFFE=true;

9382

end

9373

end

9383

end

9374

end

9384

%% for introducing Tx or Rx skew on p leg or n leg

9375

%% for introducing Tx or Rx skew on p leg or n leg

9385

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9376

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9386

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9377

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9387

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9378

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9388

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9379

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9389

9380

9390

%%

9381

%%

9391

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9382

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9392

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9383

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9393

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9384

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9394

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9385

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9395

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9386

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9396

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9387

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9397

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9388

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9398

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9389

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9399

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9390

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9400

OP.CSV_REPORT = xls_parameter(parameter, 'CSV_REPORT', false, true); % saves all the output parameters to a CSV file in the results directory, If DIAGNOSTICS is set then a mat file is also created

9391

OP.CSV_REPORT = xls_parameter(parameter, 'CSV_REPORT', false, true); % saves all the output parameters to a CSV file in the results directory, If DIAGNOSTICS is set then a mat file is also created

9401

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9392

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9402

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9393

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9403

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9394

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9404

OP.GET_FD = xls_parameter(parameter, 'Display frequency domain', false, OP.GET_FD); % Not normally set in the config file. It is normally just set to true to get FD plots

9395

OP.GET_FD = xls_parameter(parameter, 'Display frequency domain', false, OP.GET_FD); % Not normally set in the config file. It is normally just set to true to get FD plots

9405

OP.INC_PACKAGE = xls_parameter(parameter, 'INC_PACKAGE', false, true); % warning: INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1

9396

OP.INC_PACKAGE = xls_parameter(parameter, 'INC_PACKAGE', false, true); % warning: INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1

9406

if ~OP.INC_PACKAGE

9397

if ~OP.INC_PACKAGE

9407

fprintf('<strong> Warning!!! INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9398

fprintf('<strong> Warning!!! INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9408

end

9399

end

9409

9400

9410

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9401

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9411

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9402

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9412

if OP.IDEAL_TX_TERM

9403

if OP.IDEAL_TX_TERM

9413

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9404

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9414

end

9405

end

9415

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9406

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9416

if OP.IDEAL_RX_TERM

9407

if OP.IDEAL_RX_TERM

9417

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9408

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9418

end

9409

end

9419

9410

9420

OP.TDMODE = xls_parameter(parameter, 'TDMODE',false, OP.TDMODE); % Enables the the use of pulse response instead of s-parameters. Assumes no packages or the packages are included in the PR. Default is 0.

9411

OP.TDMODE = xls_parameter(parameter, 'TDMODE',false, OP.TDMODE); % Enables the the use of pulse response instead of s-parameters. Assumes no packages or the packages are included in the PR. Default is 0.

9421

9412

9422

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9413

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9423

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9414

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9424

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9415

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9425

OP.BREAD_CRUMBS = xls_parameter(parameter, 'BREAD_CRUMBS',false, false); % if DIAGNOSTICS is set then param, OP, and chdata are include in the output for each run

9416

OP.BREAD_CRUMBS = xls_parameter(parameter, 'BREAD_CRUMBS',false, false); % if DIAGNOSTICS is set then param, OP, and chdata are include in the output for each run

9426

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9417

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9427

OP.COM_CONTRIBUTION_CURVES = xls_parameter(parameter, 'COM_CONTRIBUTION',false,0); % Default is 0. If set to 1 then a bar graph of COM contributors is produce instead of bathtub curves

9418

OP.COM_CONTRIBUTION_CURVES = xls_parameter(parameter, 'COM_CONTRIBUTION',false,0); % Default is 0. If set to 1 then a bar graph of COM contributors is produce instead of bathtub curves

9428

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9419

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9429

OP.EC_REL_TOL = xls_parameter(parameter, 'Enforce Causality REL_TOL', false, 1e-2); % Relative Tolerance parameter for causality, Hard enforcement, 1e-3, Soft enforcement, 1e-2

9420

OP.EC_REL_TOL = xls_parameter(parameter, 'Enforce Causality REL_TOL', false, 1e-2); % Relative Tolerance parameter for causality, Hard enforcement, 1e-3, Soft enforcement, 1e-2

9430

OP.EC_DIFF_TOL = xls_parameter(parameter, 'Enforce Causality DIFF_TOL', false, 1e-3); % Difference Tolerance parameter for causality, Hard enforcement, 1e-4,Soft enforcement, 1e-3

9421

OP.EC_DIFF_TOL = xls_parameter(parameter, 'Enforce Causality DIFF_TOL', false, 1e-3); % Difference Tolerance parameter for causality, Hard enforcement, 1e-4,Soft enforcement, 1e-3

9431

OP.EC_PULSE_TOL = xls_parameter(parameter, 'Enforce Causality pulse start tolerance', false, 0.01); % Tolerance parameter for causality, Hard enforcement, 0.05, Soft enforcement, .01

9422

OP.EC_PULSE_TOL = xls_parameter(parameter, 'Enforce Causality pulse start tolerance', false, 0.01); % Tolerance parameter for causality, Hard enforcement, 0.05, Soft enforcement, .01

9432

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9423

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9433

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9424

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9434

OP.sigma_bn_STEP = xls_parameter(parameter, 'Sigma BBN step', false, 5e-3); % BBN step for Rx Calibration in volts. Defaults is 0.5e-3

9425

OP.sigma_bn_STEP = xls_parameter(parameter, 'Sigma BBN step', false, 5e-3); % BBN step for Rx Calibration in volts. Defaults is 0.5e-3

9435

OP.BBN_Q_factor = xls_parameter(parameter, 'BBN Q factor', false, 5); % Overrides NEXT/FEXT noise Qfactor for 'Force BBN Q factor' used for reporting. does not affect COM.

9426

OP.BBN_Q_factor = xls_parameter(parameter, 'BBN Q factor', false, 5); % Overrides NEXT/FEXT noise Qfactor for 'Force BBN Q factor' used for reporting. does not affect COM.

9436

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9427

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9437

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9428

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9438

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9429

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9439

9430

9440

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9431

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9441

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9432

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9442

OP.FORCE_TR = xls_parameter(parameter, 'FORCE_TR', false, false);% Included for earlier version support but should be set to 1 in most later config sheets.

9433

OP.FORCE_TR = xls_parameter(parameter, 'FORCE_TR', false, false);% Included for earlier version support but should be set to 1 in most later config sheets.

9443

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9434

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9444

% compatibility

9435

% compatibility

9445

if OP.FORCE_TR

9436

if OP.FORCE_TR

9446

OP.T_r_meas_point=0;

9437

OP.T_r_meas_point=0;

9447

OP.T_r_filter_type=1;

9438

OP.T_r_filter_type=1;

9448

end

9439

end

9449

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9440

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9450

OP.TDR_duration= xls_parameter(parameter, 'TDR_duration', false, 5); % only used if N*UI is longer than the TDR duration time. Default is 5 times the raw s-parameter transit time.

9441

OP.TDR_duration= xls_parameter(parameter, 'TDR_duration', false, 5); % only used if N*UI is longer than the TDR duration time. Default is 5 times the raw s-parameter transit time.

9451

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9442

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9452

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9443

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9453

OP.T_k= xls_parameter(parameter, 'T_k', false, .6)*1e-9; % Time span (ns) for which the impedance of port is determined using TDR.

9444

OP.T_k= xls_parameter(parameter, 'T_k', false, .6)*1e-9; % Time span (ns) for which the impedance of port is determined using TDR.

9454

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9445

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9455

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9446

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9456

if OP.ERL

9447

if OP.ERL

9457

OP.PTDR=1;

9448

OP.PTDR=1;

9458

else

9449

else

9459

OP.PTDR=0;

9450

OP.PTDR=0;

9460

end % ERL needs to do a TDR

9451

end % ERL needs to do a TDR

9461

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9452

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9462

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9453

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9463

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9454

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9464

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9455

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9465

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9456

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9466

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9457

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9467

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9458

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9468

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9459

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9469

OP.AUTO_TFX=xls_parameter(parameter, 'AUTO_TFX', false,0); % Mostly used for device ERL. If sent to 1 the fixture tfx will be estimated.

9460

OP.AUTO_TFX=xls_parameter(parameter, 'AUTO_TFX', false,0); % Mostly used for device ERL. If sent to 1 the fixture tfx will be estimated.

9470

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9461

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9471

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9462

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9472

OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncation threshold', false, 1e-3); % zero padding threshold in fraction of IR peak for the impulse response. Effectively controls the length of time for the PR. Larger values decrease run time and accuracy. Default is 1e-3.

9463

OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncation threshold', false, 1e-3); % zero padding threshold in fraction of IR peak for the impulse response. Effectively controls the length of time for the PR. Larger values decrease run time and accuracy. Default is 1e-3.

9473

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9464

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9474

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9465

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9475

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9466

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9476

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9467

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9477

if strcmpi(OP.PHY,'C2M')

9468

if strcmpi(OP.PHY,'C2M')

9478

OP.EW=true;

9469

OP.EW=true;

9479

else

9470

else

9480

param.T_O=0; % make sure when c2c that sample is at Ts

9471

param.T_O=0; % make sure when c2c that sample is at Ts

9481

end

9472

end

9482

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9473

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9483

OP.PHY='C2Mcom';

9474

OP.PHY='C2Mcom';

9484

end

9475

end

9485

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9476

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9486

switch lower(OP.TDECQ)

9477

switch lower(OP.TDECQ)

9487

case {false 'none' 'vma'}

9478

case {false 'none' 'vma'}

9488

otherwise

9479

otherwise

9489

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9480

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9490

end

9481

end

9491

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9482

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9492

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9483

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9493

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9484

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9494

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9485

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9495

OP.Optimize_loop_speed_up =xls_parameter(parameter, 'Optimize_loop_speed_up', true , 0);% If set to 0 (or default) normal looping, If set to 1 loop speedup by slightly reducing PD Fbin and FIR_threshold for optimize looping only

9486

OP.Optimize_loop_speed_up =xls_parameter(parameter, 'Optimize_loop_speed_up', true , 0);% If set to 0 (or default) normal looping, If set to 1 loop speedup by slightly reducing PD Fbin and FIR_threshold for optimize looping only

9496

% Parameters for error burst probability calculation. Not officially used

9487

% Parameters for error burst probability calculation. Not officially used

9497

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9488

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9498

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9489

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9499

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9490

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9500

OP.USE_ETA0_PSD = xls_parameter(parameter, 'USE_ETA0_PSD', false, 0); % Used eta_0 PSD equaiton for sigma_n. Default is 0. Do not use.

9491

OP.USE_ETA0_PSD = xls_parameter(parameter, 'USE_ETA0_PSD', false, 0); % Used eta_0 PSD equaiton for sigma_n. Default is 0. Do not use.

9501

OP.SAVE_CONFIG2MAT = xls_parameter(parameter, 'SAVE_CONFIG2MAT', false, 0); % If set to 1 (default) saves parameters in mat file. Requires DIAGNOSTICS to be set.

9492

OP.SAVE_CONFIG2MAT = xls_parameter(parameter, 'SAVE_CONFIG2MAT', false, 0); % If set to 1 (default) saves parameters in mat file. Requires DIAGNOSTICS to be set.

9502

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9493

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9503

OP.fraction_of_F_range_start_extrap_from= xls_parameter(parameter, 'fraction_of_F_range_start_extrap_from', true, 0.75); % Frequency (fb) where high frequency extropolation begins for computing IR. Helps control Gibbs phenomena. defualt is 0.75.

9494

OP.fraction_of_F_range_start_extrap_from= xls_parameter(parameter, 'fraction_of_F_range_start_extrap_from', true, 0.75); % Frequency (fb) where high frequency extropolation begins for computing IR. Helps control Gibbs phenomena. defualt is 0.75.

9504

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9495

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9505

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9496

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9506

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9497

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9507

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9498

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9508

OP.MLSE = xls_parameter(parameter, 'MLSE', false, 0); % MLSE 0,1,2, 3 (no MLSE, U1 MLSE, experimetal MLSE, U3 MLSE)

9499

OP.MLSE = xls_parameter(parameter, 'MLSE', false, 0); % MLSE 0,1,2, 3 (no MLSE, U1 MLSE, experimetal MLSE, U3 MLSE)

9509

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9500

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9510

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9501

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9511

if OP.MLSE && param.ndfe==0

9502

if OP.MLSE && param.ndfe==0

9512

error('At least DFE 1 must be set to use MLSE');

9503

error('At least DFE 1 must be set to use MLSE');

9513

end

9504

end

9514

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9505

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9515

% MNSE parameters

9506

% MNSE parameters

9516

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9507

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9517

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9508

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9518

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9509

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9519

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9510

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9520

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9511

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9521

% Commit request 4p4_7, healey_3dj_COM_01_240416

9512

% Commit request 4p4_7, healey_3dj_COM_01_240416

9522

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

9513

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

9523

% need to make sure TD mode does not invoke FD operations

9514

% need to make sure TD mode does not invoke FD operations

9524

if OP.TDMODE % need to set GET_FD false of TDMODE

9515

if OP.TDMODE % need to set GET_FD false of TDMODE

9525

OP.GET_FD=false;

9516

OP.GET_FD=false;

9526

OP.ERL_ONLY=0;

9517

OP.ERL_ONLY=0;

9527

OP.ERL=0;

9518

OP.ERL=0;

9528

OP.PTDR=0;

9519

OP.PTDR=0;

9529

OP.TDR=0;

9520

OP.TDR=0;

9530

OP.RX_CALIBRATION=0;

9521

OP.RX_CALIBRATION=0;

9531

end

9522

end

9532

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9523

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9533

save(matcongfile ,'parameter');

9524

save(matcongfile ,'parameter');

9534

end

9525

end

9535

9526

9536

9527

9537

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9528

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9538

if ~isempty(param.PKG_NAME)

9529

if ~isempty(param.PKG_NAME)

9539

if length(param.PKG_NAME) == 1

9530

if length(param.PKG_NAME) == 1

9540

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9531

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9541

end

9532

end

9542

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9533

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9543

tx_rx_fields_matrix = {'pkg_Z_c'};

9534

tx_rx_fields_matrix = {'pkg_Z_c'};

9544

tx_fields = {'z_p_tx_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9535

tx_fields = {'z_p_tx_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9545

rx_fields = {'z_p_rx_cases' 'a_next' 'z_p_next_cases'};

9536

rx_fields = {'z_p_rx_cases' 'a_next' 'z_p_next_cases'};

9546

tx_pkg_name=param.PKG_NAME{1};

9537

tx_pkg_name=param.PKG_NAME{1};

9547

rx_pkg_name=param.PKG_NAME{2};

9538

rx_pkg_name=param.PKG_NAME{2};

9548

tx_pkg_struct=param.PKG.(tx_pkg_name);

9539

tx_pkg_struct=param.PKG.(tx_pkg_name);

9549

rx_pkg_struct=param.PKG.(rx_pkg_name);

9540

rx_pkg_struct=param.PKG.(rx_pkg_name);

9550

9541

9551

%tx_rx_fields: put the value from the tx package in the Tx position and the value from the rx package in the RX position

9542

%tx_rx_fields: put the value from the tx package in the Tx position and the value from the rx package in the RX position

9552

for j=1:length(tx_rx_fields)

9543

for j=1:length(tx_rx_fields)

9553

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9544

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9554

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9545

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9555

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9546

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9556

end

9547

end

9557

9548

9558

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9549

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9559

for j=1:length(tx_rx_fields_matrix)

9550

for j=1:length(tx_rx_fields_matrix)

9560

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9551

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9561

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9552

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9562

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9553

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9563

end

9554

end

9564

9555

9565

%tx_fields: use only the tx package values

9556

%tx_fields: use only the tx package values

9566

for j=1:length(tx_fields)

9557

for j=1:length(tx_fields)

9567

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9558

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9568

end

9559

end

9569

9560

9570

%rx_fields: use only the rx package values

9561

%rx_fields: use only the rx package values

9571

for j=1:length(rx_fields)

9562

for j=1:length(rx_fields)

9572

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9563

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9573

end

9564

end

9574

9565

9575

end

9566

end

9576

9567

9577

9568

9578

%%

9569

%%

9579

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9570

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9580

%% FUNCTION :: read_sp4_sparams

9571

%% FUNCTION :: read_sp4_sparams

9581

%

9572

%

9582

% Description

9573

% Description

9583

% Read the fid of single-ended 4-port complex S-parameters

9574

% Read the fid of single-ended 4-port complex S-parameters

9584

% in Touchstone format 'file' and convert to the internal

9575

% in Touchstone format 'file' and convert to the internal

9585

% format using the port transform 'ports'

9576

% format using the port transform 'ports'

9586

%

9577

%

9587

% Created by Mike Y. He

9578

% Created by Mike Y. He

9588

% April 22, 2005

9579

% April 22, 2005

9589

%

9580

%

9590

% Reused some code from

9581

% Reused some code from

9591

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9582

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9592

% for touchstone 4-port S-matrix import.

9583

% for touchstone 4-port S-matrix import.

9593

%

9584

%

9594

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9585

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9595

% optimized for quicker parameter matching and parsing. also, separated out

9586

% optimized for quicker parameter matching and parsing. also, separated out

9596

% the plotting algorithms into their own sub-function routines

9587

% the plotting algorithms into their own sub-function routines

9597

%

9588

%

9598

% Modified December 2021 to use read_Nport_touchstone

9589

% Modified December 2021 to use read_Nport_touchstone

9599

% This is faster reader that is capable of reading touchstone with any number of ports

9590

% This is faster reader that is capable of reading touchstone with any number of ports

9600

%

9591

%

9601

% Input Variables (required)

9592

% Input Variables (required)

9602

% infile -- The s4p file to be read and converted

9593

% infile -- The s4p file to be read and converted

9603

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9594

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9604

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9595

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9605

% ports -- Re-order the port layout

9596

% ports -- Re-order the port layout

9606

%

9597

%

9607

% Output/Return Variables

9598

% Output/Return Variables

9608

% data -- structure containing network parameter data points and frequency axis

9599

% data -- structure containing network parameter data points and frequency axis

9609

% sdc -- the differential in/common-mode out s-parameter data matrix

9600

% sdc -- the differential in/common-mode out s-parameter data matrix

9610

% sdd -- the differential in/differential out s-parameter data matrix

9601

% sdd -- the differential in/differential out s-parameter data matrix

9611

%

9602

%

9612

9603

9613

9604

9614

% backwards compatibility settings. can be removed in updated code.

9605

% backwards compatibility settings. can be removed in updated code.

9615

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9606

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9616

if isempty(ports); ports = [1 2]; end % default order normally used.

9607

if isempty(ports); ports = [1 2]; end % default order normally used.

9617

ports = [1 2];

9608

ports = [1 2];

9618

9609

9619

9610

9620

if OP.DISPLAY_WINDOW

9611

if OP.DISPLAY_WINDOW

9621

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9612

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9622

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9613

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9623

end

9614

end

9624

9615

9625

%AJG: fast touchstone read for any number of ports

9616

%AJG: fast touchstone read for any number of ports

9626

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9617

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9627

9618

9628

9619

9629

9620

9630

D=NaN(size(sch));

9621

D=NaN(size(sch));

9631

% calculate differential s parameter matrix from single ended

9622

% calculate differential s parameter matrix from single ended

9632

for i=1:size(sch,1)

9623

for i=1:size(sch,1)

9633

S(:,:) = sch(i,:,:);

9624

S(:,:) = sch(i,:,:);

9634

T = [1 1 ; 1 -1 ];

9625

T = [1 1 ; 1 -1 ];

9635

W = T * (S / T);

9626

W = T * (S / T);

9636

D(i,:,:) = W(:,:);

9627

D(i,:,:) = W(:,:);

9637

end

9628

end

9638

9629

9639

% D matrix should be

9630

% D matrix should be

9640

% Scc11 Scd11 Scc12 Scd21

9631

% Scc11 Scd11 Scc12 Scd21

9641

% Sdc11 Sdd11 Sdc12 Sdd12

9632

% Sdc11 Sdd11 Sdc12 Sdd12

9642

% Scc21 Scd21 Scc22 Scd22

9633

% Scc21 Scd21 Scc22 Scd22

9643

% Sdc21 Sdd21 Sdc22 Sdd22

9634

% Sdc21 Sdd21 Sdc22 Sdd22

9644

9635

9645

% proper values

9636

% proper values

9646

%AJG: matrix can be properly referenced after fixing mapping

9637

%AJG: matrix can be properly referenced after fixing mapping

9647

SDD(:,1,1) = D(:,2,2);

9638

SDD(:,1,1) = D(:,2,2);

9648

SDC(:,1,1)= D(:,2,1);

9639

SDC(:,1,1)= D(:,2,1);

9649

SCC(:,1,1)= D(:,1,1);

9640

SCC(:,1,1)= D(:,1,1);

9650

SCD(:,1,1)= D(:,1,2);

9641

SCD(:,1,1)= D(:,1,2);

9651

9642

9652

9643

9653

9644

9654

% backwards compatibility output variables

9645

% backwards compatibility output variables

9655

data.m = sch;

9646

data.m = sch;

9656

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9647

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9657

data.freq = schFreqAxis;

9648

data.freq = schFreqAxis;

9658

colors = 'rgbk';

9649

colors = 'rgbk';

9659

9650

9660

if (plot_ini_s_params == 1)

9651

if (plot_ini_s_params == 1)

9661

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9652

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9662

for mj=1:4

9653

for mj=1:4

9663

% subplot(2,2,mj);

9654

% subplot(2,2,mj);

9664

for mi=1:4

9655

for mi=1:4

9665

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9656

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9666

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9657

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9667

hold on

9658

hold on

9668

end

9659

end

9669

xlabel('Frequency (Hz)');

9660

xlabel('Frequency (Hz)');

9670

ylabel('Magnitude (dB)');

9661

ylabel('Magnitude (dB)');

9671

legend show

9662

legend show

9672

grid on

9663

grid on

9673

title(sprintf('Output port %d', mj));

9664

title(sprintf('Output port %d', mj));

9674

end

9665

end

9675

end

9666

end

9676

plot_dif_s_params =0;

9667

plot_dif_s_params =0;

9677

if (plot_dif_s_params == 1)

9668

if (plot_dif_s_params == 1)

9678

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9669

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9679

% subplot(2,1,1);

9670

% subplot(2,1,1);

9680

for mj=1:1

9671

for mj=1:1

9681

for mi=1:1

9672

for mi=1:1

9682

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9673

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9683

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9674

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9684

hold on

9675

hold on

9685

end

9676

end

9686

end

9677

end

9687

xlabel('Frequency (Hz)');

9678

xlabel('Frequency (Hz)');

9688

ylabel('Magnitude (dB)');

9679

ylabel('Magnitude (dB)');

9689

legend show

9680

legend show

9690

grid on

9681

grid on

9691

title(infile);

9682

title(infile);

9692

9683

9693

% subplot(2,1,2);

9684

% subplot(2,1,2);

9694

% for mj=1:2

9685

% for mj=1:2

9695

% for mi=1:2

9686

% for mi=1:2

9696

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9687

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9697

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9688

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9698

% hold on

9689

% hold on

9699

% end

9690

% end

9700

% end

9691

% end

9701

% xlabel('Frequency (Hz)');

9692

% xlabel('Frequency (Hz)');

9702

% ylabel('Magnitude (dB)');

9693

% ylabel('Magnitude (dB)');

9703

% legend show

9694

% legend show

9704

% grid on

9695

% grid on

9705

end

9696

end

9706

9697

9707

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9698

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9708

% end read_sp2_sparam

9699

% end read_sp2_sparam

9709

9700

9710

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9701

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9711

%% FUNCTION :: read_sp4_sparams

9702

%% FUNCTION :: read_sp4_sparams

9712

%

9703

%

9713

% Description

9704

% Description

9714

% Read the fid of single-ended 4-port complex S-parameters

9705

% Read the fid of single-ended 4-port complex S-parameters

9715

% in Touchstone format 'file' and convert to the internal

9706

% in Touchstone format 'file' and convert to the internal

9716

% format using the port transform 'ports'

9707

% format using the port transform 'ports'

9717

%

9708

%

9718

% Created by Mike Y. He

9709

% Created by Mike Y. He

9719

% April 22, 2005

9710

% April 22, 2005

9720

%

9711

%

9721

% Reused some code from

9712

% Reused some code from

9722

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9713

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9723

% for touchstone 4-port S-matrix import.

9714

% for touchstone 4-port S-matrix import.

9724

%

9715

%

9725

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9716

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9726

% optimized for quicker parameter matching and parsing. also, separated out

9717

% optimized for quicker parameter matching and parsing. also, separated out

9727

% the plotting algorithms into their own sub-function routines

9718

% the plotting algorithms into their own sub-function routines

9728

%

9719

%

9729

% Modified December 2021 to use read_Nport_touchstone

9720

% Modified December 2021 to use read_Nport_touchstone

9730

% This is faster reader that is capable of reading touchstone with any number of ports

9721

% This is faster reader that is capable of reading touchstone with any number of ports

9731

%

9722

%

9732

% Input Variables (required)

9723

% Input Variables (required)

9733

% infile -- The s4p file to be read and converted

9724

% infile -- The s4p file to be read and converted

9734

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9725

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9735

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9726

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9736

% ports -- Re-order the port layout

9727

% ports -- Re-order the port layout

9737

% OP

9728

% OP

9738

% param

9729

% param

9739

% Output/Return Variables

9730

% Output/Return Variables

9740

% data -- structure containing network parameter data points and frequency axis

9731

% data -- structure containing network parameter data points and frequency axis

9741

% sdd -- the differential in/differential out s-parameter data matrix

9732

% sdd -- the differential in/differential out s-parameter data matrix

9742

% sdc -- the differential in/common-mode out s-parameter data matrix

9733

% sdc -- the differential in/common-mode out s-parameter data matrix

9743

% scc -- the common mode in/common-mode out s-parameter data matrix

9734

% scc -- the common mode in/common-mode out s-parameter data matrix

9744

%

9735

%

9745

%

9736

%

9746

9737

9747

9738

9748

% backwards compatibility settings. can be removed in updated code.

9739

% backwards compatibility settings. can be removed in updated code.

9749

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9740

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9750

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9741

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9751

9742

9752

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9743

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9753

% pair is reversed.

9744

% pair is reversed.

9754

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9745

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9755

9746

9756

if OP.DISPLAY_WINDOW

9747

if OP.DISPLAY_WINDOW

9757

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9748

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9758

end

9749

end

9759

9750

9760

%AJG: fast touchstone read for any number of ports

9751

%AJG: fast touchstone read for any number of ports

9761

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9752

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9762

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9753

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9763

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9754

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9764

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9755

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9765

Sigfct = ...

9756

Sigfct = ...

9766

@(sigma2,sigma1,sigma4,sigma3)reshape([sigma1.^2,sigma1.*sigma2,sigma1.*sigma3,sigma1.*sigma4,sigma1.*sigma2,sigma2.^2,sigma2.*sigma3,sigma2.*sigma4,sigma1.*sigma3,sigma2.*sigma3,sigma3.^2,sigma3.*sigma4,sigma1.*sigma4,sigma2.*sigma4,sigma3.*sigma4,sigma4.^2],[4,4]);

9757

@(sigma2,sigma1,sigma4,sigma3)reshape([sigma1.^2,sigma1.*sigma2,sigma1.*sigma3,sigma1.*sigma4,sigma1.*sigma2,sigma2.^2,sigma2.*sigma3,sigma2.*sigma4,sigma1.*sigma3,sigma2.*sigma3,sigma3.^2,sigma3.*sigma4,sigma1.*sigma4,sigma2.*sigma4,sigma3.*sigma4,sigma4.^2],[4,4]);

9767

D=NaN(size(sch));

9758

D=NaN(size(sch));

9768

% calculate differential s parameter matrix from single ended

9759

% calculate differential s parameter matrix from single ended

9769

% skew added RIM 12/29/2023

9760

% skew added RIM 12/29/2023

9770

for i=1:size(sch,1)

9761

for i=1:size(sch,1)

9771

f=schFreqAxis(i);

9762

f=schFreqAxis(i);

9772

sigma_matrix=Sigfct(exp(2i*pi*f*param.Txpskew*1e-12),exp(2i*pi*f*param.Txnskew*1e-12),exp(2i*pi*f*param.Rxpskew*1e-12),exp(2i*pi*f*param.Rxnskew*1e-12) );

9763

sigma_matrix=Sigfct(exp(2i*pi*f*param.Txpskew*1e-12),exp(2i*pi*f*param.Txnskew*1e-12),exp(2i*pi*f*param.Rxpskew*1e-12),exp(2i*pi*f*param.Rxnskew*1e-12) );

9773

S(:,:) = sch(i,:,:);

9764

S(:,:) = sch(i,:,:);

9774

Snew=sigma_matrix.*S;

9765

Snew=sigma_matrix.*S;

9775

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9766

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9776

W = T * (Snew / T);

9767

W = T * (Snew / T);

9777

D(i,:,:) = W(:,:);

9768

D(i,:,:) = W(:,:);

9778

end

9769

end

9779

9770

9780

% D matrix should be

9771

% D matrix should be

9781

% Scc11 Scd11 Scc12 Scd21

9772

% Scc11 Scd11 Scc12 Scd21

9782

% Sdc11 Sdd11 Sdc12 Sdd12

9773

% Sdc11 Sdd11 Sdc12 Sdd12

9783

% Scc21 Scd21 Scc22 Scd22

9774

% Scc21 Scd21 Scc22 Scd22

9784

% Sdc21 Sdd21 Sdc22 Sdd22

9775

% Sdc21 Sdd21 Sdc22 Sdd22

9785

9776

9786

% proper values

9777

% proper values

9787

SDD(:,1,1) = D(:,2,2);

9778

SDD(:,1,1) = D(:,2,2);

9788

SDD(:,2,2) = D(:,4,4);

9779

SDD(:,2,2) = D(:,4,4);

9789

SDD(:,1,2) = D(:,2,4);

9780

SDD(:,1,2) = D(:,2,4);

9790

SDD(:,2,1) = D(:,4,2);

9781

SDD(:,2,1) = D(:,4,2);

9791

9782

9792

SDC(:,1,1) = D(:,2,1);

9783

SDC(:,1,1) = D(:,2,1);

9793

SDC(:,2,2) = D(:,4,3);

9784

SDC(:,2,2) = D(:,4,3);

9794

SDC(:,1,2) = D(:,2,3);

9785

SDC(:,1,2) = D(:,2,3);

9795

SDC(:,2,1) = D(:,4,1);

9786

SDC(:,2,1) = D(:,4,1);

9796

9787

9797

SCC(:,1,1) = D(:,1,1);

9788

SCC(:,1,1) = D(:,1,1);

9798

SCC(:,2,2) = D(:,3,3);

9789

SCC(:,2,2) = D(:,3,3);

9799

SCC(:,1,2) = D(:,1,3);

9790

SCC(:,1,2) = D(:,1,3);

9800

SCC(:,2,1) = D(:,3,1);

9791

SCC(:,2,1) = D(:,3,1);

9801

9792

9802

% backwards compatibility output variables

9793

% backwards compatibility output variables

9803

data.m = sch;

9794

data.m = sch;

9804

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9795

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9805

data.freq = schFreqAxis;

9796

data.freq = schFreqAxis;

9806

colors = 'rgbk';

9797

colors = 'rgbk';

9807

9798

9808

if (plot_ini_s_params == 1)

9799

if (plot_ini_s_params == 1)

9809

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9800

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9810

for mj=1:4

9801

for mj=1:4

9811

subplot(2,2,mj);

9802

subplot(2,2,mj);

9812

for mi=1:4

9803

for mi=1:4

9813

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9804

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9814

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9805

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9815

hold on

9806

hold on

9816

end

9807

end

9817

xlabel('Frequency (Hz)');

9808

xlabel('Frequency (Hz)');

9818

ylabel('Magnitude (dB)');

9809

ylabel('Magnitude (dB)');

9819

legend show

9810

legend show

9820

grid on

9811

grid on

9821

title(sprintf('Output port %d', mj));

9812

title(sprintf('Output port %d', mj));

9822

end

9813

end

9823

end

9814

end

9824

plot_dif_s_params =0;

9815

plot_dif_s_params =0;

9825

if (plot_dif_s_params == 1)

9816

if (plot_dif_s_params == 1)

9826

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9817

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9827

% subplot(2,1,1);

9818

% subplot(2,1,1);

9828

for mj=1:2

9819

for mj=1:2

9829

for mi=1:2

9820

for mi=1:2

9830

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9821

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9831

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9822

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9832

hold on

9823

hold on

9833

end

9824

end

9834

end

9825

end

9835

xlabel('Frequency (Hz)');

9826

xlabel('Frequency (Hz)');

9836

ylabel('Magnitude (dB)');

9827

ylabel('Magnitude (dB)');

9837

legend show

9828

legend show

9838

grid on

9829

grid on

9839

title(infile);

9830

title(infile);

9840

%

9831

%

9841

% subplot(2,1,2);

9832

% subplot(2,1,2);

9842

% for mj=1:2

9833

% for mj=1:2

9843

% for mi=1:2

9834

% for mi=1:2

9844

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9835

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9845

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9836

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9846

% hold on

9837

% hold on

9847

% end

9838

% end

9848

% end

9839

% end

9849

% xlabel('Frequency (Hz)');

9840

% xlabel('Frequency (Hz)');

9850

% ylabel('Magnitude (dB)');

9841

% ylabel('Magnitude (dB)');

9851

% legend show

9842

% legend show

9852

% grid on

9843

% grid on

9853

end

9844

end

9854

9845

9855

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9846

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9856

% end read_sp4_sparam

9847

% end read_sp4_sparam

9857

function param_struct = read_package_parameters(parameter,param_struct)

9848

function param_struct = read_package_parameters(parameter,param_struct)

9858

9849

9859

%With the introduction of Package sections in COM spreadsheet, it makes sense to have a single function that grabs all package parameters from a parameter block

9850

%With the introduction of Package sections in COM spreadsheet, it makes sense to have a single function that grabs all package parameters from a parameter block

9860

%This block should eventually replace what is in read_ParamConfigFile

9851

%This block should eventually replace what is in read_ParamConfigFile

9861

%It can be called as: param = read_package_parameters(parameter, param)

9852

%It can be called as: param = read_package_parameters(parameter, param)

9862

9853

9863

if nargin<2

9854

if nargin<2

9864

%param_struct doesn't need to be passed when building a new package structure

9855

%param_struct doesn't need to be passed when building a new package structure

9865

%it is only needed when appending to regular param structure

9856

%it is only needed when appending to regular param structure

9866

param_struct=struct;

9857

param_struct=struct;

9867

end

9858

end

9868

9859

9869

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9860

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9870

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9861

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9871

9862

9872

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9863

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9873

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9864

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9874

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9865

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9875

9866

9876

param_struct.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9867

param_struct.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9877

[ncases, mele]=size(param_struct.z_p_tx_cases);

9868

[ncases, mele]=size(param_struct.z_p_tx_cases);

9878

if mele ==2

9869

if mele ==2

9879

param_struct.flex=2;

9870

param_struct.flex=2;

9880

elseif mele==4

9871

elseif mele==4

9881

param_struct.flex=4;

9872

param_struct.flex=4;

9882

elseif mele==1

9873

elseif mele==1

9883

param_struct.flex=1;

9874

param_struct.flex=1;

9884

else

9875

else

9885

error('config file syntax error')

9876

error('config file syntax error')

9886

end

9877

end

9887

param_struct.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9878

param_struct.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9888

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9879

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9889

if ncases ~= ncases1 || mele ~= mele1

9880

if ncases ~= ncases1 || mele ~= mele1

9890

error('All TX, NEXT, FEXT, Rx cases must agree');

9881

error('All TX, NEXT, FEXT, Rx cases must agree');

9891

else

9882

else

9892

end

9883

end

9893

param_struct.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9884

param_struct.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9894

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9885

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9895

if ncases ~= ncases1 || mele ~= mele1

9886

if ncases ~= ncases1 || mele ~= mele1

9896

error('All TX, NEXT, FEXT, Rx cases must agree');

9887

error('All TX, NEXT, FEXT, Rx cases must agree');

9897

else

9888

else

9898

end

9889

end

9899

param_struct.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9890

param_struct.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9900

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9891

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9901

if ncases ~= ncases1 || mele ~= mele1

9892

if ncases ~= ncases1 || mele ~= mele1

9902

error('All TX, NEXT, FEXT, Rx cases must agree');

9893

error('All TX, NEXT, FEXT, Rx cases must agree');

9903

else

9894

else

9904

end

9895

end

9905

% Table 93A-3 parameters

9896

% Table 93A-3 parameters

9906

param_struct.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9897

param_struct.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9907

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9898

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9908

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9899

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9909

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9900

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9910

if mele ~= mele1

9901

if mele ~= mele1

9911

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9902

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9912

else

9903

else

9913

end

9904

end

9914

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9905

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9915

for ii=1:ncases

9906

for ii=1:ncases

9916

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9907

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9917

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9908

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9918

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9909

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9919

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9910

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9920

end

9911

end

9921

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9912

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9922

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9913

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9923

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9914

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9924

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9915

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9925

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9916

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9926

end

9917

end

9927

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9918

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9928

%% extract s-parameter and convert to differential mode

9919

%% extract s-parameter and convert to differential mode

9929

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9920

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9930

num_files=length(chdata);

9921

num_files=length(chdata);

9931

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9922

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9932

for i=1:num_files

9923

for i=1:num_files

9933

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9924

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9934

progress = i/num_files;

9925

progress = i/num_files;

9935

if OP.DISPLAY_WINDOW

9926

if OP.DISPLAY_WINDOW

9936

[~,a]=fileparts(chdata(i).filename);

9927

[~,a]=fileparts(chdata(i).filename);

9937

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9928

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9938

else

9929

else

9939

fprintf('%i ',i);

9930

fprintf('%i ',i);

9940

end

9931

end

9941

9932

9942

% Skip reading file if it was already read (multiple test cases)

9933

% Skip reading file if it was already read (multiple test cases)

9943

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9934

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9944

switch lower(chdata(i).ext)

9935

switch lower(chdata(i).ext)

9945

case '.s2p' % for differential return loss

9936

case '.s2p' % for differential return loss

9946

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9937

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9947

chdata(i).fmaxi = length(Sch.freq);

9938

chdata(i).fmaxi = length(Sch.freq);

9948

chdata(i).faxis = Sch.freq;

9939

chdata(i).faxis = Sch.freq;

9949

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9940

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9950

SDDp2p(i)=NaN;

9941

SDDp2p(i)=NaN;

9951

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9942

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9952

chdata(i).sdd11=chdata(i).sdd11_raw;

9943

chdata(i).sdd11=chdata(i).sdd11_raw;

9953

case '.s4p'

9944

case '.s4p'

9954

if length(param.snpPortsOrder) ~= 4

9945

if length(param.snpPortsOrder) ~= 4

9955

error( 'warning:sNpFilePortMismatch', ...

9946

error( 'warning:sNpFilePortMismatch', ...

9956

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9947

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9957

length(param.snpPortsOrder), ...

9948

length(param.snpPortsOrder), ...

9958

chdata(i).ext ...

9949

chdata(i).ext ...

9959

);

9950

);

9960

end

9951

end

9961

% read function returns differnetial mode parameters

9952

% read function returns differnetial mode parameters

9962

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9953

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9963

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9954

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9964

% param.holdsdata(i).Sch= Sch;

9955

% param.holdsdata(i).Sch= Sch;

9965

% param.holdsdata(i).SDDch= SDDch;

9956

% param.holdsdata(i).SDDch= SDDch;

9966

% param.holdsdata(i).SDCch= SDCch;

9957

% param.holdsdata(i).SDCch= SDCch;

9967

else

9958

else

9968

error('If this line is reached, there is a logic error');

9959

error('If this line is reached, there is a logic error');

9969

% Sch=param.holdsdata(i).Sch;

9960

% Sch=param.holdsdata(i).Sch;

9970

% SDDch=param.holdsdata(i).SDDch;

9961

% SDDch=param.holdsdata(i).SDDch;

9971

% SDCch=param.holdsdata(i).SDCch;

9962

% SDCch=param.holdsdata(i).SDCch;

9972

end

9963

end

9973

chdata(i).fmaxi = length(Sch.freq);

9964

chdata(i).fmaxi = length(Sch.freq);

9974

9965

9975

9966

9976

if Sch.freq(chdata(i).fmaxi) < param.fb

9967

if Sch.freq(chdata(i).fmaxi) < param.fb

9977

warning('COM:read_s4p:MaxFreqTooLow', ...

9968

warning('COM:read_s4p:MaxFreqTooLow', ...

9978

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9969

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9979

chdata(i).filename, Sch.freq(end), param.fb);

9970

chdata(i).filename, Sch.freq(end), param.fb);

9980

end

9971

end

9981

if Sch.freq(1) > param.max_start_freq

9972

if Sch.freq(1) > param.max_start_freq

9982

warning('COM:read_s4p:StartFreqTooHigh', ...

9973

warning('COM:read_s4p:StartFreqTooHigh', ...

9983

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9974

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9984

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9975

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9985

end

9976

end

9986

freqstep=diff(Sch.freq);

9977

freqstep=diff(Sch.freq);

9987

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9978

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9988

if max(freqstep)-min(freqstep) > 1

9979

if max(freqstep)-min(freqstep) > 1

9989

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9980

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9990

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9981

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9991

end

9982

end

9992

if max(freqstep) - param.max_freq_step > 1

9983

if max(freqstep) - param.max_freq_step > 1

9993

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9984

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9994

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9985

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9995

end

9986

end

9996

9987

9997

chdata(i).faxis = Sch.freq;

9988

chdata(i).faxis = Sch.freq;

9998

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9989

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9999

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9990

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

10000

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9991

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

10001

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9992

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

10002

% mode conversion

9993

% mode conversion

10003

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9994

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

10004

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9995

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

10005

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9996

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

10006

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9997

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

10007

%save original and add board (if required)

9998

%save original and add board (if required)

10008

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9999

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

10009

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

10000

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

10010

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

10001

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

10011

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

10002

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

10012

if OP.include_pcb

10003

if OP.include_pcb

10013

% add boards to sdd

10004

% add boards to sdd

10014

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

10005

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

10015

10006

10016

end

10007

end

10017

%save final return loss (after the boards were included)

10008

%save final return loss (after the boards were included)

10018

chdata(i).sdd11=chdata(i).sdd11_raw;

10009

chdata(i).sdd11=chdata(i).sdd11_raw;

10019

chdata(i).sdd22=chdata(i).sdd22_raw;

10010

chdata(i).sdd22=chdata(i).sdd22_raw;

10020

otherwise

10011

otherwise

10021

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

10012

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

10022

end

10013

end

10023

10014

10024

%Crosstalk frequency axis must be the same as Thru

10015

%Crosstalk frequency axis must be the same as Thru

10025

if i>1

10016

if i>1

10026

%error on length difference

10017

%error on length difference

10027

if length(chdata(i).faxis)~=length(chdata(1).faxis)

10018

if length(chdata(i).faxis)~=length(chdata(1).faxis)

10028

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

10019

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

10029

end

10020

end

10030

%error if any value > 1Hz (don't want to check for exact

10021

%error if any value > 1Hz (don't want to check for exact

10031

%equality in case of floating point error)

10022

%equality in case of floating point error)

10032

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

10023

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

10033

if max(Fdiff)>1

10024

if max(Fdiff)>1

10034

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

10025

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

10035

end

10026

end

10036

end

10027

end

10037

else

10028

else

10038

SDDch(:,1,2)=chdata(i).sdd12_raw;

10029

SDDch(:,1,2)=chdata(i).sdd12_raw;

10039

SDDch(:,2,1)=chdata(i).sdd21_raw;

10030

SDDch(:,2,1)=chdata(i).sdd21_raw;

10040

SDDch(:,1,1)=chdata(i).sdd11_raw;

10031

SDDch(:,1,1)=chdata(i).sdd11_raw;

10041

SDDch(:,2,2)=chdata(i).sdd22_raw;

10032

SDDch(:,2,2)=chdata(i).sdd22_raw;

10042

end

10033

end

10043

chdata(i).sigma_ACCM_at_tp0=0;

10034

chdata(i).sigma_ACCM_at_tp0=0;

10044

if ~param.FLAG.S2P

10035

if ~param.FLAG.S2P

10045

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

10036

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

10046

if (OP.RX_CALIBRATION == 1 && i==2)

10037

if (OP.RX_CALIBRATION == 1 && i==2)

10047

chdata(i).sdd21=chdata(i).sdd21_raw;

10038

chdata(i).sdd21=chdata(i).sdd21_raw;

10048

else

10039

else

10049

%updated package construction with single function for both DD and DC

10040

%updated package construction with single function for both DD and DC

10050

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

10041

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

10051

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

10042

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

10052

chdata(i).sdd21=chdata(i).sdd21p;

10043

chdata(i).sdd21=chdata(i).sdd21p;

10053

if 1 % for AC CM noise inclusion

10044

if 1 % for AC CM noise inclusion

10054

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

10045

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

10055

chdata(i).sdc21=chdata(i).sdc21p;

10046

chdata(i).sdc21=chdata(i).sdc21p;

10056

end

10047

end

10057

end

10048

end

10058

else

10049

else

10059

chdata(i).sdd21=chdata(i).sdd21_raw;

10050

chdata(i).sdd21=chdata(i).sdd21_raw;

10060

end

10051

end

10061

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

10052

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

10062

end

10053

end

10063

end

10054

end

10064

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

10055

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

10065

10056

10066

function result = readdataSnPx(filename, nport)

10057

function result = readdataSnPx(filename, nport)

10067

%function [freq, cs] = readdataSnPx(filename, nport)

10058

%function [freq, cs] = readdataSnPx(filename, nport)

10068

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

10059

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

10069

%

10060

%

10070

% Read Touchstone file with frequencies in units of Hertz

10061

% Read Touchstone file with frequencies in units of Hertz

10071

%

10062

%

10072

% Input:

10063

% Input:

10073

% ======

10064

% ======

10074

% filename: Name of the Touchstone/SnP file

10065

% filename: Name of the Touchstone/SnP file

10075

% nport: Number of ports

10066

% nport: Number of ports

10076

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

10067

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

10077

% Touchstone file)

10068

% Touchstone file)

10078

% nheader: Number of header lines (comment lines plus option line in the

10069

% nheader: Number of header lines (comment lines plus option line in the

10079

% Touchstone file)

10070

% Touchstone file)

10080

%

10071

%

10081

% Output:

10072

% Output:

10082

% =======

10073

% =======

10083

% freq: Vector of frequencies [Hz]

10074

% freq: Vector of frequencies [Hz]

10084

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

10075

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

10085

% at frequency freq(k)

10076

% at frequency freq(k)

10086

%

10077

%

10087

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

10078

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

10088

% frequencies appropriately after reading the data.

10079

% frequencies appropriately after reading the data.

10089

%

10080

%

10090

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

10081

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

10091

% EIA/IBIS Open Forum, 2002.

10082

% EIA/IBIS Open Forum, 2002.

10092

%

10083

%

10093

% Written by Henning Braunisch, September 2004.

10084

% Written by Henning Braunisch, September 2004.

10094

% Updated by Steven Krooswyk, April 2006.

10085

% Updated by Steven Krooswyk, April 2006.

10095

10086

10096

10087

10097

fid = fopen(filename, 'r');

10088

fid = fopen(filename, 'r');

10098

10089

10099

10090

10100

% Skip header lines

10091

% Skip header lines

10101

str = ' ';

10092

str = ' ';

10102

n = 0;

10093

n = 0;

10103

while ~strcmp(str(1),'#')

10094

while ~strcmp(str(1),'#')

10104

str = fgetl(fid);

10095

str = fgetl(fid);

10105

if isempty(str)

10096

if isempty(str)

10106

str=' ' ;

10097

str=' ' ;

10107

if n > 1000

10098

if n > 1000

10108

display('error: could not find config line (#)')

10099

display('error: could not find config line (#)')

10109

break

10100

break

10110

end

10101

end

10111

end

10102

end

10112

n = n + 1;

10103

n = n + 1;

10113

end

10104

end

10114

10105

10115

% parse configuration line

10106

% parse configuration line

10116

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

10107

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

10117

p = find(A=='S'); %position of 'S'

10108

p = find(A=='S'); %position of 'S'

10118

units = lower(A(2:p-1)); %units before 'S'

10109

units = lower(A(2:p-1)); %units before 'S'

10119

format = A(p+1:p+2); %format after 'S'

10110

format = A(p+1:p+2); %format after 'S'

10120

10111

10121

% skip any more header lines

10112

% skip any more header lines

10122

%while ~str

10113

%while ~str

10123

10114

10124

nk = 0; % frequency counter

10115

nk = 0; % frequency counter

10125

while 1

10116

while 1

10126

10117

10127

[temp, count] = fscanf(fid, '%f', 1);

10118

[temp, count] = fscanf(fid, '%f', 1);

10128

if count == 0

10119

if count == 0

10129

temp2 = fscanf(fid, '%s', 1);

10120

temp2 = fscanf(fid, '%s', 1);

10130

if ~isempty(temp2), fgetl(fid); continue, end;

10121

if ~isempty(temp2), fgetl(fid); continue, end;

10131

break

10122

break

10132

end

10123

end

10133

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

10124

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

10134

for ni = 1:nport

10125

for ni = 1:nport

10135

for nj = 1:nport

10126

for nj = 1:nport

10136

switch lower(format)

10127

switch lower(format)

10137

case 'ma'

10128

case 'ma'

10138

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10129

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10139

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

10130

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

10140

case 'ri'

10131

case 'ri'

10141

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

10132

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

10142

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10133

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10143

case 'db'

10134

case 'db'

10144

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10135

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10145

M = 10^(db/20);

10136

M = 10^(db/20);

10146

%re = M*cos(ang);

10137

%re = M*cos(ang);

10147

%im = M*sin(ang);

10138

%im = M*sin(ang);

10148

re = M*cos(ang * pi / 180);

10139

re = M*cos(ang * pi / 180);

10149

im = M*sin(ang * pi / 180);

10140

im = M*sin(ang * pi / 180);

10150

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10141

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10151

otherwise

10142

otherwise

10152

error('readdataSnP: Unknown data format');

10143

error('readdataSnP: Unknown data format');

10153

end

10144

end

10154

end

10145

end

10155

end

10146

end

10156

end

10147

end

10157

10148

10158

fclose(fid);

10149

fclose(fid);

10159

10150

10160

% If 2-port then swap S_12 and S_21 per Touchstone spec

10151

% If 2-port then swap S_12 and S_21 per Touchstone spec

10161

if nport == 2

10152

if nport == 2

10162

temp = cs(2,1,:);

10153

temp = cs(2,1,:);

10163

cs(2,1,:) = cs(1,2,:);

10154

cs(2,1,:) = cs(1,2,:);

10164

cs(1,2,:) = temp;

10155

cs(1,2,:) = temp;

10165

end

10156

end

10166

10157

10167

% Update freq units to Hz

10158

% Update freq units to Hz

10168

switch lower(units)

10159

switch lower(units)

10169

case 'hz'

10160

case 'hz'

10170

10161

10171

case 'khz'

10162

case 'khz'

10172

freq=freq.*1e3;

10163

freq=freq.*1e3;

10173

case 'mhz'

10164

case 'mhz'

10174

freq=freq.*1e6;

10165

freq=freq.*1e6;

10175

case 'ghz'

10166

case 'ghz'

10176

freq=freq.*1e9;

10167

freq=freq.*1e9;

10177

end

10168

end

10178

10169

10179

% passivity check

10170

% passivity check

10180

result.freq = freq;

10171

result.freq = freq;

10181

result.cs = cs;

10172

result.cs = cs;

10182

10173

10183

function recolor_plots(ax)

10174

function recolor_plots(ax)

10184

10175

10185

if ~verLessThan('matlab', '8.4.0')

10176

if ~verLessThan('matlab', '8.4.0')

10186

return

10177

return

10187

end

10178

end

10188

colors='brgcmk';

10179

colors='brgcmk';

10189

ch=flipud(get(ax, 'children'));

10180

ch=flipud(get(ax, 'children'));

10190

10181

10191

for k=1:length(ch)

10182

for k=1:length(ch)

10192

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

10183

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

10193

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

10184

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

10194

end

10185

end

10195

legend (ax, 'off');

10186

legend (ax, 'off');

10196

warning('off', 'MATLAB:legend:PlotEmpty');

10187

warning('off', 'MATLAB:legend:PlotEmpty');

10197

set(legend (ax, 'show'), 'interp', 'none');

10188

set(legend (ax, 'show'), 'interp', 'none');

10198

10189

10199

function result = reduce(var1)

10190

function result = reduce(var1)

10200

% --- Reduce 1x1xn array to 1xn (aka squeeze)

10191

% --- Reduce 1x1xn array to 1xn (aka squeeze)

10201

out = zeros(1,length(var1));

10192

out = zeros(1,length(var1));

10202

out(1,:) = var1(1,1,:);

10193

out(1,:) = var1(1,1,:);

10203

result=out;

10194

result=out;

10204

10195

10205

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

10196

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

10206

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

10197

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

10207

% faxis is the frequency array

10198

% faxis is the frequency array

10208

% s21, s11, s22 are the corresponding array of differential parameters

10199

% s21, s11, s22 are the corresponding array of differential parameters

10209

% s21p includes the VFT and Tx filter if include_die=1

10200

% s21p includes the VFT and Tx filter if include_die=1

10210

if nargin<6

10201

if nargin<6

10211

include_die=1;

10202

include_die=1;

10212

end

10203

end

10213

if nargin<5

10204

if nargin<5

10214

mode='dd';

10205

mode='dd';

10215

end

10206

end

10216

10207

10217

s21=chdata.(['s' mode '21_raw']);

10208

s21=chdata.(['s' mode '21_raw']);

10218

s12=chdata.(['s' mode '12_raw']);

10209

s12=chdata.(['s' mode '12_raw']);

10219

s11=chdata.(['s' mode '11_raw']);

10210

s11=chdata.(['s' mode '11_raw']);

10220

s22=chdata.(['s' mode '22_raw']);

10211

s22=chdata.(['s' mode '22_raw']);

10221

faxis=chdata.faxis;

10212

faxis=chdata.faxis;

10222

channel_type=chdata.type;

10213

channel_type=chdata.type;

10223

10214

10224

if strcmpi(mode,'dd')

10215

if strcmpi(mode,'dd')

10225

s11=s11*param.kappa1;

10216

s11=s11*param.kappa1;

10226

s22=s22*param.kappa2;

10217

s22=s22*param.kappa2;

10227

end

10218

end

10228

10219

10229

10220

10230

Z0=param.Z0;

10221

Z0=param.Z0;

10231

%sigma_ACCM_at_tp0 is only used when mode=DC

10222

%sigma_ACCM_at_tp0 is only used when mode=DC

10232

sigma_ACCM_at_tp0=0;

10223

sigma_ACCM_at_tp0=0;

10233

10224

10234

% The following three parameters have possibly different valuesF for TX and

10225

% The following three parameters have possibly different valuesF for TX and

10235

% RX (so can be 2-element vectors).

10226

% RX (so can be 2-element vectors).

10236

R_diepad = param.R_diepad;

10227

R_diepad = param.R_diepad;

10237

10228

10238

%Make TX Package

10229

%Make TX Package

10239

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

10230

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

10240

10231

10241

%Make RX Package

10232

%Make RX Package

10242

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

10233

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

10243

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

10234

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

10244

10235

10245

10236

10246

% p(1 ,1, :)=s11in;

10237

% p(1 ,1, :)=s11in;

10247

% p(2 ,2, :)=s22in;

10238

% p(2 ,2, :)=s22in;

10248

% p(1 ,2, :)=s12in;

10239

% p(1 ,2, :)=s12in;

10249

% p(2 ,1, :)=s21in;

10240

% p(2 ,1, :)=s21in;

10250

%

10241

%

10251

% S=sparameters(p,faxis);

10242

% S=sparameters(p,faxis);

10252

% rfwrite(S,'temp.s4p');

10243

% rfwrite(S,'temp.s4p');

10253

10244

10254

if strcmpi(mode,'dc')

10245

if strcmpi(mode,'dc')

10255

RTX=R_diepad(param.Tx_rd_sel)/2;

10246

RTX=R_diepad(param.Tx_rd_sel)/2;

10256

RRX=R_diepad(param.Rx_rd_sel)/2;

10247

RRX=R_diepad(param.Rx_rd_sel)/2;

10257

Z0gamma=Z0/2;

10248

Z0gamma=Z0/2;

10258

else

10249

else

10259

RTX=R_diepad(param.Tx_rd_sel);

10250

RTX=R_diepad(param.Tx_rd_sel);

10260

RRX=R_diepad(param.Rx_rd_sel);

10251

RRX=R_diepad(param.Rx_rd_sel);

10261

Z0gamma=Z0;

10252

Z0gamma=Z0;

10262

end

10253

end

10263

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

10254

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

10264

gamma_tx=0;

10255

gamma_tx=0;

10265

else

10256

else

10266

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

10257

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

10267

end

10258

end

10268

if OP.IDEAL_RX_TERM

10259

if OP.IDEAL_RX_TERM

10269

gamma_rx=0;

10260

gamma_rx=0;

10270

else

10261

else

10271

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

10262

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

10272

end

10263

end

10273

10264

10274

if OP.INC_PACKAGE==0

10265

if OP.INC_PACKAGE==0

10275

s21p= s21;

10266

s21p= s21;

10276

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

10267

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

10277

else

10268

else

10278

if OP.RX_CALIBRATION == 1 && channel_number == 2

10269

if OP.RX_CALIBRATION == 1 && channel_number == 2

10279

% for calibration do not include the transmitter package

10270

% for calibration do not include the transmitter package

10280

[s11out_rx, s12out_rx, s21out_rx, s22out_rx ] = combines4p( s11, s12, s21, s22, s22out, s12out, s21out, s11out ); %#ok<ASGLU> % s22 is ball side of package

10271

[s11out_rx, s12out_rx, s21out_rx, s22out_rx ] = combines4p( s11, s12, s21, s22, s22out, s12out, s21out, s11out ); %#ok<ASGLU> % s22 is ball side of package

10281

SCH.Frequencies=faxis;

10272

SCH.Frequencies=faxis;

10282

SCH.Parameters(1,1,:)=s11out_rx;

10273

SCH.Parameters(1,1,:)=s11out_rx;

10283

SCH.Parameters(2,2,:)=s22out_rx;

10274

SCH.Parameters(2,2,:)=s22out_rx;

10284

SCH.Parameters(1,2,:)=s12out_rx;

10275

SCH.Parameters(1,2,:)=s12out_rx;

10285

SCH.Parameters(2,1,:)=s21out_rx;

10276

SCH.Parameters(2,1,:)=s21out_rx;

10286

SCH.NumPorts=2;

10277

SCH.NumPorts=2;

10287

SCH.Impedance=100;

10278

SCH.Impedance=100;

10288

%% Equation 93A-18

10279

%% Equation 93A-18

10289

if include_die

10280

if include_die

10290

s21p= s21out_rx.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11out_rx.*gamma_tx - s22out_rx.*gamma_rx -s21out_rx.^2.*gamma_tx.*gamma_rx +s11out_rx.*s22out_rx.*gamma_tx.*gamma_rx);

10281

s21p= s21out_rx.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11out_rx.*gamma_tx - s22out_rx.*gamma_rx -s21out_rx.^2.*gamma_tx.*gamma_rx +s11out_rx.*s22out_rx.*gamma_tx.*gamma_rx);

10291

else

10282

else

10292

s21p=s21out_rx; % if no die we do not want a VTF

10283

s21p=s21out_rx; % if no die we do not want a VTF

10293

end

10284

end

10294

else

10285

else

10295

%% Equations 93A-4 to 93A-7

10286

%% Equations 93A-4 to 93A-7

10296

if ~OP.IDEAL_TX_TERM

10287

if ~OP.IDEAL_TX_TERM

10297

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10288

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10298

end

10289

end

10299

H_t=ones(1,length(faxis)); % .3bj compatibility

10290

H_t=ones(1,length(faxis)); % .3bj compatibility

10300

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10291

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10301

% for RITT testing with good termination as in some instruments

10292

% for RITT testing with good termination as in some instruments

10302

% and tx filter when required

10293

% and tx filter when required

10303

if OP.T_r_filter_type==0

10294

if OP.T_r_filter_type==0

10304

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10295

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10305

else

10296

else

10306

tr=OP.transmitter_transition_time;

10297

tr=OP.transmitter_transition_time;

10307

f9=faxis/1e9;

10298

f9=faxis/1e9;

10308

if OP.T_r_meas_point == 1

10299

if OP.T_r_meas_point == 1

10309

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10300

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10310

H_t=105./(f9.^4*(k*tr)^4 - f9.^3*(k*tr)^3*10i - 45*f9.^2*(k*tr)^2 + f9*(k*tr)*105i + 105);

10301

H_t=105./(f9.^4*(k*tr)^4 - f9.^3*(k*tr)^3*10i - 45*f9.^2*(k*tr)^2 + f9*(k*tr)*105i + 105);

10311

else

10302

else

10312

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10303

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10313

end

10304

end

10314

10305

10315

end

10306

end

10316

end

10307

end

10317

if strcmpi(mode,'dc')

10308

if strcmpi(mode,'dc')

10318

% H_t=ones(1,length(faxis)); % not sure if we need a H_t or not. Is the CM noise correlated to the edge rate?

10309

% H_t=ones(1,length(faxis)); % not sure if we need a H_t or not. Is the CM noise correlated to the edge rate?

10319

end

10310

end

10320

if ~OP.IDEAL_RX_TERM

10311

if ~OP.IDEAL_RX_TERM

10321

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10312

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10322

else

10313

else

10323

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10314

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10324

end

10315

end

10325

%% Equation 93A-18 and part of 93A-1: Ht fix in V290 identified by Bill Kirkland and Ed Frlan ( s21^2 changed to s12*s21 )

10316

%% Equation 93A-18 and part of 93A-1: Ht fix in V290 identified by Bill Kirkland and Ed Frlan ( s21^2 changed to s12*s21 )

10326

if include_die

10317

if include_die

10327

s21p= H_t.*s21.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11.*gamma_tx - s22.*gamma_rx -s21.*s12.*gamma_tx.*gamma_rx +s11.*s22.*gamma_tx.*gamma_rx);

10318

s21p= H_t.*s21.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11.*gamma_tx - s22.*gamma_rx -s21.*s12.*gamma_tx.*gamma_rx +s11.*s22.*gamma_tx.*gamma_rx);

10328

else

10319

else

10329

s21p=s21; % if no die we do not want a VTF

10320

s21p=s21; % if no die we do not want a VTF

10330

end

10321

end

10331

end

10322

end

10332

10323

10333

if strcmpi(mode,'dc')

10324

if strcmpi(mode,'dc')

10334

% compute AC_CM_RMS at tp0

10325

% compute AC_CM_RMS at tp0

10335

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10326

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10336

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10327

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10337

if channel_number == 1

10328

if channel_number == 1

10338

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10329

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10339

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10330

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10340

sigma_ACCM_at_tp0= sqrt(2*param.AC_CM_RMS_TX^2*sum( abs( H_cc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end)) ;

10331

sigma_ACCM_at_tp0= sqrt(2*param.AC_CM_RMS_TX^2*sum( abs( H_cc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end)) ;

10341

% S=sparameters(p,faxis);

10332

% S=sparameters(p,faxis);

10342

% rfwrite(S,'temp.s4p');

10333

% rfwrite(S,'temp.s4p');

10343

end

10334

end

10344

end

10335

end

10345

10336

10346

SCH.Frequencies=faxis;

10337

SCH.Frequencies=faxis;

10347

SCH.Parameters(1,1,:)=s11;

10338

SCH.Parameters(1,1,:)=s11;

10348

SCH.Parameters(2,2,:)=s22;

10339

SCH.Parameters(2,2,:)=s22;

10349

SCH.Parameters(1,2,:)=s12;

10340

SCH.Parameters(1,2,:)=s12;

10350

SCH.Parameters(2,1,:)=s21;

10341

SCH.Parameters(2,1,:)=s21;

10351

SCH.NumPorts=2;

10342

SCH.NumPorts=2;

10352

if strcmpi(mode,'dc')

10343

if strcmpi(mode,'dc')

10353

SCH.Impedance=25;

10344

SCH.Impedance=25;

10354

else

10345

else

10355

SCH.Impedance=100;

10346

SCH.Impedance=100;

10356

end

10347

end

10357

10348

10358

end

10349

end

10359

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10350

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10360

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10351

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10361

% Creates a time-domain impulse response from frequency-domain IL data.

10352

% Creates a time-domain impulse response from frequency-domain IL data.

10362

% IL does not need to have DC but a corresponding frequency array

10353

% IL does not need to have DC but a corresponding frequency array

10363

% (freq_array) is required.

10354

% (freq_array) is required.

10364

%

10355

%

10365

% Causality is imposed using the Alternating Projections Method. See also:

10356

% Causality is imposed using the Alternating Projections Method. See also:

10366

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10357

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10367

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10358

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10368

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10359

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10369

10360

10370

ILin=IL;

10361

ILin=IL;

10371

fmax=1/time_step/2;

10362

fmax=1/time_step/2;

10372

freq_step=(freq_array(3)-freq_array(2))/1;

10363

freq_step=(freq_array(3)-freq_array(2))/1;

10373

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10364

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10374

if all(IL==0)

10365

if all(IL==0)

10375

%response with all zeros is problematic. set to all eps and avoid interp function

10366

%response with all zeros is problematic. set to all eps and avoid interp function

10376

IL=ones(1,length(fout))*eps;

10367

IL=ones(1,length(fout))*eps;

10377

else

10368

else

10378

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10369

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10379

IL_nan = find(isnan(IL));

10370

IL_nan = find(isnan(IL));

10380

for in=IL_nan

10371

for in=IL_nan

10381

IL(in)=IL(in-1);

10372

IL(in)=IL(in-1);

10382

end

10373

end

10383

end

10374

end

10384

IL = IL(:);

10375

IL = IL(:);

10385

% add padding for time steps

10376

% add padding for time steps

10386

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10377

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10387

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10378

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10388

impulse_response = real(ifft(IL_symmetric));

10379

impulse_response = real(ifft(IL_symmetric));

10389

L = length(impulse_response);

10380

L = length(impulse_response);

10390

t_base = (0:L-1)/(freq_step*L);

10381

t_base = (0:L-1)/(freq_step*L);

10391

10382

10392

original_impulse_response=impulse_response;

10383

original_impulse_response=impulse_response;

10393

% Correct non-causal effects frequently caused by extrapolation of IL

10384

% Correct non-causal effects frequently caused by extrapolation of IL

10394

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10385

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10395

abs_ir=abs(impulse_response);

10386

abs_ir=abs(impulse_response);

10396

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10387

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10397

start_ind = a(1);

10388

start_ind = a(1);

10398

10389

10399

err=inf;

10390

err=inf;

10400

while ~all(impulse_response==0)

10391

while ~all(impulse_response==0)

10401

impulse_response(1:start_ind)=0;

10392

impulse_response(1:start_ind)=0;

10402

impulse_response(floor(L/2):end)=0;

10393

impulse_response(floor(L/2):end)=0;

10403

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10394

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10404

ir_modified = real(ifft(IL_modified));

10395

ir_modified = real(ifft(IL_modified));

10405

delta = abs(impulse_response-ir_modified);

10396

delta = abs(impulse_response-ir_modified);

10406

10397

10407

err_prev = err;

10398

err_prev = err;

10408

err=max(delta)/max(impulse_response);

10399

err=max(delta)/max(impulse_response);

10409

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10400

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10410

break;

10401

break;

10411

end

10402

end

10412

10403

10413

impulse_response=ir_modified;

10404

impulse_response=ir_modified;

10414

end

10405

end

10415

10406

10416

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10407

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10417

10408

10418

if ~OP.ENFORCE_CAUSALITY

10409

if ~OP.ENFORCE_CAUSALITY

10419

impulse_response = original_impulse_response;

10410

impulse_response = original_impulse_response;

10420

end

10411

end

10421

% truncate final samples smaller than 1e-3 of the peak

10412

% truncate final samples smaller than 1e-3 of the peak

10422

ir_peak = max(abs(impulse_response));

10413

ir_peak = max(abs(impulse_response));

10423

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10414

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10424

10415

10425

voltage = impulse_response(1:ir_last);

10416

voltage = impulse_response(1:ir_last);

10426

t_base = t_base(1:ir_last);

10417

t_base = t_base(1:ir_last);

10427

10418

10428

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10419

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10429

10420

10430

function S =s_for_c2(zref,f,cpad)

10421

function S =s_for_c2(zref,f,cpad)

10431

% S is 2 port s parameters out

10422

% S is 2 port s parameters out

10432

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10423

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10433

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10424

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10434

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10425

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10435

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10426

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10436

S=sparameters(S_Parameters,f,zref);

10427

S=sparameters(S_Parameters,f,zref);

10437

10428

10438

function S =s_for_c4(zref,f,cpad)

10429

function S =s_for_c4(zref,f,cpad)

10439

10430

10440

S2 = s_for_c2(zref,f,cpad);

10431

S2 = s_for_c2(zref,f,cpad);

10441

S4P=s2_to_s4(S2.Parameters);

10432

S4P=s2_to_s4(S2.Parameters);

10442

S=sparameters(S4P,f,zref);

10433

S=sparameters(S4P,f,zref);

10443

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10434

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10444

10435

10445

10436

10446

10437

10447

10438

10448

%%

10439

%%

10449

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10440

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10450

% save commmend string

10441

% save commmend string

10451

% for saving from interactive queries

10442

% for saving from interactive queries

10452

10443

10453

10444

10454

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10445

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10455

for i=1:num_next+num_fext

10446

for i=1:num_next+num_fext

10456

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10447

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10457

end

10448

end

10458

cmd_str= [ cmd_str ')'];

10449

cmd_str= [ cmd_str ')'];

10459

10450

10460

10451

10461

%%%%% require the RF tool box

10452

%%%%% require the RF tool box

10462

%%

10453

%%

10463

function [ h ] = savefigs( param, OP )

10454

function [ h ] = savefigs( param, OP )

10464

10455

10465

%% find the figures

10456

%% find the figures

10466

hw = waitbar(0,'Saving figures...');

10457

hw = waitbar(0,'Saving figures...');

10467

h = findobj(0, 'Type', 'figure');

10458

h = findobj(0, 'Type', 'figure');

10468

for ii=1:length(h)

10459

for ii=1:length(h)

10469

10460

10470

figname= get(h(ii), 'Name'); % use the figure name as file name

10461

figname= get(h(ii), 'Name'); % use the figure name as file name

10471

if isempty(strfind(figname,param.base))

10462

if isempty(strfind(figname,param.base))

10472

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10463

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10473

end

10464

end

10474

if verLessThan('matlab', '8.4.0')

10465

if verLessThan('matlab', '8.4.0')

10475

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10466

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10476

else

10467

else

10477

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10468

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10478

end

10469

end

10479

figname = strrep(figname,':','-');

10470

figname = strrep(figname,':','-');

10480

figname = strrep(figname,' ','_');

10471

figname = strrep(figname,' ','_');

10481

if OP.SAVE_FIGURES==1

10472

if OP.SAVE_FIGURES==1

10482

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10473

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10483

end

10474

end

10484

%% get x y data

10475

%% get x y data

10485

if OP.SAVE_FIGURE_to_CSV==1

10476

if OP.SAVE_FIGURE_to_CSV==1

10486

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10477

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10487

M=[]; %ncol=1;

10478

M=[]; %ncol=1;

10488

for nk=1:length(h_L)

10479

for nk=1:length(h_L)

10489

% get x and data for a line.

10480

% get x and data for a line.

10490

x_data=get(h_L(nk),'xdata')';

10481

x_data=get(h_L(nk),'xdata')';

10491

y_data=get(h_L(nk),'ydata')';

10482

y_data=get(h_L(nk),'ydata')';

10492

% .........>> need to get data in the line structure (legend or label) for headers

10483

% .........>> need to get data in the line structure (legend or label) for headers

10493

M=[M; x_data; y_data]; %#ok<AGROW>

10484

M=[M; x_data; y_data]; %#ok<AGROW>

10494

end

10485

end

10495

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10486

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10496

% clear M y x header h_L

10487

% clear M y x header h_L

10497

end

10488

end

10498

waitbar(ii/length(h),hw)

10489

waitbar(ii/length(h),hw)

10499

10490

10500

end

10491

end

10501

10492

10502

close(hw)

10493

close(hw)

10503

10494

10504

%%

10495

%%

10505

function [ h ] = savefigs_png( param, OP )

10496

function [ h ] = savefigs_png( param, OP )

10506

10497

10507

%% find the figures

10498

%% find the figures

10508

hw = waitbar(0,'Saving figures...');

10499

hw = waitbar(0,'Saving figures...');

10509

h = findobj(0, 'Type', 'figure');

10500

h = findobj(0, 'Type', 'figure');

10510

for ii=1:length(h)

10501

for ii=1:length(h)

10511

10502

10512

figname= get(h(ii), 'Name'); % use the figure name as file name

10503

figname= get(h(ii), 'Name'); % use the figure name as file name

10513

if isempty(strfind(figname,param.base))

10504

if isempty(strfind(figname,param.base))

10514

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10505

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10515

end

10506

end

10516

if verLessThan('matlab', '8.4.0')

10507

if verLessThan('matlab', '8.4.0')

10517

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10508

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10518

else

10509

else

10519

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10510

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10520

end

10511

end

10521

figname = strrep(figname,':','-');

10512

figname = strrep(figname,':','-');

10522

figname = strrep(figname,' ','_');

10513

figname = strrep(figname,' ','_');

10523

if OP.SAVE_FIGURES==1

10514

if OP.SAVE_FIGURES==1

10524

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10515

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10525

end

10516

end

10526

%% get x y data

10517

%% get x y data

10527

if OP.SAVE_FIGURE_to_CSV==1

10518

if OP.SAVE_FIGURE_to_CSV==1

10528

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10519

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10529

M=[]; %ncol=1;

10520

M=[]; %ncol=1;

10530

for nk=1:length(h_L)

10521

for nk=1:length(h_L)

10531

% get x and data for a line.

10522

% get x and data for a line.

10532

x_data=get(h_L(nk),'xdata')';

10523

x_data=get(h_L(nk),'xdata')';

10533

y_data=get(h_L(nk),'ydata')';

10524

y_data=get(h_L(nk),'ydata')';

10534

% .........>> need to get data in the line structure (legend or label) for headers

10525

% .........>> need to get data in the line structure (legend or label) for headers

10535

M=[M; x_data; y_data]; %#ok<AGROW>

10526

M=[M; x_data; y_data]; %#ok<AGROW>

10536

end

10527

end

10537

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10528

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10538

% clear M y x header h_L

10529

% clear M y x header h_L

10539

end

10530

end

10540

waitbar(ii/length(h),hw)

10531

waitbar(ii/length(h),hw)

10541

10532

10542

end

10533

end

10543

10534

10544

close(hw)

10535

close(hw)

10545

10536

10546

%%

10537

%%

10547

function pdf_out = scalePDF(pdf,scale_factor)

10538

function pdf_out = scalePDF(pdf,scale_factor)

10548

pdf_out=pdf;

10539

pdf_out=pdf;

10549

pdf_out.Min=floor(pdf.Min*scale_factor);

10540

pdf_out.Min=floor(pdf.Min*scale_factor);

10550

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10541

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10551

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10542

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10552

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10543

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10553

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10544

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10554

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10545

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10555

function t_params = stot(s_params)

10546

function t_params = stot(s_params)

10556

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10547

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10557

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10548

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10558

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10549

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10559

delta = (s11.*s22-s12.*s21);

10550

delta = (s11.*s22-s12.*s21);

10560

s21(s21==0)=eps;

10551

s21(s21==0)=eps;

10561

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10552

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10562

10553

10563

function csv_string = str2csv(c)

10554

function csv_string = str2csv(c)

10564

% convert a cell array of strings to a csv string

10555

% convert a cell array of strings to a csv string

10565

cell_tmp = cell(2, length(c));

10556

cell_tmp = cell(2, length(c));

10566

cell_tmp(1,:)=c;

10557

cell_tmp(1,:)=c;

10567

cell_tmp(2,:) = {','};

10558

cell_tmp(2,:) = {','};

10568

cell_tmp{2,end} = '';

10559

cell_tmp{2,end} = '';

10569

csv_string=strcat(cell_tmp{:});

10560

csv_string=strcat(cell_tmp{:});

10570

10561

10571

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10562

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10572

f_GHz=f/1e9;

10563

f_GHz=f/1e9;

10573

%% Equation 93A-10 %%

10564

%% Equation 93A-10 %%

10574

gamma_1 = gamma_coeff(2)*(1+1i);

10565

gamma_1 = gamma_coeff(2)*(1+1i);

10575

%% Equation 93A-11 %%

10566

%% Equation 93A-11 %%

10576

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10567

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10577

%% Equation 93A-9 %%

10568

%% Equation 93A-9 %%

10578

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10569

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10579

gamma(f_GHz==0) = gamma_coeff(1);

10570

gamma(f_GHz==0) = gamma_coeff(1);

10580

10571

10581

%% Equation 93A-12 %%

10572

%% Equation 93A-12 %%

10582

if d==0

10573

if d==0

10583

%force matched impedance if length is 0

10574

%force matched impedance if length is 0

10584

%otherwise divide by zero can occur if Z_c=0

10575

%otherwise divide by zero can occur if Z_c=0

10585

rho_rl=0;

10576

rho_rl=0;

10586

else

10577

else

10587

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10578

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10588

end

10579

end

10589

10580

10590

exp_gamma_d = exp(-d*gamma);

10581

exp_gamma_d = exp(-d*gamma);

10591

%% Equations 93A-13 and 93A-14 %%

10582

%% Equations 93A-13 and 93A-14 %%

10592

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10583

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10593

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10584

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10594

s12 = s21;

10585

s12 = s21;

10595

s22 = s11;

10586

s22 = s11;

10596

10587

10597

function s_params = ttos(t_params)

10588

function s_params = ttos(t_params)

10598

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10589

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10599

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10590

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10600

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10591

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10601

delta = t11.*t22-t21.*t12;

10592

delta = t11.*t22-t21.*t12;

10602

t11(t11==0)=eps;

10593

t11(t11==0)=eps;

10603

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10594

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10604

10595

10605

function [out_var,varg_out]=varargin_extractor(varargin)

10596

function [out_var,varg_out]=varargin_extractor(varargin)

10606

10597

10607

if isempty(varargin)

10598

if isempty(varargin)

10608

out_var=[];

10599

out_var=[];

10609

varg_out={};

10600

varg_out={};

10610

else

10601

else

10611

out_var=varargin{1};

10602

out_var=varargin{1};

10612

varg_out=varargin;

10603

varg_out=varargin;

10613

varg_out(1)=[];

10604

varg_out(1)=[];

10614

end

10605

end

10615

10606

10616

10607

10617

function results= vma(PR, M)

10608

function results= vma(PR, M)

10618

% PR=sbr.Data;

10609

% PR=sbr.Data;

10619

% M=32;

10610

% M=32;

10620

% PR is the pulse response

10611

% PR is the pulse response

10621

% M is samples per UI

10612

% M is samples per UI

10622

[ seq, syms, syms_nrz ] = PRBS13Q( );

10613

[ seq, syms, syms_nrz ] = PRBS13Q( );

10623

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10614

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10624

symbols=seq;

10615

symbols=seq;

10625

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10616

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10626

% start end symbols index for 7 3's and 6 0's

10617

% start end symbols index for 7 3's and 6 0's

10627

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10618

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10628

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10619

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10629

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10620

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10630

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10621

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10631

% superposition code

10622

% superposition code

10632

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10623

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10633

Bit_stream_response=filter(PR,1, shifting_vector);

10624

Bit_stream_response=filter(PR,1, shifting_vector);

10634

% find center of 3's and 0's

10625

% find center of 3's and 0's

10635

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10626

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10636

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10627

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10637

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10628

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10638

% hold on

10629

% hold on

10639

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10630

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10640

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10631

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10641

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10632

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10642

VMA= P_3 - P_0;

10633

VMA= P_3 - P_0;

10643

results.P_3=P_3;

10634

results.P_3=P_3;

10644

results.P_0=P_0;

10635

results.P_0=P_0;

10645

results.VMA=VMA;

10636

results.VMA=VMA;

10646

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10637

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10647

10638

10648

%slope of the 2 sample points around vref crossing

10639

%slope of the 2 sample points around vref crossing

10649

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10640

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10650

%x-intercept for the line

10641

%x-intercept for the line

10651

b1=eye_contour(x_in,1)-m1*x_in;

10642

b1=eye_contour(x_in,1)-m1*x_in;

10652

% drawing a horizontal line through vref so slope = 0

10643

% drawing a horizontal line through vref so slope = 0

10653

m2=0;

10644

m2=0;

10654

%special case for horizontal line, b=y

10645

%special case for horizontal line, b=y

10655

b2=vref;

10646

b2=vref;

10656

%the x-value of line intersection = (b2-b1)/(m1-m2)

10647

%the x-value of line intersection = (b2-b1)/(m1-m2)

10657

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10648

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10658

%And usually vref is 0, so it further reduces to -b1/m1

10649

%And usually vref is 0, so it further reduces to -b1/m1

10659

line_intersection=(b2-b1)/(m1-m2);

10650

line_intersection=(b2-b1)/(m1-m2);

10660

10651

10661

10652

10662

10653

10663

10654

10664

10655

10665

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10656

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10666

% helper function to read parameter values from XLS file. Uses names to find values.

10657

% helper function to read parameter values from XLS file. Uses names to find values.

10667

if nargin<3, eval_if_string=0; end

10658

if nargin<3, eval_if_string=0; end

10668

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10659

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10669

if numel(row)*numel(col)==0

10660

if numel(row)*numel(col)==0

10670

if nargin<4

10661

if nargin<4

10671

missingParameter(param_name);

10662

missingParameter(param_name);

10672

else

10663

else

10673

p = default_value;

10664

p = default_value;

10674

end

10665

end

10675

elseif numel(row)*numel(col)>1

10666

elseif numel(row)*numel(col)>1

10676

% if there are several occurrences, use the first, but warn

10667

% if there are several occurrences, use the first, but warn

10677

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10668

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10678

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10669

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10679

error('COM:XLS_parameter:MultipleOccurrence', ...

10670

error('COM:XLS_parameter:MultipleOccurrence', ...

10680

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10671

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10681

p=param_sheet{row(1), col(1)+1};

10672

p=param_sheet{row(1), col(1)+1};

10682

else

10673

else

10683

p=param_sheet{row, col+1};

10674

p=param_sheet{row, col+1};

10684

end

10675

end

10685

if ischar(p) && eval_if_string

10676

if ischar(p) && eval_if_string

10686

p=eval(p);

10677

p=eval(p);

10687

end

10678

end

10688

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10679

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10689

if OP.SAVE_KEYWORD_FILE

10680

if OP.SAVE_KEYWORD_FILE

10690

10681

10691

if nargin<3 || ~exist('default_value','var')

10682

if nargin<3 || ~exist('default_value','var')

10692

default_value=p;

10683

default_value=p;

10693

end

10684

end

10694

if isempty(default_value)

10685

if isempty(default_value)

10695

default_value='-';

10686

default_value='-';

10696

end

10687

end

10697

%%

10688

%%

10698

% Get call-stack info:

10689

% Get call-stack info:

10699

stDebug = dbstack;

10690

stDebug = dbstack;

10700

callerFileName = stDebug(2).file;

10691

callerFileName = stDebug(2).file;

10701

callerLineNumber = stDebug(2).line;

10692

callerLineNumber = stDebug(2).line;

10702

% Open caller file:

10693

% Open caller file:

10703

fCaller = fopen(callerFileName);

10694

fCaller = fopen(callerFileName);

10704

% Iterate through lines to get to desired line number:

10695

% Iterate through lines to get to desired line number:

10705

for iLine = 1 : callerLineNumber

10696

for iLine = 1 : callerLineNumber

10706

% Read current line of text:

10697

% Read current line of text:

10707

currLine = fgetl(fCaller);

10698

currLine = fgetl(fCaller);

10708

end

10699

end

10709

% (currLine) now reflects calling desired code: display this code:

10700

% (currLine) now reflects calling desired code: display this code:

10710

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10701

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10711

% Close caller file:

10702

% Close caller file:

10712

left_side=currLine(1:strfind(currLine,'=')-1);

10703

left_side=currLine(1:strfind(currLine,'=')-1);

10713

cmt_side=currLine(strfind(currLine,'%')+1:end);

10704

cmt_side=currLine(strfind(currLine,'%')+1:end);

10714

if isempty(cmt_side), cmt_side=' ';end

10705

if isempty(cmt_side), cmt_side=' ';end

10715

fclose(fCaller);

10706

fclose(fCaller);

10716

10707

10717

if ~ischar(default_value)

10708

if ~ischar(default_value)

10718

default_str=sprintf('%g ',default_value);

10709

default_str=sprintf('%g ',default_value);

10719

else

10710

else

10720

default_str=default_value;

10711

default_str=default_value;

10721

end

10712

end

10722

if ~isfile('keyworklog.mat')

10713

if ~isfile('keyworklog.mat')

10723

save_p=param_name;

10714

save_p=param_name;

10724

save_d=default_str;

10715

save_d=default_str;

10725

save_r=left_side;

10716

save_r=left_side;

10726

save_c=cmt_side;

10717

save_c=cmt_side;

10727

param_name = {'keyword'};

10718

param_name = {'keyword'};

10728

default_str = {'default'};

10719

default_str = {'default'};

10729

left_side={'matlab variable'};

10720

left_side={'matlab variable'};

10730

cmt_side={'info'};

10721

cmt_side={'info'};

10731

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10722

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10732

param_name=save_p;

10723

param_name=save_p;

10733

default_str=save_d;

10724

default_str=save_d;

10734

left_side=save_r;

10725

left_side=save_r;

10735

cmt_side=save_c;

10726

cmt_side=save_c;

10736

data=load('keyworklog.mat');

10727

data=load('keyworklog.mat');

10737

else

10728

else

10738

load('keyworklog.mat');

10729

load('keyworklog.mat');

10739

end

10730

end

10740

data.left_side = [ data.left_side; left_side];

10731

data.left_side = [ data.left_side; left_side];

10741

data.param_name = [data.param_name; param_name];

10732

data.param_name = [data.param_name; param_name];

10742

data.default_str = [data.default_str; default_str ];

10733

data.default_str = [data.default_str; default_str ];

10743

data.cmt_side = [ data.cmt_side; cmt_side];

10734

data.cmt_side = [ data.cmt_side; cmt_side];

10744

if length(data.default_str)~=length(data.default_str)

10735

if length(data.default_str)~=length(data.default_str)

10745

a=1;

10736

a=1;

10746

end

10737

end

10747

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10738

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10748

save('keyworklog.mat','data');

10739

save('keyworklog.mat','data');

10749

writetable(T,[ 'keywords_' date '.csv' ]);

10740

writetable(T,[ 'keywords_' date '.csv' ]);

10750

end

10741

end

10751

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10742

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10752

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10743

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10753

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10744

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10754

10745

10755

found=1;

10746

found=1;

10756

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10747

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10757

if numel(row)*numel(col)==0

10748

if numel(row)*numel(col)==0

10758

p = 0;

10749

p = 0;

10759

found=0;

10750

found=0;

10760

elseif numel(row)*numel(col)>1

10751

elseif numel(row)*numel(col)>1

10761

% if there are several occurrences, use the first, but warn

10752

% if there are several occurrences, use the first, but warn

10762

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10753

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10763

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10754

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10764

error('COM:XLS_parameter:MultipleOccurrence', ...

10755

error('COM:XLS_parameter:MultipleOccurrence', ...

10765

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10756

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10766

p=param_sheet{row(1), col(1)+1};

10757

p=param_sheet{row(1), col(1)+1};

10767

else

10758

else

10768

p=param_sheet{row, col+1};

10759

p=param_sheet{row, col+1};

10769

end

10760

end

10770

if ischar(p)

10761

if ischar(p)

10771

p=eval(p);

10762

p=eval(p);

10772

end

10763

end

10773

function zzz_list_of_changes

10764

function zzz_list_of_changes

10774

% structures:

10765

% structures:

10775

% chdata(i)

10766

% chdata(i)

10776

% i= 1 --> THRU index

10767

% i= 1 --> THRU index

10777

% i= 2, num_fext+1 --> FEXT channel index

10768

% i= 2, num_fext+1 --> FEXT channel index

10778

% i= num_fext+2, num_next+num_fext+1

10769

% i= num_fext+2, num_next+num_fext+1

10779

% base: name of THRU file

10770

% base: name of THRU file

10780

% A: amplitude

10771

% A: amplitude

10781

% type: 'THRU', 'NEXT', or 'FEXT'

10772

% type: 'THRU', 'NEXT', or 'FEXT'

10782

% ftr: Rise time frequency

10773

% ftr: Rise time frequency

10783

% fmaxi: max number of frequency points

10774

% fmaxi: max number of frequency points

10784

% faxis: frequency array [Hz]

10775

% faxis: frequency array [Hz]

10785

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10776

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10786

% sdd22: differential RL

10777

% sdd22: differential RL

10787

% sdd11: differential RL

10778

% sdd11: differential RL

10788

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10779

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10789

% sdd21f: raw differential IL not filtered use for FD plots

10780

% sdd21f: raw differential IL not filtered use for FD plots

10790

% added output_args.peak_uneq_pulse_mV

10781

% added output_args.peak_uneq_pulse_mV

10791

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10782

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10792

% added: tap c(-2) c(2) and c(3)

10783

% added: tap c(-2) c(2) and c(3)

10793

% added: g_DC_HP and f_HP_PZ

10784

% added: g_DC_HP and f_HP_PZ

10794

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10785

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10795

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10786

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10796

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10787

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10797

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10788

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10798

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10789

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10799

% fixed INCLUDE_CTLE=0 to really remove from computation

10790

% fixed INCLUDE_CTLE=0 to really remove from computation

10800

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10791

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10801

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10792

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10802

% r162 tx and rx package impedance {Zc)

10793

% r162 tx and rx package impedance {Zc)

10803

% r162a Gaussian equation corrected

10794

% r162a Gaussian equation corrected

10804

% r163 cast snr_tx with package test case

10795

% r163 cast snr_tx with package test case

10805

% r164 fix pdf for very low noise and lo pass filter enhancements

10796

% r164 fix pdf for very low noise and lo pass filter enhancements

10806

% r164 add zero gain at nqyist CTLE as in CL12e

10797

% r164 add zero gain at nqyist CTLE as in CL12e

10807

% r165 add simpler congfig command called FORCE_TR (force risetime)

10798

% r165 add simpler congfig command called FORCE_TR (force risetime)

10808

% r200 cm3 and cm4 added cp3 removed

10799

% r200 cm3 and cm4 added cp3 removed

10809

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10800

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10810

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10801

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10811

% r200 improved phase interpolation for return loss time conversion

10802

% r200 improved phase interpolation for return loss time conversion

10812

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10803

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10813

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10804

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10814

% r200c missed on fix for interpolation

10805

% r200c missed on fix for interpolation

10815

% r210 new ERL with time gating function

10806

% r210 new ERL with time gating function

10816

% r224 update ERL with from D3.1

10807

% r224 update ERL with from D3.1

10817

% r226 fix s2p reading problem

10808

% r226 fix s2p reading problem

10818

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10809

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10819

% Fix Rx calibration issue

10810

% Fix Rx calibration issue

10820

% added ERL limit and Nd

10811

% added ERL limit and Nd

10821

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10812

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10822

% INC_PACKAGE=0 not fully supported message

10813

% INC_PACKAGE=0 not fully supported message

10823

% if N=0 use TDR_duration

10814

% if N=0 use TDR_duration

10824

% red display text for fail ERL and COM

10815

% red display text for fail ERL and COM

10825

% r228 fixed ERL pass fail report, default Grr_limit to 1

10816

% r228 fixed ERL pass fail report, default Grr_limit to 1

10826

% r230 add rx ffe

10817

% r230 add rx ffe

10827

% r231 change crosstalk noise to icn like to speed things up

10818

% r231 change crosstalk noise to icn like to speed things up

10828

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10819

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10829

% 1e-5mof-

10820

% 1e-5mof-

10830

% r232 fix default for Rx eq so old spead sheets work

10821

% r232 fix default for Rx eq so old spead sheets work

10831

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10822

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10832

% r235 adding dfe quantization changed to normalized DFE taps reported

10823

% r235 adding dfe quantization changed to normalized DFE taps reported

10833

% r236 adding ffe gain loop and resample after RxFFE

10824

% r236 adding ffe gain loop and resample after RxFFE

10834

% r240 added output for C2M and setting defaults for some FFE eq

10825

% r240 added output for C2M and setting defaults for some FFE eq

10835

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10826

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10836

% r250 adding more complex package

10827

% r250 adding more complex package

10837

% r251 post cursor fix for DFE in force() and ffe backoff

10828

% r251 post cursor fix for DFE in force() and ffe backoff

10838

% r251 remove TDR threshold noise filter

10829

% r251 remove TDR threshold noise filter

10839

% r252 add rx FFE filter to receiver noise filter

10830

% r252 add rx FFE filter to receiver noise filter

10840

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10831

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10841

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10832

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10842

% r254 precursor check fix in optimize_fom % mod fix in force

10833

% r254 precursor check fix in optimize_fom % mod fix in force

10843

% r254 help to align columns in csv file

10834

% r254 help to align columns in csv file

10844

% r254 accept syntax for 2 tline flex package model

10835

% r254 accept syntax for 2 tline flex package model

10845

% r256 speed up optimize FOM

10836

% r256 speed up optimize FOM

10846

% r256 fix problem reading in config file from q/a

10837

% r256 fix problem reading in config file from q/a

10847

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10838

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10848

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10839

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10849

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10840

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10850

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10841

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10851

% r258 CDR switch 'MM' or 'mod-MM'

10842

% r258 CDR switch 'MM' or 'mod-MM'

10852

% r258 correction for asymentirc tx/Rx packages

10843

% r258 correction for asymentirc tx/Rx packages

10853

% r258 revamped display results display window

10844

% r258 revamped display results display window

10854

% r259 fix problem if Min_VEO is set in spreadsheet.

10845

% r259 fix problem if Min_VEO is set in spreadsheet.

10855

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10846

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10856

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10847

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10857

% r259 putting COM_db and IL last in output to terminal

10848

% r259 putting COM_db and IL last in output to terminal

10858

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10849

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10859

% r259 use N_bx for ERL rather than Nb (ndfe))

10850

% r259 use N_bx for ERL rather than Nb (ndfe))

10860

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10851

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10861

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10852

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10862

% r260 used eta_0 PSD equation for sigma_n

10853

% r260 used eta_0 PSD equation for sigma_n

10863

% r260 fix IL graph legend to w/pkg and Tr

10854

% r260 fix IL graph legend to w/pkg and Tr

10864

% r260 define tfx for each port

10855

% r260 define tfx for each port

10865

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10856

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10866

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10857

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10867

% r262 reset on exit default text interpreter to tex

10858

% r262 reset on exit default text interpreter to tex

10868

% r262 localize run timer (John Buck 1/17/19)

10859

% r262 localize run timer (John Buck 1/17/19)

10869

% r262 set db as internal function in force to avoid tool box

10860

% r262 set db as internal function in force to avoid tool box

10870

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10861

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10871

% r263 added to output_args RL structure and report "struct" in csv file

10862

% r263 added to output_args RL structure and report "struct" in csv file

10872

% r264 added EW estimate

10863

% r264 added EW estimate

10873

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10864

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10874

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10865

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10875

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10866

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10876

% r269 changed param.N_bmax to param.N_f

10867

% r269 changed param.N_bmax to param.N_f

10877

% r270 implement JingBo Li's and Howard Heck's floating tap method

10868

% r270 implement JingBo Li's and Howard Heck's floating tap method

10878

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10869

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10879

% r270 added c_0 and c_1 for CA in add_brd

10870

% r270 added c_0 and c_1 for CA in add_brd

10880

% r272 fixed version syntax problem in output_args RL report

10871

% r272 fixed version syntax problem in output_args RL report

10881

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10872

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10882

% r272 removed eye width report if doing a Rx calibration

10873

% r272 removed eye width report if doing a Rx calibration

10883

% r273 better alignment and control for ICN reporting

10874

% r273 better alignment and control for ICN reporting

10884

% r273 fixed PSXTK graph

10875

% r273 fixed PSXTK graph

10885

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10876

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10886

% r276 go back to reporting channel IL results (output_args.IL_dB_channel_only_at_Fnq) with board added read_s4p_files (as in r270)

10877

% r276 go back to reporting channel IL results (output_args.IL_dB_channel_only_at_Fnq) with board added read_s4p_files (as in r270)

10887

% r276 chdata(i).Aicn=param.a_icn_fext should have been chdata(i).Aicn=param.a_icn_next for the next selection. Since in most spec's they are the same there is little no impact in results

10878

% r276 chdata(i).Aicn=param.a_icn_fext should have been chdata(i).Aicn=param.a_icn_next for the next selection. Since in most spec's they are the same there is little no impact in results

10888

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10879

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10889

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10880

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10890

% r276 C_1 was instantiated as C_0. This was fixed

10881

% r276 C_1 was instantiated as C_0. This was fixed

10891

% r276 fixed rounding problem in reporting of loss at f_nq

10882

% r276 fixed rounding problem in reporting of loss at f_nq

10892

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10883

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10893

% r277 added nv for deterining steady state voltage for fitting compatibility

10884

% r277 added nv for deterining steady state voltage for fitting compatibility

10894

% r278 added b_min to support asymmetric bmax

10885

% r278 added b_min to support asymmetric bmax

10895

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10886

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10896

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10887

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10897

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10888

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10898

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10889

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10899

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10890

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10900

% r292 eq. 93A-19 and 93-20 code implementation bug when include .3by change% to fix edge rate equation 93A-46 (h_T). no effect if Rd=50 or IL > 5 dB

10891

% r292 eq. 93A-19 and 93-20 code implementation bug when include .3by change% to fix edge rate equation 93A-46 (h_T). no effect if Rd=50 or IL > 5 dB

10901

% r292 H_t implemented in s21_pkg

10892

% r292 H_t implemented in s21_pkg

10902

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10893

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10903

% r292 add GDC_MIN to optimize_FOM

10894

% r292 add GDC_MIN to optimize_FOM

10904

% r293 fix if ndfe-0 and ERL only and s2p issue

10895

% r293 fix if ndfe-0 and ERL only and s2p issue

10905

% r293a investigate the Tukey filtering

10896

% r293a investigate the Tukey filtering

10906

% r293a if fix if bmin is missing

10897

% r293a if fix if bmin is missing

10907

% r294 fix problems reading s2p files for ERL computation

10898

% r294 fix problems reading s2p files for ERL computation

10908

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10899

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10909

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10900

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10910

% r294 add gdc and gdc2 range limitations

10901

% r294 add gdc and gdc2 range limitations

10911

% r295 add VEC Pass threshold

10902

% r295 add VEC Pass threshold

10912

% r295 removed close force all. Tagged all figures with "COM"

10903

% r295 removed close force all. Tagged all figures with "COM"

10913

% r295 consolidated print in new function "end_display_control"

10904

% r295 consolidated print in new function "end_display_control"

10914

% r295 report pre/pmax for Txffe

10905

% r295 report pre/pmax for Txffe

10915

% r295 speed up test cases by not re-reading in s4p files

10906

% r295 speed up test cases by not re-reading in s4p files

10916

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10907

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10917

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10908

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10918

% r310 refine VEC and EH for C2M from Adam Gregory in

10909

% r310 refine VEC and EH for C2M from Adam Gregory in

10919

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10910

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10920

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10911

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10921

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10912

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10922

% r311 added RILN

10913

% r311 added RILN

10923

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10914

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10924

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10915

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10925

% r316 remove DC computation for RX Calibration loops

10916

% r316 remove DC computation for RX Calibration loops

10926

% r317 for SAVE_TD to include EQ and unEQ FIR

10917

% r317 for SAVE_TD to include EQ and unEQ FIR

10927

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10918

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10928

% r318 if min_VEO_test fails to find a solution the loop is restarted with min_VEO_test to near zero. Makes sure COM returns results

10919

% r318 if min_VEO_test fails to find a solution the loop is restarted with min_VEO_test to near zero. Makes sure COM returns results

10929

% r320 fixed RX_CALIBRATION which was broken in r310

10920

% r320 fixed RX_CALIBRATION which was broken in r310

10930

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10921

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10931

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10922

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10932

% r320 removed external feature and replace with TDMODE

10923

% r320 removed external feature and replace with TDMODE

10933

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10924

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10934

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10925

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10935

% r335 fixed typo in when processing the bessel thompson filter option

10926

% r335 fixed typo in when processing the bessel thompson filter option

10936

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10927

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10937

% r335 compute and report CD_CM_RMS

10928

% r335 compute and report CD_CM_RMS

10938

% r335 fixed where output_arg is save i.e. move to end

10929

% r335 fixed where output_arg is save i.e. move to end

10939

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10930

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10940

% r335 change raw IL plot to not include boards

10931

% r335 change raw IL plot to not include boards

10941

% r335 set T_0 to zero if not C2M

10932

% r335 set T_0 to zero if not C2M

10942

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10933

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10943

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10934

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10944

% r335 TD_RILN changes from Hansel Dsilva

10935

% r335 TD_RILN changes from Hansel Dsilva

10945

% r335 Fixed sigma_N for RxFFE

10936

% r335 Fixed sigma_N for RxFFE

10946

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10937

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10947

% r335 added c(2) and C(3) back to read_ParamConfigFile

10938

% r335 added c(2) and C(3) back to read_ParamConfigFile

10948

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10939

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10949

% r335 corrected GDC_MIN per 0.3ck D2.3

10940

% r335 corrected GDC_MIN per 0.3ck D2.3

10950

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10941

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10951

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10942

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10952

% r370 speed up

10943

% r370 speed up

10953

% r370 fix for floating tap missing locations

10944

% r370 fix for floating tap missing locations

10954

% r370 variable Tx FFE taps

10945

% r370 variable Tx FFE taps

10955

% r370 package die load with ladder circuit

10946

% r370 package die load with ladder circuit

10956

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10947

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10957

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10948

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10958

% r380 added capabablity to enable a raised cosine Rx filter0

10949

% r380 added capabablity to enable a raised cosine Rx filter0

10959

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10950

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10960

% r380 added plot for VTF

10951

% r380 added plot for VTF

10961

% r385 added capability for additional Tx FFE per package

10952

% r385 added capability for additional Tx FFE per package

10962

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10953

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10963

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10954

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10964

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10955

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10965

% r389 Improvement by A. Ran for reporting loss at Nq

10956

% r389 Improvement by A. Ran for reporting loss at Nq

10966

% r389 Fixed typo: changed VIM to VMP

10957

% r389 Fixed typo: changed VIM to VMP

10967

% r400 fixed PR with zero pad extension

10958

% r400 fixed PR with zero pad extension

10968

% r400 keyword MLSE and SNRADJ_EQUA for future work

10959

% r400 keyword MLSE and SNRADJ_EQUA for future work

10969

% r400 replaced function db with instances of 20*log10(abs(...))

10960

% r400 replaced function db with instances of 20*log10(abs(...))

10970

% r410 widen voltage distriution for normal_dist doubled max Q

10961

% r410 widen voltage distriution for normal_dist doubled max Q

10971

% r410 improve reading in of config files

10962

% r410 improve reading in of config files

10972

% r410 renormalize s-parameter if not 50 ohm ref

10963

% r410 renormalize s-parameter if not 50 ohm ref

10973

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10964

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10974

% r410 remove RL from output_args bc not need and too much storage allocation

10965

% r410 remove RL from output_args bc not need and too much storage allocation

10975

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10966

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10976

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10967

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10977

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10968

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10978

% r420 updade force to account for pulse responces with short delays in force

10969

% r420 updade force to account for pulse responces with short delays in force

10979

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10970

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10980

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10971

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10981

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10972

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10982

% r420 Wiener-Kofp MMSE optimization for RxFFE

10973

% r420 Wiener-Kofp MMSE optimization for RxFFE

10983

% r430 first pass at healey_3dj_01_2401

10974

% r430 first pass at healey_3dj_01_2401

10984

% r430 RxFFE fixed taps

10975

% r430 RxFFE fixed taps

10985

% r440 RxffE fixed tap index corrections and floating taps

10976

% r440 RxffE fixed tap index corrections and floating taps

10986

% r440 first pass implemenation of MLSE U3

10977

% r440 first pass implemenation of MLSE U3

10987

% r450 fix MLSE_FOM typos, sigma_e,and FOM.

10978

% r450 fix MLSE_FOM typos, sigma_e,and FOM.

10988

% r450 incude Hisi in PSD in get_PSDs

10979

% r450 incude Hisi in PSD in get_PSDs

+10980

% r450 is basically getting RxFFE and MLSE ironed out

10989

% r460 is working out reporting bug from RxFFE and package A,B invocations

10981

% r460 is working out reporting bug from RxFFE and package A,B invocations

10990

% r460 align package config Tx and Rx cases with selected casting 4p5_3

10991

% r460 fix RxFFE floating taps display (indexing error) 4p5_4

10992

10982