File Comparison Report

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

richardm

31-Oct-2024

Files

Left FileRight File
File namecom_ieee8023_93a_470com_ieee8023_93a_460
File pathC:\Users\richardm\OneDrive - Samtec\COM\COM\srcC:\Users\richardm\OneDrive - Samtec\COM\COM\src
Last modified31-Oct-2024 14:41:0930-Jul-2024 15:59: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

chdata(i).pdfr=pdf;

490

chdata(i).pdfr=pdf;

490

% reporting

491

% reporting

491

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

492

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

492

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

493

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

493

494

494

end

495

end

495

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

496

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

496

497

497

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

498

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

498

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

499

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

499

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

500

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

500

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

501

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

501

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

502

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

502

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

503

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

503

combined_interference_and_noise_pdf=PDF;

504

combined_interference_and_noise_pdf=PDF;

504

combined_interference_and_noise_cdf=CDF;

505

combined_interference_and_noise_cdf=CDF;

505

506

506

507

507

%% Calculate COM and other associated outputs

508

%% Calculate COM and other associated outputs

508

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

509

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

509

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

510

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

510

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

511

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

511

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

512

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

512

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

513

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

513

% that satisfies the relationship P(y0) = DER_0

514

% that satisfies the relationship P(y0) = DER_0

514

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

515

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

515

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

516

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

516

517

517

% begin yasuo patch 3/18/2019

518

% begin yasuo patch 3/18/2019

518

% estimate DER at threshold COM

519

% estimate DER at threshold COM

519

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

520

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

520

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

521

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

521

threshold_DER_max = max(threshold_DER_max, threshold_DER);

522

threshold_DER_max = max(threshold_DER_max, threshold_DER);

522

% end yasuo patch

523

% end yasuo patch

523

524

524

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

525

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

525

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

526

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

526

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

527

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

527

if OP.DISPLAY_WINDOW && OP.DEBUG

528

if OP.DISPLAY_WINDOW && OP.DEBUG

528

figure_name = 'Eye at DER0 estimate';

529

figure_name = 'Eye at DER0 estimate';

529

fig=findobj('Name', figure_name);

530

fig=findobj('Name', figure_name);

530

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

531

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

531

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

532

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

532

movegui(fig,'southwest')

533

movegui(fig,'southwest')

533

plot(eye_contour)

534

plot(eye_contour)

534

xlabel('UI %')

535

xlabel('UI %')

535

ylabel('V')

536

ylabel('V')

536

end

537

end

537

538

538

else

539

else

539

EW_UI=0;

540

EW_UI=0;

540

eye_contour=[];

541

eye_contour=[];

541

end

542

end

542

if OP.MLSE==0

543

if OP.MLSE==0

543

if param.T_O ~=0

544

if param.T_O ~=0

544

eye_opening=EH_T_C2M-EH_B_C2M;

545

eye_opening=EH_T_C2M-EH_B_C2M;

545

A_ni=2*A_s-eye_opening;

546

A_ni=2*A_s-eye_opening;

546

%eq 124E-4

547

%eq 124E-4

547

vec_arg=2*A_s/eye_opening;

548

vec_arg=2*A_s/eye_opening;

548

if vec_arg<eps

549

if vec_arg<eps

549

vec_arg=eps;

550

vec_arg=eps;

550

end

551

end

551

VEC_dB = 20*log10(vec_arg);

552

VEC_dB = 20*log10(vec_arg);

552

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

553

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

553

VEO_mV=eye_opening*1000;

554

VEO_mV=eye_opening*1000;

554

min_COM = min(min_COM, COM);

555

min_COM = min(min_COM, COM);

555

min_VEO_mV = min(min_VEO_mV,VEO_mV);

556

min_VEO_mV = min(min_VEO_mV,VEO_mV);

556

max_VEC_dB = max(max_VEC_dB, VEC_dB);

557

max_VEC_dB = max(max_VEC_dB, VEC_dB);

557

else

558

else

558

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

559

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

559

vec_arg=(A_s-A_ni)/A_s;

560

vec_arg=(A_s-A_ni)/A_s;

560

if vec_arg<eps

561

if vec_arg<eps

561

vec_arg=eps;

562

vec_arg=eps;

562

end

563

end

563

VEC_dB = -20*log10(vec_arg);

564

VEC_dB = -20*log10(vec_arg);

564

COM=20*log10(A_s/A_ni);

565

COM=20*log10(A_s/A_ni);

565

min_COM = min(min_COM, COM);

566

min_COM = min(min_COM, COM);

566

min_VEO_mV = min(min_VEO_mV,VEO_mV);

567

min_VEO_mV = min(min_VEO_mV,VEO_mV);

567

max_VEC_dB = max(max_VEC_dB, VEC_dB);

568

max_VEC_dB = max(max_VEC_dB, VEC_dB);

568

end

569

end

569

MLSE_results=struct;

570

MLSE_results=struct;

570

else

571

else

571

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

572

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

572

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

573

if param.T_O ~=0

573

if param.T_O ~=0

574

eye_opening=EH_T_C2M-EH_B_C2M;

574

eye_opening=EH_T_C2M-EH_B_C2M;

575

A_ni=2*A_s-eye_opening;

575

A_ni=2*A_s-eye_opening;

576

%eq 124E-4

576

%eq 124E-4

577

vec_arg=2*A_s/eye_opening;

577

vec_arg=2*A_s/eye_opening;

578

if vec_arg<eps

578

if vec_arg<eps

579

vec_arg=eps;

579

vec_arg=eps;

580

end

580

end

581

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

581

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

582

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

582

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

583

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

583

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

584

COM=MLSE_results.COM;

584

COM=MLSE_results.COM;

585

VEO_mV=eye_opening*1000;

585

VEO_mV=eye_opening*1000;

586

min_COM = min(min_COM, COM);

586

min_COM = min(min_COM, COM);

587

min_VEO_mV = min(min_VEO_mV,VEO_mV);

587

min_VEO_mV = min(min_VEO_mV,VEO_mV);

588

max_VEC_dB = max(max_VEC_dB, VEC_dB);

588

max_VEC_dB = max(max_VEC_dB, VEC_dB);

589

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

589

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

590

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

590

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

591

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

591

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

592

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

592

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

593

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

593

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

594

COM_SNR_Struct.VEC_dB=VEC_dB;

594

COM_SNR_Struct.VEC_dB=VEC_dB;

595

else

595

else

596

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

596

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

597

vec_arg=(A_s-A_ni)/A_s;

597

vec_arg=(A_s-A_ni)/A_s;

598

if vec_arg<eps

598

if vec_arg<eps

599

vec_arg=eps;

599

vec_arg=eps;

600

end

600

end

601

VEC_dB_orig = -20*log10(vec_arg);

601

VEC_dB_orig = -20*log10(vec_arg);

602

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

602

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

603

COM_orig=20*log10(A_s/A_ni);

603

COM_orig=20*log10(A_s/A_ni);

604

COM=MLSE_results.COM;

604

COM=MLSE_results.COM;

605

min_COM = min(min_COM, COM);

605

min_COM = min(min_COM, COM);

606

min_VEO_mV = min(min_VEO_mV,VEO_mV);

606

min_VEO_mV = min(min_VEO_mV,VEO_mV);

607

max_VEC_dB = max(max_VEC_dB, VEC_dB);

607

max_VEC_dB = max(max_VEC_dB, VEC_dB);

608

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

608

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

609

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

609

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

610

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

610

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

611

COM_SNR_Struct.VEC_dB=VEC_dB;

611

COM_SNR_Struct.VEC_dB=VEC_dB;

612

end

612

end

613

end

613

end

614

614

615

%% Create COM_SNR_Struct to hold the main COM outputs

615

%% Create COM_SNR_Struct to hold the main COM outputs

616

COM_SNR_Struct.A_s=A_s;

616

COM_SNR_Struct.A_s=A_s;

617

COM_SNR_Struct.A_ni=A_ni;

617

COM_SNR_Struct.A_ni=A_ni;

618

COM_SNR_Struct.threshold_DER=threshold_DER;

618

COM_SNR_Struct.threshold_DER=threshold_DER;

619

COM_SNR_Struct.EW_UI=EW_UI;

619

COM_SNR_Struct.EW_UI=EW_UI;

620

COM_SNR_Struct.COM=COM;

620

COM_SNR_Struct.COM=COM;

621

COM_SNR_Struct.VEC_dB=VEC_dB;

621

COM_SNR_Struct.VEC_dB=VEC_dB;

622

if OP.MLSE == 0

622

if OP.MLSE == 0

623

COM_SNR_Struct.COM_orig=[];

623

COM_SNR_Struct.COM_orig=[];

624

COM_SNR_Struct.VEC_dB_orig=[];

624

COM_SNR_Struct.VEC_dB_orig=[];

625

else

625

else

626

COM_SNR_Struct.COM_orig=COM_orig;

626

COM_SNR_Struct.COM_orig=COM_orig;

627

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

627

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

628

end

628

end

629

COM_SNR_Struct.VEO_mV=VEO_mV;

629

COM_SNR_Struct.VEO_mV=VEO_mV;

630

COM_SNR_Struct.combined_interference_and_noise_pdf=combined_interference_and_noise_pdf;

630

COM_SNR_Struct.combined_interference_and_noise_pdf=combined_interference_and_noise_pdf;

631

COM_SNR_Struct.combined_interference_and_noise_cdf=combined_interference_and_noise_cdf;

631

COM_SNR_Struct.combined_interference_and_noise_cdf=combined_interference_and_noise_cdf;

632

COM_SNR_Struct.eye_contour=eye_contour;

632

COM_SNR_Struct.eye_contour=eye_contour;

633

633

634

634

635

%% Save TD

635

%% Save TD

636

if OP.SAVE_TD

636

if OP.SAVE_TD

637

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

637

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

638

if ~OP.TDMODE

638

if ~OP.TDMODE

639

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

639

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

640

end

640

end

641

for i=1:param.number_of_s4p_files

641

for i=1:param.number_of_s4p_files

+642

642

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

643

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

644

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

644

if ~OP.TDMODE

645

if ~OP.TDMODE

645

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

646

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

647

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

647

end

648

end

648

end

649

end

649

if OP.TDMODE

650

if OP.TDMODE

650

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

651

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

651

else

652

else

652

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

653

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

653

end

654

end

654

end

655

end

655

656

656

%% Bathtub/Contribution Plot

657

%% Bathtub/Contribution Plot

657

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

658

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

658

if OP.MLSE ~= 0

659

COM_SNR_Struct.combined_interference_and_noise_pdf=MLSE_results.PDF;

660

COM_SNR_Struct.combined_interference_and_noise_cdf=MLSE_results.CDF;

661

end

662

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

659

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

663

end

660

end

664

661

665

%% Msg management

662

%% Msg management

666

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

663

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

667

msg=[];

664

msg=[];

668

end

665

end

669

if OP.DEBUG

666

if OP.DEBUG

670

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

667

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

671

switch param.flex

668

switch param.flex

672

case 4

669

case 4

673

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

670

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

674

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

671

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

675

);

672

);

676

case 2

673

case 2

677

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

674

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

678

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

675

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

679

);

676

);

680

otherwise

677

otherwise

681

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

678

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

682

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

679

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

683

);

680

);

684

681

685

end

682

end

686

else

683

else

687

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

684

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

688

end

685

end

689

686

690

if OP.TDMODE

687

if OP.TDMODE

691

min_ERL=inf;

688

min_ERL=inf;

692

ERL=[inf inf];

689

ERL=[inf inf];

693

end

690

end

694

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

691

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

695

692

696

693

697

%% Output Args

694

%% Output Args

698

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

695

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

699

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

696

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

700

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

697

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

701

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

698

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

702

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

699

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

703

rt=toc(t0);

700

rt=toc(t0);

704

output_args.rtmin=rt/60;

701

output_args.rtmin=rt/60;

705

702

706

if OP.BREAD_CRUMBS

703

if OP.BREAD_CRUMBS

707

output_args.OP=OP;

704

output_args.OP=OP;

708

output_args.param=param;

705

output_args.param=param;

709

output_args.chdata=chdata;

706

output_args.chdata=chdata;

710

output_args.fom_result = fom_result;

707

output_args.fom_result = fom_result;

711

output_args.PDF=PDF; % for exploration

708

output_args.PDF=PDF; % for exploration

712

output_args.CDF=CDF; % for exploration

709

output_args.CDF=CDF; % for exploration

713

output_args.MLSE_results=MLSE_results;

710

output_args.MLSE_results=MLSE_results;

714

output_args.PSD_results=PSD_results;

711

output_args.PSD_results=PSD_results;

715

end

712

end

716

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

713

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

717

714

718

%% making csv file

715

%% making csv file

719

if OP.CSV_REPORT ==1

716

if OP.CSV_REPORT ==1

720

Write_CSV(output_args,CSV_FILE);

717

Write_CSV(output_args,CSV_FILE);

721

end

718

end

722

%% making mat file

719

%% making mat file

723

if(OP.DEBUG)

720

if(OP.DEBUG)

724

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

721

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

725

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

722

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

726

end

723

end

727

if 1

724

if 1

728

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

725

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

729

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

726

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

730

end

727

end

731

728

732

if nargout==0

729

if nargout==0

733

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

730

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

734

disp(output_args)

731

disp(output_args)

735

end

732

end

736

733

737

if OP.BREAD_CRUMBS

734

if OP.BREAD_CRUMBS

738

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

735

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

739

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

736

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

740

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

737

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

741

try

738

try

742

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

739

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

743

catch

740

catch

744

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

741

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

745

end

742

end

746

end

743

end

747

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

744

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

748

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

745

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

749

end

746

end

750

747

751

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

748

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

752

end

749

end

753

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

750

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

754

%%

751

%%

755

752

756

if OP.RX_CALIBRATION ==1

753

if OP.RX_CALIBRATION ==1

757

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

754

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

758

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

755

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

759

end

756

end

760

DO_ONCE=false;

757

DO_ONCE=false;

761

end

758

end

762

759

763

%% Final cleanup

760

%% Final cleanup

764

if OP.DISPLAY_WINDOW

761

if OP.DISPLAY_WINDOW

765

savefigs(param, OP);

762

savefigs(param, OP);

766

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

763

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

767

end

764

end

768

765

769

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

766

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

770

if ~param.f_hp==0

767

if ~param.f_hp==0

771

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

768

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

772

if OP.DISPLAY_WINDOW

769

if OP.DISPLAY_WINDOW

773

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

770

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

774

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

771

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

775

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

772

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

776

end

773

end

777

else

774

else

778

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

775

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

779

if OP.DISPLAY_WINDOW

776

if OP.DISPLAY_WINDOW

780

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

777

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

781

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

778

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

782

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

779

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

783

end

780

end

784

end

781

end

785

end

782

end

786

783

787

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

784

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

788

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

785

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

789

disp(redo_cmd_str);

786

disp(redo_cmd_str);

790

if isdeployed

787

if isdeployed

791

if OP.exit_if_deployed

788

if OP.exit_if_deployed

792

quit

789

quit

793

end

790

end

794

end

791

end

795

%%

792

%%

796

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

793

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

797

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

794

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

798

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

795

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

799

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

796

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

800

797

801

FB=param.fb;

798

FB=param.fb;

802

FZ=param.CTLE_fz(fom_result.ctle);

799

FZ=param.CTLE_fz(fom_result.ctle);

803

FP1=param.CTLE_fp1(fom_result.ctle);

800

FP1=param.CTLE_fp1(fom_result.ctle);

804

FP2=param.CTLE_fp2(fom_result.ctle);

801

FP2=param.CTLE_fp2(fom_result.ctle);

805

GDC=param.ctle_gdc_values(fom_result.ctle);

802

GDC=param.ctle_gdc_values(fom_result.ctle);

806

if ~isempty(param.f_HP)

803

if ~isempty(param.f_HP)

807

FHP=param.f_HP(fom_result.best_G_high_pass);

804

FHP=param.f_HP(fom_result.best_G_high_pass);

808

end

805

end

809

if ~isempty(param.g_DC_HP_values)

806

if ~isempty(param.g_DC_HP_values)

810

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

807

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

811

end

808

end

812

if ~isempty(param.f_HP_Z)

809

if ~isempty(param.f_HP_Z)

813

FHPZ=param.f_HP_Z(fom_result.ctle);

810

FHPZ=param.f_HP_Z(fom_result.ctle);

814

end

811

end

815

if ~isempty(param.f_HP_P)

812

if ~isempty(param.f_HP_P)

816

FHPP=param.f_HP_P(fom_result.ctle);

813

FHPP=param.f_HP_P(fom_result.ctle);

817

end

814

end

818

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

815

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

819

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

816

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

820

%length

817

%length

821

SBR_Len=length(fom_result.sbr);

818

SBR_Len=length(fom_result.sbr);

822

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

819

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

823

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

820

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

824

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

821

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

825

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

822

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

826

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

823

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

827

end

824

end

828

for i=1:param.number_of_s4p_files

825

for i=1:param.number_of_s4p_files

829

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

826

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

830

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

827

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

831

if OP.INCLUDE_CTLE==1

828

if OP.INCLUDE_CTLE==1

832

switch param.CTLE_type

829

switch param.CTLE_type

833

case 'CL93'

830

case 'CL93'

834

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

831

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

835

case 'CL120d'

832

case 'CL120d'

836

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

833

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

837

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

834

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

838

case 'CL120e' % z has been adjusted for gain

835

case 'CL120e' % z has been adjusted for gain

839

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

836

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

840

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

837

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

841

end

838

end

842

else

839

else

843

eq_ir=uneq_ir;

840

eq_ir=uneq_ir;

844

end

841

end

845

chdata(i).eq_imp_response=eq_ir;

842

chdata(i).eq_imp_response=eq_ir;

846

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

843

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

847

844

848

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

845

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

849

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

846

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

850

end

847

end

851

% chdata(i).ctle_imp_response

848

% chdata(i).ctle_imp_response

852

if OP.RxFFE

849

if OP.RxFFE

853

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

850

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

854

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

851

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

855

end

852

end

856

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

853

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

857

end

854

end

858

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

855

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

859

end

856

end

860

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

857

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

861

858

862

% display bathtub curves in one axis per test case.

859

% display bathtub curves in one axis per test case.

863

case_number=param.package_testcase_i;

860

case_number=param.package_testcase_i;

864

if ~OP.COM_CONTRIBUTION_CURVES

861

if ~OP.COM_CONTRIBUTION_CURVES

865

figure_name = 'Voltage bathtub curves';

862

figure_name = 'Voltage bathtub curves';

866

fig=findobj('Name', figure_name);

863

fig=findobj('Name', figure_name);

867

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

864

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

868

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

865

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

869

movegui(fig,'south')

866

movegui(fig,'south')

870

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

867

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

871

plot_bathtub_curves( hax ...

868

plot_bathtub_curves( hax ...

872

, COM_SNR_Struct.A_s ...

869

, COM_SNR_Struct.A_s ...

873

, Noise_Struct.sci_pdf ...

870

, Noise_Struct.sci_pdf ...

874

, Noise_Struct.cci_pdf ...

871

, Noise_Struct.cci_pdf ...

875

, Noise_Struct.isi_and_xtalk_pdf ...

872

, Noise_Struct.isi_and_xtalk_pdf ...

876

, Noise_Struct.noise_pdf ...

873

, Noise_Struct.noise_pdf ...

877

, Noise_Struct.jitt_pdf ...

874

, Noise_Struct.jitt_pdf ...

878

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

875

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

879

, param.delta_y ...

876

, param.delta_y ...

880

);

877

);

881

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

878

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

882

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

879

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

883

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

880

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

884

% show BER target line

881

% show BER target line

885

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

882

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

886

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

883

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

887

else

884

else

888

figure_name = 'COM Contributions (Rough Allocations)';

885

figure_name = 'COM Contributions (Rough Allocations)';

889

fig=findobj('Name', figure_name);

886

fig=findobj('Name', figure_name);

890

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

887

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

891

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

888

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

892

movegui(fig,'south')

889

movegui(fig,'south')

893

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

890

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

894

891

895

plot_pie_com( hax ...

892

plot_pie_com( hax ...

896

, COM_SNR_Struct.A_s ...

893

, COM_SNR_Struct.A_s ...

897

, Noise_Struct.sci_pdf ...

894

, Noise_Struct.sci_pdf ...

898

, Noise_Struct.cci_pdf ...

895

, Noise_Struct.cci_pdf ...

899

, Noise_Struct.isi_and_xtalk_pdf ...

896

, Noise_Struct.isi_and_xtalk_pdf ...

900

, Noise_Struct.noise_pdf ...

897

, Noise_Struct.noise_pdf ...

901

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

898

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

902

, param.delta_y, param...

899

, param.delta_y, param...

903

);

900

);

904

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

901

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

905

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

902

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

906

end

903

end

907

904

908

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

905

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

909

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

906

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

910

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

907

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

911

end

908

end

912

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

909

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

913

910

914

if use_BT

911

if use_BT

915

a = bessel( param.BTorder );

912

a = bessel( param.BTorder );

916

acoef=fliplr( a );

913

acoef=fliplr( a );

917

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

914

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

918

else

915

else

919

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

916

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

920

end

917

end

921

918

922

919

923

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

920

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

924

921

925

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

922

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

926

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

923

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

927

%All subsequent lines are field names in chdata

924

%All subsequent lines are field names in chdata

928

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

925

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

929

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

926

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

930

%

927

%

931

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

928

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

932

%#reduce

929

%#reduce

933

%sdd12_raw

930

%sdd12_raw

934

%sdd21_raw

931

%sdd21_raw

935

%sdd22_raw

932

%sdd22_raw

936

%sdd11_raw

933

%sdd11_raw

937

%

934

%

938

935

939

fid=fopen(fields_file,'r');

936

fid=fopen(fields_file,'r');

940

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

937

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

941

938

942

file_data=file_data{1};

939

file_data=file_data{1};

943

fclose(fid);

940

fclose(fid);

944

941

945

%remove blank lines

942

%remove blank lines

946

L=cellfun('length',file_data);

943

L=cellfun('length',file_data);

947

file_data=file_data(L~=0);

944

file_data=file_data(L~=0);

948

945

949

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

946

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

950

type=file_data{1};

947

type=file_data{1};

951

field_names=file_data(2:end);

948

field_names=file_data(2:end);

952

switch lower(type)

949

switch lower(type)

953

case '#reduce'

950

case '#reduce'

954

remove_fields=field_names;

951

remove_fields=field_names;

955

case '#include'

952

case '#include'

956

all_fields=fieldnames(chdata);

953

all_fields=fieldnames(chdata);

957

remove_fields=setdiff(all_fields,field_names);

954

remove_fields=setdiff(all_fields,field_names);

958

otherwise

955

otherwise

959

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

956

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

960

end

957

end

961

958

962

%remove the "remove_fields" from chdata

959

%remove the "remove_fields" from chdata

963

for j=1:length(remove_fields)

960

for j=1:length(remove_fields)

964

this_field=remove_fields{j};

961

this_field=remove_fields{j};

965

if isfield(chdata,this_field)

962

if isfield(chdata,this_field)

966

chdata=rmfield(chdata,this_field);

963

chdata=rmfield(chdata,this_field);

967

end

964

end

968

end

965

end

969

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

966

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

970

967

971

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

968

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

972

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

969

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

973

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

970

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

974

971

975

A_s=COM_SNR_Struct.A_s;

972

A_s=COM_SNR_Struct.A_s;

976

% initialize loop with uncorrelated noise and BER

973

% initialize loop with uncorrelated noise and BER

977

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

974

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

978

975

979

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

976

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

980

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

977

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

981

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

978

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

982

% below target BER).

979

% below target BER).

983

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

980

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

984

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

981

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

985

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

982

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

986

if isempty(x_error_propagation)

983

if isempty(x_error_propagation)

987

p_error_propagation(1) = 1e-20;

984

p_error_propagation(1) = 1e-20;

988

else

985

else

989

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

986

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

990

end

987

end

991

988

992

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

989

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

993

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

990

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

994

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

991

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

995

if OP.use_simple_EP_model

992

if OP.use_simple_EP_model

996

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

993

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

997

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

994

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

998

else

995

else

999

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

996

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

1000

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

997

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

1001

end

998

end

1002

999

1003

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

1000

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

1004

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

1001

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

1005

if isempty(x_error_propagation)

1002

if isempty(x_error_propagation)

1006

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

1003

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

1007

else

1004

else

1008

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

1005

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

1009

end

1006

end

1010

end

1007

end

1011

1008

1012

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

1009

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

1013

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

1010

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

1014

% of this event by partial sum of the PDF.

1011

% of this event by partial sum of the PDF.

1015

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

1012

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

1016

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

1013

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

1017

1014

1018

% probability of bursts of different lengths

1015

% probability of bursts of different lengths

1019

p_burst = cumprod(p_error_propagation);

1016

p_burst = cumprod(p_error_propagation);

1020

function H_bw=Butterworth_Filter(param,f,use_BW)

1017

function H_bw=Butterworth_Filter(param,f,use_BW)

1021

1018

1022

if use_BW

1019

if use_BW

1023

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

1020

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

1024

else

1021

else

1025

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

1022

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

1026

end

1023

end

1027

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

1024

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

1028

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

1025

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

1029

CDF_ev=CDF(index);

1026

CDF_ev=CDF(index);

1030

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

1027

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

1031

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

1028

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

1032

if isempty(index)

1029

if isempty(index)

1033

CDF_inv_ev=PDF.x(end);

1030

CDF_inv_ev=PDF.x(end);

1034

else

1031

else

1035

CDF_inv_ev=PDF.x(index);

1032

CDF_inv_ev=PDF.x(index);

1036

end

1033

end

1037

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

1034

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

1038

1035

1039

1036

1040

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

1037

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

1041

Remember_keyword='Legacy';

1038

Remember_keyword='Legacy';

1042

OP.TDMODE=false;

1039

OP.TDMODE=false;

1043

OP.GET_FD=true;

1040

OP.GET_FD=true;

1044

OP.CONFIG2MAT_ONLY=false;

1041

OP.CONFIG2MAT_ONLY=false;

1045

config_file='';

1042

config_file='';

1046

num_fext=[];

1043

num_fext=[];

1047

num_next=[];

1044

num_next=[];

1048

if ~isempty(varargin)

1045

if ~isempty(varargin)

1049

if ~ischar(varargin{1})

1046

if ~ischar(varargin{1})

1050

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

1047

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

1051

end

1048

end

1052

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

1049

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

1053

if isempty(keyword_idx)

1050

if isempty(keyword_idx)

1054

%Legacy Mode

1051

%Legacy Mode

1055

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

1052

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

1056

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

1053

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

1057

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

1054

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

1058

else

1055

else

1059

%Keyword Mode

1056

%Keyword Mode

1060

my_keyword=varargin{1};

1057

my_keyword=varargin{1};

1061

Remember_keyword=my_keyword;

1058

Remember_keyword=my_keyword;

1062

varargin(1)=[];

1059

varargin(1)=[];

1063

switch my_keyword

1060

switch my_keyword

1064

1061

1065

case 'Legacy'

1062

case 'Legacy'

1066

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

1063

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

1067

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

1064

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

1068

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

1065

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

1069

case 'TD'

1066

case 'TD'

1070

OP.TDMODE=true;

1067

OP.TDMODE=true;

1071

OP.GET_FD=false;

1068

OP.GET_FD=false;

1072

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

1069

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

1073

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

1070

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

1074

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

1071

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

1075

case 'Config2Mat'

1072

case 'Config2Mat'

1076

OP.CONFIG2MAT_ONLY=true;

1073

OP.CONFIG2MAT_ONLY=true;

1077

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

1074

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

1078

end

1075

end

1079

end

1076

end

1080

end

1077

end

1081

function chdata=COM_FD_to_TD(chdata,param,OP)

1078

function chdata=COM_FD_to_TD(chdata,param,OP)

1082

1079

1083

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

1080

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

1084

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

1081

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

1085

case_number=param.package_testcase_i;

1082

case_number=param.package_testcase_i;

1086

for i=1:param.number_of_s4p_files

1083

for i=1:param.number_of_s4p_files

1087

% RIM 2-01-2023 moved to FD_Processing

1084

% RIM 2-01-2023 moved to FD_Processing

1088

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1085

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1089

% % Equation 93A-20 %%

1086

% % Equation 93A-20 %%

1090

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

1087

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

1091

% f=chdata(i).faxis;

1088

% f=chdata(i).faxis;

1092

% %

1089

% %

1093

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

1090

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

1094

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

1091

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

1095

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

1092

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

1096

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

1093

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

1097

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

1094

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

1098

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

1095

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

1099

% if OP.DISPLAY_WINDOW

1096

% if OP.DISPLAY_WINDOW

1100

% if i==1

1097

% if i==1

1101

% figure(300+param.package_testcase_i);

1098

% figure(300+param.package_testcase_i);

1102

% subplot(3,1,1)

1099

% subplot(3,1,1)

1103

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

1100

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

1104

% try

1101

% try

1105

% legend('NumColumns',2)

1102

% legend('NumColumns',2)

1106

% legend('location','south')

1103

% legend('location','south')

1107

% catch

1104

% catch

1108

% end

1105

% end

1109

% end

1106

% end

1110

% end

1107

% end

1111

% end

1108

% end

1112

[chdata(i).uneq_imp_response, ...

1109

[chdata(i).uneq_imp_response, ...

1113

chdata(i).t, ...

1110

chdata(i).t, ...

1114

chdata(i).causality_correction_dB, ...

1111

chdata(i).causality_correction_dB, ...

1115

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

1112

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

1116

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

1113

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

1117

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

1114

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

1118

[chdata(i).uneq_CD_imp_response, ...

1115

[chdata(i).uneq_CD_imp_response, ...

1119

chdata(i).t_DC, ...

1116

chdata(i).t_DC, ...

1120

chdata(i).causality_correction_DC_dB, ...

1117

chdata(i).causality_correction_DC_dB, ...

1121

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

1118

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

1122

end

1119

end

1123

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

1120

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

1124

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

1121

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

1125

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

1122

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

1126

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

1123

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

1127

1124

1128

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

1125

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

1129

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

1126

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

1130

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

1127

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

1131

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

1128

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

1132

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

1129

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

1133

rss=-inf;

1130

rss=-inf;

1134

for im=1:param.samples_per_ui

1131

for im=1:param.samples_per_ui

1135

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

1132

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

1136

end

1133

end

1137

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

1134

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

1138

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

1135

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

1139

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

1136

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

1140

end

1137

end

1141

if OP.DEBUG && OP.DISPLAY_WINDOW

1138

if OP.DEBUG && OP.DISPLAY_WINDOW

1142

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1139

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1143

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

1140

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

1144

screen_size=get(0,'ScreenSize');

1141

screen_size=get(0,'ScreenSize');

1145

pos = get(gcf, 'OuterPosition');

1142

pos = get(gcf, 'OuterPosition');

1146

set(gcf, 'OuterPosition', ...

1143

set(gcf, 'OuterPosition', ...

1147

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

1144

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

1148

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

1145

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

1149

%movegui(gcf,'northeast')

1146

%movegui(gcf,'northeast')

1150

1147

1151

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

1148

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

1152

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

1149

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

1153

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

1150

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

1154

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

1151

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

1155

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

1152

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

1156

end

1153

end

1157

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

1154

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

1158

% scale. thru is shown in another plot.

1155

% scale. thru is shown in another plot.

1159

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

1156

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

1160

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

1157

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

1161

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

1158

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

1162

end

1159

end

1163

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

1160

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

1164

ylabel('Volts')

1161

ylabel('Volts')

1165

xlabel('seconds')

1162

xlabel('seconds')

1166

1163

1167

recolor_plots(gca);

1164

recolor_plots(gca);

1168

else

1165

else

1169

if param.ndfe~=0

1166

if param.ndfe~=0

1170

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

1167

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

1171

end

1168

end

1172

end

1169

end

1173

1170

1174

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

1171

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

1175

if OP.ENFORCE_CAUSALITY

1172

if OP.ENFORCE_CAUSALITY

1176

fprintf('\n');

1173

fprintf('\n');

1177

else

1174

else

1178

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

1175

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

1179

end

1176

end

1180

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

1177

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

1181

1178

1182

end

1179

end

1183

function [Left_EW,Right_EW,eye_contour,out_VT,out_VB]=COM_eye_width(chdata,delta_y,fom_result,param,OP,Struct_Noise,pdf_range_flag)

1180

function [Left_EW,Right_EW,eye_contour,out_VT,out_VB]=COM_eye_width(chdata,delta_y,fom_result,param,OP,Struct_Noise,pdf_range_flag)

1184

1181

1185

1182

1186

debug_plot=0;

1183

debug_plot=0;

1187

1184

1188

1185

1189

samp_UI=param.samples_for_C2M;

1186

samp_UI=param.samples_for_C2M;

1190

half_UI=get_center_of_UI(samp_UI);

1187

half_UI=get_center_of_UI(samp_UI);

1191

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

1188

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

1192

start_sample=half_UI-T_O;

1189

start_sample=half_UI-T_O;

1193

end_sample=half_UI+T_O;

1190

end_sample=half_UI+T_O;

1194

1191

1195

1192

1196

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

1193

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

1197

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

1194

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

1198

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

1195

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

1199

if pdf_range_flag

1196

if pdf_range_flag

1200

pdf_range=[start_sample end_sample];

1197

pdf_range=[start_sample end_sample];

1201

else

1198

else

1202

pdf_range=[];

1199

pdf_range=[];

1203

end

1200

end

1204

1201

1205

%pdf_full is self ISI pdf for each sample point

1202

%pdf_full is self ISI pdf for each sample point

1206

%h_j_full is the v/t calculation for each sample point

1203

%h_j_full is the v/t calculation for each sample point

1207

%the center vector for each should be identical to the standard COM variables

1204

%the center vector for each should be identical to the standard COM variables

1208

[pdf_full_1,h_j_full,A_s_vec] = get_pdf_full(chdata(1), delta_y, fom_result.t_s, param, OP,pdf_range) ;

1205

[pdf_full_1,h_j_full,A_s_vec] = get_pdf_full(chdata(1), delta_y, fom_result.t_s, param, OP,pdf_range) ;

1209

1206

1210

1207

1211

1208

1212

if isempty(pdf_range)

1209

if isempty(pdf_range)

1213

pdf_range=1:samp_UI;

1210

pdf_range=1:samp_UI;

1214

else

1211

else

1215

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

1212

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

1216

end

1213

end

1217

1214

1218

%Test doing Level PDFs

1215

%Test doing Level PDFs

1219

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

1216

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

1220

%A_s_vec=A_s_vec*(param.levels-1)/param.R_LM;

1217

%A_s_vec=A_s_vec*(param.levels-1)/param.R_LM;

1221

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

1218

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

1222

1219

1223

%add signal vector into pdf

1220

%add signal vector into pdf

1224

for n=1:param.levels

1221

for n=1:param.levels

1225

pdf_full{n}=pdf_full_1;

1222

pdf_full{n}=pdf_full_1;

1226

for j=pdf_range

1223

for j=pdf_range

1227

pdf_full{n}(j).x=pdf_full{n}(j).x+A_s_vec(j)*Levels(n);

1224

pdf_full{n}(j).x=pdf_full{n}(j).x+A_s_vec(j)*Levels(n);

1228

pdf_full{n}(j).Min=pdf_full{n}(j).x(1)/pdf_full{n}(j).BinSize;

1225

pdf_full{n}(j).Min=pdf_full{n}(j).x(1)/pdf_full{n}(j).BinSize;

1229

end

1226

end

1230

end

1227

end

1231

1228

1232

1229

1233

% figure;

1230

% figure;

1234

% hold on;

1231

% hold on;

1235

%This loop builds the same PDF/CDF structures from regular COM, but it is

1232

%This loop builds the same PDF/CDF structures from regular COM, but it is

1236

%computed for every sample point

1233

%computed for every sample point

1237

for n=1:param.levels

1234

for n=1:param.levels

1238

for j=pdf_range

1235

for j=pdf_range

1239

sigma_G_full(j) = norm([param.sigma_RJ*param.sigma_X*norm(h_j_full(:,j)), Struct_Noise.sigma_N, Struct_Noise.sigma_TX]);

1236

sigma_G_full(j) = norm([param.sigma_RJ*param.sigma_X*norm(h_j_full(:,j)), Struct_Noise.sigma_N, Struct_Noise.sigma_TX]);

1240

gaussian_noise_pdf_full(j) = normal_dist(sigma_G_full(j), Struct_Noise.ber_q, delta_y);

1237

gaussian_noise_pdf_full(j) = normal_dist(sigma_G_full(j), Struct_Noise.ber_q, delta_y);

1241

gaussian_noise_pdf_full(j) = conv_fct(gaussian_noise_pdf_full(j), Struct_Noise.ne_noise_pdf);

1238

gaussian_noise_pdf_full(j) = conv_fct(gaussian_noise_pdf_full(j), Struct_Noise.ne_noise_pdf);

1242

p_DD_full(j) = get_pdf_from_sampled_signal(param.A_DD*h_j_full(:,j), param.levels, delta_y);

1239

p_DD_full(j) = get_pdf_from_sampled_signal(param.A_DD*h_j_full(:,j), param.levels, delta_y);

1243

noise_pdf_full(j)=conv_fct(gaussian_noise_pdf_full(j), p_DD_full(j));

1240

noise_pdf_full(j)=conv_fct(gaussian_noise_pdf_full(j), p_DD_full(j));

1244

isi_and_xtalk_pdf_full(j) = conv_fct_MeanNotZero(pdf_full{n}(j), Struct_Noise.cci_pdf);

1241

isi_and_xtalk_pdf_full(j) = conv_fct_MeanNotZero(pdf_full{n}(j), Struct_Noise.cci_pdf);

1245

% change from adam gregory to include crosstalk

1242

% change from adam gregory to include crosstalk

1246

% combined_interference_and_noise_pdf_full = conv_fct(pdf_full(j), noise_pdf_full(j));

1243

% combined_interference_and_noise_pdf_full = conv_fct(pdf_full(j), noise_pdf_full(j));

1247

combined_interference_and_noise_pdf_full{n}(j) = conv_fct_MeanNotZero(isi_and_xtalk_pdf_full(j), noise_pdf_full(j));

1244

combined_interference_and_noise_pdf_full{n}(j) = conv_fct_MeanNotZero(isi_and_xtalk_pdf_full(j), noise_pdf_full(j));

1248

1245

1249

%PDF to CDF

1246

%PDF to CDF

1250

combined_interference_and_noise_cdf_full{n}(j)=pdf_to_cdf(combined_interference_and_noise_pdf_full{n}(j));

1247

combined_interference_and_noise_cdf_full{n}(j)=pdf_to_cdf(combined_interference_and_noise_pdf_full{n}(j));

1251

1248

1252

end

1249

end

1253

end

1250

end

1254

%hold off;

1251

%hold off;

1255

1252

1256

1253

1257

%For the given BER, find the top & bottom voltage level in the CDF

1254

%For the given BER, find the top & bottom voltage level in the CDF

1258

for n=1:param.levels

1255

for n=1:param.levels

1259

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

1256

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

1260

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

1257

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

1261

for j=pdf_range

1258

for j=pdf_range

1262

[A_ni_top{n}(j),A_ni_bottom{n}(j)]=cdf_to_ber_contour(combined_interference_and_noise_cdf_full{n}(j),param.specBER);

1259

[A_ni_top{n}(j),A_ni_bottom{n}(j)]=cdf_to_ber_contour(combined_interference_and_noise_cdf_full{n}(j),param.specBER);

1263

end

1260

end

1264

end

1261

end

1265

%plot(1:samp_UI,cursor_vector-A_ni_top,1:samp_UI,-cursor_vector+A_ni_bottom)

1262

%plot(1:samp_UI,cursor_vector-A_ni_top,1:samp_UI,-cursor_vector+A_ni_bottom)

1266

1263

1267

for n=1:param.levels-1

1264

for n=1:param.levels-1

1268

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

1265

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

1269

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

1266

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

1270

end

1267

end

1271

1268

1272

1269

1273

for n=1:param.levels-1

1270

for n=1:param.levels-1

1274

%eye_contour holds the top eye in the 1st column & bottom eye in the 2nd column

1271

%eye_contour holds the top eye in the 1st column & bottom eye in the 2nd column

1275

%define vref as middle of top eye height and bottom eye height. Now

1272

%define vref as middle of top eye height and bottom eye height. Now

1276

%that all eyes are created, vref is non-zero except for middle eye

1273

%that all eyes are created, vref is non-zero except for middle eye

1277

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

1274

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

1278

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

1275

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

1279

EH=EH_top-EH_bot;

1276

EH=EH_top-EH_bot;

1280

vref=EH_top/2+EH_bot/2;

1277

vref=EH_top/2+EH_bot/2;

1281

%This function finds left/right eye width by finding the vref crossings of

1278

%This function finds left/right eye width by finding the vref crossings of

1282

%the top and bottom eye contours

1279

%the top and bottom eye contours

1283

[Left_EW(n),Right_EW(n)]=find_eye_width(eye_contour{n},half_UI,samp_UI,vref);

1280

[Left_EW(n),Right_EW(n)]=find_eye_width(eye_contour{n},half_UI,samp_UI,vref);

1284

end

1281

end

1285

1282

1286

%For reporting to .csv, need eye contour to be a matrix instead of cell

1283

%For reporting to .csv, need eye contour to be a matrix instead of cell

1287

eye_contour_tmp=eye_contour;

1284

eye_contour_tmp=eye_contour;

1288

eye_contour=[];

1285

eye_contour=[];

1289

for n=1:param.levels-1

1286

for n=1:param.levels-1

1290

eye_contour(:,(n-1)*2+1:n*2)=eye_contour_tmp{n};

1287

eye_contour(:,(n-1)*2+1:n*2)=eye_contour_tmp{n};

1291

end

1288

end

1292

1289

1293

1290

1294

%Find VEC eye height

1291

%Find VEC eye height

1295

out_VT=[];

1292

out_VT=[];

1296

out_VB=[];

1293

out_VB=[];

1297

if param.T_O ~=0

1294

if param.T_O ~=0

1298

1295

1299

switch lower(OP.Histogram_Window_Weight)

1296

switch lower(OP.Histogram_Window_Weight)

1300

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

1297

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

1301

%build a gaussian window of weights that are multiplied by each pdf in the T_O range

1298

%build a gaussian window of weights that are multiplied by each pdf in the T_O range

1302

%Sigma = T_O/QL. Default QL=2.5. This gives a nice descent to near 0 at the edge of the window

1299

%Sigma = T_O/QL. Default QL=2.5. This gives a nice descent to near 0 at the edge of the window

1303

QL_sigma=T_O/param.QL;

1300

QL_sigma=T_O/param.QL;

1304

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

1301

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

1305

case 'triangle'

1302

case 'triangle'

1306

%triangle window. linear slope from 0 to 1 and back down to 0

1303

%triangle window. linear slope from 0 to 1 and back down to 0

1307

%for the weights

1304

%for the weights

1308

t_slope=1/(T_O);

1305

t_slope=1/(T_O);

1309

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

1306

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

1310

case 'rectangle'

1307

case 'rectangle'

1311

%default = rectangle. all weights = 1

1308

%default = rectangle. all weights = 1

1312

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

1309

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

1313

case 'dual_rayleigh'

1310

case 'dual_rayleigh'

1314

QL_sigma=T_O/param.QL;

1311

QL_sigma=T_O/param.QL;

1315

X=-T_O:T_O;

1312

X=-T_O:T_O;

1316

weights=(X+T_O)/QL_sigma^2.*exp(-1/2 * ((X+T_O)/QL_sigma).^2)...

1313

weights=(X+T_O)/QL_sigma^2.*exp(-1/2 * ((X+T_O)/QL_sigma).^2)...

1317

-(X-T_O)/QL_sigma^2.*exp(-1/2 * ((X-T_O)/QL_sigma).^2);

1314

-(X-T_O)/QL_sigma^2.*exp(-1/2 * ((X-T_O)/QL_sigma).^2);

1318

weights=weights/max(weights);

1315

weights=weights/max(weights);

1319

otherwise

1316

otherwise

1320

error('%s not recognized for Histogram_Window_Weight',OP.Histogram_Window_Weight)

1317

error('%s not recognized for Histogram_Window_Weight',OP.Histogram_Window_Weight)

1321

end

1318

end

1322

1319

1323

for n=1:param.levels

1320

for n=1:param.levels

1324

out_pdf{n}=[];

1321

out_pdf{n}=[];

1325

for j=start_sample:end_sample

1322

for j=start_sample:end_sample

1326

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1323

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1327

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

1324

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

1328

if isempty(out_pdf{n})

1325

if isempty(out_pdf{n})

1329

out_pdf{n}=target_pdf;

1326

out_pdf{n}=target_pdf;

1330

else

1327

else

1331

out_pdf{n} = combine_pdf_same_voltage_axis(out_pdf{n}, target_pdf);

1328

out_pdf{n} = combine_pdf_same_voltage_axis(out_pdf{n}, target_pdf);

1332

end

1329

end

1333

end

1330

end

1334

out_pdf{n}.y=out_pdf{n}.y/sum(out_pdf{n}.y);

1331

out_pdf{n}.y=out_pdf{n}.y/sum(out_pdf{n}.y);

1335

end

1332

end

1336

1333

1337

for n=1:param.levels

1334

for n=1:param.levels

1338

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

1335

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

1339

end

1336

end

1340

1337

1341

for n=1:param.levels

1338

for n=1:param.levels

1342

[A_ni_top_O(n),A_ni_bottom_O(n)]=cdf_to_ber_contour(out_cdf{n},param.specBER);

1339

[A_ni_top_O(n),A_ni_bottom_O(n)]=cdf_to_ber_contour(out_cdf{n},param.specBER);

1343

end

1340

end

1344

1341

1345

for n=1:param.levels-1

1342

for n=1:param.levels-1

1346

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

1343

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

1347

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

1344

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

1348

end

1345

end

1349

1346

1350

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

1347

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

1351

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

1348

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

1352

[mineh,min_idx]=min(EH_VT);

1349

[mineh,min_idx]=min(EH_VT);

1353

out_VT=OUT_VT_L(min_idx,1);

1350

out_VT=OUT_VT_L(min_idx,1);

1354

out_VB=OUT_VT_L(min_idx,2);

1351

out_VB=OUT_VT_L(min_idx,2);

1355

1352

1356

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

1353

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

1357

% out_VT=2*CDF_Mean-A_ni_top_O;

1354

% out_VT=2*CDF_Mean-A_ni_top_O;

1358

% out_VB=-1*A_ni_bottom_O;

1355

% out_VB=-1*A_ni_bottom_O;

1359

1356

1360

if debug_plot

1357

if debug_plot

1361

figure;

1358

figure;

1362

hold on;

1359

hold on;

1363

for j=start_sample:end_sample

1360

for j=start_sample:end_sample

1364

plot(combined_interference_and_noise_pdf_full(j).x,combined_interference_and_noise_pdf_full(j).y);

1361

plot(combined_interference_and_noise_pdf_full(j).x,combined_interference_and_noise_pdf_full(j).y);

1365

end

1362

end

1366

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

1363

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

1367

hold off;

1364

hold off;

1368

end

1365

end

1369

end

1366

end

1370

1367

1371

1368

1372

1369

1373

1370

1374

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

1371

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

1375

1372

1376

%This block was originally in main COM function but was moved here for

1373

%This block was originally in main COM function but was moved here for

1377

%cleanup. It returns the combined interference and noise PDF & CDF as well

1374

%cleanup. It returns the combined interference and noise PDF & CDF as well

1378

%as a structure "NS" that contains all the noise parameters that are used

1375

%as a structure "NS" that contains all the noise parameters that are used

1379

%in other places in COM

1376

%in other places in COM

1380

1377

1381

if OP.RX_CALIBRATION

1378

if OP.RX_CALIBRATION

1382

ctle_gain2 = (10.^(param.ctle_gdc_values(fom_result.ctle)/20) + 1i*chdata(2).faxis/param.CTLE_fz(fom_result.ctle)) ./ ...

1379

ctle_gain2 = (10.^(param.ctle_gdc_values(fom_result.ctle)/20) + 1i*chdata(2).faxis/param.CTLE_fz(fom_result.ctle)) ./ ...

1383

((1+1i*chdata(2).faxis/param.CTLE_fp1(fom_result.ctle)).*(1+1i*chdata(2).faxis/param.CTLE_fp2(fom_result.ctle)));

1380

((1+1i*chdata(2).faxis/param.CTLE_fp1(fom_result.ctle)).*(1+1i*chdata(2).faxis/param.CTLE_fp2(fom_result.ctle)));

1384

switch param.CTLE_type

1381

switch param.CTLE_type

1385

case 'CL93'

1382

case 'CL93'

1386

H_low2=1;

1383

H_low2=1;

1387

case 'CL120d' % this clause uses two gain indexes

1384

case 'CL120d' % this clause uses two gain indexes

1388

H_low2=(10.^(param.g_DC_HP_values(fom_result.best_G_high_pass)/20) + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass))./(1 + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass));

1385

H_low2=(10.^(param.g_DC_HP_values(fom_result.best_G_high_pass)/20) + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass))./(1 + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass));

1389

case 'CL120e' % Z1 has been adjusted

1386

case 'CL120e' % Z1 has been adjusted

1390

H_low2=(1 + 1i*chdata(2).faxis/f_HP_P(fom_result.ctle))./(1 + 1i*chdata(2).faxis/f_HP_Z(fom_result.ctle));

1387

H_low2=(1 + 1i*chdata(2).faxis/f_HP_P(fom_result.ctle))./(1 + 1i*chdata(2).faxis/f_HP_Z(fom_result.ctle));

1391

end

1388

end

1392

H_ctf2=H_low2.*ctle_gain2;

1389

H_ctf2=H_low2.*ctle_gain2;

1393

[ sigma_ne, NS.sigma_hp] = get_sigma_noise( H_ctf2, param, chdata, sigma_bn );

1390

[ sigma_ne, NS.sigma_hp] = get_sigma_noise( H_ctf2, param, chdata, sigma_bn );

1394

else

1391

else

1395

sigma_ne=0;

1392

sigma_ne=0;

1396

end

1393

end

1397

1394

1398

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

1395

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

1399

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

1396

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

1400

if ~OP.SNR_TXwC0

1397

if ~OP.SNR_TXwC0

1401

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

1398

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

1402

NS.sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx and RLM

1399

NS.sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx and RLM

1403

else

1400

else

1404

NS.sigma_TX = (param.levels-1)*A_s/fom_result.txffe(fom_result.cur) /param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx from Adee

1401

NS.sigma_TX = (param.levels-1)*A_s/fom_result.txffe(fom_result.cur) /param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx from Adee

1405

end

1402

end

1406

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

1403

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

1407

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

1404

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

1408

else

1405

else

1409

NS.sigma_TX =PSD_results.S_tn_rms;

1406

NS.sigma_TX =PSD_results.S_tn_rms;

1410

NS.sigma_G = PSD_results.S_G_rms;

1407

NS.sigma_G = PSD_results.S_G_rms;

1411

NS.sigma_rjit=PSD_results.S_rj_rms ;

1408

NS.sigma_rjit=PSD_results.S_rj_rms ;

1412

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

1409

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

1413

end

1410

end

1414

% Equation 93A-41 %%

1411

% Equation 93A-41 %%

1415

1412

1416

1413

1417

% Equation 93A-42 %%

1414

% Equation 93A-42 %%

1418

% number of sigmas needed depends on the required BER.

1415

% number of sigmas needed depends on the required BER.

1419

if param.Noise_Crest_Factor == 0

1416

if param.Noise_Crest_Factor == 0

1420

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

1417

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

1421

else

1418

else

1422

NS.ber_q=param.Noise_Crest_Factor;

1419

NS.ber_q=param.Noise_Crest_Factor;

1423

end

1420

end

1424

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

1421

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

1425

% enable overriding the Q factor of the BBN instrument.

1422

% enable overriding the Q factor of the BBN instrument.

1426

if OP.force_BBN_Q_factor

1423

if OP.force_BBN_Q_factor

1427

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

1424

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

1428

else

1425

else

1429

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

1426

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

1430

end

1427

end

1431

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

1428

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

1432

1429

1433

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

1430

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

1434

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

1431

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

1435

1432

1436

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

1433

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

1437

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

1434

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

1438

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

1435

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

1439

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

1436

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

1440

1437

1441

% Implementation of 93A.1.7.3 combination procedure

1438

% Implementation of 93A.1.7.3 combination procedure

1442

% (effectively Equation 93A-44) %%

1439

% (effectively Equation 93A-44) %%

1443

1440

1444

% Self-Channel Interference is thru residual result

1441

% Self-Channel Interference is thru residual result

1445

NS.sci_pdf = chdata(1).pdfr;

1442

NS.sci_pdf = chdata(1).pdfr;

1446

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

1443

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

1447

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

1444

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

1448

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

1445

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

1449

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

1446

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

1450

if OP.RX_CALIBRATION ==0

1447

if OP.RX_CALIBRATION ==0

1451

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

1448

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

1452

% initialize to deltas

1449

% initialize to deltas

1453

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

1450

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

1454

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

1451

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

1455

% serially convolve FEXT/NEXT PDFs

1452

% serially convolve FEXT/NEXT PDFs

1456

for k=2:param.number_of_s4p_files

1453

for k=2:param.number_of_s4p_files

1457

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

1454

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

1458

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

1455

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

1459

else % ... must be FEXT

1456

else % ... must be FEXT

1460

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

1457

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

1461

end

1458

end

1462

end

1459

end

1463

1460

1464

% find "peaks" of MDNEXT/MDFEXT for reporting

1461

% find "peaks" of MDNEXT/MDFEXT for reporting

1465

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

1462

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

1466

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

1463

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

1467

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

1464

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

1468

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

1465

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

1469

1466

1470

% Combined crosstalk effect

1467

% Combined crosstalk effect

1471

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1468

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1472

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

1469

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

1473

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

1470

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

1474

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

1471

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

1475

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

1472

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

1476

% combine cci and sci

1473

% combine cci and sci

1477

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

1474

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

1478

else

1475

else

1479

% for calibration there is no cci

1476

% for calibration there is no cci

1480

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1477

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1481

end

1478

end

1482

1479

1483

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

1480

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

1484

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

1481

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

1485

1482

1486

1483

1487

% Equation 93A-45

1484

% Equation 93A-45

1488

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

1485

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

1489

PDF=combined_interference_and_noise_pdf;

1486

PDF=combined_interference_and_noise_pdf;

1490

1487

1491

% Equation 93A-37

1488

% Equation 93A-37

1492

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1489

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1493

CDF=combined_interference_and_noise_cdf;

1490

CDF=combined_interference_and_noise_cdf;

1494

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

1491

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

1495

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

1492

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

1496

1493

1497

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

1494

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

1498

%This function calculates various frequency domain metrics

1495

%This function calculates various frequency domain metrics

1499

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

1496

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

1500

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

1497

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

1501

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1498

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1502

if OP.WC_PORTZ

1499

if OP.WC_PORTZ

1503

A_thru = param.a_thru(param.Tx_rd_sel);

1500

A_thru = param.a_thru(param.Tx_rd_sel);

1504

A_fext = param.a_fext(param.Tx_rd_sel);

1501

A_fext = param.a_fext(param.Tx_rd_sel);

1505

A_next = param.a_next(param.Tx_rd_sel);

1502

A_next = param.a_next(param.Tx_rd_sel);

1506

else

1503

else

1507

A_thru = param.a_thru(package_testcase);

1504

A_thru = param.a_thru(package_testcase);

1508

A_fext = param.a_fext(package_testcase);

1505

A_fext = param.a_fext(package_testcase);

1509

A_next = param.a_next(package_testcase);

1506

A_next = param.a_next(package_testcase);

1510

end

1507

end

1511

for i=1:param.number_of_s4p_files

1508

for i=1:param.number_of_s4p_files

1512

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

1509

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

1513

chdata(i).A=A_thru;

1510

chdata(i).A=A_thru;

1514

chdata(i).Aicn=A_thru;

1511

chdata(i).Aicn=A_thru;

1515

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

1512

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

1516

chdata(i).A=A_fext;

1513

chdata(i).A=A_fext;

1517

chdata(i).Aicn=param.a_icn_fext;

1514

chdata(i).Aicn=param.a_icn_fext;

1518

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

1515

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

1519

chdata(i).A=A_next;

1516

chdata(i).A=A_next;

1520

chdata(i).Aicn=param.a_icn_next;

1517

chdata(i).Aicn=param.a_icn_next;

1521

end

1518

end

1522

end

1519

end

1523

if OP.TDMODE

1520

if OP.TDMODE

1524

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

1521

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

1525

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

1522

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

1526

end

1523

end

1527

end

1524

end

1528

if ~DO_ONCE

1525

if ~DO_ONCE

1529

return;

1526

return;

1530

end

1527

end

1531

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

1528

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

1532

output_args.fitted_IL_dB_at_Fnq = [];

1529

output_args.fitted_IL_dB_at_Fnq = [];

1533

output_args.cable__assembley_loss=[];

1530

output_args.cable__assembley_loss=[];

1534

output_args.loss_with_PCB=[];

1531

output_args.loss_with_PCB=[];

1535

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1532

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1536

output_args.IL_dB_channel_only_at_Fnq=[];

1533

output_args.IL_dB_channel_only_at_Fnq=[];

1537

output_args.VTF_loss_dB_at_Fnq=[];

1534

output_args.VTF_loss_dB_at_Fnq=[];

1538

output_args.IL_db_die_to_die_at_Fnq=[];

1535

output_args.IL_db_die_to_die_at_Fnq=[];

1539

output_args.FOM_TDILN=[];

1536

output_args.FOM_TDILN=[];

1540

output_args.TD_ILN=[];

1537

output_args.TD_ILN=[];

1541

output_args.FOM_RILN=[];

1538

output_args.FOM_RILN=[];

1542

output_args.FOM_ILD=[];

1539

output_args.FOM_ILD=[];

1543

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

1540

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

1544

if ~OP.GET_FD

1541

if ~OP.GET_FD

1545

return;

1542

return;

1546

end

1543

end

1547

case_number=param.package_testcase_i;

1544

case_number=param.package_testcase_i;

1548

f2=param.f2;

1545

f2=param.f2;

1549

f1=param.f1;

1546

f1=param.f1;

1550

MDFEXT_ICN=0; MDNEXT_ICN=0;

1547

MDFEXT_ICN=0; MDNEXT_ICN=0;

1551

for i=1:param.number_of_s4p_files

1548

for i=1:param.number_of_s4p_files

1552

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1549

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1553

% Equation 93A-20 %%

1550

% Equation 93A-20 %%

1554

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

1551

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

1555

f=chdata(i).faxis;

1552

f=chdata(i).faxis;

1556

%

1553

%

1557

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

1554

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

1558

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

1555

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

1559

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

1556

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

1560

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

1557

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

1561

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

1558

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

1562

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

1559

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

1563

if OP.DISPLAY_WINDOW

1560

if OP.DISPLAY_WINDOW

1564

if i==1

1561

if i==1

1565

figure(300+param.package_testcase_i);

1562

figure(300+param.package_testcase_i);

1566

subplot(3,1,1)

1563

subplot(3,1,1)

1567

hold on

1564

hold on

1568

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

1565

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

1569

try

1566

try

1570

legend('NumColumns',2)

1567

legend('NumColumns',2)

1571

legend('location','south')

1568

legend('location','south')

1572

catch

1569

catch

1573

end

1570

end

1574

end

1571

end

1575

end

1572

end

1576

end

1573

end

1577

end

1574

end

1578

for i=1:param.number_of_s4p_files

1575

for i=1:param.number_of_s4p_files

1579

if i == 2

1576

if i == 2

1580

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

1577

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

1581

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

1578

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

1582

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

1579

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

1583

end

1580

end

1584

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

1581

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

1585

if isempty(a)

1582

if isempty(a)

1586

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

1583

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

1587

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

1584

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

1588

else

1585

else

1589

index_f2=a(1);

1586

index_f2=a(1);

1590

end

1587

end

1591

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

1588

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

1592

if isempty(b)

1589

if isempty(b)

1593

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

1590

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

1594

index_f1=1;

1591

index_f1=1;

1595

else

1592

else

1596

index_f1=b(1);

1593

index_f1=b(1);

1597

end

1594

end

1598

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

1595

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

1599

% PWF for ICN

1596

% PWF for ICN

1600

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

1597

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

1601

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

1598

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

1602

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

1599

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

1603

end

1600

end

1604

SINC = sin(temp_angle)./temp_angle;

1601

SINC = sin(temp_angle)./temp_angle;

1605

PWF_data=SINC.^2;

1602

PWF_data=SINC.^2;

1606

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

1603

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

1607

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

1604

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

1608

fr=param.f_r*param.fb;

1605

fr=param.f_r*param.fb;

1609

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

1606

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

1610

PWF_highpass=1;

1607

PWF_highpass=1;

1611

% Equation 93A-57 %

1608

% Equation 93A-57 %

1612

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

1609

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

1613

% freq delta for integration

1610

% freq delta for integration

1614

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

1611

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

1615

% from ba spec, this is basically ICN

1612

% from ba spec, this is basically ICN

1616

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

1613

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

1617

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

1614

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

1618

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

1615

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

1619

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

1616

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

1620

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

1617

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

1621

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

1618

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

1622

chdata(i).fit_ILatNq = fit_loss;

1619

chdata(i).fit_ILatNq = fit_loss;

1623

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1620

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1624

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

1621

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

1625

chdata(i).ILatNq = IL_interp;

1622

chdata(i).ILatNq = IL_interp;

1626

if OP.include_pcb

1623

if OP.include_pcb

1627

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

1624

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

1628

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

1625

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

1629

output_args.cable__assembley_loss=cable_loss;

1626

output_args.cable__assembley_loss=cable_loss;

1630

output_args.loss_with_PCB=loss_with_PCB;

1627

output_args.loss_with_PCB=loss_with_PCB;

1631

end

1628

end

1632

Nq_loss=chdata(i).ILatNq;

1629

Nq_loss=chdata(i).ILatNq;

1633

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1630

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1634

% time domain ref RR = complex fit pulse

1631

% time domain ref RR = complex fit pulse

1635

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1632

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1636

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

1633

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

1637

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1634

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1638

FOM_ILN_complex= TD_ILN.FOM;

1635

FOM_ILN_complex= TD_ILN.FOM;

1639

end

1636

end

1640

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1637

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1641

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

1638

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

1642

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1639

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1643

FOM_ILN_complex= TD_ILN.FOM;

1640

FOM_ILN_complex= TD_ILN.FOM;

1644

end

1641

end

1645

if OP.COMPUTE_TDILN

1642

if OP.COMPUTE_TDILN

1646

output_args.FOM_TDILN=FOM_TDILN;

1643

output_args.FOM_TDILN=FOM_TDILN;

1647

output_args.TD_ILN=TD_ILN; % struct

1644

output_args.TD_ILN=TD_ILN; % struct

1648

end

1645

end

1649

if OP.COMPUTE_RILN

1646

if OP.COMPUTE_RILN

1650

% Get RIL, RILN, and TD_RILN

1647

% Get RIL, RILN, and TD_RILN

1651

[RIL_struct]= capture_RIL_RILN(chdata);

1648

[RIL_struct]= capture_RIL_RILN(chdata);

1652

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

1649

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

1653

output_args.FOM_RILN=FOM_RILN;

1650

output_args.FOM_RILN=FOM_RILN;

1654

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

1651

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

1655

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

1652

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

1656

if plot_tdomain_debug== 1

1653

if plot_tdomain_debug== 1

1657

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

1654

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

1658

ax_1= subplot(3,1,1);

1655

ax_1= subplot(3,1,1);

1659

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

1656

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

1660

hold on;

1657

hold on;

1661

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

1658

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

1662

hold on;

1659

hold on;

1663

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

1660

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

1664

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

1661

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

1665

grid on;

1662

grid on;

1666

box on;

1663

box on;

1667

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

1664

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

1668

xlabel('Time [nsec]');

1665

xlabel('Time [nsec]');

1669

ylabel('Pulse Response [mV]');

1666

ylabel('Pulse Response [mV]');

1670

1667

1671

ax_2= subplot(3,1,2);

1668

ax_2= subplot(3,1,2);

1672

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

1669

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

1673

hold on;

1670

hold on;

1674

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

1671

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

1675

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

1672

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

1676

grid on;

1673

grid on;

1677

box on;

1674

box on;

1678

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

1675

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

1679

xlabel('Time [nsec]');

1676

xlabel('Time [nsec]');

1680

ylabel('Pulse Response [mV]');

1677

ylabel('Pulse Response [mV]');

1681

ax_3= subplot(3,1,3);

1678

ax_3= subplot(3,1,3);

1682

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

1679

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

1683

hold on;

1680

hold on;

1684

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

1681

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

1685

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

1682

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

1686

grid on;

1683

grid on;

1687

box on;

1684

box on;

1688

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

1685

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

1689

xlabel('Time [nsec]');

1686

xlabel('Time [nsec]');

1690

ylabel('Pulse Response [mV]');

1687

ylabel('Pulse Response [mV]');

1691

1688

1692

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

1689

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

1693

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

1690

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

1694

end

1691

end

1695

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

1692

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

1696

end

1693

end

1697

% Equation 93A-56 %

1694

% Equation 93A-56 %

1698

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

1695

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

1699

output_args.FOM_ILD=FOM_ILD;

1696

output_args.FOM_ILD=FOM_ILD;

1700

if OP.DEBUG

1697

if OP.DEBUG

1701

if OP.DISPLAY_WINDOW

1698

if OP.DISPLAY_WINDOW

1702

figure(300+case_number);

1699

figure(300+case_number);

1703

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

1700

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

1704

screen_size=get(0,'ScreenSize');

1701

screen_size=get(0,'ScreenSize');

1705

pos = get(gcf, 'OuterPosition');

1702

pos = get(gcf, 'OuterPosition');

1706

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

1703

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

1707

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

1704

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

1708

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

1705

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

1709

subplot(3,1,1)

1706

subplot(3,1,1)

1710

title('Losses')

1707

title('Losses')

1711

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

1708

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

1712

hold on

1709

hold on

1713

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_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1714

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

1711

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

1715

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

1712

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

1716

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

1713

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

1717

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

1714

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

1718

subplot(3,1,3)

1715

subplot(3,1,3)

1719

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

1716

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

1720

if OP.PLOT_CM

1717

if OP.PLOT_CM

1721

if case_number ==1

1718

if case_number ==1

1722

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

1719

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

1723

screen_size=get(0,'ScreenSize');

1720

screen_size=get(0,'ScreenSize');

1724

pos = get(gcf, 'OuterPosition');

1721

pos = get(gcf, 'OuterPosition');

1725

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

1722

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

1726

movegui(gcf,'center');

1723

movegui(gcf,'center');

1727

htabgroup350 = uitabgroup(h350);

1724

htabgroup350 = uitabgroup(h350);

1728

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

1725

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

1729

hax1 = axes('Parent', htab1);

1726

hax1 = axes('Parent', htab1);

1730

set(h350,'CurrentAxes',hax1)

1727

set(h350,'CurrentAxes',hax1)

1731

hold on

1728

hold on

1732

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

1729

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

1733

screen_size=get(0,'ScreenSize');

1730

screen_size=get(0,'ScreenSize');

1734

pos = get(gcf, 'OuterPosition');

1731

pos = get(gcf, 'OuterPosition');

1735

title('IL & CM Losses')

1732

title('IL & CM Losses')

1736

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

1733

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

1737

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

1734

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

1738

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

1735

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

1739

ylabel('dB')

1736

ylabel('dB')

1740

xlabel('GHz')

1737

xlabel('GHz')

1741

legend show

1738

legend show

1742

legend('Location','eastoutside')

1739

legend('Location','eastoutside')

1743

hold on

1740

hold on

1744

grid on

1741

grid on

1745

if param.number_of_s4p_files > 1

1742

if param.number_of_s4p_files > 1

1746

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

1743

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

1747

hax2 = axes('Parent', htab2);

1744

hax2 = axes('Parent', htab2);

1748

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

1745

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

1749

hax3 = axes('Parent', htab3);

1746

hax3 = axes('Parent', htab3);

1750

end

1747

end

1751

1748

1752

end

1749

end

1753

end

1750

end

1754

else

1751

else

1755

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

1752

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

1756

end

1753

end

1757

end

1754

end

1758

else % NEXT or FEXT

1755

else % NEXT or FEXT

1759

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

1756

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

1760

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

1757

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

1761

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

1758

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

1762

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1759

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1763

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

1760

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

1764

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

1761

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

1765

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

1762

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

1766

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1763

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1767

end

1764

end

1768

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

1765

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

1769

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

1766

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

1770

output_args.ICN_mV=ICN*1000;

1767

output_args.ICN_mV=ICN*1000;

1771

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1768

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1772

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1769

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1773

if case_number ==1

1770

if case_number ==1

1774

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

1771

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

1775

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

1772

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

1776

set(h350,'CurrentAxes',hax2)

1773

set(h350,'CurrentAxes',hax2)

1777

hold on

1774

hold on

1778

title('CM Losses')

1775

title('CM Losses')

1779

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

1776

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

1780

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

1777

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

1781

legend('Location','eastoutside')

1778

legend('Location','eastoutside')

1782

hold on

1779

hold on

1783

grid on

1780

grid on

1784

set(h350,'CurrentAxes',hax3)

1781

set(h350,'CurrentAxes',hax3)

1785

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

1782

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

1786

legend('Location','eastoutside')

1783

legend('Location','eastoutside')

1787

hold on

1784

hold on

1788

grid on

1785

grid on

1789

end

1786

end

1790

end

1787

end

1791

end

1788

end

1792

end % for loop

1789

end % for loop

1793

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1790

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1794

if OP.DEBUG && OP.DISPLAY_WINDOW

1791

if OP.DEBUG && OP.DISPLAY_WINDOW

1795

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

1792

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

1796

if param.number_of_s4p_files > 1

1793

if param.number_of_s4p_files > 1

1797

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

1794

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

1798

subplot(3,1,1)

1795

subplot(3,1,1)

1799

hold on

1796

hold on

1800

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

1797

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

1801

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

1798

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

1802

subplot(3,1,2)

1799

subplot(3,1,2)

1803

grid on

1800

grid on

1804

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

1801

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

1805

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

1802

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

1806

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

1803

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

1807

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1804

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1808

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1805

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1809

hold on

1806

hold on

1810

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1807

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1811

end

1808

end

1812

subplot(3,1,1)

1809

subplot(3,1,1)

1813

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1810

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1814

grid on; legend show

1811

grid on; legend show

1815

subplot(3,1,2)

1812

subplot(3,1,2)

1816

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1813

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1817

ylim([0 80])

1814

ylim([0 80])

1818

xlim([.1 100])

1815

xlim([.1 100])

1819

grid on; %legend show

1816

grid on; %legend show

1820

subplot(3,1,3)

1817

subplot(3,1,3)

1821

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1818

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1822

ylim([-3 3])

1819

ylim([-3 3])

1823

grid on; legend show

1820

grid on; legend show

1824

end

1821

end

1825

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1822

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1826

total_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21)), 1/param.ui/2);

1823

total_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21)), 1/param.ui/2);

1827

d2d_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p_nodie)), 1/param.ui/2);

1824

d2d_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p_nodie)), 1/param.ui/2);

1828

VIP_VMP_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p)), 1/param.ui/2);

1825

VIP_VMP_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p)), 1/param.ui/2);

1829

output_args.VTF_loss_dB_at_Fnq=total_loss;

1826

output_args.VTF_loss_dB_at_Fnq=total_loss;

1830

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1827

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1831

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1828

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1832

function [ V0 ] = FFE( C , cmx,spui, V )

1829

function [ V0 ] = FFE( C , cmx,spui, V )

1833

% C FFE taps

1830

% C FFE taps

1834

% cmx number of precursors taps

1831

% cmx number of precursors taps

1835

% spui samples per ui

1832

% spui samples per ui

1836

% V input signal

1833

% V input signal

1837

%speed ups implemented:

1834

%speed ups implemented:

1838

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1835

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1839

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1836

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1840

1837

1841

V0=0;

1838

V0=0;

1842

if iscolumn(V); V=V.';end

1839

if iscolumn(V); V=V.';end

1843

for i=1:length(C)

1840

for i=1:length(C)

1844

if C(i)~=0

1841

if C(i)~=0

1845

ishift=(i-1-cmx)*spui;

1842

ishift=(i-1-cmx)*spui;

1846

V0=circshift(V',[ishift,0])*C(i)+V0;

1843

V0=circshift(V',[ishift,0])*C(i)+V0;

1847

end

1844

end

1848

end

1845

end

1849

%V0=circshift(V0,[(-cmx)*spui,0]);

1846

%V0=circshift(V0,[(-cmx)*spui,0]);

1850

% disp(max(V0));

1847

% disp(max(V0));

1851

1848

1852

1849

1853

% begin yasuo patch 12/11/2018

1850

% begin yasuo patch 12/11/2018

1854

% calculate sigma (standard deviation) value of PDF

1851

% calculate sigma (standard deviation) value of PDF

1855

function [ V0 ] = FFE_Fast( C,V_shift )

1852

function [ V0 ] = FFE_Fast( C,V_shift )

1856

% C FFE taps

1853

% C FFE taps

1857

% V input signal separated into length(C) columns with circshift already performed

1854

% V input signal separated into length(C) columns with circshift already performed

1858

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1855

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1859

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1856

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1860

% saved by pre-shifting it and remembering it across loops

1857

% saved by pre-shifting it and remembering it across loops

1861

% Another speed up: only multiply by indices of C that are not 0

1858

% Another speed up: only multiply by indices of C that are not 0

1862

1859

1863

V0=0;

1860

V0=0;

1864

for i=1:length(C)

1861

for i=1:length(C)

1865

if C(i)~=0

1862

if C(i)~=0

1866

V0=V_shift(:,i)*C(i)+V0;

1863

V0=V_shift(:,i)*C(i)+V0;

1867

end

1864

end

1868

end

1865

end

1869

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1866

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1870

1867

1871

hisi=h(isi_start:isi_end);

1868

hisi=h(isi_start:isi_end);

1872

hisi=hisi(param.RxFFE_cpx+1:param.N_bmax);

1869

hisi=hisi(param.RxFFE_cpx+1:param.N_bmax);

1873

bank_size = param.N_bf;

1870

bank_size = param.N_bf;

1874

num_groups = param.N_bg;

1871

num_groups = param.N_bg;

1875

1872

1876

1873

1877

%start with one by one Floating Tap

1874

%start with one by one Floating Tap

1878

num_isi=length(hisi);

1875

num_isi=length(hisi);

1879

max_isi=num_isi-bank_size+1;

1876

max_isi=num_isi-bank_size+1;

1880

valid_tap_locations=1:max_isi;

1877

valid_tap_locations=1:max_isi;

1881

all_idx=[];

1878

all_idx=[];

1882

for j=1:num_groups

1879

for j=1:num_groups

1883

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1880

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1884

for k=1:length(valid_tap_locations)

1881

for k=1:length(valid_tap_locations)

1885

this_location=valid_tap_locations(k);

1882

this_location=valid_tap_locations(k);

1886

new_idx = [all_idx this_location:this_location+bank_size-1];

1883

new_idx = [all_idx this_location:this_location+bank_size-1];

1887

new_idx=sort(new_idx);

1884

new_idx=sort(new_idx);

1888

new_idx = new_idx+param.RxFFE_cpx;

1885

new_idx = new_idx+param.RxFFE_cpx;

1889

%calculate FOM for each one

1886

%calculate FOM for each one

1890

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1887

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1891

end

1888

end

1892

%choose the location with best FOM

1889

%choose the location with best FOM

1893

%add it to the "all_idx" list and remove it from valid locations

1890

%add it to the "all_idx" list and remove it from valid locations

1894

[~,best_FOM_idx]=max(best_FOM);

1891

[~,best_FOM_idx]=max(best_FOM);

1895

start_tap = valid_tap_locations(best_FOM_idx);

1892

start_tap = valid_tap_locations(best_FOM_idx);

1896

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1893

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1897

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1894

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1898

remove_range(remove_range>length(valid_tap_locations))=[];

1895

remove_range(remove_range>length(valid_tap_locations))=[];

1899

valid_tap_locations(remove_range)=[];

1896

valid_tap_locations(remove_range)=[];

1900

1897

1901

%Also remove illegal taps from valid locations

1898

%Also remove illegal taps from valid locations

1902

%illegal taps are ones that would overlap with the chosen bank

1899

%illegal taps are ones that would overlap with the chosen bank

1903

bad_tap=start_tap-bank_size+1:start_tap-1;

1900

bad_tap=start_tap-bank_size+1:start_tap-1;

1904

bad_tap(bad_tap<1)=[];

1901

bad_tap(bad_tap<1)=[];

1905

for n=1:length(bad_tap)

1902

for n=1:length(bad_tap)

1906

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1903

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1907

if ~isempty(bad_tap_idx)

1904

if ~isempty(bad_tap_idx)

1908

valid_tap_locations(bad_tap_idx)=[];

1905

valid_tap_locations(bad_tap_idx)=[];

1909

end

1906

end

1910

end

1907

end

1911

end

1908

end

1912

1909

1913

%put idx back in the right location (adding RxFFE_cpx)

1910

%put idx back in the right location (adding RxFFE_cpx)

1914

idx = all_idx+param.RxFFE_cpx;

1911

idx = all_idx+param.RxFFE_cpx;

1915

idx = sort(idx);

1912

idx = sort(idx);

1916

function [ V0 ] = Fract_T_FFE( V , skew_step)

1913

function [ V0 ] = Fract_T_FFE( V , skew_step)

1917

% skew_step sub UI skew assuming param.samples_per_ui

1914

% skew_step sub UI skew assuming param.samples_per_ui

1918

% V input signal

1915

% V input signal

1919

% V0 output signal

1916

% V0 output signal

1920

% Richard Mellitz 8/17/2021

1917

% Richard Mellitz 8/17/2021

1921

V0=0;

1918

V0=0;

1922

if iscolumn(V); V=V.';end

1919

if iscolumn(V); V=V.';end

1923

ishift=skew_step;

1920

ishift=skew_step;

1924

V0=circshift(V',[ishift,0])'+V;

1921

V0=circshift(V',[ishift,0])'+V;

1925

V0=V0/2;

1922

V0=V0/2;

1926

function out=Full_Grid_Matrix(in)

1923

function out=Full_Grid_Matrix(in)

1927

1924

1928

%create a full grid matrix of input variables

1925

%create a full grid matrix of input variables

1929

%used to create the full grid of all txffe cases

1926

%used to create the full grid of all txffe cases

1930

%example:

1927

%example:

1931

%Full_Grid_Matrix({ [1 2] [100 200] })

1928

%Full_Grid_Matrix({ [1 2] [100 200] })

1932

%out =

1929

%out =

1933

% 1 100

1930

% 1 100

1934

% 1 200

1931

% 1 200

1935

% 2 100

1932

% 2 100

1936

% 2 200

1933

% 2 200

1937

%

1934

%

1938

%input can also be mixed between numeric and cell of char

1935

%input can also be mixed between numeric and cell of char

1939

%example:

1936

%example:

1940

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1937

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1941

%out =

1938

%out =

1942

% {[1]} {'A'}

1939

% {[1]} {'A'}

1943

% {[1]} {'B'}

1940

% {[1]} {'B'}

1944

% {[2]} {'A'}

1941

% {[2]} {'A'}

1945

% {[2]} {'B'}

1942

% {[2]} {'B'}

1946

1943

1947

if ~iscell(in)

1944

if ~iscell(in)

1948

error('input must be cell array of individual sweep variables');

1945

error('input must be cell array of individual sweep variables');

1949

end

1946

end

1950

1947

1951

num_columns=length(in);

1948

num_columns=length(in);

1952

num_cases=prod(cellfun('length',in));

1949

num_cases=prod(cellfun('length',in));

1953

1950

1954

cell_output=0;

1951

cell_output=0;

1955

cell_indices=cellfun(@(x) iscell(x),in);

1952

cell_indices=cellfun(@(x) iscell(x),in);

1956

if any(cell_indices)

1953

if any(cell_indices)

1957

cell_output=1;

1954

cell_output=1;

1958

end

1955

end

1959

if cell_output

1956

if cell_output

1960

for k=find(~cell_indices)

1957

for k=find(~cell_indices)

1961

in{k}=num2cell(in{k});

1958

in{k}=num2cell(in{k});

1962

end

1959

end

1963

end

1960

end

1964

1961

1965

if cell_output

1962

if cell_output

1966

out=cell(num_cases,num_columns);

1963

out=cell(num_cases,num_columns);

1967

else

1964

else

1968

out=zeros(num_cases,num_columns);

1965

out=zeros(num_cases,num_columns);

1969

end

1966

end

1970

1967

1971

%num_repetitions controls how many times each element of the column

1968

%num_repetitions controls how many times each element of the column

1972

%repeats. The first column is always just a copy of itself since every

1969

%repeats. The first column is always just a copy of itself since every

1973

%case will vary.

1970

%case will vary.

1974

num_repetitions=1;

1971

num_repetitions=1;

1975

for k=num_columns:-1:1

1972

for k=num_columns:-1:1

1976

this_column=in{k}(:);

1973

this_column=in{k}(:);

1977

%copy the column into a matrix to create the repetitions needed

1974

%copy the column into a matrix to create the repetitions needed

1978

B=repmat(this_column,[1 num_repetitions]);

1975

B=repmat(this_column,[1 num_repetitions]);

1979

%reshape into single column (actual repetitions)

1976

%reshape into single column (actual repetitions)

1980

C=reshape(B',[numel(B) 1]);

1977

C=reshape(B',[numel(B) 1]);

1981

%repeat the single column to build the entire length required

1978

%repeat the single column to build the entire length required

1982

num_repeats=num_cases/length(C);

1979

num_repeats=num_cases/length(C);

1983

D=repmat(C,[num_repeats 1]);

1980

D=repmat(C,[num_repeats 1]);

1984

out(:,k)=D;

1981

out(:,k)=D;

1985

%determine how many repetitions the next column needs

1982

%determine how many repetitions the next column needs

1986

num_repetitions=num_repetitions*length(this_column);

1983

num_repetitions=num_repetitions*length(this_column);

1987

end

1984

end

1988

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1985

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1989

% p=cpdf(type, ...)

1986

% p=cpdf(type, ...)

1990

%

1987

%

1991

% CPDF is a probability mass function for discrete distributions or an

1988

% CPDF is a probability mass function for discrete distributions or an

1992

% approxmation of a PDF for continuous distributions.

1989

% approxmation of a PDF for continuous distributions.

1993

%

1990

%

1994

% cpdf is internally normalized so that the sum of probabilities is 1

1991

% cpdf is internally normalized so that the sum of probabilities is 1

1995

% (regardless of bin size).

1992

% (regardless of bin size).

1996

1993

1997

% Internal fields:

1994

% Internal fields:

1998

% Min: *bin number* of minimum value.

1995

% Min: *bin number* of minimum value.

1999

% BinSize: size of PDF bins. Bin center is the representative value.

1996

% BinSize: size of PDF bins. Bin center is the representative value.

2000

% Vec: vector of probabilities per bin.

1997

% Vec: vector of probabilities per bin.

2001

1998

2002

pdf=EmptyPDF;

1999

pdf=EmptyPDF;

2003

2000

2004

rounded_values_div_binsize=round(values/pdf.BinSize);

2001

rounded_values_div_binsize=round(values/pdf.BinSize);

2005

%values=pdf.BinSize*rounded_values_div_binsize;

2002

%values=pdf.BinSize*rounded_values_div_binsize;

2006

2003

2007

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2004

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2008

% if all(values==0)

2005

% if all(values==0)

2009

% return;

2006

% return;

2010

% end

2007

% end

2011

%

2008

%

2012

% %speed up for all values rounded to the same bin

2009

% %speed up for all values rounded to the same bin

2013

% %The output pdf is the same as the

2010

% %The output pdf is the same as the

2014

% %empty pdf, but the x value is non-zero (but still scalar)

2011

% %empty pdf, but the x value is non-zero (but still scalar)

2015

% if all(values==values(1))

2012

% if all(values==values(1))

2016

% pdf.Min=rounded_values_div_binsize(1);

2013

% pdf.Min=rounded_values_div_binsize(1);

2017

% pdf.x=values(1);

2014

% pdf.x=values(1);

2018

% return;

2015

% return;

2019

% end

2016

% end

2020

%

2017

%

2021

% %The code below requires that values is

2018

% %The code below requires that values is

2022

% %sorted. Generally this should be true, but check to be sure

2019

% %sorted. Generally this should be true, but check to be sure

2023

% if ~issorted(values)

2020

% if ~issorted(values)

2024

% [values,si]=sort(values);

2021

% [values,si]=sort(values);

2025

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2022

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2026

% probs=probs(si);

2023

% probs=probs(si);

2027

% end

2024

% end

2028

2025

2029

2026

2030

%pdf.x=values(1):pdf.BinSize:values(end);

2027

%pdf.x=values(1):pdf.BinSize:values(end);

2031

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2028

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2032

pdf.Min=rounded_values_div_binsize(1);

2029

pdf.Min=rounded_values_div_binsize(1);

2033

2030

2034

pdf.y=zeros(size(pdf.x));

2031

pdf.y=zeros(size(pdf.x));

2035

%The rounded values divided by binsize will reveal the bin number if

2032

%The rounded values divided by binsize will reveal the bin number if

2036

%pdf.Min is subtracted from it

2033

%pdf.Min is subtracted from it

2037

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2034

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2038

%Can avoid one addition by inserting the first probability

2035

%Can avoid one addition by inserting the first probability

2039

%actually helps when calling this 2 million times

2036

%actually helps when calling this 2 million times

2040

pdf.y(bin_placement(1))=probs(1);

2037

pdf.y(bin_placement(1))=probs(1);

2041

for k=2:length(values)

2038

for k=2:length(values)

2042

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2039

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2043

end

2040

end

2044

2041

2045

2042

2046

%Have already ensured that sum(pdf.y)=1

2043

%Have already ensured that sum(pdf.y)=1

2047

%pdf.y=pdf.y/sum(pdf.y);

2044

%pdf.y=pdf.y/sum(pdf.y);

2048

2045

2049

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2046

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2050

% error('PDF must be real and nonnegative');

2047

% error('PDF must be real and nonnegative');

2051

% end

2048

% end

2052

2049

2053

% pMax=pdf.Min+length(pdf.y)-1;

2050

% pMax=pdf.Min+length(pdf.y)-1;

2054

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2051

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2055

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2052

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2056

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2053

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2057

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2054

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2058

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2055

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2059

2056

2060

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2057

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2061

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2058

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2062

2059

2063

%% step 0

2060

%% step 0

2064

COM_from_matlab=20*log10(A_s/A_ni);

2061

COM_from_matlab=20*log10(A_s/A_ni);

2065

L=param.levels;

2062

L=param.levels;

2066

DER0=param.specBER;

2063

DER0=param.specBER;

2067

%% step 1 from slide 6/5

2064

%% step 1 from slide 6/5

2068

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2065

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2069

main=A_peak;

2066

main=A_peak;

2070

k_DER=qfuncinv(param.specBER);

2067

k_DER=qfuncinv(param.specBER);

2071

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2068

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2072

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2069

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2073

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2070

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2074

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2071

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2075

if A_s >= A_ni

2072

if A_s >= A_ni

2076

%% step 2 slide 10/8

2073

%% step 2 slide 10/8

2077

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2074

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2078

%% step 2 slide 10/8

2075

%% step 2 slide 10/8

2079

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2076

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2080

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2077

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2081

%% step 3 side 11/9

2078

%% step 3 side 11/9

2082

j=1:200;

2079

j=1:200;

2083

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2080

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2084

DER_MLSE_CDF=0; jj=1;

2081

DER_MLSE_CDF=0; jj=1;

2085

DER_delta = inf;

2082

DER_delta = inf;

2086

while DER_delta > .001

2083

while DER_delta > .001

2087

last_DER_MLSE_CDF=DER_MLSE_CDF;

2084

last_DER_MLSE_CDF=DER_MLSE_CDF;

2088

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2085

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2089

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2086

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2090

jj=jj+1;

2087

jj=jj+1;

2091

end

2088

end

2092

%% step 4 slide 12/10

2089

%% step 4 slide 12/10

2093

SNR_DFE_eqivalent=SNR_DFE*(...

2090

SNR_DFE_eqivalent=SNR_DFE*(...

2094

(L-1)*sigma_noise/main * qfuncinv(...

2091

(L-1)*sigma_noise/main * qfuncinv(...

2095

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2092

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2096

) ...

2093

) ...

2097

)^2;

2094

)^2;

2098

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2095

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2099

(L-1)/main * CDF_inv_ev(...

2096

(L-1)/main * CDF_inv_ev(...

2100

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2097

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2101

,PDF, CDF ) ...

2098

,PDF, CDF ) ...

2102

)^2;

2099

)^2;

2103

2100

2104

%% step 5 slide 13/11

2101

%% step 5 slide 13/11

2105

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2102

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2106

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2103

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2107

new_com_CDF=COM_from_matlab+delta_com_CDF;

2104

new_com_CDF=COM_from_matlab+delta_com_CDF;

2108

else

2105

else

2109

warning('MLSE not applied because there is more noise than signal')

2106

warning('MLSE not applied because there is more noise than signal')

2110

DER_MLSE=[];

2107

DER_MLSE=[];

2111

DER_MLSE_CDF=[];

2108

DER_MLSE_CDF=[];

2112

SNR_DFE_eqivalent=[];

2109

SNR_DFE_eqivalent=[];

2113

SNR_DFE_eqivalent_CDF=[];

2110

SNR_DFE_eqivalent_CDF=[];

2114

new_com_CDF=COM_from_matlab;

2111

new_com_CDF=COM_from_matlab;

2115

delta_com_CDF=0;

2112

delta_com_CDF=0;

2116

delta_com=0;

2113

delta_com=0;

2117

SNR_DFE=[];

2114

SNR_DFE=[];

+2115

end

2116

2117

%%

2118

MLSE_results.COM_from_matlab=COM_from_matlab;

2119

MLSE_results.SNR_DFE=SNR_DFE;

2120

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2121

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2122

MLSE_results.sigma_noise=sigma_noise;

2123

MLSE_results.SNR_dB=SNR_dB ;

2124

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2125

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2126

MLSE_results.COM_Gaussian=new_com_CDF;

2127

MLSE_results.COM_CDF=new_com_CDF;

2128

MLSE_results.k_DER=k_DER;

2129

MLSE_results.delta_com_CDF=delta_com_CDF;

2130

MLSE_results.delta_com_Gaussian=delta_com;

2131

2132

2133

2134

function [MLSE_results] = MLSE_U1_c(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2135

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2136

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2137

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2138

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2139

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2140

%% step 0

2141

COM_from_matlab=20*log10(A_s/A_ni);

2142

L=param.levels;

2143

DER0=param.specBER;

2144

%% step 1 from slide 6 shakiba_3dj_01_230116

2145

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2146

main=A_peak;

2147

k_DER=qfuncinv(param.specBER);

2148

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2149

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2150

% if A_s >= A_ni

2151

if 1

2152

%% step 2 slide 10 shakiba_3dj_01_230116

2153

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2154

%% step 2 slide 10 not used

2155

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2156

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2157

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2158

S_n=PSD_results.Sn_rho; % total agregate noise PSD

2159

Rn=ifft(S_n)*param.fb;

2160

Rho_row=Rn/Rn(1);

2161

Rn_len=length(Rn);

2162

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2163

for j=1:Rn_len

2164

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2165

end

2166

rho_noiseEE_row=Rho_row.*alphas_row;

2167

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2168

for j=1:Rn_len

2169

rho_noiseEE(j,j)=(1-alpha)^2;

2170

end

2171

rho_noiseEE(1,1)=1;

2172

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2173

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2174

% determine complete matrix

2175

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2176

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2177

%% shakiba_3dj_elec_01a_230504 slide 17

2178

j=1:Rn_len;

2179

DER_MLSE=[];

2180

DER_MLSE_CDF=0; jj=1;

2181

DER_MLSE_CDFold=0;

2182

DER_delta = inf;

2183

% slight modified for PAM4 DER vs SER

2184

while DER_delta > .0001 && jj<=Rn_len || jj==1

2185

last_DER_MLSE_CDF=DER_MLSE_CDF;

2186

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2187

DER_MLSE_CDF= ...

2188

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;

2189

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;

2190

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2191

jj=jj+1;

2118

end

2192

end

+2193

%% shakiba_3dj_elec_01a_230504 slide 19

2194

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2195

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2196

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2197

(L-1)/main * CDF_inv_ev(...

2198

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2199

,PDF, CDF ) ...

2200

)^2;

2201

%% step 5 shakiba_3dj_01_230116 slide 13

2202

delta_com=[];

2203

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2204

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2119

2205

+2206

new_com_CDF=COM_from_matlab+delta_com_CDF;

2207

else

2208

warning('MLSE not applied because there is more noise than signal')

2209

DER_MLSE=[];

2210

DER_MLSE_CDF=[];

2211

SNR_DFE_eqivalent=[];

2212

SNR_DFE_eqivalent_CDF=[];

2213

new_com_CDF=COM_from_matlab;

2214

delta_com_CDF=0;

2215

delta_com=0;

2216

SNR_DFE=[];

2217

end

2218

SNR_DFE_eqivalent=[];

2120

%%

2219

%%

2121

MLSE_results.COM_from_matlab=COM_from_matlab;

2220

MLSE_results.COM_from_matlab=COM_from_matlab;

2122

MLSE_results.SNR_DFE=SNR_DFE;

2221

MLSE_results.SNR_DFE=SNR_DFE;

2123

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2222

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2124

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2223

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2125

MLSE_results.sigma_noise=sigma_noise;

2224

MLSE_results.sigma_noise=sigma_noise;

2126

MLSE_results.SNR_dB=SNR_dB ;

2225

MLSE_results.SNR_dB=SNR_dB ;

2127

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2226

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2128

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2227

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2129

MLSE_results.COM_Gaussian=new_com_CDF;

2228

MLSE_results.COM_Gaussian=new_com_CDF;

2130

MLSE_results.COM_CDF=new_com_CDF;

2229

MLSE_results.COM_CDF=new_com_CDF;

2131

MLSE_results.k_DER=k_DER;

2230

MLSE_results.k_DER=k_DER;

2132

MLSE_results.delta_com_CDF=delta_com_CDF;

2231

MLSE_results.delta_com_CDF=delta_com_CDF;

2133

MLSE_results.delta_com_Gaussian=delta_com;

2232

MLSE_results.delta_com_Gaussian=delta_com;

2134

2233

2135

2234

2136

2235

2137

function [MLSE_results] = MLSE_U1_c_178A(param,b,A_s,A_ni,PDF,CDF,PSD_results)

2236

function [MLSE_results] = MLSE_U1_c_178A(param,b,A_s,A_ni,PDF,CDF,PSD_results)

2138

if 1

2237

if 1

2139

num_ui=param.num_ui_RXFF_noise;

2238

num_ui=param.num_ui_RXFF_noise;

2140

M=param.samples_per_ui;

2239

M=param.samples_per_ui;

2141

L=param.levels;

2240

L=param.levels;

2142

sigma_X2=(L^2-1)/(3*(L-1)^2);

2241

sigma_X2=(L^2-1)/(3*(L-1)^2);

2143

f_b=param.fb;

2242

f_b=param.fb;

2144

DER0=param.specBER; % align terminology

2145

delta_COM_an=param.pass_threshold; % align terminology

2146

end

2243

end

2147

% new function to scale CDF at specified DER; healey_3dj_01_2409 slide 8, 12, and 13

2148

% directly compute p_an (PDF) and P_an (CDF);

2149

[p_an, P_an, ~] = scaleCDF( PDF,delta_COM_an,DER0, A_s );

2150

sigma_an_2_pdf=sum(p_an.y.*p_an.x.^2)-sum(PDF.y.*PDF.x.^2);

2151

sigma_G_2=PSD_results.S_G_rms^2;

2152

g_an=(sigma_an_2_pdf-PSD_results.S_G_rms^2)/PSD_results.S_rn_rms^2;

2153

2154

% g_an be squared since votltage was scalted: healey_3dj_01_2409 slide 12 (178A –X) units are power

2155

% g_an=g_an^2;

2156

COM_from_matlab=20*log10(A_s/A_ni);

2244

COM_from_matlab=20*log10(A_s/A_ni);

2157

DER_DFE= 2*(L-1)/L*CDF_ev(A_s,PDF, CDF);

2245

DER_DFE= 2*(L-1)/L*CDF_ev(A_s,PDF, CDF);

2158

if 1 % comparing to healey_3dj_01_2409 slide 8

2159

figure(1200);set(gcf,'Tag','COM');

2160

semilogy(PDF.x/A_s,CDF,'disp',sprintf('P(y) case %g',param.package_testcase_i))

2161

ylim([1e-7 1e-1])

2162

grid on

2163

movegui(gcf,[randn randn]*100)

2164

xlabel('-A_ni/A_s')

2165

ylabel('DER')

2166

hold on

2167

semilogy(p_an.x/A_s,P_an,'disp',sprintf('P_a_n(y) case %g',param.package_testcase_i'))

2168

legend show

2169

% fprintf('checking %.4g dB is the com threshold\n', db(CDF_inv_ev ( param.specBER,p_an,P_an )/CDF_inv_ev ( param.specBER,PDF,CDF ) ))

2170

end

2171

% PDF=p_an;

2172

% CDF=P_an;

2173

S_an=g_an*PSD_results.S_rn.*PSD_results.H_rxffe_2; % healey_3dj_01_2409 slide 12

2174

S_ni=PSD_results.S_isi +PSD_results.S_n +S_an; % 178A-40, healey_3dj_01_2409 slide 15

2246

S_ni=PSD_results.Sn_rho;

2175

R_ni=ifft(S_ni)*f_b;

2247

R_ni=ifft(S_ni)*f_b;

2176

p_scaled_by_b=scalePDF(p_an,b(1));

2248

p_scaled_by_b=scalePDF(PDF,b(1));

2177

p_j=conv_fct(p_an,p_scaled_by_b);

2249

p_j=conv_fct(PDF,p_scaled_by_b);

2178

p_scaled_by_1mb=scalePDF(p_an,1-b(1));

2250

p_scaled_by_1mb=scalePDF(PDF,1-b(1));

2179

%% %% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2180

p_trunc = p_an;

2181

%

2251

%

2182

j=1; DER_MLSE=0; DER_MLSE_j= inf;

2252

j=1; DER_MLSE=0; DER_MLSE_j= inf;

2183

P_j.y=cumsum(p_j.y);

2253

P_j.y=cumsum(p_j.y);

2184

smallest_relative_change=.0001;

2254

smallest_relative_change=.0001;

2185

%% 178A–37

2255

%% 178A–37

2186

rou=R_ni'/R_ni(1);

2256

rou=R_ni'/R_ni(1);

2187

if DER_DFE <= param.DER_CDR

2257

if DER_DFE <= param.DER_CDR

2188

while j <= floor(num_ui/2) && DER_MLSE_j> DER_MLSE*smallest_relative_change

2258

while j <= floor(num_ui/2) && DER_MLSE_j> DER_MLSE*smallest_relative_change

2189

u_j=[ 1;(1-b(1))*ones(j-1,1); (-1)^(j+1)*b(1) ] ;% Eq slide (178A–38)

2259

u_j=[ 1;(1-b(1))*ones(j-1,1); (-1)^(j+1)*b(1) ] ;% Eq slide (178A–38)

2190

u_j(2:2:end-1)=-u_j(2:2:end-1);

2260

u_j(2:2:end-1)=-u_j(2:2:end-1);

2191

% V_j=toeplitz(R_ni(1:j+1).'/R_ni(1));

2261

% V_j=toeplitz(R_ni(1:j+1).'/R_ni(1));

2192

V_j=toeplitz(rou(1:j+1));

2262

V_j=toeplitz(rou(1:j+1));

2193

P_j=cumsum(p_j.y);

2263

P_j=cumsum(p_j.y);

2194

DER_MLSE_j= ((L-1)/L)^(j-1) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(1/2), p_j, P_j ) ) ; % CDF_ev is (1-P_an)

2264

DER_MLSE_j= ((L-1)/L)^(j-1) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(1/2), p_j, P_j ) ) ; % CDF_ev is (1-CDF)

2195

% DER_MLSE_j= 2*(3/4)^(j) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(0.5), p_j, P_j ) ) ; % CDF_ev is (1-CDF)

2265

% DER_MLSE_j= 2*(3/4)^(j) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(0.5), p_j, P_j ) ) ; % CDF_ev is (1-CDF)

2196

DER_MLSE=DER_MLSE+DER_MLSE_j;

2266

DER_MLSE=DER_MLSE+DER_MLSE_j;

2197

p_j=conv_fct(p_j,p_scaled_by_1mb);

2267

p_j=conv_fct(p_j,p_scaled_by_1mb);

2198

%% %% shakiba_3dj_01_2407(to add MLSE sequence truncation penalty)

2199

if j == param.trunc

2200

u_trunc = u_j(1:j);

2201

V_trunc = V_j(1:j, 1:j);

2202

P_trunc = cumsum(p_trunc.y);

2203

DER_MLSE_trunc = DER_MLSE_trunc+L*((L-1)/L)^(j-1)*CDF_ev(A_s*(u_trunc'*u_trunc)^(3/2)/(u_trunc'*V_trunc*u_trunc)^(1/2), p_trunc, P_trunc);

2204

elseif j < param.trunc

2205

DER_MLSE_trunc = DER_MLSE;

2206

p_trunc = conv_fct(p_trunc, p_scaled_by_1mb); % Convolves trunc-1 times

2207

P_trunc = cumsum(p_trunc.y);

2208

end

2209

j=j+1;

2268

j=j+1;

2210

end

2269

end

2211

%% healey_3dj_01a_2407

2212

if param.Q_budget_adj == 0

2213

Q_budget_adj=0;

2214

else

2215

Q_budget_adj=param.Q_budget_adj(1) -param.Q_budget_adj(2)*COM_from_matlab;

2270

%% Eq (178A–36) a

2216

end

2217

%% shakiba_3dj_01_2407

2218

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE ,p_an,P_an ) )- param.Q ;% shakiba_3dj_01_2405

2271

delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE,PDF,CDF ) )- param.Q ;% shakiba_3dj_01_2405

2219

delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE_trunc,p_an,P_an ) )- Q_budget_adj ;% shakiba_3dj_01_2405

2220

%% shakiba_3dj_01_2407

2221

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( 2/3*DER_MLSE,p_an,CDF ) )- Q ;% (178A–36)

2272

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( 2/3*DER_MLSE,PDF,CDF ) )- param.Q ;% (178A–36)

2222

new_com=COM_from_matlab+delta_com;

2273

new_com=COM_from_matlab+delta_com;

2223

if(delta_com<0)

2224

delta_com=0;

2225

warning('MLSE truncation failed. Try increasing trunc')

2226

try

2227

hx=msgbox('MLSE truncation failed. Try increasing N_tc','warning','warn');

2228

set(hx,'Color',[1 0 1]);

2229

movegui(hx,[randn randn]*100)

2230

set(hx,'Tag','COM') %

2231

catch

2232

end

2233

end

2234

else

2274

else

2235

warning('MLSE not applied because the DER is less than that required for the CDR to lock')

2275

warning('MLSE not applied because the DER is less than that required for the CDR to lock')

2236

DER_MLSE=NaN;

2276

DER_MLSE=NaN;

2237

new_com=COM_from_matlab;

2277

new_com=COM_from_matlab;

2238

delta_com=0;

2278

delta_com=0;

2239

Q=0;

2279

delta_com=0;

2240

Q_budget_adj=0;

2241

DER_MLSE_trunc=NaN;

2242

%% shakiba_3dj_01_2407

2243

end

2280

end

2244

2281

2245

%%

2282

%%

2246

[PDF1, CDF1, ~] = scaleCDF( PDF,-delta_com,DER0, A_s ); % create new pdf/cdf estimate for display only

2247

MLSE_results.CDF=CDF1;

2248

MLSE_results.PDF=PDF1;

2249

MLSE_results.DER_MLSE_trunc = DER_MLSE_trunc;% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2250

MLSE_results.Q_budget_adj=Q_budget_adj; % healey_3dj_01a_2407

2251

MLSE_results.COM_from_matlab=COM_from_matlab;

2283

MLSE_results.COM_from_matlab=COM_from_matlab;

2252

MLSE_results.DER_MLSE=DER_MLSE;

2284

MLSE_results.DER_MLSE=DER_MLSE;

2253

MLSE_results.DER_DFE=DER_DFE;

2285

MLSE_results.DER_DFE=DER_DFE;

2254

MLSE_results.COM=new_com;

2286

MLSE_results.COM=new_com;

2255

MLSE_results.delta_com=delta_com;

2287

MLSE_results.delta_com=delta_com;

+2288

2289

2290

2291

function [MLSE_results] = MLSE_U3(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2292

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2293

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2294

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2295

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2296

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2297

%% step 0

2298

COM_from_matlab=20*log10(A_s/A_ni);

2299

L=param.levels;

2300

DER0=param.specBER;

2301

%% step 1 from slide 6 shakiba_3dj_01_230116

2302

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2303

main=A_peak;

2304

k_DER=qfuncinv(param.specBER);

2305

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2306

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2307

% if A_s >= A_ni

2308

if 1

2309

%% step 2 slide 10 shakiba_3dj_01_230116

2310

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2311

%% step 2 slide 10 not used

2312

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2313

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2314

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2315

S_n=PSD_results.S_n; % total agregate noise PSD

2316

Rn=ifft(S_n)*param.fb;

2317

Rho_row=Rn/Rn(1);

2318

Rn_len=length(Rn);

2319

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2320

for j=1:Rn_len

2321

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2322

end

2323

rho_noiseEE_row=Rho_row.*alphas_row;

2324

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2325

for j=1:Rn_len

2326

rho_noiseEE(j,j)=(1-alpha)^2;

2327

end

2328

rho_noiseEE(1,1)=1;

2329

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2330

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2331

% determine complete matrix

2332

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2333

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2334

%% shakiba_3dj_elec_01a_230504 slide 17

2335

j=1:Rn_len;

2336

DER_MLSE=[];

2337

DER_MLSE_CDF=0; jj=1;

2338

DER_MLSE_CDFold=0;

2339

DER_delta = inf;

2340

% slight modified for PAM4 DER vs SER

2341

while DER_delta > .0001 && jj<=Rn_len || jj==1

2342

last_DER_MLSE_CDF=DER_MLSE_CDF;

2343

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2344

DER_MLSE_CDF= ...

2345

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;

2346

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;

2347

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2348

jj=jj+1;

2349

end

2350

%% shakiba_3dj_elec_01a_230504 slide 19

2351

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2352

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2353

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2354

(L-1)/main * CDF_inv_ev(...

2355

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2356

,PDF, CDF ) ...

2357

)^2;

2358

%% step 5 shakiba_3dj_01_230116 slide 13

2359

delta_com=[];

2360

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2361

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2362

new_com_CDF=COM_from_matlab+delta_com_CDF;

2363

else

2364

warning('MLSE not applied because there is more noise than signal')

2365

DER_MLSE=[];

2366

DER_MLSE_CDF=[];

2367

SNR_DFE_eqivalent=[];

2368

SNR_DFE_eqivalent_CDF=[];

2369

new_com_CDF=COM_from_matlab;

2370

delta_com_CDF=0;

2371

delta_com=0;

2372

SNR_DFE=[];

2373

end

2374

SNR_DFE_eqivalent=[];

2375

%%

2376

MLSE_results.COM_from_matlab=COM_from_matlab;

2377

MLSE_results.SNR_DFE=SNR_DFE;

2378

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2379

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2380

MLSE_results.sigma_noise=sigma_noise;

2381

MLSE_results.SNR_dB=SNR_dB ;

2382

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2383

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2384

MLSE_results.COM_Gaussian=new_com_CDF;

2385

MLSE_results.COM_CDF=new_com_CDF;

2386

MLSE_results.k_DER=k_DER;

2387

MLSE_results.delta_com_CDF=delta_com_CDF;

2388

MLSE_results.delta_com_Gaussian=delta_com;

2389

2390

2391

2392

function [MLSE_results] = MLSE_instu(param,alpha,A_s,A_ni,PDF,CDF)

2393

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2394

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2395

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2396

2397

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2398

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2399

2400

%% step 0

2401

COM_from_matlab=20*log10(A_s/A_ni);

2402

L=param.levels;

2403

DER0=param.specBER;

2404

%% step 1 from slide 6/5

2405

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2406

main=A_peak;

2407

k_DER=qfuncinv(param.specBER);

2408

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2409

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2410

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2411

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2412

if A_s >= A_ni

2413

%% step 2 slide 10/8

2414

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2415

%% step 2 slide 10/8

2416

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) ;

2417

2418

%% step 3 side 11/9

2419

j=1:200;

2420

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2421

DER_MLSE_CDF=0; jj=1;

2422

DER_delta = inf;

2423

while DER_delta > .001

2424

last_DER_MLSE_CDF=DER_MLSE_CDF;

2425

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;

2426

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2427

jj=jj+1;

2428

end

2429

%%

2430

dscale=.05;

2431

scale=1;

2432

last_scale_tune=inf;

2433

scale_tune=inf;

2434

while abs(scale_tune) >= .1

2435

istart=-PDF.Min+1;

2436

scale=scale-dscale;

2437

PDF_SCALED = scalePDF(PDF,scale);

2438

cdf_scaled=pdf_to_cdf(PDF_SCALED);

2439

test_snr=snr_dfe(DER_MLSE_CDF,PDF_SCALED,cdf_scaled.y);

2440

test_DER=2*(L-1)/L* (CDF_ev(main/(L-1),PDF_SCALED,cdf_scaled.y) );

2441

scale_tune=(test_DER-DER_MLSE_CDF)/DER_MLSE_CDF;

2442

if sign(scale_tune) ~= sign(last_scale_tune)

2443

% scale=scale+dscale % back up

2444

dscale=-dscale/2;

2445

end

2446

last_scale_tune=scale_tune;

2447

end

2448

new_com_CDF=10*log10((A_s./CDF_inv_ev(DER0,PDF_SCALED,cdf_scaled.y)).^2);

2449

delta_com=new_com_CDF-10*log10((A_s./CDF_inv_ev(DER0,PDF,CDF)).^2);

2450

else

2451

warning('MLSE not applied because there is more noise than signal')

2452

DER_MLSE=[];

2453

DER_MLSE_CDF=[];

2454

SNR_DFE_eqivalent=[];

2455

SNR_DFE_eqivalent_CDF=[];

2456

new_com_CDF=COM_from_matlab;

2457

delta_com_CDF=0;

2458

delta_com=0;

2459

SNR_DFE=[];

2460

PDF_SCALED=[];

2461

cdf_scaled=[];

2462

end

2463

2464

%%

2465

MLSE_results.COM_from_matlab=COM_from_matlab;

2466

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2467

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2468

MLSE_results.sigma_noise=sigma_noise;

2469

MLSE_results.k_DER=k_DER;

2470

MLSE_results.COM_CDF=new_com_CDF;

2471

MLSE_results.delta_com_CDF=delta_com;

2472

MLSE_results.delta_com_Gaussian=delta_com;

2473

MLSE_results.PDF=PDF_SCALED;

2474

MLSE_results.CDF=cdf_scaled.y;

2256

MLSE_results.g_an=g_an;

2475

MLSE_results.PDF_scale=scale;

+2476

2257

2477

2258

2478

2259

2479

2260

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2480

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2261

if 1

2481

if 1

2262

num_ui=param.num_ui_RXFF_noise;

2482

num_ui=param.num_ui_RXFF_noise;

2263

M=param.samples_per_ui;

2483

M=param.samples_per_ui;

2264

L=param.levels;

2484

L=param.levels;

2265

sigma_X2=(L^2-1)/(3*(L-1)^2);

2485

sigma_X2=(L^2-1)/(3*(L-1)^2);

2266

fb=param.fb;

2486

fb=param.fb;

2267

R_LM=param.R_LM;

2487

R_LM=param.R_LM;

2268

end

2488

end

2269

% h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2489

% h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2270

% h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2490

% h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2271

% h=reshape(h,1,[]); % make row vectors

2491

% h=reshape(h,1,[]); % make row vectors

2272

% h=[ h(1:floor(length(h)/M)*M) ];

2492

% h=[ h(1:floor(length(h)/M)*M) ];

2273

% h= [h zeros(1,num_ui*M-length(h)) ];

2493

% h= [h zeros(1,num_ui*M-length(h)) ];

2274

% h=h(1:M:end);% resample

2494

% h=h(1:M:end);% resample

2275

% N=length(h);

2495

% N=length(h);

2276

% dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2496

% dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2277

% dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2497

% dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2278

2498

2279

samp_idx = (mod(cursor_i-1,M )+1):M:length(sbr);

2499

samp_idx = (mod(cursor_i-1,M )+1):M:length(sbr);

2280

dh= find(samp_idx == cursor_i)-1;

2500

dh= find(samp_idx == cursor_i)-1;

2281

dw=param.RxFFE_cmx;

2501

dw=param.RxFFE_cmx;

2282

h = reshape(sbr(samp_idx),1,[]); % make row vector

2502

h = reshape(sbr(samp_idx),1,[]); % make row vector

2283

h(end+1:num_ui)=0;

2503

h(end+1:num_ui)=0;

2284

h = h(1:num_ui); % h needs to have num_ui points

2504

h = h(1:num_ui); % h needs to have num_ui points

2285

N=length(h); % used in subsequent expressions

2505

N=length(h); % used in subsequent expressions

2286

2506

2287

if param.N_bg == 0

2507

if param.N_bg == 0

2288

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2508

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2289

bmax=param.bmax;

2509

bmax=param.bmax;

2290

bmin=param.bmin ;

2510

bmin=param.bmin ;

2291

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2511

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2292

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2512

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2293

idx=[];

2513

idx=[];

2294

else

2514

else

2295

Nfloating_taps=param.N_bf*param.N_bg;

2515

Nfloating_taps=param.N_bf*param.N_bg;

2296

Nmax=param.N_bmax;

2516

Nmax=param.N_bmax;

2297

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2517

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2298

Ng=param.N_bg;

2518

Ng=param.N_bg;

2299

Nf=param.N_bf;

2519

Nf=param.N_bf;

2300

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2520

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2301

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2521

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2302

% hisi=h(dh+2:((dh-dw)+Nw));

2522

% hisi=h(dh+2:((dh-dw)+Nw));

2303

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2523

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2304

% idx=sort(idx);

2524

% idx=sort(idx);

2305

bmax=param.bmax;

2525

bmax=param.bmax;

2306

bmin=param.bmin ;

2526

bmin=param.bmin ;

2307

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ones(1,Nfloating_taps)*param.bmaxg ];

2527

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ones(1,Nfloating_taps)*param.bmaxg ];

2308

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max -ones(1,Nfloating_taps)*param.bmaxg ];

2528

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max -ones(1,Nfloating_taps)*param.bmaxg ];

2309

end

2529

end

2310

Nb=param.ndfe; % DFE taps

2530

Nb=param.ndfe; % DFE taps

2311

d=dw+dh; % used for index in algorithms

2531

d=dw+dh; % used for index in algorithms

2312

indx(1:N)=(1:N)-dh-1;

2532

indx(1:N)=(1:N)-dh-1;

2313

S_n=PSD_results.S_n; % total agregate noise PSD

2533

S_n=PSD_results.S_n; % total agregate noise PSD

2314

Rn=ifft(S_n)*fb;

2534

Rn=ifft(S_n)*fb;

2315

%% HH and R

2535

%% HH and R

2316

2536

2317

%Test routine finding rxffe floating taps using best FOM for each bank

2537

%Test routine finding rxffe floating taps using best FOM for each bank

2318

isi_start = dh+2;

2538

isi_start = dh+2;

2319

isi_end = (dh-dw)+Nw;

2539

isi_end = (dh-dw)+Nw;

2320

2540

2321

%check for num_ui too small

2541

%check for num_ui too small

2322

if isi_end > length(h)

2542

if isi_end > length(h)

2323

error('num_ui_RXFF_noise (%d) is too small',num_ui);

2543

error('num_ui_RXFF_noise (%d) is too small',num_ui);

2324

end

2544

end

2325

2545

2326

hc1=[ h zeros(1,Nw-1) ];

2546

hc1=[ h zeros(1,Nw-1) ];

2327

hr1=[ h(1) zeros(1,Nw-1)];

2547

hr1=[ h(1) zeros(1,Nw-1)];

2328

H=toeplitz(hc1,hr1);

2548

H=toeplitz(hc1,hr1);

2329

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2549

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2330

if param.N_bg ~= 0

2550

if param.N_bg ~= 0

2331

switch lower(OP.RXFFE_FLOAT_CTL)

2551

switch lower(OP.RXFFE_FLOAT_CTL)

2332

case 'isi'

2552

case 'isi'

2333

hisi=h(dh+2:((dh-dw)+Nw));

2553

hisi=h(dh+2:((dh-dw)+Nw));

2334

[idx]=findbankloc( hisi ,param.RxFFE_cpx+1,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2554

[idx]=findbankloc( hisi ,param.RxFFE_cpx+1,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2335

idx=sort(idx);

2555

idx=sort(idx);

2336

otherwise

2556

otherwise

2337

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2557

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2338

idx=sort(idx);

2558

idx=sort(idx);

2339

end

2559

end

2340

end

2560

end

2341

[sigma_e,FOM,w,idx,Nw,blim] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx); % bring out blim for

2561

[sigma_e,FOM,w,idx] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx);

2342

MMSE_results.sigma_e=sigma_e; %

2562

MMSE_results.sigma_e=sigma_e; %

2343

MMSE_results.FOM=FOM;

2563

MMSE_results.FOM=FOM;

2344

Craw=w/w(dw+1); % returned Rx FFE taps

2564

Craw=w/w(dw+1); % returned Rx FFE taps

2345

% re-align Cmod to floating tap locations

2565

% re-align Cmod to floating tap locations

2346

if param.N_bg ~= 0

2566

if param.N_bg ~= 0

2347

C=Craw;

2567

C=Craw;

2348

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2568

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2349

C(idx+param.RxFFE_cmx+1 )=Craw(Nfix+(1:Nfloating_taps));

2569

C(idx+param.RxFFE_cmx+1 )=Craw(Nfix+(1:Nfloating_taps));

2350

else

2570

else

2351

C=Craw;

2571

C=Craw;

2352

end

2572

end

2353

MMSE_results.floating_tap_locations=idx + param.RxFFE_cmx+1;

2573

MMSE_results.floating_tap_locations=idx + param.RxFFE_cmx+1;

2354

MMSE_results.C=C;

2574

MMSE_results.C=C;

2355

MMSE_results.blim=blim; % added blim passed out for MLSD for 178A-39

2356

MMSE_results.Nw=Nw;

2357

2575

2358

2576

2359

2577

2360

2578

2361

2362

function [sigma_e,FOM,w,idx,Nw,blim] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2579

function [sigma_e,FOM,w,idx,Nw] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2363

% added blim passed out for MLSD

2364

if isempty(idx)

2580

if isempty(idx)

2365

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2581

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2366

bmax=param.bmax;

2582

bmax=param.bmax;

2367

bmin=param.bmin ;

2583

bmin=param.bmin ;

2368

else

2584

else

2369

Nfloating_taps=param.N_bf*param.N_bg;

2585

Nfloating_taps=param.N_bf*param.N_bg;

2370

%If using the routine that finds RXFFE floating taps bank-by-bank, the number of total floating taps can be less than the final amount

2586

%If using the routine that finds RXFFE floating taps bank-by-bank, the number of total floating taps can be less than the final amount

2371

Nfloating_taps = length(idx);

2587

Nfloating_taps = length(idx);

2372

Nmax=param.N_bmax;

2588

Nmax=param.N_bmax;

2373

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2589

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2374

Ng=param.N_bg;

2590

Ng=param.N_bg;

2375

Nf=param.N_bf;

2591

Nf=param.N_bf;

2376

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2592

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2377

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2593

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2378

end

2594

end

2379

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2595

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2380

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2596

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2381

% hc1=[ h zeros(1,Nw-1) ];

2597

% hc1=[ h zeros(1,Nw-1) ];

2382

% hr1=[ h(1) zeros(1,Nw-1)];

2598

% hr1=[ h(1) zeros(1,Nw-1)];

2383

% H=toeplitz(hc1,hr1);

2599

% H=toeplitz(hc1,hr1);

2384

2600

2385

if param.N_bg ~= 0

2601

if param.N_bg ~= 0

2386

H=H( :,[1:Nfix idx+param.RxFFE_cmx+1 ]);

2602

H=H( :,[1:Nfix idx+param.RxFFE_cmx+1 ]);

2387

end

2603

end

2388

%% HH and R

2604

%% HH and R

2389

HH= H'*H;

2605

HH= H'*H;

2390

if param.N_bg ~= 0

2606

if param.N_bg ~= 0

2391

Rnn=Rnn( [1:Nfix idx+param.RxFFE_cmx+1],[1:Nfix idx+param.RxFFE_cmx+1]);

2607

Rnn=Rnn( [1:Nfix idx+param.RxFFE_cmx+1],[1:Nfix idx+param.RxFFE_cmx+1]);

2392

end

2608

end

2393

R=HH+Rnn/sigma_X2;

2609

R=HH+Rnn/sigma_X2;

2394

%% hb and h0

2610

%% hb and h0

2395

Hb= H(d+2:d+Nb+1,:);

2611

Hb= H(d+2:d+Nb+1,:);

2396

h0=H(d+1,:);

2612

h0=H(d+1,:);

2397

% display(floor(h0));

2613

% display(floor(h0));

2398

2614

2399

%% Ib and zb (slide 10)

2615

%% Ib and zb (slide 10)

2400

ib=eye(Nb);

2616

ib=eye(Nb);

2401

zb=zeros(1,Nb);

2617

zb=zeros(1,Nb);

2402

wbl= [ R -Hb' -h0';...

2618

wbl= [ R -Hb' -h0';...

2403

-Hb ib zb'; ...

2619

-Hb ib zb'; ...

2404

h0 zb 0]\[h0'; zb' ;1];

2620

h0 zb 0]\[h0'; zb' ;1];

2405

2621

2406

%% re-adjust Nw to number of used taps

2622

%% re-adjust Nw to number of used taps

2407

if param.N_bg ~= 0

2623

if param.N_bg ~= 0

2408

Nw=Nwft;

2624

Nw=Nwft;

2409

end

2625

end

2410

%% check equalized pulse

2626

%% check equalized pulse

2411

w=wbl(1:Nw);

2627

w=wbl(1:Nw);

2412

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2628

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2413

2629

2414

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2630

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2415

blim = min(bmax(:), max(bmin(:), b));

2631

blim = min(bmax(:), max(bmin(:), b));

2416

if (Nb > 0) && ~isequal(b, blim)

2632

if (Nb > 0) && ~isequal(b, blim)

2417

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2633

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2418

w = wl(1:Nw);

2634

w = wl(1:Nw);

2419

end

2635

end

2420

2636

2421

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2637

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2422

%so need to chop off the extra indices on wmax and wmin

2638

%so need to chop off the extra indices on wmax and wmin

2423

if length(w)<length(wmax)

2639

if length(w)<length(wmax)

2424

wmax=wmax(1:length(w));

2640

wmax=wmax(1:length(w));

2425

wmin=wmin(1:length(w));

2641

wmin=wmin(1:length(w));

2426

end

2642

end

2427

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2643

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2428

if ~isequal(w, wlim)

2644

if ~isequal(w, wlim)

2429

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2645

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2430

if Nb > 0

2646

if Nb > 0

2431

b = Hb*wlim; % Update the feedback coefficients.

2647

b = Hb*wlim; % Update the feedback coefficients.

2432

blim = min(bmax(:), max(bmin(:), b));

2648

blim = min(bmax(:), max(bmin(:), b));

2433

end

2649

end

2434

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2650

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2435

% wl = wl(1:Nw);

2651

% wl = wl(1:Nw);

2436

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2652

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2437

end

2653

end

2438

% w=w(1:Nw) ;

2654

% w=w(1:Nw) ;

2439

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2655

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2440

w=wlim;

2656

w=wlim;

2441

b=blim;

2657

b=blim;

2442

sigma_e=sqrt(sigma_X2*(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b)); % Commit request 4p4_5 from healey_3dj_COM_01_240416

2658

sigma_e=sqrt(sigma_X2*(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b)); % Commit request 4p4_5 from healey_3dj_COM_01_240416

2443

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2659

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2444

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2660

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2445

2661

2446

%not all output_args are filled here but most are

2662

%not all output_args are filled here but most are

2447

2663

2448

switch lower(OP.TDECQ)

2664

switch lower(OP.TDECQ)

2449

case { false 'none' } % should be the default

2665

case { false 'none' } % should be the default

2450

output_args.VMA=[];

2666

output_args.VMA=[];

2451

case 'vma'

2667

case 'vma'

2452

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2668

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2453

output_args.VMA=est_vma.VMA;

2669

output_args.VMA=est_vma.VMA;

2454

otherwise

2670

otherwise

2455

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2671

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2456

end

2672

end

2457

2673

2458

fileset_str=str2csv({chdata.base});

2674

fileset_str=str2csv({chdata.base});

2459

output_args.file_names=sprintf('"%s"', fileset_str);

2675

output_args.file_names=sprintf('"%s"', fileset_str);

2460

% [ahealey] Echo the termination parameters in the output arguments..

2676

% [ahealey] Echo the termination parameters in the output arguments..

2461

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2677

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2462

output_args.(odt_param{:}) = param.(odt_param{:});

2678

output_args.(odt_param{:}) = param.(odt_param{:});

2463

end

2679

end

2464

% [ahealey] End of modifications.

2680

% [ahealey] End of modifications.

2465

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2681

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2466

output_args.(pkg_params{:})= param.(pkg_params{:});

2682

output_args.(pkg_params{:})= param.(pkg_params{:});

2467

end

2683

end

2468

output_args.baud_rate_GHz=param.fb/1e9;

2684

output_args.baud_rate_GHz=param.fb/1e9;

2469

output_args.f_Nyquist_GHz = param.fb/2e9;

2685

output_args.f_Nyquist_GHz = param.fb/2e9;

2470

output_args.BER=param.specBER;

2686

output_args.BER=param.specBER;

2471

output_args.FOM = fom_result.FOM;

2687

output_args.FOM = fom_result.FOM;

2472

output_args.sigma_N=Noise_Struct.sigma_N;

2688

output_args.sigma_N=Noise_Struct.sigma_N;

2473

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2689

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2474

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2690

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2475

output_args.tail_RSS=fom_result.tail_RSS;

2691

output_args.tail_RSS=fom_result.tail_RSS;

2476

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2692

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2477

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2693

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2478

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2694

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2479

try

2695

try

2480

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2696

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2481

catch

2697

catch

2482

output_args.uneq_FIR_peak_time=[];

2698

output_args.uneq_FIR_peak_time=[];

2483

end

2699

end

2484

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2700

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2485

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2701

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2486

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2702

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2487

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2703

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2488

2704

2489

if OP.RX_CALIBRATION== 1

2705

if OP.RX_CALIBRATION== 1

2490

output_args.sigma_bn=sigma_bn;

2706

output_args.sigma_bn=sigma_bn;

2491

else

2707

else

2492

output_args.sigma_bn=[];

2708

output_args.sigma_bn=[];

2493

end

2709

end

2494

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2710

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2495

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2711

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2496

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2712

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2497

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2713

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2498

2714

2499

if OP.RX_CALIBRATION == 0

2715

if OP.RX_CALIBRATION == 0

2500

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2716

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2501

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2717

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2502

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2718

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2503

else

2719

else

2504

output_args.peak_MDXTK_interference_at_BER_mV=[];

2720

output_args.peak_MDXTK_interference_at_BER_mV=[];

2505

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2721

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2506

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2722

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2507

end

2723

end

2508

%output_args.ICN_mV=ICN*1000;

2724

%output_args.ICN_mV=ICN*1000;

2509

% output_args.ICN_test_mV=ICN_test*1000;

2725

% output_args.ICN_test_mV=ICN_test*1000;

2510

xtk=param.num_next+param.num_fext;

2726

xtk=param.num_next+param.num_fext;

2511

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2727

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2512

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2728

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2513

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2729

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2514

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2730

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2515

else

2731

else

2516

output_args.MDNEXT_ICN_92_46_mV=0;

2732

output_args.MDNEXT_ICN_92_46_mV=0;

2517

output_args.MDFEXT_ICN_92_47_mV=0;

2733

output_args.MDFEXT_ICN_92_47_mV=0;

2518

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2734

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2519

end

2735

end

2520

%output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(A_s/(peak_interference_at_BER/qfuncinv(param.specBER))); modified by Yasuo Hidaka, 8/7/17

2736

%output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(A_s/(peak_interference_at_BER/qfuncinv(param.specBER))); modified by Yasuo Hidaka, 8/7/17

2521

if 1

2737

if 1

2522

output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(COM_SNR_Struct.A_s/(Noise_Struct.peak_interference_at_BER/sqrt(2)/erfcinv(2*param.specBER)));

2738

output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(COM_SNR_Struct.A_s/(Noise_Struct.peak_interference_at_BER/sqrt(2)/erfcinv(2*param.specBER)));

2523

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2739

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2524

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2740

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2525

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2741

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2526

end

2742

end

2527

2743

2528

2744

2529

switch param.CTLE_type

2745

switch param.CTLE_type

2530

case 'CL93'

2746

case 'CL93'

2531

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2747

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2532

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2748

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2533

output_args.g_DC_HP=[];

2749

output_args.g_DC_HP=[];

2534

output_args.HP_poles_zero=[];

2750

output_args.HP_poles_zero=[];

2535

case 'CL120d'

2751

case 'CL120d'

2536

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2752

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2537

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2753

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2538

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2754

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2539

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2755

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2540

case 'CL120e'

2756

case 'CL120e'

2541

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.f_HP_Z(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle) param.f_HP_P(fom_result.ctle)];

2757

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.f_HP_Z(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle) param.f_HP_P(fom_result.ctle)];

2542

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2758

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2543

output_args.g_DC_HP=[];

2759

output_args.g_DC_HP=[];

2544

output_args.HP_poles_zero=[];

2760

output_args.HP_poles_zero=[];

2545

end

2761

end

2546

output_args.TXLE_taps=fom_result.txffe;

2762

output_args.TXLE_taps=fom_result.txffe;

2547

if length(output_args.TXLE_taps) >= 3

2763

if length(output_args.TXLE_taps) >= 3

2548

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2764

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2549

else

2765

else

2550

output_args.Pre2Pmax=[];

2766

output_args.Pre2Pmax=[];

2551

end

2767

end

2552

output_args.DFE_taps=fom_result.DFE_taps;

2768

output_args.DFE_taps=fom_result.DFE_taps;

2553

if param.Floating_DFE || param.Floating_RXFFE

2769

if param.Floating_DFE || param.Floating_RXFFE

2554

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2770

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2555

else

2771

else

2556

output_args.floating_tap_locations=[];

2772

output_args.floating_tap_locations=[];

2557

end

2773

end

2558

2774

2559

if OP.RxFFE

2775

if OP.RxFFE

2560

output_args.RxFFE=fom_result.RxFFE;

2776

output_args.RxFFE=fom_result.RxFFE;

2561

output_args.RxFFEgain=param.current_ffegain;

2777

output_args.RxFFEgain=param.current_ffegain;

2562

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2778

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2563

output_args.RxFFE=[];

2779

output_args.RxFFE=[];

2564

output_args.RxFFEgain=[];

2780

output_args.RxFFEgain=[];

2565

end

2781

end

2566

2782

2567

output_args.itick=fom_result.itick;

2783

output_args.itick=fom_result.itick;

2568

2784

2569

% Calculation of error propagation and burst probability

2785

% Calculation of error propagation and burst probability

2570

if OP.nburst>0

2786

if OP.nburst>0

2571

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2787

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2572

output_args.error_propagation_probability = p_error_propagation;

2788

output_args.error_propagation_probability = p_error_propagation;

2573

output_args.burst_probabilities = p_burst;

2789

output_args.burst_probabilities = p_burst;

2574

else

2790

else

2575

output_args.error_propagation_probability = [];

2791

output_args.error_propagation_probability = [];

2576

output_args.burst_probabilities = [];

2792

output_args.burst_probabilities = [];

2577

end

2793

end

2578

2794

2579

2795

2580

%begin yasuo patch 12/11/2018

2796

%begin yasuo patch 12/11/2018

2581

% collect sigma values to report

2797

% collect sigma values to report

2582

% pdf2sgm() is a function to calculate sigma value from PDF

2798

% pdf2sgm() is a function to calculate sigma value from PDF

2583

% It is added at the end of this file code.

2799

% It is added at the end of this file code.

2584

% I am not sure if an equivalent function already exists.

2800

% I am not sure if an equivalent function already exists.

2585

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2801

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2586

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2802

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2587

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2803

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2588

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2804

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2589

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2805

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2590

output_args.sgm_G = Noise_Struct.sigma_G;

2806

output_args.sgm_G = Noise_Struct.sigma_G;

2591

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2807

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2592

output_args.sgm_N = Noise_Struct.sigma_N;

2808

output_args.sgm_N = Noise_Struct.sigma_N;

2593

output_args.sgm_TX = Noise_Struct.sigma_TX;

2809

output_args.sgm_TX = Noise_Struct.sigma_TX;

2594

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2810

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2595

if OP.RX_CALIBRATION == 0

2811

if OP.RX_CALIBRATION == 0

2596

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2812

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2597

else

2813

else

2598

output_args.sgm_xt=[];

2814

output_args.sgm_xt=[];

2599

end

2815

end

2600

% end yasuo patch

2816

% end yasuo patch

2601

2817

2602

% r259 putting COM, VEO and loss last in report

2818

% r259 putting COM, VEO and loss last in report

2603

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2819

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2604

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2820

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2605

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2821

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2606

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2822

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2607

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2823

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2608

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2824

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2609

output_args.VEO_window_mUI= param.T_O;

2825

output_args.VEO_window_mUI= param.T_O;

2610

else

2826

else

2611

output_args.EW_UI_est=[];

2827

output_args.EW_UI_est=[];

2612

output_args.eye_contour=[];

2828

output_args.eye_contour=[];

2613

output_args.VEO_window_mUI= [];

2829

output_args.VEO_window_mUI= [];

2614

end

2830

end

2615

2831

2616

if sum(param.AC_CM_RMS) ~= 0

2832

if sum(param.AC_CM_RMS) ~= 0

2617

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2833

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2618

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2834

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2619

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2835

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2620

else

2836

else

2621

output_args.sigma_ACCM_at_tp0_mV=[];

2837

output_args.sigma_ACCM_at_tp0_mV=[];

2622

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2838

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2623

end

2839

end

2624

if OP.MLSE

2840

if OP.MLSE

2625

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2841

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2626

output_args.delta_COM = COM_SNR_Struct.delta_COM;

2842

output_args.delta_COM = COM_SNR_Struct.delta_COM;

2627

output_args.DER_DFE= COM_SNR_Struct.DER_DFE;

2843

output_args.DER_DFE= COM_SNR_Struct.DER_DFE;

2628

output_args.DER_MLSE= COM_SNR_Struct.DER_MLSE;

2844

output_args.DER_MLSE= COM_SNR_Struct.DER_MLSE;

2629

if strcmpi(upper(OP.PHY),'C2M')

2845

if strcmpi(upper(OP.PHY),'C2M')

2630

output_args.VEC_dB_orig= COM_SNR_Struct.VEC_dB_orig;

2846

output_args.VEC_dB_orig= COM_SNR_Struct.VEC_dB_orig;

2631

output_args.delta_VEC = COM_SNR_Struct.delta_VEC;

2847

output_args.delta_VEC = COM_SNR_Struct.delta_VEC;

2632

output_args.VEC_dB_orig = COM_SNR_Struct.VEC_dB_orig;

2848

output_args.VEC_dB_orig = COM_SNR_Struct.VEC_dB_orig;

2633

output_args.VEC_dB= COM_SNR_Struct.VEC_dB;

2849

output_args.VEC_dB= COM_SNR_Struct.VEC_dB;

2634

end

2850

end

2635

end

2851

end

2636

%

2852

%

2637

output_args.COM_dB=COM_SNR_Struct.COM;

2853

output_args.COM_dB=COM_SNR_Struct.COM;

2638

% end yasuo patch

2854

% end yasuo patch

2639

% begin yasuo patch 3/18/2019

2855

% begin yasuo patch 3/18/2019

2640

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2856

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2641

% end yasuo patch

2857

% end yasuo patch

2642

function [ seq syms syms_nrz ] = PRBS13Q( )

2858

function [ seq syms syms_nrz ] = PRBS13Q( )

2643

%UNTITLED Summary of this function goes here

2859

%UNTITLED Summary of this function goes here

2644

% Detailed explanation goes here

2860

% Detailed explanation goes here

2645

2861

2646

2862

2647

taps = ([13 12 2 1]);

2863

taps = ([13 12 2 1]);

2648

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2864

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2649

[seq_nrz c] =LFSR(seed,taps);

2865

[seq_nrz c] =LFSR(seed,taps);

2650

seq_nrz=2*(seq_nrz-0.5);

2866

seq_nrz=2*(seq_nrz-0.5);

2651

seq=pam(seq_nrz);

2867

seq=pam(seq_nrz);

2652

% syms=round(2*(seq+1));

2868

% syms=round(2*(seq+1));

2653

syms((round(2*(seq+1))/2==2))=3;

2869

syms((round(2*(seq+1))/2==2))=3;

2654

syms((round(2*(seq+1))/2==1.5))=2;

2870

syms((round(2*(seq+1))/2==1.5))=2;

2655

syms((round(2*(seq+1))/2==.5))=1;

2871

syms((round(2*(seq+1))/2==.5))=1;

2656

syms((round(2*(seq+1))/2==0))=0;

2872

syms((round(2*(seq+1))/2==0))=0;

2657

2873

2658

% syms_nrz=((seq_nrz+1)/2);

2874

% syms_nrz=((seq_nrz+1)/2);

2659

2875

2660

syms_nrz=seq_nrz;

2876

syms_nrz=seq_nrz;

2661

2877

2662

2878

2663

function[seq c]=LFSR(s,t)

2879

function[seq c]=LFSR(s,t)

2664

%s=initial state of LFSR, you can choose any lenght of LFSR

2880

%s=initial state of LFSR, you can choose any lenght of LFSR

2665

%Instruction:==========

2881

%Instruction:==========

2666

%Save LFSR.m in your current directory and type following

2882

%Save LFSR.m in your current directory and type following

2667

%on Command window for simulating 5 bit LFSR with tap [5 2]

2883

%on Command window for simulating 5 bit LFSR with tap [5 2]

2668

%---------------------

2884

%---------------------

2669

%>>s=[1 1 0 0 1]

2885

%>>s=[1 1 0 0 1]

2670

%>>t=[5 2]

2886

%>>t=[5 2]

2671

%>>[seq c] =LFSR(s,t)

2887

%>>[seq c] =LFSR(s,t)

2672

%---------------------------

2888

%---------------------------

2673

%seq = generated sequence

2889

%seq = generated sequence

2674

%c will be matrix containing the states of LFSR raw wise

2890

%c will be matrix containing the states of LFSR raw wise

2675

%

2891

%

2676

%-----------------------------------------------------------

2892

%-----------------------------------------------------------

2677

%If any doubt, confusion or feedback please contact me

2893

%If any doubt, confusion or feedback please contact me

2678

% NIKESH BAJAJ

2894

% NIKESH BAJAJ

2679

% bajaj.nikkey@gmail.com (+91-9915522564)

2895

% bajaj.nikkey@gmail.com (+91-9915522564)

2680

% Asst. Professor at Lovely Profesional University

2896

% Asst. Professor at Lovely Profesional University

2681

% Masters from Aligarh Muslim University,INDIA

2897

% Masters from Aligarh Muslim University,INDIA

2682

%--------------------------------------------------

2898

%--------------------------------------------------

2683

n=length(s);

2899

n=length(s);

2684

c(1,:)=s;

2900

c(1,:)=s;

2685

m=length(t);

2901

m=length(t);

2686

for k=1:2^n-2;

2902

for k=1:2^n-2;

2687

b(1)=xor(s(t(1)), s(t(2)));

2903

b(1)=xor(s(t(1)), s(t(2)));

2688

if m>2;

2904

if m>2;

2689

for i=1:m-2;

2905

for i=1:m-2;

2690

b(i+1)=xor(s(t(i+2)), b(i));

2906

b(i+1)=xor(s(t(i+2)), b(i));

2691

end

2907

end

2692

end

2908

end

2693

j=1:n-1;

2909

j=1:n-1;

2694

s(n+1-j)=s(n-j);

2910

s(n+1-j)=s(n-j);

2695

s(1)=b(m-1);

2911

s(1)=b(m-1);

2696

c(k+1,:)=s;

2912

c(k+1,:)=s;

2697

end

2913

end

2698

seq=c(:,n)';

2914

seq=c(:,n)';

2699

2915

2700

function [ dataout ] = pam( data )

2916

function [ dataout ] = pam( data )

2701

% mapping data usng Grey Coding

2917

% mapping data usng Grey Coding

2702

for i=1:2:floor(length(data)/2)*2

2918

for i=1:2:floor(length(data)/2)*2

2703

if data(i:i+1)==[ -1 -1 ]

2919

if data(i:i+1)==[ -1 -1 ]

2704

dataout(ceil(i/2)) = -1;

2920

dataout(ceil(i/2)) = -1;

2705

elseif data(i:i+1)==[ -1 1 ]

2921

elseif data(i:i+1)==[ -1 1 ]

2706

dataout(ceil(i/2)) = -1/3;

2922

dataout(ceil(i/2)) = -1/3;

2707

elseif data(i:i+1)==[ 1 1 ]

2923

elseif data(i:i+1)==[ 1 1 ]

2708

dataout(ceil(i/2)) = 1/3;

2924

dataout(ceil(i/2)) = 1/3;

2709

elseif data(i:i+1)==[ 1 -1 ]

2925

elseif data(i:i+1)==[ 1 -1 ]

2710

dataout(ceil(i/2)) = 1;

2926

dataout(ceil(i/2)) = 1;

2711

end

2927

end

2712

end

2928

end

2713

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2929

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2714

db = @(x) 20*log10(abs(x));

2930

db = @(x) 20*log10(abs(x));

2715

disp('computing TD_RILN...')

2931

disp('computing TD_RILN...')

2716

sdd21=squeeze(sdd21);

2932

sdd21=squeeze(sdd21);

2717

if iscolumn(sdd21)

2933

if iscolumn(sdd21)

2718

sdd21=sdd21.';

2934

sdd21=sdd21.';

2719

end

2935

end

2720

RIL=squeeze(RIL);

2936

RIL=squeeze(RIL);

2721

if iscolumn(RIL)

2937

if iscolumn(RIL)

2722

RIL=RIL.';

2938

RIL=RIL.';

2723

end

2939

end

2724

print_for_codereview=1;

2940

print_for_codereview=1;

2725

if exist('OP','var')

2941

if exist('OP','var')

2726

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2942

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2727

2943

2728

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2944

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2729

H_bw=Butterworth_Filter(param,faxis_f2,1);

2945

H_bw=Butterworth_Filter(param,faxis_f2,1);

2730

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2946

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2731

H_tw=Tukey_Window(faxis_f2,param);

2947

H_tw=Tukey_Window(faxis_f2,param);

2732

H_tw=ones(1,length(faxis_f2) );

2948

H_tw=ones(1,length(faxis_f2) );

2733

[RILN_TD_struct.REF.FIR, ...

2949

[RILN_TD_struct.REF.FIR, ...

2734

RILN_TD_struct.REF.t, ...

2950

RILN_TD_struct.REF.t, ...

2735

RILN_TD_struct.REF.causality_correction_dB, ...

2951

RILN_TD_struct.REF.causality_correction_dB, ...

2736

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2952

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2737

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2953

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2738

[RILN_TD_struct.FIT.FIR, ...

2954

[RILN_TD_struct.FIT.FIR, ...

2739

RILN_TD_struct.FIT.t, ...

2955

RILN_TD_struct.FIT.t, ...

2740

RILN_TD_struct.FIT.causality_correction_dB, ...

2956

RILN_TD_struct.FIT.causality_correction_dB, ...

2741

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2957

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2742

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2958

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2743

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2959

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2744

NrangeUI=1000;

2960

NrangeUI=1000;

2745

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2961

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2746

range=ipeak:range_end;

2962

range=ipeak:range_end;

2747

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2963

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2748

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2964

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2749

RILN_TD_struct.FOM=-inf;

2965

RILN_TD_struct.FOM=-inf;

2750

RILN_TD_struct.FOM_PDF=-inf;

2966

RILN_TD_struct.FOM_PDF=-inf;

2751

rms_fom=-inf;

2967

rms_fom=-inf;

2752

for im=1:param.samples_per_ui

2968

for im=1:param.samples_per_ui

2753

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2969

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2754

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2970

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2755

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2971

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2756

cdf=pdf; cdf.y=cumsum(pdf.y);

2972

cdf=pdf; cdf.y=cumsum(pdf.y);

2757

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2973

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2758

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2974

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2759

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2975

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2760

if print_for_codereview % remove once all checked out

2976

if print_for_codereview % remove once all checked out

2761

h=figure(191);set(gcf,'Tag','COM');

2977

h=figure(191);set(gcf,'Tag','COM');

2762

semilogy(-cdf.x,cdf.y);

2978

semilogy(-cdf.x,cdf.y);

2763

% xlim ([0,-cdf.x(1)])

2979

% xlim ([0,-cdf.x(1)])

2764

ylim([param.specBER 1]);title ('CDF of RILN')

2980

ylim([param.specBER 1]);title ('CDF of RILN')

2765

hold on

2981

hold on

2766

end

2982

end

2767

if rms>rms_fom

2983

if rms>rms_fom

2768

rms_fom=rms;

2984

rms_fom=rms;

2769

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2985

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2770

RILN_TD_struct.PDF=pdf;

2986

RILN_TD_struct.PDF=pdf;

2771

end

2987

end

2772

end

2988

end

2773

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2989

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2774

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2990

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2775

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2991

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2776

if print_for_codereview % remove once all checked out

2992

if print_for_codereview % remove once all checked out

2777

figure(9003);set(gcf,'Tag','COM');

2993

figure(9003);set(gcf,'Tag','COM');

2778

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2994

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2779

hold on

2995

hold on

2780

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2996

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2781

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2997

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2782

hold off

2998

hold off

2783

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

2999

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

2784

figure(9004);set(gcf,'Tag','COM');

3000

figure(9004);set(gcf,'Tag','COM');

2785

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

3001

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2786

hold on

3002

hold on

2787

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

3003

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2788

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

3004

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2789

grid on

3005

grid on

2790

legend('show')

3006

legend('show')

2791

end

3007

end

2792

end

3008

end

2793

function is_illegal=RXFFE_Illegal(C,param,last_index)

3009

function is_illegal=RXFFE_Illegal(C,param,last_index)

2794

3010

2795

%check if RXFFE taps are illegal

3011

%check if RXFFE taps are illegal

2796

%C = RXFFE taps

3012

%C = RXFFE taps

2797

%param = COM param struct

3013

%param = COM param struct

2798

%last_index is used when computing illegality prior to Backoff. It will be set so taps

3014

%last_index is used when computing illegality prior to Backoff. It will be set so taps

2799

% in the Backoff region are not considered in the legality check.

3015

% in the Backoff region are not considered in the legality check.

2800

3016

2801

%If last index is omitted, set it to length(C)

3017

%If last index is omitted, set it to length(C)

2802

if nargin<3

3018

if nargin<3

2803

last_index=length(C);

3019

last_index=length(C);

2804

end

3020

end

2805

3021

2806

is_illegal=0;

3022

is_illegal=0;

2807

3023

2808

%Check cursor tap

3024

%Check cursor tap

2809

Ccur_i=param.RxFFE_cmx+1;

3025

Ccur_i=param.RxFFE_cmx+1;

2810

if C(Ccur_i) < param.ffe_main_cursor_min

3026

if C(Ccur_i) < param.ffe_main_cursor_min

2811

is_illegal=1;

3027

is_illegal=1;

2812

return;

3028

return;

2813

end

3029

end

2814

3030

2815

%Check postcursors

3031

%Check postcursors

2816

if param.ffe_post_tap_len ~=0

3032

if param.ffe_post_tap_len ~=0

2817

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

3033

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

2818

is_illegal=1;

3034

is_illegal=1;

2819

return;

3035

return;

2820

end

3036

end

2821

if (param.ffe_post_tap_len > 1)

3037

if (param.ffe_post_tap_len > 1)

2822

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

3038

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

2823

is_illegal=1;

3039

is_illegal=1;

2824

return;

3040

return;

2825

end

3041

end

2826

end

3042

end

2827

end

3043

end

2828

3044

2829

%Check precursors

3045

%Check precursors

2830

if param.ffe_pre_tap_len ~=0

3046

if param.ffe_pre_tap_len ~=0

2831

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

3047

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

2832

is_illegal=1;

3048

is_illegal=1;

2833

return;

3049

return;

2834

end

3050

end

2835

if (param.ffe_pre_tap_len > 1)

3051

if (param.ffe_pre_tap_len > 1)

2836

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

3052

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

2837

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

3053

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

2838

is_illegal=1;

3054

is_illegal=1;

2839

return;

3055

return;

2840

end % 11.22.2018 Yasou Hadaka

3056

end % 11.22.2018 Yasou Hadaka

2841

end

3057

end

2842

end

3058

end

2843

function S =R_series2(zref,f,R)

3059

function S =R_series2(zref,f,R)

2844

r=ones(1,length(f))*R;

3060

r=ones(1,length(f))*R;

2845

S.Parameters(1,1,:) = r./(r + 2*zref);

3061

S.Parameters(1,1,:) = r./(r + 2*zref);

2846

S.Parameters(2,2,:) = r./(r + 2*zref);

3062

S.Parameters(2,2,:) = r./(r + 2*zref);

2847

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

3063

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

2848

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

3064

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

2849

% Sm=sparameters(S.Parameters,f,zref);

3065

% Sm=sparameters(S.Parameters,f,zref);

2850

3066

2851

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

3067

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

2852

3068

2853

if use_RC

3069

if use_RC

2854

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

3070

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

2855

else

3071

else

2856

H_tw=ones(1,length(f));

3072

H_tw=ones(1,length(f));

2857

end

3073

end

2858

function SLD=SL(S,f,R)

3074

function SLD=SL(S,f,R)

2859

% source load impact return loss add to S21

3075

% source load impact return loss add to S21

2860

% S and SLD are the same structure

3076

% S and SLD are the same structure

2861

% S.Parameters

3077

% S.Parameters

2862

% S.Impedance

3078

% S.Impedance

2863

% S.NumPorts

3079

% S.NumPorts

2864

% S.Frequencies

3080

% S.Frequencies

2865

SLD=S; % assign the fields

3081

SLD=S; % assign the fields

2866

zref=100;

3082

zref=100;

2867

if R==0

3083

if R==0

2868

warndlg('Termination should not be set to zero');

3084

warndlg('Termination should not be set to zero');

2869

SLD=S;

3085

SLD=S;

2870

return

3086

return

2871

end

3087

end

2872

3088

2873

if R > zref

3089

if R > zref

2874

spr =R_series2(zref,f,(R-zref)); % make series sparameter

3090

spr =R_series2(zref,f,(R-zref)); % make series sparameter

2875

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

3091

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

2876

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3092

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2877

combines4p( ...

3093

combines4p( ...

2878

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3094

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2879

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3095

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2880

);

3096

);

2881

elseif R < zref

3097

elseif R < zref

2882

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

3098

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

2883

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

3099

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

2884

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3100

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2885

combines4p( ...

3101

combines4p( ...

2886

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3102

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2887

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3103

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2888

);

3104

);

2889

else

3105

else

2890

SLD=S;

3106

SLD=S;

2891

end

3107

end

2892

3108

2893

%%

3109

%%

2894

3110

2895

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

3111

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

2896

p1=param.CTLE_fp1(1);

3112

p1=param.CTLE_fp1(1);

2897

z1=param.CTLE_fz(1);

3113

z1=param.CTLE_fz(1);

2898

p2=param.CTLE_fp2(1);

3114

p2=param.CTLE_fp2(1);

2899

zlf=param.f_HP(1);

3115

zlf=param.f_HP(1);

2900

plf=param.f_HP(1);

3116

plf=param.f_HP(1);

2901

f_b=param.fb;

3117

f_b=param.fb;

2902

f_r=param.f_r;

3118

f_r=param.f_r;

2903

eta_0=param.eta_0;

3119

eta_0=param.eta_0;

2904

H_CTF = ( 10^(G_DC/20)+ 1i*f/z1 ) .*( 10^(G_DC2/20) + 1i*f/zlf )./ ( ( 1+1i*f/p1) .* ( 1+1i*f/p2) .* ( 1+1i*f/plf));

3120

H_CTF = ( 10^(G_DC/20)+ 1i*f/z1 ) .*( 10^(G_DC2/20) + 1i*f/zlf )./ ( ( 1+1i*f/p1) .* ( 1+1i*f/p2) .* ( 1+1i*f/plf));

2905

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

3121

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

2906

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

3122

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

2907

if 0

3123

if 0

2908

figure

3124

figure

2909

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

3125

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

2910

% see if it looks correct

3126

% see if it looks correct

2911

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

3127

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

2912

ylabel('dB');

3128

ylabel('dB');

2913

xlabel('GHz');

3129

xlabel('GHz');

2914

title( 'H_ctf with H_r')

3130

title( 'H_ctf with H_r')

2915

grid on

3131

grid on

2916

ylim([-30 0])

3132

ylim([-30 0])

2917

end

3133

end

2918

3134

2919

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

3135

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

2920

3136

2921

%Fill TDR data

3137

%Fill TDR data

2922

if package_testcase_i == 1

3138

if package_testcase_i == 1

2923

if OP.TDR

3139

if OP.TDR

2924

output_args.Z11est=chdata(1).TDR11.avgZport;

3140

output_args.Z11est=chdata(1).TDR11.avgZport;

2925

if ~param.FLAG.S2P

3141

if ~param.FLAG.S2P

2926

output_args.Z22est=chdata(1).TDR22.avgZport;

3142

output_args.Z22est=chdata(1).TDR22.avgZport;

2927

else

3143

else

2928

output_args.Z22est=[];

3144

output_args.Z22est=[];

2929

end

3145

end

2930

if OP.AUTO_TFX

3146

if OP.AUTO_TFX

2931

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

3147

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

2932

else

3148

else

2933

output_args.tfx_estimate=[];

3149

output_args.tfx_estimate=[];

2934

end

3150

end

2935

else

3151

else

2936

output_args.Z11est=[];

3152

output_args.Z11est=[];

2937

output_args.Z22est=[];

3153

output_args.Z22est=[];

2938

output_args.tfx_estimate=[];

3154

output_args.tfx_estimate=[];

2939

end

3155

end

2940

end

3156

end

2941

3157

2942

% Process ERL

3158

% Process ERL

2943

if package_testcase_i == 1

3159

if package_testcase_i == 1

2944

if OP.ERL

3160

if OP.ERL

2945

output_args.ERL11=chdata(1).TDR11.ERL;

3161

output_args.ERL11=chdata(1).TDR11.ERL;

2946

if ~param.FLAG.S2P

3162

if ~param.FLAG.S2P

2947

output_args.ERL22=chdata(1).TDR22.ERL;

3163

output_args.ERL22=chdata(1).TDR22.ERL;

2948

else

3164

else

2949

output_args.ERL22=[];

3165

output_args.ERL22=[];

2950

end

3166

end

2951

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

3167

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

2952

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

3168

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

2953

else

3169

else

2954

output_args.ERL11=[];

3170

output_args.ERL11=[];

2955

output_args.ERL22=[];

3171

output_args.ERL22=[];

2956

end

3172

end

2957

end

3173

end

2958

if OP.ERL

3174

if OP.ERL

2959

if OP.TDR_W_TXPKG

3175

if OP.TDR_W_TXPKG

2960

min_ERL=output_args.ERL22;

3176

min_ERL=output_args.ERL22;

2961

ERL= [ nan output_args.ERL22 ];

3177

ERL= [ nan output_args.ERL22 ];

2962

else

3178

else

2963

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

3179

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

2964

min_ERL=output_args.ERL11;

3180

min_ERL=output_args.ERL11;

2965

ERL= [ output_args.ERL11 nan ];

3181

ERL= [ output_args.ERL11 nan ];

2966

else

3182

else

2967

min_ERL=min(output_args.ERL11,output_args.ERL22);

3183

min_ERL=min(output_args.ERL11,output_args.ERL22);

2968

ERL= [ output_args.ERL11 output_args.ERL22 ];

3184

ERL= [ output_args.ERL11 output_args.ERL22 ];

2969

end

3185

end

2970

end

3186

end

2971

output_args.ERL=min_ERL;

3187

output_args.ERL=min_ERL;

2972

else

3188

else

2973

min_ERL=[];

3189

min_ERL=[];

2974

ERL= [];

3190

ERL= [];

2975

output_args.ERL=[];

3191

output_args.ERL=[];

2976

end

3192

end

2977

if OP.ERL_ONLY

3193

if OP.ERL_ONLY

2978

if OP.BREAD_CRUMBS

3194

if OP.BREAD_CRUMBS

2979

output_args.OP=OP;

3195

output_args.OP=OP;

2980

output_args.param=param;

3196

output_args.param=param;

2981

output_args.chdata=chdata;

3197

output_args.chdata=chdata;

2982

%This seems to be the intent of setting fom_result.ran=0. Add it

3198

%This seems to be the intent of setting fom_result.ran=0. Add it

2983

%to output_args so there is a fom_result field.

3199

%to output_args so there is a fom_result field.

2984

fom_result.ran=0;

3200

fom_result.ran=0;

2985

output_args.fom_result=fom_result;

3201

output_args.fom_result=fom_result;

2986

end

3202

end

2987

output_args.Z_t=param.Z_t;

3203

output_args.Z_t=param.Z_t;

2988

fileset_str=str2csv({chdata(1).base});

3204

fileset_str=str2csv({chdata(1).base});

2989

output_args.file_names=sprintf('"%s"', fileset_str);

3205

output_args.file_names=sprintf('"%s"', fileset_str);

2990

if OP.DISPLAY_WINDOW

3206

if OP.DISPLAY_WINDOW

2991

savefigs(param, OP);

3207

savefigs(param, OP);

2992

end

3208

end

2993

end

3209

end

2994

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3210

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

2995

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3211

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

2996

p1_ctle = -2*pi*f_p1;

3212

p1_ctle = -2*pi*f_p1;

2997

p2_ctle = -2*pi*f_p2;

3213

p2_ctle = -2*pi*f_p2;

2998

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3214

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

2999

k_ctle = -p2_ctle;

3215

k_ctle = -p2_ctle;

3000

bilinear_fs = 2*fb*oversampling;

3216

bilinear_fs = 2*fb*oversampling;

3001

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3217

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3002

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3218

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3003

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3219

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3004

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3220

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3005

% allow for different pole zeros RIM 9-29-2015

3221

% allow for different pole zeros RIM 9-29-2015

3006

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3222

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3007

B_filt =k_ctle*kd*poly([zd, -1]);

3223

B_filt =k_ctle*kd*poly([zd, -1]);

3008

A_filt=poly([p1d, p2d]);

3224

A_filt=poly([p1d, p2d]);

3009

impulse_response=filter(B_filt,A_filt,ir_in);

3225

impulse_response=filter(B_filt,A_filt,ir_in);

3010

3226

3011

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3227

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3012

Over_sample=2;

3228

Over_sample=2;

3013

num_files=length(chdata);

3229

num_files=length(chdata);

3014

for i=1:num_files

3230

for i=1:num_files

3015

V=chdata(i).uneq_pulse_response;

3231

V=chdata(i).uneq_pulse_response;

3016

T=chdata(i).t;

3232

T=chdata(i).t;

3017

dt=T(2)-T(1);

3233

dt=T(2)-T(1);

3018

f=0:1/max(T):1/dt;

3234

f=0:1/max(T):1/dt;

3019

chdata(i).faxis=f;

3235

chdata(i).faxis=f;

3020

f75=find(f >= param.fb*.75,1,'first');

3236

f75=find(f >= param.fb*.75,1,'first');

3021

fnq=find(f >= param.fb*.5,1,'first');

3237

fnq=find(f >= param.fb*.5,1,'first');

3022

chdata(i).fmaxi = length(f);

3238

chdata(i).fmaxi = length(f);

3023

chdata(i).faxis = f;

3239

chdata(i).faxis = f;

3024

UI=param.ui; % unit interval

3240

UI=param.ui; % unit interval

3025

M=param.samples_per_ui; % sample per UI

3241

M=param.samples_per_ui; % sample per UI

3026

N_v=param.N_v; % number of UI for Vf determination

3242

N_v=param.N_v; % number of UI for Vf determination

3027

3243

3028

% filters

3244

% filters

3029

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3245

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3030

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3246

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3031

H_ftr=H_bw.*H_bt;

3247

H_ftr=H_bw.*H_bt;

3032

H_ftr=H_ftr(:);

3248

H_ftr=H_ftr(:);

3033

% fd of PR

3249

% fd of PR

3034

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3250

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3035

prr = prr(:);

3251

prr = prr(:);

3036

if f(1)==0, prr(1)=1; end %remove NaN

3252

if f(1)==0, prr(1)=1; end %remove NaN

3037

fd=fft(V);

3253

fd=fft(V);

3038

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3254

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3039

3255

3040

%% get Vf

3256

%% get Vf

3041

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3257

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3042

step_response=filter(V,1, shifting_vector);

3258

step_response=filter(V,1, shifting_vector);

3043

Vf=step_response(end);

3259

Vf=step_response(end);

3044

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3260

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3045

%%

3261

%%

3046

% ILest=20.*log10(abs(fd(1:f75)/Vf/M/Over_sample)) - 20.*log10(abs(prr(1:f75))) - 20*log10(abs(squeeze(H_ftr(1:f75)))) ; %removing db function to avoid using sig proc toolbox

3262

% ILest=20.*log10(abs(fd(1:f75)/Vf/M/Over_sample)) - 20.*log10(abs(prr(1:f75))) - 20*log10(abs(squeeze(H_ftr(1:f75)))) ; %removing db function to avoid using sig proc toolbox

3047

% figure

3263

% figure

3048

% plot(f(1:f75),ILest)

3264

% plot(f(1:f75),ILest)

3049

3265

3050

IL_conv=fd(1:f75)/Vf/M/Over_sample ./ prr(1:f75) ./ H_ftr(1:f75) ; %removing db function to avoid using sig proc toolbox

3266

IL_conv=fd(1:f75)/Vf/M/Over_sample ./ prr(1:f75) ./ H_ftr(1:f75) ; %removing db function to avoid using sig proc toolbox

3051

% set same variables as get_s4p_files

3267

% set same variables as get_s4p_files

3052

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3268

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3053

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3269

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3054

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3270

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3055

zero_vector=zeros(length(IL_conv),1);

3271

zero_vector=zeros(length(IL_conv),1);

3056

for j=1:length(IL_fields)

3272

for j=1:length(IL_fields)

3057

chdata(i).(IL_fields{j})=IL_conv;

3273

chdata(i).(IL_fields{j})=IL_conv;

3058

end

3274

end

3059

for j=1:length(Zero_fields)

3275

for j=1:length(Zero_fields)

3060

chdata(i).(Zero_fields{j})=zero_vector;

3276

chdata(i).(Zero_fields{j})=zero_vector;

3061

end

3277

end

3062

3278

3063

if i==1

3279

if i==1

3064

SDDch(:,1,2)=chdata.sdd12_raw;

3280

SDDch(:,1,2)=chdata.sdd12_raw;

3065

SDDch(:,2,1)=chdata.sdd21_raw;

3281

SDDch(:,2,1)=chdata.sdd21_raw;

3066

SDDch(:,1,1)=chdata.sdd11_raw;

3282

SDDch(:,1,1)=chdata.sdd11_raw;

3067

SDDch(:,2,2)=chdata.sdd22_raw;

3283

SDDch(:,2,2)=chdata.sdd22_raw;

3068

SDDp2p= zeros(length(IL_conv),1);

3284

SDDp2p= zeros(length(IL_conv),1);

3069

end

3285

end

3070

chdata(i).TX_RL=[];

3286

chdata(i).TX_RL=[];

3071

chdata(i).TDR11=[];

3287

chdata(i).TDR11=[];

3072

chdata(i).PDTR11=[];

3288

chdata(i).PDTR11=[];

3073

chdata(i).TDR22=[];

3289

chdata(i).TDR22=[];

3074

chdata(i).PDTR22=[];

3290

chdata(i).PDTR22=[];

3075

end

3291

end

3076

3292

3077

3293

3078

function H_tw=Tukey_Window(f,param,fr,fb)

3294

function H_tw=Tukey_Window(f,param,fr,fb)

3079

% RIM 05/26/2022 added optional fr and fb

3295

% RIM 05/26/2022 added optional fr and fb

3080

% fr is the start of the raised cosine window

3296

% fr is the start of the raised cosine window

3081

% fb is the end of the raised cosine window

3297

% fb is the end of the raised cosine window

3082

if ~exist('fr','var') && ~exist('fb','var')

3298

if ~exist('fr','var') && ~exist('fb','var')

3083

fb=param.fb;

3299

fb=param.fb;

3084

fr=param.f_r*param.fb;

3300

fr=param.f_r*param.fb;

3085

end

3301

end

3086

fperiod=2*(fb-fr);

3302

fperiod=2*(fb-fr);

3087

H_tw = [ ones(1,length(f(f<fr))) ...

3303

H_tw = [ ones(1,length(f(f<fr))) ...

3088

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3304

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3089

zeros(1,length(f(f>fb)) )];

3305

zeros(1,length(f(f>fb)) )];

3090

H_tw=H_tw(1:length(f));

3306

H_tw=H_tw(1:length(f));

3091

if 0

3307

if 0

3092

plot(f/1e9,H_tw)

3308

plot(f/1e9,H_tw)

3093

end

3309

end

3094

3310

3095

3311

3096

3312

3097

%% moved output control to functions

3313

%% moved output control to functions

3098

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3314

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3099

% Author: Richard Mellitz

3315

% Author: Richard Mellitz

3100

% Date: 7/29/2022

3316

% Date: 7/29/2022

3101

% generate FD tx ffe system function

3317

% generate FD tx ffe system function

3102

% varagins...

3318

% varagins...

3103

% param - stucture

3319

% param - stucture

3104

% param.fb baud rate

3320

% param.fb baud rate

3105

% param.Tx_FFE Tx FFE coef

3321

% param.Tx_FFE Tx FFE coef

3106

% f - freq array

3322

% f - freq array

3107

% Use_Tx_FFE = flag to use or not

3323

% Use_Tx_FFE = flag to use or not

3108

% H_TxFFE is system function for Tx_FFE

3324

% H_TxFFE is system function for Tx_FFE

3109

db = @(x) 20*log10(abs(x));

3325

db = @(x) 20*log10(abs(x));

3110

[param,varargin]=varargin_extractor(varargin{:});

3326

[param,varargin]=varargin_extractor(varargin{:});

3111

[f,varargin]=varargin_extractor(varargin{:});

3327

[f,varargin]=varargin_extractor(varargin{:});

3112

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3328

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3113

if isempty(Use_Tx_FFE)

3329

if isempty(Use_Tx_FFE)

3114

Use_Tx_FFE=0;

3330

Use_Tx_FFE=0;

3115

end

3331

end

3116

if isempty(param)

3332

if isempty(param)

3117

param.fb=106.25e9;

3333

param.fb=106.25e9;

3118

Tx_FFE=[1 ];

3334

Tx_FFE=[1 ];

3119

else

3335

else

3120

if ~isfield(param, 'Pkg_TXFFE_preset')

3336

if ~isfield(param, 'Pkg_TXFFE_preset')

3121

Tx_FFE=[ 1 ];

3337

Tx_FFE=[ 1 ];

3122

else

3338

else

3123

Tx_FFE=param.Pkg_TXFFE_preset;

3339

Tx_FFE=param.Pkg_TXFFE_preset;

3124

end

3340

end

3125

end

3341

end

3126

if isempty(f)

3342

if isempty(f)

3127

f=0:10e6:param.fb;

3343

f=0:10e6:param.fb;

3128

end

3344

end

3129

3345

3130

3346

3131

if Use_Tx_FFE ~=0

3347

if Use_Tx_FFE ~=0

3132

[mcur,icur] = max(Tx_FFE);

3348

[mcur,icur] = max(Tx_FFE);

3133

H_TxFFE=zeros(1,length(f));

3349

H_TxFFE=zeros(1,length(f));

3134

for ii=1:length(Tx_FFE)

3350

for ii=1:length(Tx_FFE)

3135

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3351

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3136

end

3352

end

3137

else

3353

else

3138

H_TxFFE=ones(1,length(f));

3354

H_TxFFE=ones(1,length(f));

3139

end

3355

end

3140

% figure (1102320)

3356

% figure (1102320)

3141

% plot(f/1e9,db(H_TxFFE))

3357

% plot(f/1e9,db(H_TxFFE))

3142

% hold on

3358

% hold on

+3359

function C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs)

3360

cmx=param.RxFFE_cmx;

3361

cpx=param.RxFFE_cpx;

3362

% do this early on so we can reuse the old code

3363

% to be replaced with MMSE function from healey...

3364

if param.N_bg ~=0 % must be floating taps

3365

cpx=param.N_bmax; % N_f in spreadsheet

3366

end

3367

num_taps=cmx+cpx+1;

3368

ndfe=param.ndfe;

3369

spui=param.samples_per_ui;

3370

%% Start of WIENER-HOPF MMSE EQ code

3371

R_n = zeros(num_taps,num_taps);

3372

R_xt = zeros(num_taps,num_taps);

3373

3374

if OP.Do_Colored_Noise

3375

% Form Noise Autocorrelation matrix

3376

Noise_XC = reshape (Noise_XC,1,[]);

3377

len = length(Noise_XC);

3378

if len < num_taps, Noise_XC = [Noise_XC,zeros(1,num_taps-len)]; end

3379

Noise_XC = Noise_XC(1:num_taps);

3380

R_n = toeplitz (Noise_XC,Noise_XC);

3381

end

3382

%% Calculate Cross Talk Correlation matrix at T intervals.

3383

if OP.Do_XT_Noise

3384

% Calculate variance of Tx signal based on +/-1 outer limits

3385

Tx_sigma = sqrt( (param.levels^2-1)/(3*(param.levels-1)^2) );

3386

for jj = 2:length(chdata)

3387

if isequal(chdata(jj).type, 'FEXT') || isequal(chdata(jj).type, 'NEXT')

3388

if isequal(chdata(jj).type, 'FEXT')

3389

% len = length(chdata(jj).ctle_imp_response);

3390

% ch_imp = ifft( fft(reshape(chdata(jj).ctle_imp_response,1,[])) .* fft(reshape(upsample(txffe, param.samples_per_ui),1,[]),len) );

3391

ch_imp= FFE( txffe , cmx,param.samples_per_ui, chdata(jj).ctle_imp_response).';

3392

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3393

elseif isequal(chdata(jj).type, 'NEXT')

3394

ch_imp = chdata(jj).ctle_imp_response;

3395

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3396

end

3397

norms = zeros(1,spui);

3398

for ii = 1:spui

3399

norms(ii) = norm(ch_imp(ii:spui:end));

3400

end

3401

% Pick out sampling phase with largest noise contribution

3402

[~,cursor] = max(norms);

3403

sub_sample_ch = ch_imp(cursor:spui:end);

3404

xc = xcorr(sub_sample_ch,num_taps)* Tx_sigma^2;

3405

xc = xc(num_taps+1:end);

3406

xc = xc(1:num_taps);

3407

R = toeplitz (xc,xc);

3408

R_xt = R_xt + R;

3409

end

3410

end

3411

end

3412

%% Noise + Cross Talk contribution to R matrix

3413

R_n_xc = zeros(num_taps+ndfe);

3414

R_n_xc(1:num_taps,1:num_taps) = R_n + R_xt ;

3415

%% For least means squares, we want to solve

3416

%

3417

% ro = |Ryy Ryx| * w

3418

% |Rxy Rxx|

3419

% see Cioffi chapter 3, 3.7.3

3420

3421

himp = vsampled;

3422

RefTap = cmx+1;

3423

Signal_Variance = mean ( [-1, -1/3, 1/3, 1].^2 );

3424

Ryy.r = [1:num_taps];

3425

Ryy.c = [1:num_taps];

3426

Ryx.r = 1:num_taps;

3427

Ryx.c = num_taps + (1:ndfe);

3428

Rxy.r = num_taps + (1:ndfe);

3429

Rxy.c = 1:num_taps;

3430

Rxx.r = num_taps+(1:ndfe);

3431

Rxx.c = num_taps+(1:ndfe);

3432

himp = reshape (himp,1,[]);

3433

%% ro is simply the channel response reversed in time

3434

himp_lr = fliplr(himp); % make sure himp has enough pre/post cursors, e.g. numtaps+ndfe

3435

himp_lr = [zeros(1,num_taps+ndfe), himp_lr, zeros(1,num_taps+ndfe)];

3436

[~,pk] = max(himp_lr);

3437

r_indx = (1:num_taps) - RefTap;

3438

ro = [himp_lr(pk+r_indx), zeros(1,ndfe)].';

3439

ro = ro*Signal_Variance;

3440

%% Setup up the covariance matrix

3441

R = zeros(num_taps+ndfe);

3442

% Form Ryy

3443

% Note: important to use whole impulse response

3444

% not just the part that spans the FFE.

3445

[ryy,lags] = xcorr(himp,himp, num_taps-1);

3446

R(Ryy.r,Ryy.c) = toeplitz (ryy(num_taps:end));

3447

3448

% Form Rxx

3449

R(Rxx.r,Rxx.c) = diag(ones(1,ndfe));

3450

3451

% Form Ryx columns

3452

Ryx_indxs = (1:num_taps)-1;

3453

for jj = 0:ndfe-1

3454

% R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk+1 + Ryx_indxs -jj ).';

3455

R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk-cmx-1 + Ryx_indxs -jj ).';

3456

end

3457

% Form Rxy rows

3458

R(Rxy.r,Rxy.c ) = R(Ryx.r,Ryx.c )';

3459

3460

% add in Signal Variance

3461

R = R*Signal_Variance;

3462

Rtmp = R;

3463

% Add in Xt and colored noise terms

3464

R = R + R_n_xc;

3465

3466

% SNR = 25 dB

3467

SNR = OP.FFE_SNR;

3468

Noise_var = max(vsampled)^2*Signal_Variance/10^(SNR/10);

3469

R_noise = diag(ones(1,num_taps))*Noise_var;

3470

if ~OP.Do_Colored_Noise && ~OP.Do_XT_Noise

3471

R(Ryy.r,Ryy.c) = R(Ryy.r,Ryy.c) + R_noise;

3472

end

3473

3474

3475

%% Solve for equalizer weights

3476

w = inv(R)*ro;

3477

C = w;

3478

%% Deal with 1st post Cursor DFE weight saturation

3479

% ro = Rw by moving "saturated" weights over to the LHS

3480

DFE_h1_indx = num_taps+1;

3481

Indx_full = 1:length(C);

3482

ws = C;

3483

if ndfe>0 && abs(C(DFE_h1_indx)) > param.bmax(1)

3484

rtmp = reshape (ro,[],1);

3485

Rtmp = R;

3486

% Move saturated DFE weights over to left hand side of equation

3487

ws = zeros (size(C));

3488

ws (DFE_h1_indx) = sign(C(DFE_h1_indx))*param.bmax(1);

3489

rtmp = rtmp - Rtmp*ws;

3490

3491

% and remove the corresponding column from R

3492

Rtmp(:,DFE_h1_indx) = [];

3493

Indx_full (DFE_h1_indx) = [];

3494

% now Rtmp isn't square so have to use the R'R trick

3495

% Probably a little dicey "theoretically" because

3496

% w = inv(R)*ro is already the mmse solution

3497

% now we at doing a R'R operation, but hey

3498

% seems to work

3499

% Alternative, since R is now over specified, more rows than

3500

% columns, one could try removing one of the DFE rows from the

3501

% Rxy Rxx portion of the R matrix.

3502

3503

w_partial = inv(Rtmp'*Rtmp)*(Rtmp'*rtmp);

3504

ws (Indx_full,:) = w_partial;

3505

C = ws;

3506

end

3507

% From Cioffi, Chapter 3

3508

var_ffe_dfe = Signal_Variance-ws.'*ro;

3509

SNR_Eq = 10*log10(Signal_Variance/var_ffe_dfe-1);

3510

3511

%% Scale FFE gain to target output voltage

3512

Target_ouput = vsampled(ivs)*10^(param.current_ffegain/20);

3513

C = C*Target_ouput;

3514

C = C(1:num_taps);

3515

%% End MMSE dfe code

3143

function Write_CSV(output_args,csv_file)

3516

function Write_CSV(output_args,csv_file)

3144

3517

3145

items = fieldnames(output_args);

3518

items = fieldnames(output_args);

3146

item_value_strings = cell(size(items));

3519

item_value_strings = cell(size(items));

3147

for field_id=1:length(items)

3520

for field_id=1:length(items)

3148

field_name=items{field_id};

3521

field_name=items{field_id};

3149

field_value=output_args.(field_name);

3522

field_value=output_args.(field_name);

3150

if isstruct(output_args.(field_name))

3523

if isstruct(output_args.(field_name))

3151

field_value='struct';

3524

field_value='struct';

3152

end

3525

end

3153

if ischar(field_value)

3526

if ischar(field_value)

3154

item_value_strings{field_id}=field_value;

3527

item_value_strings{field_id}=field_value;

3155

elseif isempty(field_value)

3528

elseif isempty(field_value)

3156

item_value_strings{field_id}='';

3529

item_value_strings{field_id}='';

3157

elseif numel(field_value)==1

3530

elseif numel(field_value)==1

3158

item_value_strings{field_id}=num2str(field_value);

3531

item_value_strings{field_id}=num2str(field_value);

3159

else

3532

else

3160

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3533

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3161

end

3534

end

3162

end

3535

end

3163

3536

3164

header_string = str2csv(items);

3537

header_string = str2csv(items);

3165

data_string = str2csv(item_value_strings);

3538

data_string = str2csv(item_value_strings);

3166

fid = fopen(csv_file,'w');

3539

fid = fopen(csv_file,'w');

3167

fprintf(fid,'%s\n', header_string);

3540

fprintf(fid,'%s\n', header_string);

3168

fprintf(fid,'%s\n', data_string);

3541

fprintf(fid,'%s\n', data_string);

3169

fclose(fid);

3542

fclose(fid);

3170

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3543

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3171

%% Used in Clause 92 for adding board trace between TP0 and TP2

3544

%% Used in Clause 92 for adding board trace between TP0 and TP2

3172

3545

3173

switch chdata.type

3546

switch chdata.type

3174

case 'THRU'

3547

case 'THRU'

3175

z_bp_tx = param.z_bp_tx;

3548

z_bp_tx = param.z_bp_tx;

3176

z_bp_rx = param.z_bp_rx;

3549

z_bp_rx = param.z_bp_rx;

3177

case 'NEXT'

3550

case 'NEXT'

3178

z_bp_tx = param.z_bp_rx;

3551

z_bp_tx = param.z_bp_rx;

3179

z_bp_rx = param.z_bp_next;

3552

z_bp_rx = param.z_bp_next;

3180

case 'FEXT'

3553

case 'FEXT'

3181

z_bp_tx = param.z_bp_fext;

3554

z_bp_tx = param.z_bp_fext;

3182

z_bp_rx = param.z_bp_rx;

3555

z_bp_rx = param.z_bp_rx;

3183

end

3556

end

3184

% Same cap on each tx and rx three is a data stratue for bifrucation but

3557

% Same cap on each tx and rx three is a data stratue for bifrucation but

3185

% logic no implemented here RIM 06/28/2019

3558

% logic no implemented here RIM 06/28/2019

3186

zref=param.Z0;

3559

zref=param.Z0;

3187

c1=param.C_0;

3560

c1=param.C_0;

3188

c2=param.C_1;

3561

c2=param.C_1;

3189

f=chdata.faxis;

3562

f=chdata.faxis;

3190

f(f<eps)=eps;

3563

f(f<eps)=eps;

3191

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3564

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3192

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3565

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3193

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3566

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3194

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3567

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3195

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3568

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3196

% add Tx caps

3569

% add Tx caps

3197

[s11tx, s12tx, s21tx, s22tx ]= ...

3570

[s11tx, s12tx, s21tx, s22tx ]= ...

3198

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3571

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3199

[s11tx, s12tx, s21tx, s22tx ]= ...

3572

[s11tx, s12tx, s21tx, s22tx ]= ...

3200

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3573

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3201

3574

3202

3575

3203

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3576

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3204

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3577

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3205

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3578

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3206

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3579

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3207

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_rx);

3580

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_rx);

3208

% add Rx caps

3581

% add Rx caps

3209

[s11rx, s12rx, s21rx, s22rx ]= ...

3582

[s11rx, s12rx, s21rx, s22rx ]= ...

3210

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3583

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3211

[s11rx, s12rx, s21rx, s22rx ]= ...

3584

[s11rx, s12rx, s21rx, s22rx ]= ...

3212

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3585

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3213

3586

3214

3587

3215

switch OP.include_pcb

3588

switch OP.include_pcb

3216

case 1

3589

case 1

3217

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3590

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3218

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3591

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3219

case 2

3592

case 2

3220

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3593

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3221

end

3594

end

3222

3595

3223

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3596

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3224

% Used in Clause 92 for adding board trace between TP0 and TP2

3597

% Used in Clause 92 for adding board trace between TP0 and TP2

3225

switch chdata.type

3598

switch chdata.type

3226

case 'THRU'

3599

case 'THRU'

3227

z_bp_tx = param.z_bp_tx;

3600

z_bp_tx = param.z_bp_tx;

3228

case 'NEXT'

3601

case 'NEXT'

3229

z_bp_tx = param.z_bp_next;

3602

z_bp_tx = param.z_bp_next;

3230

case 'FEXT'

3603

case 'FEXT'

3231

z_bp_tx = param.z_bp_fext;

3604

z_bp_tx = param.z_bp_fext;

3232

end

3605

end

3233

3606

3234

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3607

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3235

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, param.z_bp_rx);

3608

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, param.z_bp_rx);

3236

3609

3237

switch OP.include_pcb

3610

switch OP.include_pcb

3238

case 1

3611

case 1

3239

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3612

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3240

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3613

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3241

case 2

3614

case 2

3242

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3615

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3243

end

3616

end

3244

3617

3245

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3618

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3246

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3619

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3247

% applying a bank of DFE at desired location

3620

% applying a bank of DFE at desired location

3248

% hisi: waveform with cursor values;

3621

% hisi: waveform with cursor values;

3249

% idx: starting index of the bank;

3622

% idx: starting index of the bank;

3250

% tap_bk: number of taps in bank;

3623

% tap_bk: number of taps in bank;

3251

% bmaxg: maxmum coefficient in bank;

3624

% bmaxg: maxmum coefficient in bank;

3252

3625

3253

if nargin<6

3626

if nargin<6

3254

dfe_delta=0;

3627

dfe_delta=0;

3255

end

3628

end

3256

3629

3257

rng=idx:idx+tap_bk-1;

3630

rng=idx:idx+tap_bk-1;

3258

flt_curval=hisi(rng);

3631

flt_curval=hisi(rng);

3259

3632

3260

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3633

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3261

3634

3262

if dfe_delta~=0

3635

if dfe_delta~=0

3263

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3636

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3264

dfe_delta.*sign(flt_curval)*curval;

3637

dfe_delta.*sign(flt_curval)*curval;

3265

else

3638

else

3266

flt_curval_q=hisi(rng);

3639

flt_curval_q=hisi(rng);

3267

end

3640

end

3268

3641

3269

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3642

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3270

hisi(rng)= hisi(rng) - curval*tap_coef;

3643

hisi(rng)= hisi(rng) - curval*tap_coef;

3271

hisi_ref(rng)=0;

3644

hisi_ref(rng)=0;

3272

3645

3273

%AJG021820

3646

%AJG021820

3274

function [ a] = bessel( n )

3647

function [ a] = bessel( n )

3275

% bessel polynomial

3648

% bessel polynomial

3276

for ii= 0:n

3649

for ii= 0:n

3277

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3650

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3278

end

3651

end

3279

3652

3280

3653

3281

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3654

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3282

% History:

3655

% History:

3283

% 1. 14th October, 2021 (Intial release)

3656

% 1. 14th October, 2021 (Intial release)

3284

3657

3285

% Definition:

3658

% Definition:

3286

% This function captures the channel delay through the time domain using causality enforcement.

3659

% This function captures the channel delay through the time domain using causality enforcement.

3287

% Following are the steps being followed.

3660

% Following are the steps being followed.

3288

% Step 1. Cascade negative frequencies

3661

% Step 1. Cascade negative frequencies

3289

% Step 2. Extract magnitude

3662

% Step 2. Extract magnitude

3290

% Step 3. IFFT of the magnitude

3663

% Step 3. IFFT of the magnitude

3291

% Step 4. Multiply by the sign(t)

3664

% Step 4. Multiply by the sign(t)

3292

% Step 5. Calculate the phase of the 1j*causal_phase

3665

% Step 5. Calculate the phase of the 1j*causal_phase

3293

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3666

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3294

% Step 7. f-domain to t-domain pulse response

3667

% Step 7. f-domain to t-domain pulse response

3295

% Step 8. Calculate the delay

3668

% Step 8. Calculate the delay

3296

3669

3297

% Author:

3670

% Author:

3298

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3671

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3299

3672

3300

% Reference:

3673

% Reference:

3301

% 1] "IEEE Standard for Electrical Characterization of Printed Circuit Board and Related Interconnects at Frequencies up to 50 GHz," in IEEE Std 370-2020 , vol., no., pp.1-147, 8 Jan. 2021, doi: 10.1109/IEEESTD.2021.9316329.

3674

% 1] "IEEE Standard for Electrical Characterization of Printed Circuit Board and Related Interconnects at Frequencies up to 50 GHz," in IEEE Std 370-2020 , vol., no., pp.1-147, 8 Jan. 2021, doi: 10.1109/IEEESTD.2021.9316329.

3302

3675

3303

% Input:

3676

% Input:

3304

% freq %frequency in hertz (odd number points)

3677

% freq %frequency in hertz (odd number points)

3305

% sdd21 %insertion loss in complex (odd number points)

3678

% sdd21 %insertion loss in complex (odd number points)

3306

% param %COM native structure passed

3679

% param %COM native structure passed

3307

% OP %COM native structure passed

3680

% OP %COM native structure passed

3308

3681

3309

% Output:

3682

% Output:

3310

% delay_sec %channel delay in seconds

3683

% delay_sec %channel delay in seconds

3311

% delay_idx %channel delay index

3684

% delay_idx %channel delay index

3312

3685

3313

if iscolumn(sdd21)

3686

if iscolumn(sdd21)

3314

sdd21= sdd21.';

3687

sdd21= sdd21.';

3315

end

3688

end

3316

if iscolumn(freq)

3689

if iscolumn(freq)

3317

freq= freq.';

3690

freq= freq.';

3318

end

3691

end

3319

3692

3320

%---start. Step 1. Cascade negative frequencies

3693

%---start. Step 1. Cascade negative frequencies

3321

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3694

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3322

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3695

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3323

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3696

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3324

%---end. Step 1. Cascade negative frequencies

3697

%---end. Step 1. Cascade negative frequencies

3325

3698

3326

%---start. Step 2. Extract magnitude

3699

%---start. Step 2. Extract magnitude

3327

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3700

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3328

%---end. Step 2. Extract magnitude

3701

%---end. Step 2. Extract magnitude

3329

3702

3330

%---start. Step 3. IFFT of the magnitude

3703

%---start. Step 3. IFFT of the magnitude

3331

sdd21_mag_time = ifft(sdd21_mag_conj);

3704

sdd21_mag_time = ifft(sdd21_mag_conj);

3332

%---end. Step 3. IFFT of the magnitude

3705

%---end. Step 3. IFFT of the magnitude

3333

3706

3334

%---start. Step 4. Multiply by the sign(t)

3707

%---start. Step 4. Multiply by the sign(t)

3335

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3708

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3336

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3709

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3337

%---end. Step 4. Multiply by the sign(t)

3710

%---end. Step 4. Multiply by the sign(t)

3338

3711

3339

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3712

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3340

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3713

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3341

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3714

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3342

3715

3343

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3716

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3344

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3717

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3345

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3718

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3346

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3719

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3347

3720

3348

%---start. Step 7. f-domain to t-domain pulse response

3721

%---start. Step 7. f-domain to t-domain pulse response

3349

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3722

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3350

%--------- Extrapolation has been already done by the COM tool

3723

%--------- Extrapolation has been already done by the COM tool

3351

freq_array= freq;

3724

freq_array= freq;

3352

time_step= param.sample_dt;

3725

time_step= param.sample_dt;

3353

fmax=1/time_step/2;

3726

fmax=1/time_step/2;

3354

freq_step=(freq_array(3)-freq_array(2))/1;

3727

freq_step=(freq_array(3)-freq_array(2))/1;

3355

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3728

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3356

3729

3357

ILin=sdd21;

3730

ILin=sdd21;

3358

IL=interp_Sparam(ILin,freq_array,fout, ...

3731

IL=interp_Sparam(ILin,freq_array,fout, ...

3359

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3732

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3360

IL_nan = find(isnan(IL));

3733

IL_nan = find(isnan(IL));

3361

for in=IL_nan

3734

for in=IL_nan

3362

IL(in)=IL(in-1);

3735

IL(in)=IL(in-1);

3363

end

3736

end

3364

IL = IL(:);

3737

IL = IL(:);

3365

% add padding for time steps

3738

% add padding for time steps

3366

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3739

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3367

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3740

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3368

clear IL IL_nan IL_symmetric

3741

clear IL IL_nan IL_symmetric

3369

3742

3370

ILin=sdd21_causality_enforced;

3743

ILin=sdd21_causality_enforced;

3371

IL=interp_Sparam(ILin,freq_array,fout, ...

3744

IL=interp_Sparam(ILin,freq_array,fout, ...

3372

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3745

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3373

IL_nan = find(isnan(IL));

3746

IL_nan = find(isnan(IL));

3374

for in=IL_nan

3747

for in=IL_nan

3375

IL(in)=IL(in-1);

3748

IL(in)=IL(in-1);

3376

end

3749

end

3377

IL = IL(:);

3750

IL = IL(:);

3378

% add padding for time steps

3751

% add padding for time steps

3379

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3752

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3380

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3753

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3381

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3754

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3382

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3755

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3383

clear IL IL_nan IL_symmetric

3756

clear IL IL_nan IL_symmetric

3384

3757

3385

clear time_step fmax freq_step freq_array

3758

clear time_step fmax freq_step freq_array

3386

3759

3387

freq_step=(fout(3)-fout(2))/1;

3760

freq_step=(fout(3)-fout(2))/1;

3388

L= length(sdd21_PR);

3761

L= length(sdd21_PR);

3389

t_base = (0:L-1)/(freq_step*L);

3762

t_base = (0:L-1)/(freq_step*L);

3390

clear fout freq_step L

3763

clear fout freq_step L

3391

%---end. Step 7. f-domain to t-domain pulse response

3764

%---end. Step 7. f-domain to t-domain pulse response

3392

3765

3393

%---start. Step 8. Calculate the delay

3766

%---start. Step 8. Calculate the delay

3394

%------start. Remove the last 5% of the waveform for noise due to IFFT

3767

%------start. Remove the last 5% of the waveform for noise due to IFFT

3395

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3768

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3396

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3769

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3397

%------end. Remove the last 5% of the waveform for noise due to IFFT

3770

%------end. Remove the last 5% of the waveform for noise due to IFFT

3398

3771

3399

%---start. calculate the difference in index between the peaks

3772

%---start. calculate the difference in index between the peaks

3400

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3773

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3401

[~, peak_y_idx] = max(sdd21_PR_reduced);

3774

[~, peak_y_idx] = max(sdd21_PR_reduced);

3402

peak_idx_difference = peak_x_idx - peak_y_idx;

3775

peak_idx_difference = peak_x_idx - peak_y_idx;

3403

%---end. calculate the difference in index between the peaks

3776

%---end. calculate the difference in index between the peaks

3404

3777

3405

if peak_idx_difference~=0

3778

if peak_idx_difference~=0

3406

search_bounds = min(peak_x_idx, peak_y_idx);%<----one may fix it to 1e3; using minimum of the peaks in assuming the other signal has zero delay

3779

search_bounds = min(peak_x_idx, peak_y_idx);%<----one may fix it to 1e3; using minimum of the peaks in assuming the other signal has zero delay

3407

error_value = length(sdd21_causality_enforced_PR_reduced);

3780

error_value = length(sdd21_causality_enforced_PR_reduced);

3408

error_idx = 0;

3781

error_idx = 0;

3409

% i= 1;

3782

% i= 1;

3410

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3783

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3411

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3784

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3412

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3785

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3413

if (error_value > current_error)

3786

if (error_value > current_error)

3414

error_idx = shift_value;

3787

error_idx = shift_value;

3415

error_value = current_error;

3788

error_value = current_error;

3416

end

3789

end

3417

% error_idx_H(i)= error_idx;

3790

% error_idx_H(i)= error_idx;

3418

% i= i+ 1;

3791

% i= i+ 1;

3419

end

3792

end

3420

%plot(error_idx_H);

3793

%plot(error_idx_H);

3421

3794

3422

if error_idx==0

3795

if error_idx==0

3423

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3796

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3424

end

3797

end

3425

3798

3426

delay_idx = error_idx;

3799

delay_idx = error_idx;

3427

else

3800

else

3428

delay_idx= 1;

3801

delay_idx= 1;

3429

end

3802

end

3430

3803

3431

delay_sec= t_base(abs(delay_idx));

3804

delay_sec= t_base(abs(delay_idx));

3432

3805

3433

3806

3434

function [return_struct]= capture_RIL_RILN(chdata)

3807

function [return_struct]= capture_RIL_RILN(chdata)

3435

% History:

3808

% History:

3436

% 1. 12th April, 2019 (Intial release)

3809

% 1. 12th April, 2019 (Intial release)

3437

%

3810

%

3438

% 2. 11th October, 2021

3811

% 2. 11th October, 2021

3439

% - Details:

3812

% - Details:

3440

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3813

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3441

% 2] Revised the selection criteria for the solution of the quadratic

3814

% 2] Revised the selection criteria for the solution of the quadratic

3442

% equation in finding the reflection coefficient (rho).

3815

% equation in finding the reflection coefficient (rho).

3443

% - Impact:

3816

% - Impact:

3444

% => Zero impact in |RIL|, while impact on angle(RIL).

3817

% => Zero impact in |RIL|, while impact on angle(RIL).

3445

% - Previous:

3818

% - Previous:

3446

% %---start. For passive networks the reflection coefficient should be less than one

3819

% %---start. For passive networks the reflection coefficient should be less than one

3447

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3820

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3448

% rho_port2= solution_1;

3821

% rho_port2= solution_1;

3449

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3822

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3450

% rho_port2= solution_2;

3823

% rho_port2= solution_2;

3451

% else

3824

% else

3452

% rho_port2= solution_1;

3825

% rho_port2= solution_1;

3453

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3826

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3454

% end

3827

% end

3455

% %---end. For passive networks the reflection coefficient should be less than one

3828

% %---end. For passive networks the reflection coefficient should be less than one

3456

%

3829

%

3457

% RIL= conj((1- rho_port1).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- rho_port2).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3830

% RIL= conj((1- rho_port1).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- rho_port2).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3458

% - Change:

3831

% - Change:

3459

% %---start. Given the real part of the impedance is to be positive

3832

% %---start. Given the real part of the impedance is to be positive

3460

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3833

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3461

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3834

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3462

%

3835

%

3463

% rho_port2= zeros(length(solution_1), 1);

3836

% rho_port2= zeros(length(solution_1), 1);

3464

% for solution_idx= 1:length(solution_1)

3837

% for solution_idx= 1:length(solution_1)

3465

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3838

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3466

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3839

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3467

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3840

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3468

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3841

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3469

% else

3842

% else

3470

% error('An odd case has occured. Please contact the tool developer.');

3843

% error('An odd case has occured. Please contact the tool developer.');

3471

% end

3844

% end

3472

% end

3845

% end

3473

% %---end. Given the real part of the impedance is to be positive

3846

% %---end. Given the real part of the impedance is to be positive

3474

% RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3847

% RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3475

3848

3476

% Definition:

3849

% Definition:

3477

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3850

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3478

3851

3479

% Author:

3852

% Author:

3480

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3853

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3481

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3854

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3482

3855

3483

% This function has been shared by Hansel for others to evaluate for reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter.

3856

% This function has been shared by Hansel for others to evaluate for reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter.

3484

3857

3485

% Reference:

3858

% Reference:

3486

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3859

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3487

% 2] H. Dsilva, A. Jain, J. Sasikala and A. Kumar, "Novel Signal Integrity Application of Power Wave Scattering Matrix theory," 2019 IEEE MTT-S International Microwave and RF Conference (IMARC), 2019, pp. 1-7, doi: 10.1109/IMaRC45935.2019.9118701.

3860

% 2] H. Dsilva, A. Jain, J. Sasikala and A. Kumar, "Novel Signal Integrity Application of Power Wave Scattering Matrix theory," 2019 IEEE MTT-S International Microwave and RF Conference (IMARC), 2019, pp. 1-7, doi: 10.1109/IMaRC45935.2019.9118701.

3488

3861

3489

% Input:

3862

% Input:

3490

% 1] SCH: S-matrix structure

3863

% 1] SCH: S-matrix structure

3491

% SCH.Frequencies= faxis;

3864

% SCH.Frequencies= faxis;

3492

% SCH.Parameters(1,1,:)= sdd11;

3865

% SCH.Parameters(1,1,:)= sdd11;

3493

% SCH.Parameters(2,2,:)= sdd22;

3866

% SCH.Parameters(2,2,:)= sdd22;

3494

% SCH.Parameters(1,2,:)= sdd12;

3867

% SCH.Parameters(1,2,:)= sdd12;

3495

% SCH.Parameters(2,1,:)= sdd21;

3868

% SCH.Parameters(2,1,:)= sdd21;

3496

% SCH.NumPorts= 2;

3869

% SCH.NumPorts= 2;

3497

% SCH.Impedance= 100;

3870

% SCH.Impedance= 100;

3498

3871

3499

% Output: Struct returned has the following,

3872

% Output: Struct returned has the following,

3500

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3873

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3501

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3874

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3502

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3875

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3503

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3876

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3504

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3877

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3505

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3878

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3506

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3879

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3507

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3880

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3508

% return_struct.freq %Frequency axis

3881

% return_struct.freq %Frequency axis

3509

3882

3510

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3883

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3511

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3884

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3512

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3885

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3513

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3886

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3514

SCH.Frequencies=chdata(1).faxis;

3887

SCH.Frequencies=chdata(1).faxis;

3515

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3888

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3516

SCH.NumPorts= 2;

3889

SCH.NumPorts= 2;

3517

3890

3518

%---start. allowed is only a 2-port network having a transmitter and receiver

3891

%---start. allowed is only a 2-port network having a transmitter and receiver

3519

if size(SCH.Parameters, 1)~=2

3892

if size(SCH.Parameters, 1)~=2

3520

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3893

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3521

error('Allowed is only a 2-port network having a transmitter and receiver.');

3894

error('Allowed is only a 2-port network having a transmitter and receiver.');

3522

end

3895

end

3523

%---end. allowed is only a 2-port network having a transmitter and receiver

3896

%---end. allowed is only a 2-port network having a transmitter and receiver

3524

3897

3525

%---start. do not include the DC point given sinusoidals at DC are not

3898

%---start. do not include the DC point given sinusoidals at DC are not

3526

%defined

3899

%defined

3527

if SCH.Frequencies(1)==0

3900

if SCH.Frequencies(1)==0

3528

idx_start= 2;

3901

idx_start= 2;

3529

else

3902

else

3530

idx_start= 1;

3903

idx_start= 1;

3531

end

3904

end

3532

%---end. do not include the DC point given sinusoidals at DC are not

3905

%---end. do not include the DC point given sinusoidals at DC are not

3533

%defined

3906

%defined

3534

3907

3535

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3908

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3536

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3909

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3537

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3910

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3538

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3911

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3539

3912

3540

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3913

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3541

b= 1+ Sdd22.*conj(Sdd22)+...

3914

b= 1+ Sdd22.*conj(Sdd22)+...

3542

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3915

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3543

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3916

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3544

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3917

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3545

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3918

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3546

Sdd11.*conj(Sdd11);

3919

Sdd11.*conj(Sdd11);

3547

c= -conj(Sdd22)-...

3920

c= -conj(Sdd22)-...

3548

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3921

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3549

Sdd11.*conj(Sdd11).*conj(Sdd22);

3922

Sdd11.*conj(Sdd11).*conj(Sdd22);

3550

3923

3551

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3924

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3552

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3925

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3553

3926

3554

clear a b c

3927

clear a b c

3555

3928

3556

%---start. Given the real part of the impedance is to be positive

3929

%---start. Given the real part of the impedance is to be positive

3557

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3930

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3558

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3931

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3559

3932

3560

rho_port2= zeros(length(solution_1), 1);

3933

rho_port2= zeros(length(solution_1), 1);

3561

for solution_idx= 1:length(solution_1)

3934

for solution_idx= 1:length(solution_1)

3562

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3935

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3563

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3936

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3564

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3937

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3565

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3938

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3566

else

3939

else

3567

error('An odd case has occured. Please contact the tool developer.');

3940

error('An odd case has occured. Please contact the tool developer.');

3568

end

3941

end

3569

end

3942

end

3570

%---end. Given the real part of the impedance is to be positive

3943

%---end. Given the real part of the impedance is to be positive

3571

3944

3572

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3945

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3573

3946

3574

%---start. calculate the equivalent port impedance

3947

%---start. calculate the equivalent port impedance

3575

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3948

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3576

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3949

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3577

%---end. calculate the equivalent port impedance

3950

%---end. calculate the equivalent port impedance

3578

3951

3579

3952

3580

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3953

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3581

% %to zero reflections.

3954

% %to zero reflections.

3582

RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3955

RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3583

%---end. The reflectionless insertion loss is the insertion loss corresponding

3956

%---end. The reflectionless insertion loss is the insertion loss corresponding

3584

%to zero reflections.

3957

%to zero reflections.

3585

3958

3586

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3959

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3587

RILN= RIL- Sdd21;

3960

RILN= RIL- Sdd21;

3588

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3961

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3589

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3962

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3590

3963

3591

%---start. preparing returns struct

3964

%---start. preparing returns struct

3592

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3965

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3593

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3966

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3594

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3967

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3595

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3968

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3596

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3969

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3597

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3970

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3598

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3971

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3599

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3972

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3600

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3973

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3601

%---end. preparing returns struct

3974

%---end. preparing returns struct

3602

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3975

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3603

3976

3604

3977

3605

%For the given BER, find the top & bottom voltage level in the CDF

3978

%For the given BER, find the top & bottom voltage level in the CDF

3606

3979

3607

%for the top, just find the first index at the spec BER

3980

%for the top, just find the first index at the spec BER

3608

nidx=find(cdf.y>specBER, 1, 'first');

3981

nidx=find(cdf.y>specBER, 1, 'first');

3609

noise_bottom = cdf.x(nidx);

3982

noise_bottom = cdf.x(nidx);

3610

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3983

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3611

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3984

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3612

%the true index without flipping

3985

%the true index without flipping

3613

nidx=length(cdf.y)-nidx+1;

3986

nidx=length(cdf.y)-nidx+1;

3614

noise_top = cdf.x(nidx);

3987

noise_top = cdf.x(nidx);

3615

function p=comb_fct(p1, p2)

3988

function p=comb_fct(p1, p2)

3616

if p1.BinSize ~= p2.BinSize

3989

if p1.BinSize ~= p2.BinSize

3617

error('bin size must be equal')

3990

error('bin size must be equal')

3618

end

3991

end

3619

3992

3620

p=p1;

3993

p=p1;

3621

p.BinSize=p1.BinSize;

3994

p.BinSize=p1.BinSize;

3622

%p.Min=p1.Min+p2.Min;

3995

%p.Min=p1.Min+p2.Min;

3623

p.Min=min(p1.Min,p2.Min);

3996

p.Min=min(p1.Min,p2.Min);

3624

difsz=abs(p1.Min-p2.Min);

3997

difsz=abs(p1.Min-p2.Min);

3625

lp1=length(p1.y);

3998

lp1=length(p1.y);

3626

lp2=length(p2.y);

3999

lp2=length(p2.y);

3627

if p1.Min == p.Min

4000

if p1.Min == p.Min

3628

p2.y(difsz+1:lp2+difsz)=p2.y;

4001

p2.y(difsz+1:lp2+difsz)=p2.y;

3629

p2.y(1:difsz)=0;

4002

p2.y(1:difsz)=0;

3630

p2.y(lp2+difsz+1:lp1)=0;

4003

p2.y(lp2+difsz+1:lp1)=0;

3631

elseif p2.Min == p.Min

4004

elseif p2.Min == p.Min

3632

p1.y(difsz+1:lp1+difsz)=p1.y;

4005

p1.y(difsz+1:lp1+difsz)=p1.y;

3633

p1.y(1:difsz)=0;

4006

p1.y(1:difsz)=0;

3634

p1.y(lp1+difsz+1:lp2)=0;

4007

p1.y(lp1+difsz+1:lp2)=0;

3635

end

4008

end

3636

% p.y=conv(p1.y, p2.y);

4009

% p.y=conv(p1.y, p2.y);

3637

p.y=(p1.y+p2.y);

4010

p.y=(p1.y+p2.y);

3638

% p.y=p.y/sum(p.y);

4011

% p.y=p.y/sum(p.y);

3639

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

4012

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3640

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

4013

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3641

4014

3642

4015

3643

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

4016

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

3644

4017

3645

if pdf1.BinSize ~= pdf2.BinSize

4018

if pdf1.BinSize ~= pdf2.BinSize

3646

error('bin size must be equal')

4019

error('bin size must be equal')

3647

end

4020

end

3648

4021

3649

x1=pdf1.x;

4022

x1=pdf1.x;

3650

y1=pdf1.y;

4023

y1=pdf1.y;

3651

x2=pdf2.x;

4024

x2=pdf2.x;

3652

y2=pdf2.y;

4025

y2=pdf2.y;

3653

%find the pdf with a larger min, force it to have the same min, and insert

4026

%find the pdf with a larger min, force it to have the same min, and insert

3654

%probability = 0

4027

%probability = 0

3655

min1=pdf1.x(1);

4028

min1=pdf1.x(1);

3656

min2=pdf2.x(1);

4029

min2=pdf2.x(1);

3657

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

4030

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

3658

if min1<min2

4031

if min1<min2

3659

x2=[pdf1.x(1:shift_amount) pdf2.x];

4032

x2=[pdf1.x(1:shift_amount) pdf2.x];

3660

y2=[zeros(1,shift_amount) pdf2.y];

4033

y2=[zeros(1,shift_amount) pdf2.y];

3661

else

4034

else

3662

x1=[pdf2.x(1:shift_amount) pdf1.x];

4035

x1=[pdf2.x(1:shift_amount) pdf1.x];

3663

y1=[zeros(1,shift_amount) pdf1.y];

4036

y1=[zeros(1,shift_amount) pdf1.y];

3664

end

4037

end

3665

%find the pdf with smaller max, force it to have the same max, and insert

4038

%find the pdf with smaller max, force it to have the same max, and insert

3666

%probability=0

4039

%probability=0

3667

L1=length(x1);

4040

L1=length(x1);

3668

L2=length(x2);

4041

L2=length(x2);

3669

Ldiff=abs(L1-L2);

4042

Ldiff=abs(L1-L2);

3670

if L1>L2

4043

if L1>L2

3671

out_x=x1;

4044

out_x=x1;

3672

y2=[y2 zeros(1,Ldiff)];

4045

y2=[y2 zeros(1,Ldiff)];

3673

else

4046

else

3674

out_x=x2;

4047

out_x=x2;

3675

y1=[y1 zeros(1,Ldiff)];

4048

y1=[y1 zeros(1,Ldiff)];

3676

end

4049

end

3677

%now the 2 pdfs have the same voltage axis, add probabilities together

4050

%now the 2 pdfs have the same voltage axis, add probabilities together

3678

%renormalization is not handled here, so the output pdf will not have sum=1

4051

%renormalization is not handled here, so the output pdf will not have sum=1

3679

%It is the responsibility of the calling function to handle renormalization

4052

%It is the responsibility of the calling function to handle renormalization

3680

%if needed

4053

%if needed

3681

out_y=y1+y2;

4054

out_y=y1+y2;

3682

out_pdf.x=out_x;

4055

out_pdf.x=out_x;

3683

out_pdf.y=out_y;

4056

out_pdf.y=out_y;

3684

out_pdf.BinSize=pdf1.BinSize;

4057

out_pdf.BinSize=pdf1.BinSize;

3685

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

4058

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

3686

4059

3687

%original method:

4060

%original method:

3688

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

4061

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

3689

% for i=1:length(s11in1)

4062

% for i=1:length(s11in1)

3690

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

4063

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

3691

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

4064

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

3692

% end

4065

% end

3693

% t1=stot(s1);

4066

% t1=stot(s1);

3694

% t2=stot(s2);

4067

% t2=stot(s2);

3695

% for i=1:length(s11in1)

4068

% for i=1:length(s11in1)

3696

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

4069

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

3697

% end

4070

% end

3698

% s3=ttos(t3);

4071

% s3=ttos(t3);

3699

% s11out=s3(1,1,:);

4072

% s11out=s3(1,1,:);

3700

% s11out=transpose(s11out(:));

4073

% s11out=transpose(s11out(:));

3701

% s12out=s3(1,2,:);

4074

% s12out=s3(1,2,:);

3702

% s12out=transpose(s12out(:));

4075

% s12out=transpose(s12out(:));

3703

% s21out=s3(2,1,:);

4076

% s21out=s3(2,1,:);

3704

% s21out=transpose(s21out(:));

4077

% s21out=transpose(s21out(:));

3705

% s22out=s3(2,2,:);

4078

% s22out=s3(2,2,:);

3706

% s22out=transpose(s22out(:));

4079

% s22out=transpose(s22out(:));

3707

4080

3708

4081

3709

%vectorized method:

4082

%vectorized method:

3710

s1(1,1,:)=s11in1;

4083

s1(1,1,:)=s11in1;

3711

s1(1,2,:)=s12in1;

4084

s1(1,2,:)=s12in1;

3712

s1(2,1,:)=s21in1;

4085

s1(2,1,:)=s21in1;

3713

s1(2,2,:)=s22in1;

4086

s1(2,2,:)=s22in1;

3714

s2(1,1,:)=s11in2;

4087

s2(1,1,:)=s11in2;

3715

s2(1,2,:)=s12in2;

4088

s2(1,2,:)=s12in2;

3716

s2(2,1,:)=s21in2;

4089

s2(2,1,:)=s21in2;

3717

s2(2,2,:)=s22in2;

4090

s2(2,2,:)=s22in2;

3718

4091

3719

4092

3720

N = (1-s1(2,2,:).*s2(1,1,:)) ;

4093

N = (1-s1(2,2,:).*s2(1,1,:)) ;

3721

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

4094

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

3722

s12out = s1(1,2,:).*s2(1,2,:)./N ;

4095

s12out = s1(1,2,:).*s2(1,2,:)./N ;

3723

s21out = s2(2,1,:).*s1(2,1,:)./N;

4096

s21out = s2(2,1,:).*s1(2,1,:)./N;

3724

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

4097

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

3725

4098

3726

s11out=transpose(squeeze(s11out));

4099

s11out=transpose(squeeze(s11out));

3727

s12out=transpose(squeeze(s12out));

4100

s12out=transpose(squeeze(s12out));

3728

s21out=transpose(squeeze(s21out));

4101

s21out=transpose(squeeze(s21out));

3729

s22out=transpose(squeeze(s22out));

4102

s22out=transpose(squeeze(s22out));

3730

function p=conv_fct(p1, p2)

4103

function p=conv_fct(p1, p2)

3731

if p1.BinSize ~= p2.BinSize

4104

if p1.BinSize ~= p2.BinSize

3732

error('bin size must be equal')

4105

error('bin size must be equal')

3733

end

4106

end

3734

4107

3735

p=p1;

4108

p=p1;

3736

%p.BinSize=p1.BinSize;

4109

%p.BinSize=p1.BinSize;

3737

%p.Min=p1.Min+p2.Min;

4110

%p.Min=p1.Min+p2.Min;

3738

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4111

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3739

p.y=conv2(p1.y, p2.y);

4112

p.y=conv2(p1.y, p2.y);

3740

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

4113

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3741

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

4114

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3742

pMax=p.Min+length(p.y)-1;

4115

pMax=p.Min+length(p.y)-1;

3743

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4116

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3744

4117

3745

4118

3746

4119

3747

4120

3748

function p=conv_fct_MeanNotZero(p1, p2)

4121

function p=conv_fct_MeanNotZero(p1, p2)

3749

4122

3750

if p1.BinSize ~= p2.BinSize

4123

if p1.BinSize ~= p2.BinSize

3751

error('bin size must be equal')

4124

error('bin size must be equal')

3752

end

4125

end

3753

4126

3754

p=p1;

4127

p=p1;

3755

%p.BinSize=p1.BinSize;

4128

%p.BinSize=p1.BinSize;

3756

%p.Min=p1.Min+p2.Min;

4129

%p.Min=p1.Min+p2.Min;

3757

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4130

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3758

p.y=conv2(p1.y, p2.y);

4131

p.y=conv2(p1.y, p2.y);

3759

4132

3760

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

4133

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

3761

%But it is faster to pre-multiply BinSize instead of multiplying the entire

4134

%But it is faster to pre-multiply BinSize instead of multiplying the entire

3762

%vector by BinSize

4135

%vector by BinSize

3763

pMax=p.Min+length(p.y)-1;

4136

pMax=p.Min+length(p.y)-1;

3764

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4137

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3765

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

4138

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

3766

4139

3767

%IN:

4140

%IN:

3768

%sbr = pulse response

4141

%sbr = pulse response

3769

%param = COM "param" struct

4142

%param = COM "param" struct

3770

%OP = COM "OP" struct

4143

%OP = COM "OP" struct

3771

%peak_search_range= a limited range to search for the peak (for speed up)

4144

%peak_search_range= a limited range to search for the peak (for speed up)

3772

% it is usually +/- 20 UI

4145

% it is usually +/- 20 UI

3773

%

4146

%

3774

%OUT:

4147

%OUT:

3775

%cursor_i = sampling location

4148

%cursor_i = sampling location

3776

%no_zero_crossing = flag that reveals if sampling is not possible.

4149

%no_zero_crossing = flag that reveals if sampling is not possible.

3777

% When this function is called in optimize_fom, it signals to quit the current case

4150

% When this function is called in optimize_fom, it signals to quit the current case

3778

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

4151

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

3779

% time consuming, so saving the peak in one spot is advantageous

4152

% time consuming, so saving the peak in one spot is advantageous

3780

%zxi = zero crossing index (returned because RXFFE uses it)

4153

%zxi = zero crossing index (returned because RXFFE uses it)

3781

4154

3782

no_zero_crossing=0;

4155

no_zero_crossing=0;

3783

%need to set cursor_i to empty in case no_zero_crossing flag is set

4156

%need to set cursor_i to empty in case no_zero_crossing flag is set

3784

cursor_i=[];

4157

cursor_i=[];

3785

4158

3786

%get peak of pulse and peak index

4159

%get peak of pulse and peak index

3787

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

4160

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

3788

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

4161

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

3789

4162

3790

4163

3791

% initial guess at cursor location (t_s) - based on approximate zero crossing

4164

% initial guess at cursor location (t_s) - based on approximate zero crossing

3792

%limit search space for speed up

4165

%limit search space for speed up

3793

search_start=sbr_peak_i-4*param.samples_per_ui;

4166

search_start=sbr_peak_i-4*param.samples_per_ui;

3794

if search_start<1

4167

if search_start<1

3795

search_start=1;

4168

search_start=1;

3796

end

4169

end

3797

%Find zero crossings

4170

%Find zero crossings

3798

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

4171

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

3799

4172

3800

%Note: the original implementation of zxi:

4173

%Note: the original implementation of zxi:

3801

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

4174

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

3802

% zxi = zxi(zxi<sbr_peak_i);

4175

% zxi = zxi(zxi<sbr_peak_i);

3803

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

4176

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

3804

% The changes to limit search space and remember max(sbr) give 10x speed up

4177

% The changes to limit search space and remember max(sbr) give 10x speed up

3805

% A test case of 25k runs, reduced from 1.2s to 0.1s

4178

% A test case of 25k runs, reduced from 1.2s to 0.1s

3806

4179

3807

4180

3808

if isempty(zxi)

4181

if isempty(zxi)

3809

%if no zero crossing, the calling program must respond (since sample point will be empty)

4182

%if no zero crossing, the calling program must respond (since sample point will be empty)

3810

no_zero_crossing=1;

4183

no_zero_crossing=1;

3811

return;

4184

return;

3812

elseif length(zxi)>1

4185

elseif length(zxi)>1

3813

%only need the last zero crossing

4186

%only need the last zero crossing

3814

zxi=zxi(end);

4187

zxi=zxi(end);

3815

end

4188

end

3816

if param.ndfe==0

4189

if param.ndfe==0

3817

max_dfe1=0;

4190

max_dfe1=0;

3818

else

4191

else

3819

max_dfe1=param.bmax(1);

4192

max_dfe1=param.bmax(1);

3820

end

4193

end

3821

% adjust cursor_i to Solve equation 93A-25 %%

4194

% adjust cursor_i to Solve equation 93A-25 %%

3822

% Muller-Mueller criterion with DFE

4195

% Muller-Mueller criterion with DFE

3823

mm_range = zxi+(0:2*param.samples_per_ui);

4196

mm_range = zxi+(0:2*param.samples_per_ui);

3824

switch OP.CDR

4197

switch OP.CDR

3825

case 'Mod-MM'

4198

case 'Mod-MM'

3826

mm_metric = ...

4199

mm_metric = ...

3827

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

4200

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

3828

otherwise % MM

4201

otherwise % MM

3829

%MM is generally: first precursor = 0

4202

%MM is generally: first precursor = 0

3830

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

4203

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

3831

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

4204

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

3832

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

4205

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

3833

%first precursor = first postcursor - max_dfe

4206

%first precursor = first postcursor - max_dfe

3834

mm_metric = ...

4207

mm_metric = ...

3835

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

4208

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

3836

end

4209

end

3837

[~, mm_cursor_offset] = min(mm_metric);

4210

[~, mm_cursor_offset] = min(mm_metric);

3838

4211

3839

%cursor_i = the sample location

4212

%cursor_i = the sample location

3840

cursor_i = zxi+mm_cursor_offset-1;

4213

cursor_i = zxi+mm_cursor_offset-1;

3841

function pdf=d_cpdf( binsize, values, probs)

4214

function pdf=d_cpdf( binsize, values, probs)

3842

% p=cpdf(type, ...)

4215

% p=cpdf(type, ...)

3843

%

4216

%

3844

% CPDF is a probability mass function for discrete distributions or an

4217

% CPDF is a probability mass function for discrete distributions or an

3845

% approxmation of a PDF for continuous distributions.

4218

% approxmation of a PDF for continuous distributions.

3846

%

4219

%

3847

% cpdf is internally normalized so that the sum of probabilities is 1

4220

% cpdf is internally normalized so that the sum of probabilities is 1

3848

% (regardless of bin size).

4221

% (regardless of bin size).

3849

4222

3850

% Internal fields:

4223

% Internal fields:

3851

% Min: *bin number* of minimum value.

4224

% Min: *bin number* of minimum value.

3852

% BinSize: size of PDF bins. Bin center is the representative value.

4225

% BinSize: size of PDF bins. Bin center is the representative value.

3853

% Vec: vector of probabilities per bin.

4226

% Vec: vector of probabilities per bin.

3854

4227

3855

%speed up for initializing empty pdf

4228

%speed up for initializing empty pdf

3856

if all(values==0)

4229

if all(values==0)

3857

pdf.BinSize=binsize;

4230

pdf.BinSize=binsize;

3858

pdf.Min=0;

4231

pdf.Min=0;

3859

pdf.y=1;

4232

pdf.y=1;

3860

pdf.x=0;

4233

pdf.x=0;

3861

return;

4234

return;

3862

end

4235

end

3863

4236

3864

if ~issorted(values)

4237

if ~issorted(values)

3865

[values,si]=sort(values);

4238

[values,si]=sort(values);

3866

probs=probs(si);

4239

probs=probs(si);

3867

end

4240

end

3868

values=binsize*round(values/binsize);

4241

values=binsize*round(values/binsize);

3869

t=(values(1):binsize:values(end));

4242

t=(values(1):binsize:values(end));

3870

pdf.Min=values(1)/binsize;

4243

pdf.Min=values(1)/binsize;

3871

pdf.y=zeros(size(t));

4244

pdf.y=zeros(size(t));

3872

for k=1:length(values)

4245

for k=1:length(values)

3873

if k==1

4246

if k==1

3874

bin=1;

4247

bin=1;

3875

elseif k==length(values)

4248

elseif k==length(values)

3876

bin=length(t);

4249

bin=length(t);

3877

else

4250

else

3878

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

4251

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

3879

end

4252

end

3880

pdf.y(bin) = pdf.y(bin)+probs(k);

4253

pdf.y(bin) = pdf.y(bin)+probs(k);

3881

end

4254

end

3882

4255

3883

pdf.BinSize=binsize;

4256

pdf.BinSize=binsize;

3884

pdf.y=pdf.y/sum(pdf.y);

4257

pdf.y=pdf.y/sum(pdf.y);

3885

if any(~isreal(pdf.y)) || any(pdf.y<0)

4258

if any(~isreal(pdf.y)) || any(pdf.y<0)

3886

error('PDF must be real and nonnegative');

4259

error('PDF must be real and nonnegative');

3887

end

4260

end

3888

support=find(pdf.y);

4261

support=find(pdf.y);

3889

pdf.y=pdf.y(support(1):support(end));

4262

pdf.y=pdf.y(support(1):support(end));

3890

pdf.Min=pdf.Min+(support(1)-1);

4263

pdf.Min=pdf.Min+(support(1)-1);

3891

pdf.x=(pdf.Min:-pdf.Min)*binsize;

4264

pdf.x=(pdf.Min:-pdf.Min)*binsize;

3892

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

4265

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

3893

4266

3894

if isrow(input)

4267

if isrow(input)

3895

max_threshold=max_threshold(:).';

4268

max_threshold=max_threshold(:).';

3896

min_threshold=min_threshold(:).';

4269

min_threshold=min_threshold(:).';

3897

else

4270

else

3898

max_threshold=max_threshold(:);

4271

max_threshold=max_threshold(:);

3899

min_threshold=min_threshold(:);

4272

min_threshold=min_threshold(:);

3900

end

4273

end

3901

4274

3902

clip_output=input;

4275

clip_output=input;

3903

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

4276

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

3904

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

4277

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

3905

4278

3906

4279

3907

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

4280

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

3908

[ncases, mele]=size(param.z_p_tx_cases);

4281

[ncases, mele]=size(param.z_p_tx_cases);

3909

if mele ==2

4282

if mele ==2

3910

param.flex=2;

4283

param.flex=2;

3911

elseif mele==4

4284

elseif mele==4

3912

param.flex=4;

4285

param.flex=4;

3913

elseif mele==1

4286

elseif mele==1

3914

param.flex=1;

4287

param.flex=1;

3915

else

4288

else

3916

error(springf('config file syntax error'))

4289

error(springf('config file syntax error'))

3917

end

4290

end

3918

4291

3919

4292

3920

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

4293

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

3921

% display bathtub curves in one axis per test case.

4294

% display bathtub curves in one axis per test case.

3922

% h=findall(0, 'Name', 'COM results');

4295

% h=findall(0, 'Name', 'COM results');

3923

if ~exist('h','var')

4296

if ~exist('h','var')

3924

msgtext = cell(1, length(OP.pkg_len_select));

4297

msgtext = cell(1, length(OP.pkg_len_select));

3925

msgcolor = 'g';

4298

msgcolor = 'g';

3926

else

4299

else

3927

msgtext=get(findobj(h, 'type', 'text'), 'string');

4300

msgtext=get(findobj(h, 'type', 'text'), 'string');

3928

msgcolor = get(h, 'color');

4301

msgcolor = get(h, 'color');

3929

close(h); % will be recreated

4302

close(h); % will be recreated

3930

end

4303

end

3931

msgctr=size(msgtext,1)+1;

4304

msgctr=size(msgtext,1)+1;

3932

if ~OP.ERL_ONLY

4305

if ~OP.ERL_ONLY

3933

switch OP.PHY

4306

switch OP.PHY

3934

case 'C2M'

4307

case 'C2M'

3935

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4308

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

3936

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4309

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

3937

msg, VEO_mV);

4310

msg, VEO_mV);

3938

else

4311

else

3939

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4312

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

3940

msg, VEO_mV);

4313

msg, VEO_mV);

3941

msgcolor = 'r';

4314

msgcolor = 'r';

3942

end

4315

end

3943

4316

3944

if VEC_dB <= param.VEC_pass_threshold

4317

if VEC_dB <= param.VEC_pass_threshold

3945

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4318

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

3946

(msg), VEC_dB);

4319

(msg), VEC_dB);

3947

else

4320

else

3948

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4321

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

3949

(msg), VEC_dB);

4322

(msg), VEC_dB);

3950

msgcolor = 'r';

4323

msgcolor = 'r';

3951

end

4324

end

3952

case 'C2C'

4325

case 'C2C'

3953

if COM >= param.pass_threshold

4326

if COM >= param.pass_threshold

3954

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4327

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

3955

% msg, COM);

4328

% msg, COM);

3956

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4329

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

3957

msg, COM);

4330

msg, COM);

3958

else

4331

else

3959

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4332

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

3960

% msg, COM);

4333

% msg, COM);

3961

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4334

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

3962

msg, COM);

4335

msg, COM);

3963

msgcolor = 'r';

4336

msgcolor = 'r';

3964

end

4337

end

3965

% begin yasuo patch 3/18/2019

4338

% begin yasuo patch 3/18/2019

3966

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4339

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

3967

% end yasuo patch

4340

% end yasuo patch

3968

case 'C2Mcom'

4341

case 'C2Mcom'

3969

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4342

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

3970

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4343

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

3971

msg, VEO_mV);

4344

msg, VEO_mV);

3972

else

4345

else

3973

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4346

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

3974

msg, VEO_mV);

4347

msg, VEO_mV);

3975

msgcolor = 'r';

4348

msgcolor = 'r';

3976

end

4349

end

3977

4350

3978

if VEC_dB <= param.VEC_pass_threshold

4351

if VEC_dB <= param.VEC_pass_threshold

3979

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4352

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

3980

(msg), VEC_dB);

4353

(msg), VEC_dB);

3981

else

4354

else

3982

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4355

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

3983

(msg), VEC_dB);

4356

(msg), VEC_dB);

3984

msgcolor = 'r';

4357

msgcolor = 'r';

3985

end

4358

end

3986

if COM >= param.pass_threshold

4359

if COM >= param.pass_threshold

3987

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4360

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

3988

% msg, COM);

4361

% msg, COM);

3989

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4362

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

3990

msg, COM);

4363

msg, COM);

3991

else

4364

else

3992

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4365

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

3993

% msg, COM);

4366

% msg, COM);

3994

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4367

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

3995

msg, COM);

4368

msg, COM);

3996

msgcolor = 'r';

4369

msgcolor = 'r';

3997

end

4370

end

3998

% begin yasuo patch 3/18/2019

4371

% begin yasuo patch 3/18/2019

3999

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4372

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4000

% end yasuo patch

4373

% end yasuo patch

4001

end

4374

end

4002

end

4375

end

4003

if OP.ERL

4376

if OP.ERL

4004

if ~isempty(ERL)

4377

if ~isempty(ERL)

4005

if min_ERL >= param.ERL_pass_threshold

4378

if min_ERL >= param.ERL_pass_threshold

4006

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4379

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4007

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4380

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4008

else

4381

else

4009

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4382

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4010

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4383

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4011

msgcolor = 'r';

4384

msgcolor = 'r';

4012

end

4385

end

4013

end

4386

end

4014

end

4387

end

4015

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4388

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4016

set(h, 'color', msgcolor, 'tag', 'COM');

4389

set(h, 'color', msgcolor, 'tag', 'COM');

4017

movegui(h, 'center');

4390

movegui(h, 'center');

4018

else % no windows

4391

else % no windows

4019

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4392

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4020

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4393

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4021

if ~OP.ERL_ONLY

4394

if ~OP.ERL_ONLY

4022

switch OP.PHY

4395

switch OP.PHY

4023

case 'C2C'

4396

case 'C2C'

4024

if COM >= param.pass_threshold

4397

if COM >= param.pass_threshold

4025

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4398

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4026

else

4399

else

4027

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4400

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4028

end

4401

end

4029

% begin yasuo patch 3/18/2019

4402

% begin yasuo patch 3/18/2019

4030

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4403

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4031

% end yasuo patch

4404

% end yasuo patch

4032

case 'C2Mcom'

4405

case 'C2Mcom'

4033

if VEC_dB <= param.VEC_pass_threshold

4406

if VEC_dB <= param.VEC_pass_threshold

4034

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4407

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4035

else

4408

else

4036

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4409

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4037

end

4410

end

4038

4411

4039

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4412

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4040

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4413

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4041

else

4414

else

4042

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4415

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4043

end

4416

end

4044

if COM >= param.pass_threshold

4417

if COM >= param.pass_threshold

4045

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4418

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4046

else

4419

else

4047

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4420

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4048

end

4421

end

4049

% begin yasuo patch 3/18/2019

4422

% begin yasuo patch 3/18/2019

4050

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4423

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4051

% end yasuo patch

4424

% end yasuo patch

4052

case 'C2M'

4425

case 'C2M'

4053

if VEC_dB <= param.VEC_pass_threshold

4426

if VEC_dB <= param.VEC_pass_threshold

4054

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4427

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4055

else

4428

else

4056

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4429

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4057

end

4430

end

4058

4431

4059

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4432

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4060

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4433

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4061

else

4434

else

4062

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4435

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4063

end

4436

end

4064

end

4437

end

4065

end

4438

end

4066

if OP.ERL

4439

if OP.ERL

4067

if ~isempty(ERL)

4440

if ~isempty(ERL)

4068

if min_ERL >= param.ERL_pass_threshold

4441

if min_ERL >= param.ERL_pass_threshold

4069

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4442

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4070

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4443

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4071

else

4444

else

4072

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4445

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4073

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4446

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4074

end

4447

end

4075

end

4448

end

4076

end

4449

end

4077

end

4450

end

4078

4451

4079

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4452

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4080

4453

4081

%Left eye Width (Top Eye)

4454

%Left eye Width (Top Eye)

4082

left_top=eye_contour(half_UI:-1:1,1);

4455

left_top=eye_contour(half_UI:-1:1,1);

4083

%vref_crossing is the first point less than vref (usually first point < 0)

4456

%vref_crossing is the first point less than vref (usually first point < 0)

4084

vref_crossing=find(left_top<vref,1,'first');

4457

vref_crossing=find(left_top<vref,1,'first');

4085

if isempty(vref_crossing)

4458

if isempty(vref_crossing)

4086

%this case handles completely open eye

4459

%this case handles completely open eye

4087

L1=half_UI;

4460

L1=half_UI;

4088

elseif vref_crossing==1

4461

elseif vref_crossing==1

4089

%this case handles completely closed eye

4462

%this case handles completely closed eye

4090

L1=0;

4463

L1=0;

4091

else

4464

else

4092

%this case handles the normal eye

4465

%this case handles the normal eye

4093

%INT is a linear interpolation between the 2 points on either side of

4466

%INT is a linear interpolation between the 2 points on either side of

4094

%vref to determine where the vref crossing occurred. In systems with

4467

%vref to determine where the vref crossing occurred. In systems with

4095

%a small number of samples_per_UI, interpolation improves accuracy over

4468

%a small number of samples_per_UI, interpolation improves accuracy over

4096

%just using the integer sample point

4469

%just using the integer sample point

4097

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4470

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4098

L1=half_UI-INT;

4471

L1=half_UI-INT;

4099

end

4472

end

4100

%Left eye Width (Bottom Eye)

4473

%Left eye Width (Bottom Eye)

4101

left_bot=eye_contour(half_UI:-1:1,2);

4474

left_bot=eye_contour(half_UI:-1:1,2);

4102

vref_crossing=find(left_bot>vref,1,'first');

4475

vref_crossing=find(left_bot>vref,1,'first');

4103

if isempty(vref_crossing)

4476

if isempty(vref_crossing)

4104

L0=half_UI;

4477

L0=half_UI;

4105

elseif vref_crossing==1

4478

elseif vref_crossing==1

4106

L0=0;

4479

L0=0;

4107

else

4480

else

4108

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4481

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4109

L0=half_UI-INT;

4482

L0=half_UI-INT;

4110

end

4483

end

4111

%Right eye Width (Top Eye)

4484

%Right eye Width (Top Eye)

4112

right_top=eye_contour(half_UI:end,1);

4485

right_top=eye_contour(half_UI:end,1);

4113

vref_crossing=find(right_top<vref,1,'first');

4486

vref_crossing=find(right_top<vref,1,'first');

4114

if isempty(vref_crossing)

4487

if isempty(vref_crossing)

4115

R1=samples_per_UI-half_UI;

4488

R1=samples_per_UI-half_UI;

4116

elseif vref_crossing==1

4489

elseif vref_crossing==1

4117

R1=0;

4490

R1=0;

4118

else

4491

else

4119

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4492

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4120

R1=INT-half_UI;

4493

R1=INT-half_UI;

4121

end

4494

end

4122

%Right eye Width (Bottom Eye)

4495

%Right eye Width (Bottom Eye)

4123

right_bot=eye_contour(half_UI:end,2);

4496

right_bot=eye_contour(half_UI:end,2);

4124

vref_crossing=find(right_bot>vref,1,'first');

4497

vref_crossing=find(right_bot>vref,1,'first');

4125

if isempty(vref_crossing)

4498

if isempty(vref_crossing)

4126

R0=samples_per_UI-half_UI;

4499

R0=samples_per_UI-half_UI;

4127

elseif vref_crossing==1

4500

elseif vref_crossing==1

4128

R0=0;

4501

R0=0;

4129

else

4502

else

4130

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4503

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4131

R0=INT-half_UI;

4504

R0=INT-half_UI;

4132

end

4505

end

4133

4506

4134

%L1 = top left eye width

4507

%L1 = top left eye width

4135

%L0 = bottom left eye width

4508

%L0 = bottom left eye width

4136

%Left eye width is the minimum

4509

%Left eye width is the minimum

4137

%R1 = top right eye width

4510

%R1 = top right eye width

4138

%R0 = bottom right eye width

4511

%R0 = bottom right eye width

4139

%Right eye width is the minimum

4512

%Right eye width is the minimum

4140

Left_EW=min([L1 L0]);

4513

Left_EW=min([L1 L0]);

4141

Right_EW=min([R1 R0]);

4514

Right_EW=min([R1 R0]);

4142

4515

4143

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4516

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4144

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4517

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4145

% find the location of the DFE bank

4518

% find the location of the DFE bank

4146

% hisi: waveform with cursor values;

4519

% hisi: waveform with cursor values;

4147

% idx_st: starting index;

4520

% idx_st: starting index;

4148

% idx_en: ending index ;

4521

% idx_en: ending index ;

4149

% tap_bk: number of taps per bank;

4522

% tap_bk: number of taps per bank;

4150

% bmaxg: maximum coefficient;

4523

% bmaxg: maximum coefficient;

4151

4524

4152

hisi=hisi(:);

4525

hisi=hisi(:);

4153

len=idx_en-idx_st+1;

4526

len=idx_en-idx_st+1;

4154

h0=abs(hisi(idx_st:idx_en));

4527

h0=abs(hisi(idx_st:idx_en));

4155

h1=max(0,h0-bmaxg*curval);

4528

h1=max(0,h0-bmaxg*curval);

4156

4529

4157

%if cursor value is negative, force h1 to all zeros

4530

%if cursor value is negative, force h1 to all zeros

4158

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4531

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4159

%this makes the weakest isi the most desirable to choose so everything breaks

4532

%this makes the weakest isi the most desirable to choose so everything breaks

4160

if curval<0

4533

if curval<0

4161

h1=zeros(size(h0));

4534

h1=zeros(size(h0));

4162

end

4535

end

4163

4536

4164

h0n=zeros(len-tap_bk+1,1);

4537

h0n=zeros(len-tap_bk+1,1);

4165

h1n=h0n;

4538

h1n=h0n;

4166

4539

4167

for ii=1:tap_bk

4540

for ii=1:tap_bk

4168

h0tmp=h0(ii:ii+len-tap_bk);

4541

h0tmp=h0(ii:ii+len-tap_bk);

4169

h0n=h0n+h0tmp.^2;

4542

h0n=h0n+h0tmp.^2;

4170

h1tmp=h1(ii:ii+len-tap_bk);

4543

h1tmp=h1(ii:ii+len-tap_bk);

4171

h1n=h1n+h1tmp.^2;

4544

h1n=h1n+h1tmp.^2;

4172

end

4545

end

4173

4546

4174

ndiff=h0n-h1n;

4547

ndiff=h0n-h1n;

4175

4548

4176

min_energy = -Inf;

4549

min_energy = -Inf;

4177

4550

4178

idx=zeros(1,tap_bk*N_bg);

4551

idx=zeros(1,tap_bk*N_bg);

4179

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4552

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4180

set_next_bank=0;

4553

set_next_bank=0;

4181

%Loop through each group

4554

%Loop through each group

4182

for k=1:N_bg

4555

for k=1:N_bg

4183

%Sort to choose the strongest

4556

%Sort to choose the strongest

4184

[~,val_sort]=sort(ndiff,'descend');

4557

[~,val_sort]=sort(ndiff,'descend');

4185

if k==1

4558

if k==1

4186

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4559

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4187

if isequal(sort(val_sort(ordered_set)),ordered_set)

4560

if isequal(sort(val_sort(ordered_set)),ordered_set)

4188

idx=1:N_bg*tap_bk;

4561

idx=1:N_bg*tap_bk;

4189

break;

4562

break;

4190

end

4563

end

4191

end

4564

end

4192

if set_next_bank>0

4565

if set_next_bank>0

4193

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4566

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4194

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4567

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4195

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4568

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4196

set_next_bank=0;

4569

set_next_bank=0;

4197

ndiff(new_bank)=min_energy;

4570

ndiff(new_bank)=min_energy;

4198

bad_start=new_bank(1)-tap_bk+1;

4571

bad_start=new_bank(1)-tap_bk+1;

4199

bad_end=new_bank(1)-1;

4572

bad_end=new_bank(1)-1;

4200

if bad_end<=0

4573

if bad_end<=0

4201

badV=[];

4574

badV=[];

4202

elseif bad_start>0

4575

elseif bad_start>0

4203

badV=bad_start:bad_end;

4576

badV=bad_start:bad_end;

4204

else

4577

else

4205

badV=1:bad_end;

4578

badV=1:bad_end;

4206

end

4579

end

4207

if ~isempty(badV)

4580

if ~isempty(badV)

4208

ndiff(badV)=min_energy;

4581

ndiff(badV)=min_energy;

4209

end

4582

end

4210

continue;

4583

continue;

4211

end

4584

end

4212

%potential bank = the strongest tap group

4585

%potential bank = the strongest tap group

4213

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4586

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4214

if k==N_bg

4587

if k==N_bg

4215

%Last group: just choose the strongest

4588

%Last group: just choose the strongest

4216

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4589

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4217

break;

4590

break;

4218

end

4591

end

4219

4592

4220

do_it_again=1;

4593

do_it_again=1;

4221

first_time=1;

4594

first_time=1;

4222

num_loops=0;

4595

num_loops=0;

4223

while do_it_again

4596

while do_it_again

4224

do_it_again=0;

4597

do_it_again=0;

4225

if num_loops>length(ndiff)

4598

if num_loops>length(ndiff)

4226

break;

4599

break;

4227

end

4600

end

4228

%note badV: taps smaller and less than 1 group away

4601

%note badV: taps smaller and less than 1 group away

4229

bad_start=new_bank(1)-tap_bk+1;

4602

bad_start=new_bank(1)-tap_bk+1;

4230

bad_end=new_bank(1)-1;

4603

bad_end=new_bank(1)-1;

4231

if bad_end<=0

4604

if bad_end<=0

4232

badV=[];

4605

badV=[];

4233

elseif bad_start>0

4606

elseif bad_start>0

4234

badV=bad_start:bad_end;

4607

badV=bad_start:bad_end;

4235

else

4608

else

4236

badV=1:bad_end;

4609

badV=1:bad_end;

4237

end

4610

end

4238

for j=length(badV):-1:1

4611

for j=length(badV):-1:1

4239

if any(badV(j)-idx==0)

4612

if any(badV(j)-idx==0)

4240

badV(j)=[];

4613

badV(j)=[];

4241

end

4614

end

4242

end

4615

end

4243

%note goodV: the tap exactly 1 tap_bk smaller

4616

%note goodV: the tap exactly 1 tap_bk smaller

4244

goodV=new_bank(1)-tap_bk;

4617

goodV=new_bank(1)-tap_bk;

4245

if ~isempty(badV)

4618

if ~isempty(badV)

4246

if ~first_time

4619

if ~first_time

4247

[~,val_sort]=sort(ndiff,'descend');

4620

[~,val_sort]=sort(ndiff,'descend');

4248

end

4621

end

4249

first_time=0;

4622

first_time=0;

4250

checkV=[badV new_bank];

4623

checkV=[badV new_bank];

4251

4624

4252

badV_pos=zeros(1,length(badV));

4625

badV_pos=zeros(1,length(badV));

4253

for j=1:length(badV)

4626

for j=1:length(badV)

4254

badV_pos(j)=find(badV(j)==val_sort);

4627

badV_pos(j)=find(badV(j)==val_sort);

4255

end

4628

end

4256

4629

4257

%loop through the sorted list to find the first tap outside the group and not a member of badV

4630

%loop through the sorted list to find the first tap outside the group and not a member of badV

4258

found_goodV=0;

4631

found_goodV=0;

4259

for ii=1:length(val_sort)

4632

for ii=1:length(val_sort)

4260

if val_sort(ii)==goodV

4633

if val_sort(ii)==goodV

4261

found_goodV=1;

4634

found_goodV=1;

4262

break;

4635

break;

4263

end

4636

end

4264

if all(val_sort(ii)-checkV~=0)

4637

if all(val_sort(ii)-checkV~=0)

4265

break;

4638

break;

4266

end

4639

end

4267

end

4640

end

4268

4641

4269

if ~found_goodV && min(badV_pos)<ii

4642

if ~found_goodV && min(badV_pos)<ii

4270

%if goodV wasn't found and bad taps occur before non group members are found

4643

%if goodV wasn't found and bad taps occur before non group members are found

4271

%throw out the strongest tap and take the next strongest

4644

%throw out the strongest tap and take the next strongest

4272

do_it_again=1;

4645

do_it_again=1;

4273

ndiff(new_bank(1))=min_energy;

4646

ndiff(new_bank(1))=min_energy;

4274

%speed up: new max_val is always val_sort(2)

4647

%speed up: new max_val is always val_sort(2)

4275

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4648

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4276

end

4649

end

4277

if found_goodV

4650

if found_goodV

4278

%if goodV was found, set the next bank to goodV

4651

%if goodV was found, set the next bank to goodV

4279

set_next_bank=goodV;

4652

set_next_bank=goodV;

4280

end

4653

end

4281

end

4654

end

4282

num_loops=num_loops+1;

4655

num_loops=num_loops+1;

4283

end

4656

end

4284

%at the end, the floating taps are set to idx

4657

%at the end, the floating taps are set to idx

4285

%and ndiff has illegal values set to zero

4658

%and ndiff has illegal values set to zero

4286

ndiff(new_bank)=min_energy;

4659

ndiff(new_bank)=min_energy;

4287

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4660

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4288

if ~isempty(badV)

4661

if ~isempty(badV)

4289

ndiff(badV)=min_energy;

4662

ndiff(badV)=min_energy;

4290

end

4663

end

4291

end

4664

end

4292

4665

4293

4666

4294

idx=idx+idx_st-1;

4667

idx=idx+idx_st-1;

4295

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4668

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4296

4669

4297

% hisi = postcursor isi

4670

% hisi = postcursor isi

4298

% N_b = number of fixed dfe taps (before floating taps begin)

4671

% N_b = number of fixed dfe taps (before floating taps begin)

4299

% N_bf = number of floating taps per group

4672

% N_bf = number of floating taps per group

4300

% N_bg = nubmber of groups

4673

% N_bg = nubmber of groups

4301

% N_bmax = max tap number that can be used for floating tap

4674

% N_bmax = max tap number that can be used for floating tap

4302

% bmaxg = max tap strength for floating taps

4675

% bmaxg = max tap strength for floating taps

4303

% curval = value of the cursor

4676

% curval = value of the cursor

4304

4677

4305

4678

4306

if nargin<8, dfe_delta=0;end

4679

if nargin<8, dfe_delta=0;end

4307

4680

4308

4681

4309

tap_coef=zeros(1,length(hisi));

4682

tap_coef=zeros(1,length(hisi));

4310

b=zeros(1,length(hisi));

4683

b=zeros(1,length(hisi));

4311

4684

4312

4685

4313

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4686

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4314

4687

4315

%Apply DFE to all taps

4688

%Apply DFE to all taps

4316

flt_curval=hisi(tap_loc);

4689

flt_curval=hisi(tap_loc);

4317

if dfe_delta~=0

4690

if dfe_delta~=0

4318

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4691

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4319

dfe_delta.*sign(flt_curval)*curval;

4692

dfe_delta.*sign(flt_curval)*curval;

4320

else

4693

else

4321

flt_curval_q=hisi(tap_loc);

4694

flt_curval_q=hisi(tap_loc);

4322

end

4695

end

4323

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4696

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4324

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4697

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4325

tap_coef(tap_loc)=applied_coef;

4698

tap_coef(tap_loc)=applied_coef;

4326

4699

4327

4700

4328

4701

4329

tap_loc=sort(tap_loc,'ascend');

4702

tap_loc=sort(tap_loc,'ascend');

4330

b(tap_loc)=bmaxg;

4703

b(tap_loc)=bmaxg;

4331

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4704

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4332

% Richard Mellitz: 04/23/2019

4705

% Richard Mellitz: 04/23/2019

4333

% hisi is the isi 1 ui/sample

4706

% hisi is the isi 1 ui/sample

4334

% N_b number of fixed dfe taps

4707

% N_b number of fixed dfe taps

4335

% N_bf number of floating taps per group

4708

% N_bf number of floating taps per group

4336

% N_bg number of floating tap groups. 1 2 or 3 right now

4709

% N_bg number of floating tap groups. 1 2 or 3 right now

4337

% N_bmax number of ui for the max reach of the floating taps

4710

% N_bmax number of ui for the max reach of the floating taps

4338

% bmaxg limit for the floating taps

4711

% bmaxg limit for the floating taps

4339

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4712

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4340

%

4713

%

4341

%

4714

%

4342

% function to remove isi or add noise above bmaxg

4715

% function to remove isi or add noise above bmaxg

4343

if ~exist('COOP','var'), COOP=0;end

4716

if ~exist('COOP','var'), COOP=0;end

4344

if iscolumn(hisi); hisi=hisi.';end

4717

if iscolumn(hisi); hisi=hisi.';end

4345

hsis_in=hisi;

4718

hsis_in=hisi;

4346

% find all the reduction group taken N_bf at a time

4719

% find all the reduction group taken N_bf at a time

4347

% we are looking for the group when when remove yield the miminim isi, h, power

4720

% we are looking for the group when when remove yield the miminim isi, h, power

4348

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4721

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4349

% add on switch and loop for each potential group

4722

% add on switch and loop for each potential group

4350

switch N_bg

4723

switch N_bg

4351

case 0

4724

case 0

4352

bmax=0;

4725

bmax=0;

4353

return

4726

return

4354

case 1

4727

case 1

4355

end1=N_bmax-N_bf;

4728

end1=N_bmax-N_bf;

4356

end2=N_b+1;

4729

end2=N_b+1;

4357

end3=N_b+1;

4730

end3=N_b+1;

4358

case 2

4731

case 2

4359

end1=N_bmax-N_bf;

4732

end1=N_bmax-N_bf;

4360

end2=N_bmax-N_bf;

4733

end2=N_bmax-N_bf;

4361

end3=N_b+1;

4734

end3=N_b+1;

4362

case 3

4735

case 3

4363

end1=N_bmax-N_bf;

4736

end1=N_bmax-N_bf;

4364

end2=N_bmax-N_bf;

4737

end2=N_bmax-N_bf;

4365

end3=N_bmax-N_bf;

4738

end3=N_bmax-N_bf;

4366

end

4739

end

4367

if COOP

4740

if COOP

4368

for ig1= N_b+1:end1 % now remove the 2nd group

4741

for ig1= N_b+1:end1 % now remove the 2nd group

4369

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4742

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4370

% loop for 2rd group

4743

% loop for 2rd group

4371

for ig2= N_b+1: end2

4744

for ig2= N_b+1: end2

4372

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4745

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4373

if N_bg < 2; hcap2 =hcap; end

4746

if N_bg < 2; hcap2 =hcap; end

4374

for ig3= N_b+1: end3

4747

for ig3= N_b+1: end3

4375

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4748

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4376

if N_bg < 3 ; hcap3=hcap2 ; end

4749

if N_bg < 3 ; hcap3=hcap2 ; end

4377

sigma=norm( hcap3 );

4750

sigma=norm( hcap3 );

4378

if sigma < best_sigma

4751

if sigma < best_sigma

4379

best_sigma=sigma;

4752

best_sigma=sigma;

4380

best_ig1=ig1;

4753

best_ig1=ig1;

4381

best_ig2=ig2;

4754

best_ig2=ig2;

4382

best_ig3=ig3;

4755

best_ig3=ig3;

4383

best_hcap=hcap3;

4756

best_hcap=hcap3;

4384

end

4757

end

4385

end

4758

end

4386

end

4759

end

4387

end

4760

end

4388

else % sequentail

4761

else % sequentail

4389

for ig1= N_b+1:end1 % now remove the 1st group

4762

for ig1= N_b+1:end1 % now remove the 1st group

4390

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4763

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4391

sigma=norm( hcap );

4764

sigma=norm( hcap );

4392

if sigma < best_sigma

4765

if sigma < best_sigma

4393

best_sigma=sigma;

4766

best_sigma=sigma;

4394

best_ig1=ig1;

4767

best_ig1=ig1;

4395

best_hcap=hcap;

4768

best_hcap=hcap;

4396

end

4769

end

4397

end

4770

end

4398

% loop for 2rd group

4771

% loop for 2rd group

4399

hisi=best_hcap;

4772

hisi=best_hcap;

4400

for ig2= N_b+1: end2

4773

for ig2= N_b+1: end2

4401

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4774

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4402

sigma=norm( hcap );

4775

sigma=norm( hcap );

4403

if sigma < best_sigma

4776

if sigma < best_sigma

4404

best_sigma=sigma;

4777

best_sigma=sigma;

4405

best_ig2=ig2;

4778

best_ig2=ig2;

4406

best_hcap=hcap;

4779

best_hcap=hcap;

4407

end

4780

end

4408

end

4781

end

4409

hisi=best_hcap;

4782

hisi=best_hcap;

4410

% loop for 3rd group

4783

% loop for 3rd group

4411

for ig3= N_b+1: end3

4784

for ig3= N_b+1: end3

4412

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4785

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4413

sigma=norm( hcap );

4786

sigma=norm( hcap );

4414

if sigma < best_sigma

4787

if sigma < best_sigma

4415

best_sigma=sigma;

4788

best_sigma=sigma;

4416

best_ig3=ig3;

4789

best_ig3=ig3;

4417

best_hcap=hcap;

4790

best_hcap=hcap;

4418

end

4791

end

4419

end

4792

end

4420

4793

4421

end

4794

end

4422

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4795

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4423

switch N_bg

4796

switch N_bg

4424

case 1

4797

case 1

4425

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4798

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4426

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4799

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4427

case 2

4800

case 2

4428

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4801

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4429

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4802

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4430

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4803

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4431

case 3

4804

case 3

4432

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4805

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4433

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4806

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4434

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4807

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4435

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4808

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4436

end

4809

end

4437

floating_tap_locations=sort(floating_tap_locations);

4810

floating_tap_locations=sort(floating_tap_locations);

4438

if 0 % for code debug

4811

if 0 % for code debug

4439

close force all

4812

close force all

4440

stem(best_hcap,'disp','hcap')

4813

stem(best_hcap,'disp','hcap')

4441

hold on

4814

hold on

4442

stem(bmax,'-k','disp','bmax')

4815

stem(bmax,'-k','disp','bmax')

4443

stem(hisi,'disp','hisi')

4816

stem(hisi,'disp','hisi')

4444

hold off

4817

hold off

4445

end

4818

end

4446

4819

4447

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4820

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4448

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4821

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4449

% Vfilter is vector forced filtered sbr

4822

% Vfilter is vector forced filtered sbr

4450

% Cmod is the ffe tap co-efficient vector

4823

% Cmod is the ffe tap co-efficient vector

4451

% if C is passed, just process V with C else compute C

4824

% if C is passed, just process V with C else compute C

4452

% cmx=param.rx_cmx; number of pre cursor taps

4825

% cmx=param.rx_cmx; number of pre cursor taps

4453

% cpx=param.rx_cps; number of post cursor taps

4826

% cpx=param.rx_cps; number of post cursor taps

4454

% V=sbr; pass pulse response

4827

% V=sbr; pass pulse response

4455

% ix the sample point in the passed pulse response

4828

% ix the sample point in the passed pulse response

4456

% the sample point is recomputed by optimize_fom

4829

% the sample point is recomputed by optimize_fom

4457

% idx - return floating tap location (RIM 9-19-2023)

4830

% idx - return floating tap location (RIM 9-19-2023)

4458

% OP not used for now

4831

% OP not used for now

4459

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4832

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4460

% this allows significant speed up in optimize_fom since FFE is time consuming

4833

% this allows significant speed up in optimize_fom since FFE is time consuming

4461

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4834

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4462

% Vfiltered to be calculated

4835

% Vfiltered to be calculated

4463

% test with load('SBR_FIR_resp.mydata','-mat')

4836

% test with load('SBR_FIR_resp.mydata','-mat')

4464

idx=[];

4837

idx=[];

4465

if nargin<4

4838

if nargin<4

4466

ix=find(V==max(V),1,'first');

4839

ix=find(V==max(V),1,'first');

4467

end

4840

end

4468

if nargin<5

4841

if nargin<5

4469

C=[];

4842

C=[];

4470

end

4843

end

4471

if nargin<6

4844

if nargin<6

4472

return_V=1;

4845

return_V=1;

4473

end

4846

end

4474

cmx=param.RxFFE_cmx;

4847

cmx=param.RxFFE_cmx;

4475

cpx=param.RxFFE_cpx;

4848

cpx=param.RxFFE_cpx;

4476

% do this early on so we can reuse the old code

4849

% do this early on so we can reuse the old code

4477

if param.N_bg ~=0 % must be floating taps

4850

if param.N_bg ~=0 % must be floating taps

4478

cpx=param.N_bmax; % N_f in spreadsheet

4851

cpx=param.N_bmax; % N_f in spreadsheet

4479

end

4852

end

4480

num_taps=cmx+cpx+1;

4853

num_taps=cmx+cpx+1;

4481

cstep=param.RxFFE_stepz;

4854

cstep=param.RxFFE_stepz;

4482

ndfe=param.ndfe;

4855

ndfe=param.ndfe;

4483

spui=param.samples_per_ui;

4856

spui=param.samples_per_ui;

4484

param.current_ffegain=0;

4857

param.current_ffegain=0;

4485

if return_V && ~isempty(C)

4858

if return_V && ~isempty(C)

4486

% RIM 2-3-23 when we just want to EQ not find EQ

4859

% RIM 2-3-23 when we just want to EQ not find EQ

4487

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4860

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4488

Cmod=C;

4861

Cmod=C;

4489

return

4862

return

4490

end

4863

end

4491

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4864

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4492

if ix < length(V)

4865

if ix < length(V)

4493

if isrow(V)

4866

if isrow(V)

4494

if mod(ix,spui) == 0

4867

if mod(ix,spui) == 0

4495

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4868

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4496

else

4869

else

4497

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4870

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4498

end

4871

end

4499

4872

4500

else

4873

else

4501

if mod(ix,spui) == 0

4874

if mod(ix,spui) == 0

4502

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4875

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4503

else

4876

else

4504

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4877

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4505

end

4878

end

4506

end

4879

end

4507

else

4880

else

4508

if isrow(V)

4881

if isrow(V)

4509

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4882

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4510

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4883

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4511

else

4884

else

4512

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4885

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4513

end

4886

end

4514

else

4887

else

4515

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4888

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4516

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4889

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4517

else

4890

else

4518

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4891

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4519

end

4892

end

4520

end

4893

end

4521

end

4894

end

4522

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4895

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4523

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4896

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4524

4897

4525

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4898

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4526

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4899

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4527

% Upen Kareti suggested fix for indexing 11/04/18

4900

% Upen Kareti suggested fix for indexing 11/04/18

4528

if ix < length(V)

4901

if ix < length(V)

4529

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4902

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4530

else

4903

else

4531

ivs=find(vsampled == max(vsampled),1,'first');

4904

ivs=find(vsampled == max(vsampled),1,'first');

4532

end

4905

end

4533

4906

4534

4907

4535

%% create VV matrix of shifted UI spaced sample of the pulse response

4908

%% create VV matrix of shifted UI spaced sample of the pulse response

4536

% only consider the VV matrix that correstonds to the FFE taps

4909

% only consider the VV matrix that correstonds to the FFE taps

4537

VV=zeros(num_taps,num_taps);

4910

VV=zeros(num_taps,num_taps);

4538

for i=1:num_taps

4911

for i=1:num_taps

4539

start_idx=ivs+i-1;

4912

start_idx=ivs+i-1;

4540

end_idx=start_idx-num_taps+1;

4913

end_idx=start_idx-num_taps+1;

4541

VV(:,i)=vsampled(start_idx:-1:end_idx);

4914

VV(:,i)=vsampled(start_idx:-1:end_idx);

4542

end

4915

end

4543

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4916

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4544

%% Apply RXFFE

4917

%% Apply RXFFE

4545

if isempty(C)

4918

if isempty(C)

4546

switch upper(OP.FFE_OPT_METHOD)

4919

switch upper(OP.FFE_OPT_METHOD)

4547

case 'WIENER-HOPF'

4920

case 'WIENER-HOPF'

4548

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4921

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4549

Cmod=C(1:num_taps);

4922

Cmod=C(1:num_taps);

4550

otherwise

4923

otherwise

4551

% cmx+1 is the cursor or sample point

4924

% cmx+1 is the cursor or sample point

4552

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4925

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4553

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4926

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4554

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4927

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4555

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4928

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4556

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4929

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4557

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4930

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4558

end

4931

end

4559

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4932

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4560

if diff(size(VV))==0

4933

if diff(size(VV))==0

4561

%For square matrix, can solve C using simple inv(VV')*FV'

4934

%For square matrix, can solve C using simple inv(VV')*FV'

4562

C=VV'\FV';

4935

C=VV'\FV';

4563

else

4936

else

4564

%otherwise use the general solution with psuedo inverse

4937

%otherwise use the general solution with psuedo inverse

4565

%note: this is the same as doing pinv(VV') but pinv is far slower

4938

%note: this is the same as doing pinv(VV') but pinv is far slower

4566

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4939

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4567

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4940

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4568

end

4941

end

4569

4942

4570

Cmod=C(1:num_taps);

4943

Cmod=C(1:num_taps);

4571

end

4944

end

4572

4945

4573

4946

4574

% added for 4.2 find floating taps with either ISI or taps

4947

% added for 4.2 find floating taps with either ISI or taps

4575

switch lower(OP.RXFFE_FLOAT_CTL)

4948

switch lower(OP.RXFFE_FLOAT_CTL)

4576

case 'taps'

4949

case 'taps'

4577

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4950

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4578

otherwise

4951

otherwise

4579

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4952

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4580

end

4953

end

4581

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4954

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4582

case 'unity cursor'

4955

case 'unity cursor'

4583

Cmod=Cmod/Cmod(cmx+1);

4956

Cmod=Cmod/Cmod(cmx+1);

4584

otherwise

4957

otherwise

4585

Cmod=C;

4958

Cmod=C;

4586

end

4959

end

4587

if cstep ~= 0

4960

if cstep ~= 0

4588

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4961

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4589

end

4962

end

4590

4963

4591

if ~isempty(idx)

4964

if ~isempty(idx)

4592

idx=sort(idx);

4965

idx=sort(idx);

4593

C1=Cmod;

4966

C1=Cmod;

4594

% C1(param.N_tail_start:end)=0;

4967

% C1(param.N_tail_start:end)=0;

4595

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4968

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4596

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4969

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4597

Cmod=C1;

4970

Cmod=C1;

4598

else

4971

else

4599

% Cmod=C;

4972

% Cmod=C;

4600

end

4973

end

4601

4974

4602

% now when ussing RxFFE floating taps need to tag stems correctly and

4975

% now when ussing RxFFE floating taps need to tag stems correctly and

4603

% make sure DFEfloating tap code does not get exectuted

4976

% make sure DFEfloating tap code does not get exectuted

4604

4977

4605

%

4978

%

4606

else

4979

else

4607

Cmod=C;%just us the FFE taps, C, passed for filtering

4980

Cmod=C;%just us the FFE taps, C, passed for filtering

4608

end

4981

end

4609

%%

4982

%%

4610

%% filter the pulse response with the solved FFE

4983

%% filter the pulse response with the solved FFE

4611

% (now option to avoid this and just return Cmod for speed up)

4984

% (now option to avoid this and just return Cmod for speed up)

4612

if return_V

4985

if return_V

4613

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4986

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4614

else

4987

else

4615

Vfiltered=[];

4988

Vfiltered=[];

4616

end

4989

end

4617

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4990

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4618

% used for FD IL fitting

4991

% used for FD IL fitting

4619

% sdd21 us a complex insertion loss

4992

% sdd21 us a complex insertion loss

4620

db = @(x) 20*log10(abs(x));

4993

db = @(x) 20*log10(abs(x));

4621

sdd21=squeeze(sdd21);

4994

sdd21=squeeze(sdd21);

4622

if iscolumn(sdd21)

4995

if iscolumn(sdd21)

4623

sdd21=sdd21.';

4996

sdd21=sdd21.';

4624

end

4997

end

4625

fmbg=[ones(length(faxis_f2),1).*transpose(abs(sdd21)) transpose(sqrt(faxis_f2)).*transpose(abs(sdd21)) transpose(faxis_f2).*transpose(abs(sdd21)) transpose(faxis_f2.^2).*transpose(abs(sdd21)) ];

4998

fmbg=[ones(length(faxis_f2),1).*transpose(abs(sdd21)) transpose(sqrt(faxis_f2)).*transpose(abs(sdd21)) transpose(faxis_f2).*transpose(abs(sdd21)) transpose(faxis_f2.^2).*transpose(abs(sdd21)) ];

4626

warning('off','MATLAB:nearlySingularMatrix');

4999

warning('off','MATLAB:nearlySingularMatrix');

4627

LGw=transpose(abs(sdd21).*db(sdd21));

5000

LGw=transpose(abs(sdd21).*db(sdd21));

4628

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5001

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4629

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5002

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4630

ILN = db(sdd21)-efit;

5003

ILN = db(sdd21)-efit;

4631

5004

4632

5005

4633

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

5006

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4634

% Complex IL fitting

5007

% Complex IL fitting

4635

% sdd21 us a complex insertion loss

5008

% sdd21 us a complex insertion loss

4636

% efit and ILN are in db

5009

% efit and ILN are in db

4637

% faxix_f2 needs to be at least to fb

5010

% faxix_f2 needs to be at least to fb

4638

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

5011

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

4639

% still need to settle on voltage scaling.

5012

% still need to settle on voltage scaling.

4640

% maybe db(peak/Rss

5013

% maybe db(peak/Rss

4641

5014

4642

OP.interp_sparam_mag= 'trend_to_DC';

5015

OP.interp_sparam_mag= 'trend_to_DC';

4643

OP.interp_sparam_phase= 'interp_to_DC';

5016

OP.interp_sparam_phase= 'interp_to_DC';

4644

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5017

% OP.interp_sparam_mag= 'linear_trend_to_DC';

4645

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5018

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

4646

5019

4647

print_for_codereview=0;

5020

print_for_codereview=0;

4648

if ~exist('A_T','var')

5021

if ~exist('A_T','var')

4649

A_T=1;

5022

A_T=1;

4650

end

5023

end

4651

5024

4652

db = @(x) 20*log10(abs(x));

5025

db = @(x) 20*log10(abs(x));

4653

sdd21=squeeze(sdd21);

5026

sdd21=squeeze(sdd21);

4654

if iscolumn(sdd21)

5027

if iscolumn(sdd21)

4655

sdd21=sdd21.';

5028

sdd21=sdd21.';

4656

end

5029

end

4657

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5030

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

4658

warning('off','MATLAB:nearlySingularMatrix');

5031

warning('off','MATLAB:nearlySingularMatrix');

4659

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5032

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

4660

LGw=transpose(sdd21.*unwraplog);

5033

LGw=transpose(sdd21.*unwraplog);

4661

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5034

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4662

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5035

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4663

FIT=transpose(exp(transpose(efit_C)));

5036

FIT=transpose(exp(transpose(efit_C)));

4664

efit=db(abs(FIT));

5037

efit=db(abs(FIT));

4665

ILN = db(sdd21)-efit;

5038

ILN = db(sdd21)-efit;

4666

% time domain

5039

% time domain

4667

fprintf('computing TD_ILN (dB) ...')

5040

fprintf('computing TD_ILN (dB) ...')

4668

if exist('OP','var')

5041

if exist('OP','var')

4669

% OP.fraction_of_F_range_start_extrap_from=.95;

5042

% OP.fraction_of_F_range_start_extrap_from=.95;

4670

OP.impulse_response_truncation_threshold =1e-7;

5043

OP.impulse_response_truncation_threshold =1e-7;

4671

5044

4672

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5045

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

4673

H_bw=Butterworth_Filter(param,faxis_f2,1);

5046

H_bw=Butterworth_Filter(param,faxis_f2,1);

4674

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5047

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

4675

H_tw=Tukey_Window(faxis_f2,param);

5048

H_tw=Tukey_Window(faxis_f2,param);

4676

H_tw=ones(1,length(faxis_f2) );

5049

H_tw=ones(1,length(faxis_f2) );

4677

5050

4678

[TD_ILN.REF.FIR, ...

5051

[TD_ILN.REF.FIR, ...

4679

TD_ILN.REF.t, ...

5052

TD_ILN.REF.t, ...

4680

TD_ILN.REF.causality_correction_dB, ...

5053

TD_ILN.REF.causality_correction_dB, ...

4681

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5054

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4682

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

5055

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

4683

5056

4684

[TD_ILN.FIT.FIR, ...

5057

[TD_ILN.FIT.FIR, ...

4685

TD_ILN.FIT.t, ...

5058

TD_ILN.FIT.t, ...

4686

TD_ILN.FIT.causality_correction_dB, ...

5059

TD_ILN.FIT.causality_correction_dB, ...

4687

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5060

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4688

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

5061

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

4689

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

5062

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

4690

% NrangeUI=1000;

5063

% NrangeUI=1000;

4691

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(TD_ILN.FIT.PR)-param.samples_per_ui ),length(TD_ILN.REF.PR)-param.samples_per_ui);

5064

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(TD_ILN.FIT.PR)-param.samples_per_ui ),length(TD_ILN.REF.PR)-param.samples_per_ui);

4692

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

5065

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

4693

range=ipeak:range_end;

5066

range=ipeak:range_end;

4694

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

5067

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

4695

TD_ILN.t=TD_ILN.FIT.t(range);

5068

TD_ILN.t=TD_ILN.FIT.t(range);

4696

TD_ILN.FOM=-inf;

5069

TD_ILN.FOM=-inf;

4697

TD_ILN.FOM_PDF=-inf;

5070

TD_ILN.FOM_PDF=-inf;

4698

rms_fom=-inf;

5071

rms_fom=-inf;

4699

for im=1:param.samples_per_ui

5072

for im=1:param.samples_per_ui

4700

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

5073

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

4701

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5074

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

4702

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5075

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

4703

cdf=pdf; cdf.y=cumsum(pdf.y);

5076

cdf=pdf; cdf.y=cumsum(pdf.y);

4704

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5077

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

4705

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5078

% signal_and_isi_pdf = conv_fct(cursors, pdf);

4706

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5079

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

4707

if print_for_codereview % remove once all checked out

5080

if print_for_codereview % remove once all checked out

4708

h=figure(190);set(gcf,'Tag','COM');

5081

h=figure(190);set(gcf,'Tag','COM');

4709

semilogy(-cdf.x,cdf.y);

5082

semilogy(-cdf.x,cdf.y);

4710

% xlim ([0,-cdf.x(1)])

5083

% xlim ([0,-cdf.x(1)])

4711

ylim([param.specBER 1]);title ('CDF of ILN')

5084

ylim([param.specBER 1]);title ('CDF of ILN')

4712

hold on

5085

hold on

4713

end

5086

end

4714

if rms>rms_fom

5087

if rms>rms_fom

4715

rms_fom=rms;

5088

rms_fom=rms;

4716

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5089

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

4717

TD_ILN.PDF=pdf;

5090

TD_ILN.PDF=pdf;

4718

end

5091

end

4719

end

5092

end

4720

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

5093

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

4721

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

5094

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

4722

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

5095

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

4723

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

5096

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

4724

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

5097

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

4725

if print_for_codereview % remove once all checked out

5098

if print_for_codereview % remove once all checked out

4726

figure(9000);set(gcf,'Tag','COM');

5099

figure(9000);set(gcf,'Tag','COM');

4727

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

5100

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

4728

hold on

5101

hold on

4729

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

5102

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

4730

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

5103

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

4731

hold off

5104

hold off

4732

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',TD_ILN.SNR_ISI_FOM,TD_ILN.SNR_ISI_FOM_PDF)

5105

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',TD_ILN.SNR_ISI_FOM,TD_ILN.SNR_ISI_FOM_PDF)

4733

figure(9002);set(gcf,'Tag','COM');

5106

figure(9002);set(gcf,'Tag','COM');

4734

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

5107

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

4735

hold on

5108

hold on

4736

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5109

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

4737

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5110

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

4738

grid on

5111

grid on

4739

legend('show')

5112

legend('show')

4740

end

5113

end

4741

end

5114

end

4742

% display('got to end of get_ILN_cmp_td')

5115

% display('got to end of get_ILN_cmp_td')

4743

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

5116

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

4744

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

5117

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

4745

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

5118

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

4746

if 1 % force indent for doc

5119

if 1 % force indent for doc

4747

num_ui=param.num_ui_RXFF_noise;

5120

num_ui=param.num_ui_RXFF_noise;

4748

M=param.samples_per_ui;

5121

M=param.samples_per_ui;

4749

L=param.levels;

5122

L=param.levels;

4750

f_b=param.fb;

5123

f_b=param.fb;

4751

SNR_TX=param.SNR_TX;

5124

SNR_TX=param.SNR_TX;

4752

dw=param.RxFFE_cmx;

5125

dw=param.RxFFE_cmx;

4753

bmax=param.bmax;

5126

bmax=param.bmax;

4754

bmin=param.bmin ;

5127

bmin=param.bmin ;

4755

Nb=param.ndfe;

5128

Nb=param.ndfe;

4756

sigma_X2=(L^2-1)/(3*(L-1)^2);

5129

sigma_X2=(L^2-1)/(3*(L-1)^2);

4757

eta_0=param.eta_0; %V^2/GHz

5130

eta_0=param.eta_0; %V^2/GHz

4758

T_b=1/f_b;

5131

T_b=1/f_b;

4759

delta_f = f_b/num_ui; % Units are Hz.

5132

delta_f = f_b/num_ui; % Units are Hz.

4760

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

5133

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

4761

result.fvec=fvec;

5134

result.fvec=fvec;

4762

end

5135

end

4763

if OP.COMPUTE_COM

5136

if OP.COMPUTE_COM

4764

%% H_rxffe eq 178A-28 d1.0

5137

%% H_rxffe eq 178A-28 d1.0

4765

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

5138

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

4766

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

5139

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

4767

H_rxffe=0;

5140

H_rxffe=0;

4768

for nn=1:length(result.w)

5141

for nn=1:length(result.w)

4769

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

5142

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

4770

end

5143

end

4771

H_rxffe_2_of_f=abs(H_rxffe).^2;

5144

H_rxffe_2_of_f=abs(H_rxffe).^2;

4772

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

5145

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

4773

H_rxffe_2= [real( H_rxffe_2(1)), H_rxffe_2(2:end-1), real( H_rxffe_2(end)), conj( H_rxffe_2(end-1:-1:2))];

5146

H_rxffe_2= [real( H_rxffe_2(1)), H_rxffe_2(2:end-1), real( H_rxffe_2(end)), conj( H_rxffe_2(end-1:-1:2))];

4774

else

5147

else

4775

H_rxffe_2=1;

5148

H_rxffe_2=1;

4776

end

5149

end

4777

result.H_rxffe_2=H_rxffe_2;% pass as output for compuation in healey_3dj_01_2409 slide 12

+5150

4778

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

5151

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

4779

% --->this is the point in the code may fork where we add extra rx noise

5152

% --->this is the point in the code may fork where we add extra rx noise

4780

%% compute S_rn ( eq 178A-15 d0.2 )

5153

%% compute S_rn ( eq 178A-15 d0.2 )

4781

if ~OP.COMPUTE_COM

5154

if ~OP.COMPUTE_COM

4782

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

5155

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

4783

rxn_psd=[real(S_RN_of_f(1)), S_RN_of_f(2:end-1), real(S_RN_of_f(end)), conj(S_RN_of_f(end-1:-1:2))]; % Convert single-sided frequency response to conjugate-symmetric

5156

rxn_psd=[real(S_RN_of_f(1)), S_RN_of_f(2:end-1), real(S_RN_of_f(end)), conj(S_RN_of_f(end-1:-1:2))]; % Convert single-sided frequency response to conjugate-symmetric

4784

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

5157

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

4785

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

5158

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

4786

S_rn = sum(reshape(rxn_psd, num_ui, M).');

5159

S_rn = sum(reshape(rxn_psd, num_ui, M).');

4787

S_rn=S_rn(1:num_ui/2+1);

5160

S_rn=S_rn(1:num_ui/2+1);

4788

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

5161

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

4789

result.S_rn=S_rn;

5162

result.S_rn=S_rn;

4790

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5163

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4791

else

5164

else

4792

result.S_rn=result.S_rn.*H_rxffe_2;

5165

result.S_rn=result.S_rn.*H_rxffe_2;

4793

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5166

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4794

end

5167

end

4795

5168

4796

else % find noise for item that set have tx ffe for each loop

5169

else % find noise for item that set have tx ffe for each loop

4797

%% S_xn from eq 178A-16

5170

%% S_xn from eq 178A-16

4798

%% Crosstalk power spectral density

5171

%% Crosstalk power spectral density

4799

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

5172

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

4800

result.S_xn=0;

5173

result.S_xn=0;

4801

if length(chdata)~=1

5174

if length(chdata)~=1

4802

for xchan=2:length(chdata)

5175

for xchan=2:length(chdata)

4803

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

5176

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

4804

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

5177

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

4805

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

5178

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

4806

% enable less UI for computation speed improvement

5179

% enable less UI for computation speed improvement

4807

%%

5180

%%

4808

if num_ui*M > length(pulse_ctle)

5181

if num_ui*M > length(pulse_ctle)

4809

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

5182

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

4810

else

5183

else

4811

hk(xchan).k=hk(xchan).k(1:num_ui*M);

5184

hk(xchan).k=hk(xchan).k(1:num_ui*M);

4812

end

5185

end

4813

for i1=1:M

5186

for i1=1:M

4814

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

5187

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

4815

end

5188

end

4816

iphase(xchan)=find(hxn==max(hxn));

5189

iphase(xchan)=find(hxn==max(hxn));

4817

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

5190

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

4818

result.hk(xchan).hrn= hk(xchan).hrn;

5191

result.hk(xchan).hrn= hk(xchan).hrn;

4819

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

5192

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

4820

result.S_xn=hk(xchan).S_xn+result.S_xn;

5193

result.S_xn=hk(xchan).S_xn+result.S_xn;

4821

end

5194

end

4822

result.S_xn=result.S_xn;

5195

result.S_xn=result.S_xn;

4823

result.hk=hk;

5196

result.hk=hk;

4824

result.iphase=iphase;

5197

result.iphase=iphase;

4825

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5198

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4826

else % if no crosstalk, perserve structure and return 0 for S_xn

5199

else % if no crosstalk, perserve structure and return 0 for S_xn

4827

result.S_xn=0;

5200

result.S_xn=0;

4828

result.hk=[];

5201

result.hk=[];

4829

result.iphase=1;

5202

result.iphase=1;

4830

result.S_xn_rms = 0;

5203

result.S_xn_rms = 0;

4831

end

5204

end

4832

else % adjust for H_rxffe when computing COM

5205

else % adjust for H_rxffe when computing COM

4833

result.S_xn=result.S_xn.*H_rxffe_2;

5206

result.S_xn=result.S_xn.*H_rxffe_2;

4834

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5207

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4835

end

5208

end

4836

%% S_tn from eq 178A-17

5209

%% S_tn from eq 178A-17

4837

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

5210

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

4838

%% Transmitter noise power spectral density

5211

%% Transmitter noise power spectral density

4839

if ~OP.COMPUTE_COM

5212

if ~OP.COMPUTE_COM

4840

if ~OP.TDMODE

5213

if ~OP.TDMODE

4841

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

5214

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

4842

else % only use when the input was a pulse response not s-parameters

5215

else % only use when the input was a pulse response not s-parameters

4843

if isfield(chdata(1),'ctle_pulse_response')

5216

if isfield(chdata(1),'ctle_pulse_response')

4844

htn=chdata(1).ctle_pulse_response;

5217

htn=chdata(1).ctle_pulse_response;

4845

else

5218

else

4846

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

5219

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

4847

end

5220

end

4848

end

5221

end

4849

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

5222

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

4850

htn=reshape(htn,1,[]); % make row vectors

5223

htn=reshape(htn,1,[]); % make row vectors

4851

htn=[ htn(1:floor(length(htn)/M)*M) ];

5224

htn=[ htn(1:floor(length(htn)/M)*M) ];

4852

htn= [htn zeros(1,num_ui*M-length(htn)) ];

5225

htn= [htn zeros(1,num_ui*M-length(htn)) ];

4853

htn=htn(1:M:end);% resample

5226

htn=htn(1:M:end);% resample

4854

if num_ui>length(htn)

5227

if num_ui>length(htn)

4855

hext=[htn zeros(1,num_ui-length(htn))];

5228

hext=[htn zeros(1,num_ui-length(htn))];

4856

else

5229

else

4857

hext=htn(1:num_ui);

5230

hext=htn(1:num_ui);

4858

end

5231

end

4859

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

5232

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

4860

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5233

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4861

else

5234

else

4862

result.S_tn=result.S_tn.*H_rxffe_2;

5235

result.S_tn=result.S_tn.*H_rxffe_2;

4863

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5236

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4864

end

5237

end

4865

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

5238

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

4866

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

5239

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

4867

%% Power spectral density of noise due to jitter

5240

%% Power spectral density of noise due to jitter

4868

%% Eq. 93A-28 %%

5241

%% Eq. 93A-28 %%

4869

if ~OP.COMPUTE_COM

5242

if ~OP.COMPUTE_COM

4870

sampling_offset = mod(cursor_i, M);

5243

sampling_offset = mod(cursor_i, M);

4871

%ensure we can take early sample

5244

%ensure we can take early sample

4872

if sampling_offset<=1

5245

if sampling_offset<=1

4873

sampling_offset=sampling_offset+M;

5246

sampling_offset=sampling_offset+M;

4874

end

5247

end

4875

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

5248

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

4876

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

5249

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

4877

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

5250

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

4878

else

5251

else

4879

cursors_early_sample = h(sampling_offset-1:M:end);

5252

cursors_early_sample = h(sampling_offset-1:M:end);

4880

cursors_late_sample = h(sampling_offset+1:M:end);

5253

cursors_late_sample = h(sampling_offset+1:M:end);

4881

end

5254

end

4882

% ensure lengths are equal

5255

% ensure lengths are equal

4883

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

5256

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

4884

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

5257

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

4885

h_J=reshape(h_J,1,[]); % make row vectors

5258

h_J=reshape(h_J,1,[]); % make row vectors

4886

if num_ui>length(h_J)

5259

if num_ui>length(h_J)

4887

h_J=[h_J zeros(1,num_ui-length(h_J))];

5260

h_J=[h_J zeros(1,num_ui-length(h_J))];

4888

else

5261

else

4889

h_J=h_J(1:num_ui);

5262

h_J=h_J(1:num_ui);

4890

end

5263

end

4891

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5264

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4892

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5265

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4893

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5266

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4894

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5267

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4895

else

5268

else

4896

result.S_jn=result.S_jn.*H_rxffe_2;

5269

result.S_jn=result.S_jn.*H_rxffe_2;

4897

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5270

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4898

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

5271

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

4899

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5272

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4900

end

5273

end

4901

% result.S_jnesult.S_rn

5274

% result.S_jn

4902

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn;

5275

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn;

4903

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

5276

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

4904

5277

4905

%%

5278

%%

4906

%% Hisi to be included in MLSE rho eq 178a-28

5279

%% Hisi to be included in MLSE rho eq 178a-28

4907

if OP.COMPUTE_COM

5280

if OP.COMPUTE_COM

4908

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

5281

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

4909

% sampling_offset = mod(cursor_i-1, M)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

5282

% sampling_offset = mod(cursor_i-1, M)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

4910

% hisi=h(sampling_offset:M:end);

5283

% hisi=h(sampling_offset:M:end);

4911

% hisi=hisi(:).';

5284

% hisi=hisi(:).';

4912

% if num_ui>length(hisi)

5285

% if num_ui>length(hisi)

4913

% hisi=[hisi zeros(1,num_ui-length(hisi))];

5286

% hisi=[hisi zeros(1,num_ui-length(hisi))];

4914

% else

5287

% else

4915

% hisi=hisi(1:num_ui);% sometime cable channels need a bigger num_ui. prehap compare to the tripple transit time and compute num_ui

5288

% hisi=hisi(1:num_ui);% sometime cable channels need a bigger num_ui. prehap compare to the tripple transit time and compute num_ui

4916

% end

5289

% end

4917

% cursor_n=find(hisi==max(hisi),1','first');

5290

% cursor_n=find(hisi==max(hisi),1','first');

4918

samp_idx = (mod(cursor_i-1,M)+1):M:length(h);% Commit request 4p5_2, healey_3dj_COM_01_240521.pdf

5291

samp_idx = (mod(cursor_i-1,M)+1):M:length(h);% Commit request 4p5_2, healey_3dj_COM_01_240521.pdf

4919

cursor_n=find(samp_idx == cursor_i);

5292

cursor_n=find(samp_idx == cursor_i);

4920

hisi=h(samp_idx);

5293

hisi=h(samp_idx);

4921

hisi(end+1:num_ui)=0;

5294

hisi(end+1:num_ui)=0;

4922

hisi=reshape(hisi(1:num_ui),1,[]);

5295

hisi=reshape(hisi(1:num_ui),1,[]);

4923

%% Eq 178a-29

5296

%% Eq 178a-29

4924

for ii=1:length(hisi)

5297

for ii=1:length(hisi)

4925

if ii==cursor_n % cursor

5298

if ii==cursor_n % cursor

4926

cursor=hisi(ii);

5299

cursor=hisi(ii);

4927

hisi(ii)= 0;

5300

hisi(ii)= 0;

4928

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

5301

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

4929

ib_indx=ii-cursor_n;

5302

ib_indx=ii-cursor_n;

4930

if hisi(ii) >= bmax(ib_indx)*cursor

5303

if hisi(ii) >= bmax(ib_indx)*cursor

4931

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

5304

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

4932

elseif hisi(ii) <= bmin(ib_indx)*cursor

5305

elseif hisi(ii) <= bmin(ib_indx)*cursor

4933

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

5306

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

4934

else

5307

else

4935

hisi(ii)=0;

5308

hisi(ii)=0;

4936

end

5309

end

4937

end

5310

end

4938

end

5311

end

4939

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

5312

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

4940

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

5313

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

4941

%%

5314

%%

4942

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

5315

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

4943

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

5316

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

4944

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

5317

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

4945

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

5318

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

4946

end

5319

end

4947

end

5320

end

4948

function result=get_PulseR(ir,param,cb_step,ZT)

5321

function result=get_PulseR(ir,param,cb_step,ZT)

4949

%ir = impulse response

5322

%ir = impulse response

4950

%t_base=time array with equal time steps

5323

%t_base=time array with equal time steps

4951

%samp_UI = number of samples per UI for ir

5324

%samp_UI = number of samples per UI for ir

4952

5325

4953

% t for debug

5326

% t for debug

4954

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5327

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

4955

5328

4956

if cb_step

5329

if cb_step

4957

Ag=1;

5330

Ag=1;

4958

dt=1/param.fb/param.samples_per_ui;

5331

dt=1/param.fb/param.samples_per_ui;

4959

edge_time=param.TR_TDR*1e-9;

5332

edge_time=param.TR_TDR*1e-9;

4960

fedge=1/edge_time;

5333

fedge=1/edge_time;

4961

tedge=0:dt:edge_time*2;

5334

tedge=0:dt:edge_time*2;

4962

%

5335

%

4963

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5336

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

4964

drive_pulse=[edge ones(1,param.samples_per_ui)];

5337

drive_pulse=[edge ones(1,param.samples_per_ui)];

4965

%pulse=filter(UI_ones,1,ir);

5338

%pulse=filter(UI_ones,1,ir);

4966

% t for debug

5339

% t for debug

4967

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5340

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

4968

5341

4969

pulse=filter(drive_pulse,1,ir);

5342

pulse=filter(drive_pulse,1,ir);

4970

else

5343

else

4971

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5344

pulse=filter( ones(1,param.samples_per_ui),1,ir);

4972

end

5345

end

4973

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5346

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

4974

result.PDR=PDR_response;

5347

result.PDR=PDR_response;

4975

result.pulse=pulse;

5348

result.pulse=pulse;

4976

5349

4977

5350

4978

5351

4979

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5352

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

4980

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

5353

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

4981

if ~iscolumn(H), H=H.';end

5354

if ~iscolumn(H), H=H.';end

4982

if ~iscolumn(H_r), H_r=H_r.';end

5355

if ~iscolumn(H_r), H_r=H_r.';end

4983

H=H(:).*H_r;

5356

H=H(:).*H_r;

4984

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5357

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

4985

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5358

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

4986

5359

4987

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5360

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

4988

% Complex reflection and re-reflection noise using the concept of zero'ing

5361

% Complex reflection and re-reflection noise using the concept of zero'ing

4989

% out of reflections

5362

% out of reflections

4990

% sdd21 us a complex insertion loss

5363

% sdd21 us a complex insertion loss

4991

% RIL_struct is the output of capture_RIL_RILN()

5364

% RIL_struct is the output of capture_RIL_RILN()

4992

% faxix_f2 needs to be at least to fb

5365

% faxix_f2 needs to be at least to fb

4993

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5366

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

4994

% still need to settle on voltage scaling.

5367

% still need to settle on voltage scaling.

4995

% maybe db(peak/Rss

5368

% maybe db(peak/Rss

4996

db = @(x) 20*log10(abs(x));

5369

db = @(x) 20*log10(abs(x));

4997

fprintf('computing TD_RILN (dB) ...');

5370

fprintf('computing TD_RILN (dB) ...');

4998

5371

4999

OP.interp_sparam_mag= 'trend_to_DC';

5372

OP.interp_sparam_mag= 'trend_to_DC';

5000

OP.interp_sparam_phase= 'interp_to_DC';

5373

OP.interp_sparam_phase= 'interp_to_DC';

5001

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5374

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5002

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5375

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5003

5376

5004

sdd21=squeeze(sdd21);

5377

sdd21=squeeze(sdd21);

5005

if iscolumn(sdd21)

5378

if iscolumn(sdd21)

5006

sdd21=sdd21.';

5379

sdd21=sdd21.';

5007

end

5380

end

5008

RIL=squeeze(RIL_struct.RIL);

5381

RIL=squeeze(RIL_struct.RIL);

5009

if iscolumn(RIL)

5382

if iscolumn(RIL)

5010

RIL=RIL.';

5383

RIL=RIL.';

5011

end

5384

end

5012

rho_port1=squeeze(RIL_struct.rho_port1);

5385

rho_port1=squeeze(RIL_struct.rho_port1);

5013

if iscolumn(rho_port1)

5386

if iscolumn(rho_port1)

5014

rho_port1=rho_port1.';

5387

rho_port1=rho_port1.';

5015

end

5388

end

5016

rho_port2=squeeze(RIL_struct.rho_port2);

5389

rho_port2=squeeze(RIL_struct.rho_port2);

5017

if iscolumn(rho_port2)

5390

if iscolumn(rho_port2)

5018

rho_port2=rho_port2.';

5391

rho_port2=rho_port2.';

5019

end

5392

end

5020

RIL_f=squeeze(RIL_struct.freq);

5393

RIL_f=squeeze(RIL_struct.freq);

5021

if iscolumn(RIL_f)

5394

if iscolumn(RIL_f)

5022

RIL_f=RIL_f.';

5395

RIL_f=RIL_f.';

5023

end

5396

end

5024

5397

5025

%---start. Calculate the reflection and re-reflection noise

5398

%---start. Calculate the reflection and re-reflection noise

5026

number_of_echos= 1e3;

5399

number_of_echos= 1e3;

5027

fmin= 1e9;%<-------------

5400

fmin= 1e9;%<-------------

5028

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5401

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5029

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5402

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5030

for m= 1:number_of_echos

5403

for m= 1:number_of_echos

5031

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m)).*(rho_port1.^m).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port2);

5404

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m)).*(rho_port1.^m).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port2);

5032

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m-1)).*(rho_port1.^(m-1)).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port1);

5405

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m-1)).*(rho_port1.^(m-1)).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port1);

5033

end

5406

end

5034

5407

5035

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5408

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5036

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5409

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5037

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5410

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5038

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5411

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5039

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5412

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5040

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5413

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5041

5414

5042

% clear RIL RIL_f rho_port1 rho_port2

5415

% clear RIL RIL_f rho_port1 rho_port2

5043

% clear fmin m

5416

% clear fmin m

5044

%---end. Calculate the reflection and re-reflection noise

5417

%---end. Calculate the reflection and re-reflection noise

5045

5418

5046

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5419

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5047

warning('off','MATLAB:nearlySingularMatrix');

5420

warning('off','MATLAB:nearlySingularMatrix');

5048

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5421

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5049

LGw=transpose(sdd21.*unwraplog);

5422

LGw=transpose(sdd21.*unwraplog);

5050

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5423

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5051

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5424

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5052

FIT=transpose(exp(transpose(efit_C)));

5425

FIT=transpose(exp(transpose(efit_C)));

5053

efit=db(abs(FIT));

5426

efit=db(abs(FIT));

5054

ILN = db(sdd21)-efit;

5427

ILN = db(sdd21)-efit;

5055

5428

5056

5429

5057

OP.impulse_response_truncation_threshold =1e-7;

5430

OP.impulse_response_truncation_threshold =1e-7;

5058

5431

5059

print_for_codereview=0;

5432

print_for_codereview=0;

5060

if exist('OP','var')

5433

if exist('OP','var')

5061

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5434

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5062

H_bw=Butterworth_Filter(param,faxis_f2,1);

5435

H_bw=Butterworth_Filter(param,faxis_f2,1);

5063

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5436

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5064

H_tw=Tukey_Window(faxis_f2,param);

5437

H_tw=Tukey_Window(faxis_f2,param);

5065

H_tw=ones(1,length(faxis_f2) );

5438

H_tw=ones(1,length(faxis_f2) );

5066

[RILN_TD_struct.REF.FIR, ...

5439

[RILN_TD_struct.REF.FIR, ...

5067

RILN_TD_struct.REF.t, ...

5440

RILN_TD_struct.REF.t, ...

5068

RILN_TD_struct.REF.causality_correction_dB, ...

5441

RILN_TD_struct.REF.causality_correction_dB, ...

5069

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5442

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5070

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5443

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5071

5444

5072

5445

5073

[RILN_TD_struct.FIT.FIR, ...

5446

[RILN_TD_struct.FIT.FIR, ...

5074

RILN_TD_struct.FIT.t, ...

5447

RILN_TD_struct.FIT.t, ...

5075

RILN_TD_struct.FIT.causality_correction_dB, ...

5448

RILN_TD_struct.FIT.causality_correction_dB, ...

5076

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5449

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5077

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5450

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5078

5451

5079

5452

5080

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5453

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5081

H_bw=Butterworth_Filter(param,RIL_f,1);

5454

H_bw=Butterworth_Filter(param,RIL_f,1);

5082

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5455

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5083

H_tw=Tukey_Window(RIL_f,param);

5456

H_tw=Tukey_Window(RIL_f,param);

5084

H_tw=ones(1,length(RIL_f) );

5457

H_tw=ones(1,length(RIL_f) );

5085

[RILN_TD_struct.RIL.FIR, ...

5458

[RILN_TD_struct.RIL.FIR, ...

5086

RILN_TD_struct.RIL.t, ...

5459

RILN_TD_struct.RIL.t, ...

5087

RILN_TD_struct.RIL.causality_correction_dB, ...

5460

RILN_TD_struct.RIL.causality_correction_dB, ...

5088

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5461

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5089

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5462

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5090

5463

5091

5464

5092

%---start. Calculate the channel delay

5465

%---start. Calculate the channel delay

5093

try

5466

try

5094

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5467

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5095

catch

5468

catch

5096

end

5469

end

5097

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5470

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5098

clear delay_sec delay_idx

5471

clear delay_sec delay_idx

5099

%---end. Calculate the channel delay

5472

%---end. Calculate the channel delay

5100

5473

5101

5474

5102

5475

5103

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5476

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5104

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5477

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5105

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5478

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5106

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5479

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5107

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5480

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5108

[RILN_TD_struct.REF_noise.FIR, ...

5481

[RILN_TD_struct.REF_noise.FIR, ...

5109

RILN_TD_struct.REF_noise.t, ...

5482

RILN_TD_struct.REF_noise.t, ...

5110

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5483

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5111

RILN_TD_struct.REF_noise.truncation_dB] = s21_to_impulse_DC(port2_reflection_rereflection_noise.*H_bw.*H_t.*H_tw ,f_reflection_rereflection_noise, param.sample_dt, OP) ;

5484

RILN_TD_struct.REF_noise.truncation_dB] = s21_to_impulse_DC(port2_reflection_rereflection_noise.*H_bw.*H_t.*H_tw ,f_reflection_rereflection_noise, param.sample_dt, OP) ;

5112

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5485

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5113

5486

5114

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5487

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5115

% NrangeUI=1000;

5488

% NrangeUI=1000;

5116

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(RILN_TD_struct.FIT.PR)-param.samples_per_ui ),length(RILN_TD_struct.REF.PR)-param.samples_per_ui);

5489

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(RILN_TD_struct.FIT.PR)-param.samples_per_ui ),length(RILN_TD_struct.REF.PR)-param.samples_per_ui);

5117

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5490

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5118

range=ipeak:range_end;

5491

range=ipeak:range_end;

5119

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5492

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5120

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5493

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5121

RILN_TD_struct.FOM=-inf;

5494

RILN_TD_struct.FOM=-inf;

5122

RILN_TD_struct.FOM_PDF=-inf;

5495

RILN_TD_struct.FOM_PDF=-inf;

5123

rms_fom=-inf;

5496

rms_fom=-inf;

5124

for im=1:param.samples_per_ui

5497

for im=1:param.samples_per_ui

5125

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5498

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5126

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5499

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5127

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5500

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5128

cdf=pdf; cdf.y=cumsum(pdf.y);

5501

cdf=pdf; cdf.y=cumsum(pdf.y);

5129

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5502

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5130

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5503

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5131

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5504

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5132

if print_for_codereview % remove once all checked out

5505

if print_for_codereview % remove once all checked out

5133

h=figure(190);set(gcf,'Tag','COM');

5506

h=figure(190);set(gcf,'Tag','COM');

5134

semilogy(-cdf.x,cdf.y);

5507

semilogy(-cdf.x,cdf.y);

5135

% xlim ([0,-cdf.x(1)])

5508

% xlim ([0,-cdf.x(1)])

5136

ylim([param.specBER 1]);title ('CDF of ILN')

5509

ylim([param.specBER 1]);title ('CDF of ILN')

5137

hold on

5510

hold on

5138

end

5511

end

5139

if rms>rms_fom

5512

if rms>rms_fom

5140

rms_fom=rms;

5513

rms_fom=rms;

5141

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5514

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5142

RILN_TD_struct.PDF=pdf;

5515

RILN_TD_struct.PDF=pdf;

5143

end

5516

end

5144

end

5517

end

5145

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5518

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5146

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5519

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5147

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5520

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5148

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5521

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5149

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5522

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5150

if print_for_codereview % remove once all checked out

5523

if print_for_codereview % remove once all checked out

5151

figure(9000);set(gcf,'Tag','COM');

5524

figure(9000);set(gcf,'Tag','COM');

5152

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5525

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5153

hold on

5526

hold on

5154

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5527

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5155

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5528

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5156

yyaxis right

5529

yyaxis right

5157

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5530

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5158

hold off

5531

hold off

5159

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

5532

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

5160

figure(9002);set(gcf,'Tag','COM');

5533

figure(9002);set(gcf,'Tag','COM');

5161

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5534

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5162

hold on

5535

hold on

5163

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5536

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5164

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5537

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5165

grid on

5538

grid on

5166

legend('show')

5539

legend('show')

5167

end

5540

end

5168

end

5541

end

5169

function result=get_StepR(ir,param,cb_step,ZT)

5542

function result=get_StepR(ir,param,cb_step,ZT)

5170

%ir = impulse response

5543

%ir = impulse response

5171

%t_base=time array with equal time steps

5544

%t_base=time array with equal time steps

5172

%samp_UI = number of samples per UI for ir

5545

%samp_UI = number of samples per UI for ir

5173

% result.SBR

5546

% result.SBR

5174

% t for debug

5547

% t for debug

5175

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5548

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5176

5549

5177

if cb_step

5550

if cb_step

5178

Ag=1;

5551

Ag=1;

5179

dt=1/param.fb/param.samples_per_ui;

5552

dt=1/param.fb/param.samples_per_ui;

5180

edge_time=param.TR_TDR*1e-9;

5553

edge_time=param.TR_TDR*1e-9;

5181

fedge=1/edge_time;

5554

fedge=1/edge_time;

5182

tedge=0:dt:edge_time*2;

5555

tedge=0:dt:edge_time*2;

5183

%

5556

%

5184

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5557

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5185

drive_pulse=[edge ones(1,param.samples_per_ui)];

5558

drive_pulse=[edge ones(1,param.samples_per_ui)];

5186

%pulse=filter(UI_ones,1,ir);

5559

%pulse=filter(UI_ones,1,ir);

5187

5560

5188

pulse=filter(drive_pulse,1,ir);

5561

pulse=filter(drive_pulse,1,ir);

5189

else

5562

else

5190

pulse=cumsum(ir);

5563

pulse=cumsum(ir);

5191

end

5564

end

5192

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5565

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5193

result.ZSR=TDR_response;

5566

result.ZSR=TDR_response;

5194

result.pulse=pulse;

5567

result.pulse=pulse;

5195

5568

5196

5569

5197

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5570

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5198

% sdd is differential s-parameters structure (2 port assumed)

5571

% sdd is differential s-parameters structure (2 port assumed)

5199

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5572

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5200

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5573

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5201

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5574

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5202

% TDR_results.t starting at t=0

5575

% TDR_results.t starting at t=0

5203

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5576

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5204

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5577

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5205

% TDR_results.f frequency for filter and s parameters

5578

% TDR_results.f frequency for filter and s parameters

5206

% TDR_results.ptdr_RL reflection waveform from the pulse

5579

% TDR_results.ptdr_RL reflection waveform from the pulse

5207

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5580

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5208

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5581

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5209

% TDR_results.ERL reported effective return loss

5582

% TDR_results.ERL reported effective return loss

5210

%

5583

%

5211

db = @(x) 20*log10(abs(x));

5584

db = @(x) 20*log10(abs(x));

5212

rms =@(x) norm(x)/sqrt(length(x));

5585

rms =@(x) norm(x)/sqrt(length(x));

5213

if isfield(OP,'TDR_duration')

5586

if isfield(OP,'TDR_duration')

5214

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5587

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5215

else

5588

else

5216

TDR_duration=5;

5589

TDR_duration=5;

5217

end

5590

end

5218

if ~isfield(OP,'DISPLAY_WINDOW')

5591

if ~isfield(OP,'DISPLAY_WINDOW')

5219

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5592

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5220

end

5593

end

5221

f=sdd.Frequencies;

5594

f=sdd.Frequencies;

5222

TDR_results.f=f;

5595

TDR_results.f=f;

5223

% OP.Zt_adj=2;

5596

% OP.Zt_adj=2;

5224

if param.FLAG.S2P == 0

5597

if param.FLAG.S2P == 0

5225

5598

5226

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5599

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5227

TDR_RL =@(Zin,Zout,s11,s12,s21,s22)(Zin.^2.*s11+Zin.^2.*s22+Zout.^2.*s11+Zout.^2.*s22+Zin.^2-Zout.^2+Zin.*Zout.*s11.*2.0-Zin.*Zout.*s22.*2.0+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21-Zout.^2.*s11.*s22+Zout.^2.*s12.*s21)./(Zin.*Zout.*2.0+Zin.^2.*s11+Zin.^2.*s22-Zout.^2.*s11-Zout.^2.*s22+Zin.^2+Zout.^2+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21+Zout.^2.*s11.*s22-Zout.^2.*s12.*s21-Zin.*Zout.*s11.*s22.*2.0+Zin.*Zout.*s12.*s21.*2.0);

5600

TDR_RL =@(Zin,Zout,s11,s12,s21,s22)(Zin.^2.*s11+Zin.^2.*s22+Zout.^2.*s11+Zout.^2.*s22+Zin.^2-Zout.^2+Zin.*Zout.*s11.*2.0-Zin.*Zout.*s22.*2.0+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21-Zout.^2.*s11.*s22+Zout.^2.*s12.*s21)./(Zin.*Zout.*2.0+Zin.^2.*s11+Zin.^2.*s22-Zout.^2.*s11-Zout.^2.*s22+Zin.^2+Zout.^2+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21+Zout.^2.*s11.*s22-Zout.^2.*s12.*s21-Zin.*Zout.*s11.*s22.*2.0+Zin.*Zout.*s12.*s21.*2.0);

5228

5601

5229

if param.RL_sel==1, other_port=2;end

5602

if param.RL_sel==1, other_port=2;end

5230

if param.RL_sel==2, other_port=1;end

5603

if param.RL_sel==2, other_port=1;end

5231

for i = 1:length(sdd.Frequencies)

5604

for i = 1:length(sdd.Frequencies)

5232

if size(sdd.Parameters,2) ==1 % for s2p files

5605

if size(sdd.Parameters,2) ==1 % for s2p files

5233

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,1, 1 ,sdd.Parameters(param.RL_sel,param.RL_sel,i) );

5606

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,1, 1 ,sdd.Parameters(param.RL_sel,param.RL_sel,i) );

5234

else

5607

else

5235

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,sdd.Parameters( 1,2 ,i), sdd.Parameters( 2,1 ,i),sdd.Parameters( other_port,other_port ,i) );

5608

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,sdd.Parameters( 1,2 ,i), sdd.Parameters( 2,1 ,i),sdd.Parameters( other_port,other_port ,i) );

5236

end

5609

end

5237

end

5610

end

5238

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5611

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5239

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5612

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5240

% Z_t=ZT;

5613

% Z_t=ZT;

5241

% zref=sdd.Impedance/2;

5614

% zref=sdd.Impedance/2;

5242

% if Z_t > zref

5615

% if Z_t > zref

5243

% radjust= (zref-Z_t);

5616

% radjust= (zref-Z_t);

5244

% S11adjust= radjust./(radjust + 2*zref);

5617

% S11adjust= radjust./(radjust + 2*zref);

5245

% RL=RL +S11adjust;

5618

% RL=RL +S11adjust;

5246

% elseif Z_t < zref

5619

% elseif Z_t < zref

5247

% rpad=-Z_t*zref/(Z_t-zref);

5620

% rpad=-Z_t*zref/(Z_t-zref);

5248

% S11adjust=zref/(rpad*(zref/rpad + 2));

5621

% S11adjust=zref/(rpad*(zref/rpad + 2));

5249

% RL=RL + S11adjust;

5622

% RL=RL + S11adjust;

5250

% else

5623

% else

5251

% RL=RL;

5624

% RL=RL;

5252

% end

5625

% end

5253

else

5626

else

5254

for i = 1:length(sdd.Frequencies)

5627

for i = 1:length(sdd.Frequencies)

5255

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5628

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5256

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5629

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5257

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5630

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5258

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5631

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5259

end

5632

end

5260

end

5633

end

5261

5634

5262

% end

5635

% end

5263

RL=squeeze(RL);

5636

RL=squeeze(RL);

5264

f9=f/1e9;

5637

f9=f/1e9;

5265

tr=param.TR_TDR;

5638

tr=param.TR_TDR;

5266

TDR_results.delay=500e-12 ;

5639

TDR_results.delay=500e-12 ;

5267

% determine max time from thue

5640

% determine max time from thue

5268

% if sdd.NumPorts==1

5641

% if sdd.NumPorts==1

5269

% try

5642

% try

5270

% maxtime=OP.N*param.ui;

5643

% maxtime=OP.N*param.ui;

5271

% catch

5644

% catch

5272

% maxtime=2e-9;

5645

% maxtime=2e-9;

5273

% end

5646

% end

5274

% pix=1;

5647

% pix=1;

5275

% else

5648

% else

5276

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5649

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5277

% pix=find(fir4del==max(fir4del),1);

5650

% pix=find(fir4del==max(fir4del),1);

5278

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5651

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5279

% if maxtime > tu(end); maxtime=tu(end);end

5652

% if maxtime > tu(end); maxtime=tu(end);end

5280

% endS

5653

% endS

5281

5654

5282

try

5655

try

5283

maxtime=OP.N*param.ui;

5656

maxtime=OP.N*param.ui;

5284

catch

5657

catch

5285

maxtime=2e-9;

5658

maxtime=2e-9;

5286

end

5659

end

5287

if OP.N==0

5660

if OP.N==0

5288

if sdd.NumPorts==1

5661

if sdd.NumPorts==1

5289

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5662

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5290

else

5663

else

5291

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5664

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5292

pix=find(fir4del==max(fir4del),1);

5665

pix=find(fir4del==max(fir4del),1);

5293

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5666

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5294

if maxtime > tu(end); maxtime=tu(end);end

5667

if maxtime > tu(end); maxtime=tu(end);end

5295

end

5668

end

5296

end

5669

end

5297

5670

5298

5671

5299

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5672

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5300

% (makes gausian edge somewhat causal)

5673

% (makes gausian edge somewhat causal)

5301

H_t = exp( -2*(pi*f9*(tr)/1.6832).^2 ).*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9).*exp(-1j*2*pi*f9*tr*3);

5674

H_t = exp( -2*(pi*f9*(tr)/1.6832).^2 ).*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9).*exp(-1j*2*pi*f9*tr*3);

5302

if ~isfield(OP,'cb_Guassian')

5675

if ~isfield(OP,'cb_Guassian')

5303

Use_gaussian=1;

5676

Use_gaussian=1;

5304

else

5677

else

5305

Use_gaussian=OP.cb_Guassian;

5678

Use_gaussian=OP.cb_Guassian;

5306

end

5679

end

5307

if Use_gaussian

5680

if Use_gaussian

5308

if iscolumn(H_t), H_t=H_t.'; end

5681

if iscolumn(H_t), H_t=H_t.'; end

5309

RLf=RL(:).'.*H_t;

5682

RLf=RL(:).'.*H_t;

5310

else % add extra 3x tr delay for causality

5683

else % add extra 3x tr delay for causality

5311

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5684

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5312

end

5685

end

5313

5686

5314

%Bessesl-Thomson turned off here (3rd input=0)

5687

%Bessesl-Thomson turned off here (3rd input=0)

5315

OP.TDR_Bessel_Thomson=0;

5316

H_bt=Bessel_Thomson_Filter(param,f,OP.TDR_Bessel_Thomson);

5688

H_bt=Bessel_Thomson_Filter(param,f,0);

5317

5689

5318

if isfield(OP,'TDR_Butterworth')

5690

if isfield(OP,'TDR_Butterworth')

5319

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5691

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5320

else

5692

else

5321

H_bw=ones(1,length(f));

5693

H_bw=ones(1,length(f));

5322

end

5694

end

5323

5695

5324

5696

5325

if param.Tukey_Window ~= 0

5697

if param.Tukey_Window ~= 0

5326

H_tw= Tukey_Window(f,param);

5698

H_tw= Tukey_Window(f,param);

5327

else

5699

else

5328

H_tw=ones(1,length(f));

5700

H_tw=ones(1,length(f));

5329

end

5701

end

5330

5702

5331

5703

5332

if iscolumn(H_tw), H_tw=H_tw.';end

5704

if iscolumn(H_tw), H_tw=H_tw.';end

5333

if iscolumn(H_bt), H_bt=H_bt.';end

5705

if iscolumn(H_bt), H_bt=H_bt.';end

5334

if iscolumn(H_bw), H_bw=H_bw.';end

5706

if iscolumn(H_bw), H_bw=H_bw.';end

5335

if iscolumn(RLf), RLf=RLf.';end

5707

if iscolumn(RLf), RLf=RLf.';end

5336

5708

5337

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5709

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5338

RLf=RLf.*TDR_results.Rx_filter;

5710

RLf=RLf.*TDR_results.Rx_filter;

5339

TDR_results.tx_filter=H_t;

5711

TDR_results.tx_filter=H_t;

5340

5712

5341

5713

5342

[IR, t, causality_correction_dB, truncation_dB] = ...

5714

[IR, t, causality_correction_dB, truncation_dB] = ...

5343

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5715

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5344

5716

5345

5717

5346

%

5718

%

5347

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5719

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5348

tfx=param.tfx(np); % use fixture delay for port (np)

5720

tfx=param.tfx(np); % use fixture delay for port (np)

5349

5721

5350

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5722

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5351

5723

5352

t = t-TDR_results.delay;

5724

t = t-TDR_results.delay;

5353

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5725

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5354

if isempty(tend), tend=length(t); end

5726

if isempty(tend), tend=length(t); end

5355

IR=IR(1:tend);

5727

IR=IR(1:tend);

5356

t=t(1:tend);

5728

t=t(1:tend);

5357

if isempty(tend), tend=length(t); end

5729

if isempty(tend), tend=length(t); end

5358

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5730

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5359

if isempty(tstart), tstart=1;end

5731

if isempty(tstart), tstart=1;end

5360

if isempty(tend) || tstart >= tend

5732

if isempty(tend) || tstart >= tend

5361

if isempty(tend) || tstart >= tend

5733

if isempty(tend) || tstart >= tend

5362

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5734

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5363

end

5735

end

5364

tend=length(t);

5736

tend=length(t);

5365

tstart=1;

5737

tstart=1;

5366

end

5738

end

5367

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5739

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5368

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5740

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5369

TDR_results.tdr= ch.ZSR;

5741

TDR_results.tdr= ch.ZSR;

5370

TDR_results.t = t(tstart:tend);

5742

TDR_results.t = t(tstart:tend);

5371

5743

5372

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5744

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5373

if OP.TDR || OP.PTDR % determin average impededance with

5745

if OP.TDR || OP.PTDR % determin average impededance with

5374

try

5746

try

5375

tfstart=find(t>=3*tr*1e-9,1);

5747

tfstart=find(t>=3*tr*1e-9,1);

5376

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5748

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5377

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5749

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5378

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5750

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5379

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5751

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5380

catch

5752

catch

5381

TDR_results.avgZport=0;

5753

TDR_results.avgZport=0;

5382

fit=zeros(1,1);

5754

fit=zeros(1,1);

5383

p=[0 0 0 0 ];

5755

p=[0 0 0 0 ];

5384

end

5756

end

5385

TDR_results.RL=RL;

5757

TDR_results.RL=RL;

5386

end

5758

end

5387

if OP.PTDR

5759

if OP.PTDR

5388

% param.N_bx=param.ndfe;

5760

% param.N_bx=param.ndfe;

5389

RL_equiv=-inf;

5761

RL_equiv=-inf;

5390

L=param.levels;

5762

L=param.levels;

5391

BinSize=OP.BinSize;

5763

BinSize=OP.BinSize;

5392

% param.specBER=1e-5;

5764

% param.specBER=1e-5;

5393

if OP.DISPLAY_WINDOW

5765

if OP.DISPLAY_WINDOW

5394

hwaitbar=waitbar(0);

5766

hwaitbar=waitbar(0);

5395

else

5767

else

5396

fprintf('Worst ERL searching');

5768

fprintf('Worst ERL searching');

5397

end

5769

end

5398

% adjust PTDR for NDFE

5770

% adjust PTDR for NDFE

5399

% ---------------------- 2.7 code

5771

% ---------------------- 2.7 code

5400

% ntx=find(TDR_results.t >= tfx,1,'first');

5772

% ntx=find(TDR_results.t >= tfx,1,'first');

5401

% % gatestartt=TDR_results.t(ntx);

5773

% % gatestartt=TDR_results.t(ntx);

5402

% % gatestartV=PTDR.pulse(ntx);

5774

% % gatestartV=PTDR.pulse(ntx);

5403

% 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');

5404

% tk=param.ui*1*(param.N_bx+1)+tfx;

5776

% tk=param.ui*1*(param.N_bx+1)+tfx;

5405

% -------------------

5777

% -------------------

5406

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5778

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5407

% time filter.

5779

% time filter.

5408

% ntx=find(TDR_results.t >= tfx,1,'first');

5780

% ntx=find(TDR_results.t >= tfx,1,'first');

5409

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5781

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5410

% gatestartt=TDR_results.t(ntx);

5782

% gatestartt=TDR_results.t(ntx);

5411

% gatestartV=PTDR.pulse(ntx);

5783

% gatestartV=PTDR.pulse(ntx);

5412

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5784

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5413

% tk=param.ui*1*(param.N_bx+1)+tfx;

5785

% tk=param.ui*1*(param.N_bx+1)+tfx;

5414

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5786

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5415

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5787

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5416

% [ahealey] End of modifications.

5788

% [ahealey] End of modifications.

5417

if isempty(ndfex), ndfex=length(TDR_results.t); end

5789

if isempty(ndfex), ndfex=length(TDR_results.t); end

5418

PTDR.pulse_orig=PTDR.pulse;

5790

PTDR.pulse_orig=PTDR.pulse;

5419

5791

5420

switch param.Grr

5792

switch param.Grr

5421

case 0 % pre .3cd release

5793

case 0 % pre .3cd release

5422

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5794

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5423

case 1 % .3cd release

5795

case 1 % .3cd release

5424

fctrx(1:length(PTDR.pulse_orig))=1;

5796

fctrx(1:length(PTDR.pulse_orig))=1;

5425

case 2 % .3ck working

5797

case 2 % .3ck working

5426

fctrx(1:length(PTDR.pulse_orig))=1;

5798

fctrx(1:length(PTDR.pulse_orig))=1;

5427

end

5799

end

5428

Gloss(1:length(TDR_results.t))=1;

5800

Gloss(1:length(TDR_results.t))=1;

5429

Grr(1:length(TDR_results.t))=1;

5801

Grr(1:length(TDR_results.t))=1;

5430

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5802

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5431

5803

5432

for ii=ntx:ndfex

5804

for ii=ntx:ndfex

5433

% adjust for near end loss

5805

% adjust for near end loss

5434

if param.N_bx>0 && param.beta_x~=0;

5806

if param.N_bx>0 && param.beta_x~=0;

5435

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5807

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5436

else

5808

else

5437

Gloss(ii)=1;

5809

Gloss(ii)=1;

5438

end

5810

end

5439

% ---------------------- 2.7 code

5811

% ---------------------- 2.7 code

5440

% x=(TDR_results.t(ii)-tfx)/param.ui;

5812

% x=(TDR_results.t(ii)-tfx)/param.ui;

5441

% ----------------------

5813

% ----------------------

5442

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5814

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5443

% rise time filter.

5815

% rise time filter.

5444

% x=(TDR_results.t(ii)-tfx)/param.ui;

5816

% x=(TDR_results.t(ii)-tfx)/param.ui;

5445

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5817

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5446

% determine how much of the return loss to use base on expected

5818

% determine how much of the return loss to use base on expected

5447

% missing reflections

5819

% missing reflections

5448

switch param.Grr

5820

switch param.Grr

5449

case 0 % pre .3cd release

5821

case 0 % pre .3cd release

5450

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5822

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5451

case 1 % .3cd release

5823

case 1 % .3cd release

5452

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5824

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5453

case 2 % .3ck working

5825

case 2 % .3ck working

5454

Grr(ii)= param.rho_x ;

5826

Grr(ii)= param.rho_x ;

5455

end

5827

end

5456

fctrx(ii)=Gloss(ii).*Grr(ii);

5828

fctrx(ii)=Gloss(ii).*Grr(ii);

5457

end

5829

end

5458

5830

5459

if isrow(fctrx), fctrx=fctrx(:);end

5831

if isrow(fctrx), fctrx=fctrx(:);end

5460

PTDR.pulse=PTDR.pulse.*fctrx;

5832

PTDR.pulse=PTDR.pulse.*fctrx;

5461

if 0

5833

if 0

5462

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5834

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5463

s1=subplot(2,1,1);

5835

s1=subplot(2,1,1);

5464

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5836

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5465

hold on

5837

hold on

5466

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,Gloss(ntx:end),'disp','G_l_o_s_s');

5467

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5839

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5468

grid on

5840

grid on

5469

ylim([ 0 1.2])

5841

ylim([ 0 1.2])

5470

s2=subplot(2,1,2);

5842

s2=subplot(2,1,2);

5471

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5843

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5472

grid on

5844

grid on

5473

linkaxes([s1,s2],'x')

5845

linkaxes([s1,s2],'x')

5474

xlabel 'UI'

5846

xlabel 'UI'

5475

xlim ([ 1 200])

5847

xlim ([ 1 200])

5476

end

5848

end

5477

5849

5478

FAST_NOISE_CONV=0;

5850

FAST_NOISE_CONV=0;

5479

ERLRMS=rms(PTDR.pulse);

5851

ERLRMS=rms(PTDR.pulse);

5480

for ki=1:param.samples_per_ui

5852

for ki=1:param.samples_per_ui

5481

progress = ki/param.samples_per_ui;

5853

progress = ki/param.samples_per_ui;

5482

if OP.DISPLAY_WINDOW

5854

if OP.DISPLAY_WINDOW

5483

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5855

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5484

else

5856

else

5485

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5857

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5486

end

5858

end

5487

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5859

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5488

if OP.RL_norm_test

5860

if OP.RL_norm_test

5489

rl_fom=(norm(tps));

5861

rl_fom=(norm(tps));

5490

else

5862

else

5491

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5863

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5492

cdf_test=cumsum(testpdf.y);

5864

cdf_test=cumsum(testpdf.y);

5493

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5865

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5494

rl_fom=rl_test;

5866

rl_fom=rl_test;

5495

end

5867

end

5496

if rl_fom > RL_equiv

5868

if rl_fom > RL_equiv

5497

RL_equiv=rl_fom;

5869

RL_equiv=rl_fom;

5498

best_ki=ki;

5870

best_ki=ki;

5499

end

5871

end

5500

if ~OP.RL_norm_test

5872

if ~OP.RL_norm_test

5501

best_erl=rl_test;

5873

best_erl=rl_test;

5502

best_pdf=testpdf;

5874

best_pdf=testpdf;

5503

best_cdf=cdf_test;

5875

best_cdf=cdf_test;

5504

end

5876

end

5505

5877

5506

end

5878

end

5507

if OP.RL_norm_test

5879

if OP.RL_norm_test

5508

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5880

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5509

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5881

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5510

cdf_test=cumsum(testpdf.y);

5882

cdf_test=cumsum(testpdf.y);

5511

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5883

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5512

end

5884

end

5513

5885

5514

fprintf('\n');

5886

fprintf('\n');

5515

try

5887

try

5516

close(hwaitbar)

5888

close(hwaitbar)

5517

catch

5889

catch

5518

end

5890

end

5519

if ~exist('best_ki','var'),best_ki=1;end

5891

if ~exist('best_ki','var'),best_ki=1;end

5520

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5892

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5521

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5893

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5522

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5894

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5523

TDR_results.ERL=-db(best_erl);

5895

TDR_results.ERL=-db(best_erl);

5524

TDR_results.ERLRMS=-db(ERLRMS);

5896

TDR_results.ERLRMS=-db(ERLRMS);

5525

5897

5526

end

5898

end

5527

5899

5528

5900

5529

% end get TDR

5901

% end get TDR

5530

%%

5902

%%

5531

5903

5532

5904

5533

5905

5534

5906

5535

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5907

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5536

% filename parsing and acquisition

5908

% filename parsing and acquisition

5537

%------------------------------------------------------------------

5909

%------------------------------------------------------------------

5538

%----------put files names into chdata structure ---------

5910

%----------put files names into chdata structure ---------

5539

% The thru file has the index of 1

5911

% The thru file has the index of 1

5540

% crosstalk file are indexed from 2

5912

% crosstalk file are indexed from 2

5541

% nxi is incremented each time a file is read in so that nxi will end

5913

% nxi is incremented each time a file is read in so that nxi will end

5542

filepath=[]; % path name for file

5914

filepath=[]; % path name for file

5543

nxi=0; % file index

5915

nxi=0; % file index

5544

% get the THRU file

5916

% get the THRU file

5545

if size(file_list,2) ~= 0

5917

if size(file_list,2) ~= 0

5546

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5918

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5547

[filepath, basename, fileext]=fileparts(file_list{1});

5919

[filepath, basename, fileext]=fileparts(file_list{1});

5548

5920

5549

else

5921

else

5550

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5922

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5551

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5923

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5552

movegui(h,'northeast')

5924

movegui(h,'northeast')

5553

end

5925

end

5554

dir=fullfile(filepath, '*.csv');

5926

dir=fullfile(filepath, '*.csv');

5555

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5927

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5556

if filepath == 0

5928

if filepath == 0

5557

error('No Thru file')

5929

error('No Thru file')

5558

end

5930

end

5559

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5931

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5560

end

5932

end

5561

nxi=nxi+1;

5933

nxi=nxi+1;

5562

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5934

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5563

chdata(nxi).ext = fileext;

5935

chdata(nxi).ext = fileext;

5564

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5936

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5565

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5937

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5566

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5938

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5567

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5939

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5568

chdata(nxi).type='THRU';

5940

chdata(nxi).type='THRU';

5569

chdata(nxi).ftr=param.fb*param.f_v;

5941

chdata(nxi).ftr=param.fb*param.f_v;

5570

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5942

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5571

5943

5572

% now get FEXT file names into chdata structure

5944

% now get FEXT file names into chdata structure

5573

kxi=nxi;

5945

kxi=nxi;

5574

for nxi=kxi+1:num_fext+kxi

5946

for nxi=kxi+1:num_fext+kxi

5575

lastfilepath=filepath;

5947

lastfilepath=filepath;

5576

if size(file_list,2) ~= 0

5948

if size(file_list,2) ~= 0

5577

[filepath, basename, fileext]=fileparts(file_list{nxi});

5949

[filepath, basename, fileext]=fileparts(file_list{nxi});

5578

else

5950

else

5579

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5951

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5580

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5952

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5581

movegui(h,'northeast')

5953

movegui(h,'northeast')

5582

end

5954

end

5583

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5955

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5584

dir=fullfile(filepath, '*.csv');

5956

dir=fullfile(filepath, '*.csv');

5585

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5957

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5586

if filepath==0

5958

if filepath==0

5587

error('Not enough NEXT files')

5959

error('Not enough NEXT files')

5588

end

5960

end

5589

else

5961

else

5590

dir=fullfile(filepath, '*.csv');

5962

dir=fullfile(filepath, '*.csv');

5591

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5963

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5592

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5964

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5593

else

5965

else

5594

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5966

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5595

end

5967

end

5596

if filepath==0

5968

if filepath==0

5597

error('Not enough NEXT files')

5969

error('Not enough NEXT files')

5598

end

5970

end

5599

end

5971

end

5600

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5972

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5601

end

5973

end

5602

if isempty( filepath), filepath=lastfilepath; end

5974

if isempty( filepath), filepath=lastfilepath; end

5603

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5975

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5604

chdata(nxi).ext = fileext;

5976

chdata(nxi).ext = fileext;

5605

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5977

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5606

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5978

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5607

% chdata(nxi).A=param.a_fext;

5979

% chdata(nxi).A=param.a_fext;

5608

chdata(nxi).ftr=param.fb*param.f_f;

5980

chdata(nxi).ftr=param.fb*param.f_f;

5609

chdata(nxi).type='FEXT';

5981

chdata(nxi).type='FEXT';

5610

end

5982

end

5611

% now get NEXT file names into chdata structure

5983

% now get NEXT file names into chdata structure

5612

kxi=num_fext+kxi;

5984

kxi=num_fext+kxi;

5613

for nxi=kxi+1:num_next+kxi

5985

for nxi=kxi+1:num_next+kxi

5614

lastfilepath=filepath;

5986

lastfilepath=filepath;

5615

if size(file_list,2) ~= 0

5987

if size(file_list,2) ~= 0

5616

[filepath, basename, fileext]=fileparts(file_list{nxi});

5988

[filepath, basename, fileext]=fileparts(file_list{nxi});

5617

else

5989

else

5618

dir=fullfile(filepath, '*.csv');

5990

dir=fullfile(filepath, '*.csv');

5619

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5991

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5620

if filepath==0

5992

if filepath==0

5621

error('Not enough NEXT files')

5993

error('Not enough NEXT files')

5622

end

5994

end

5623

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5995

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5624

end

5996

end

5625

if isempty( filepath), filepath=lastfilepath; end

5997

if isempty( filepath), filepath=lastfilepath; end

5626

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5998

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5627

chdata(nxi).ext = fileext;

5999

chdata(nxi).ext = fileext;

5628

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6000

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5629

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6001

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5630

% chdata(nxi).A=param.A_next;

6002

% chdata(nxi).A=param.A_next;

5631

chdata(nxi).ftr=param.fb*param.f_n;

6003

chdata(nxi).ftr=param.fb*param.f_n;

5632

chdata(nxi).type='NEXT';

6004

chdata(nxi).type='NEXT';

5633

end

6005

end

5634

function half_UI=get_center_of_UI(samples_per_UI)

6006

function half_UI=get_center_of_UI(samples_per_UI)

5635

6007

5636

%half_UI reveals which value to use for the center of the UI. For eye

6008

%half_UI reveals which value to use for the center of the UI. For eye

5637

%width calculations, it is necessary to place the cursor in the center of the

6009

%width calculations, it is necessary to place the cursor in the center of the

5638

%UI window to ensure a 0 crossing on both left/right inside the window.

6010

%UI window to ensure a 0 crossing on both left/right inside the window.

5639

%This function was written in order to support even and odd samples_per_UI

6011

%This function was written in order to support even and odd samples_per_UI

5640

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

6012

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

5641

6013

5642

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

6014

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

5643

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

6015

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

5644

%the center of the UI is sample closest to 0.5

6016

%the center of the UI is sample closest to 0.5

5645

[temp_diff,half_UI]=min(abs(UI_window-0.5));

6017

[temp_diff,half_UI]=min(abs(UI_window-0.5));

5646

function results= get_cm_noise(M,PR,L,BER,OP)

6018

function results= get_cm_noise(M,PR,L,BER,OP)

5647

6019

5648

if ~exist('OP')

6020

if ~exist('OP')

5649

OP.DC_norm_test=0;

6021

OP.DC_norm_test=0;

5650

OP.DISPLAY_WINDOW=1;

6022

OP.DISPLAY_WINDOW=1;

5651

end

6023

end

5652

param.BinSize=1e-5;

6024

param.BinSize=1e-5;

5653

PR_test=-inf;

6025

PR_test=-inf;

5654

PR_fom_best=-inf;

6026

PR_fom_best=-inf;

5655

% hwaitbar=waitbar(0);

6027

% hwaitbar=waitbar(0);

5656

for ki=1:M

6028

for ki=1:M

5657

progress = ki/M;

6029

progress = ki/M;

5658

% if OP.DISPLAY_WINDOW

6030

% if OP.DISPLAY_WINDOW

5659

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

6031

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

5660

% else

6032

% else

5661

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

6033

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5662

% end

6034

% end

5663

tps=PR(ki:M:end);

6035

tps=PR(ki:M:end);

5664

if OP.DC_norm_test

6036

if OP.DC_norm_test

5665

PR_fom=(norm(tps));

6037

PR_fom=(norm(tps));

5666

else

6038

else

5667

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

6039

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

5668

cdf_test=cumsum(testpdf.y);

6040

cdf_test=cumsum(testpdf.y);

5669

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

6041

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

5670

PR_fom=PRn_test;

6042

PR_fom=PRn_test;

5671

end

6043

end

5672

if PR_fom > PR_fom_best

6044

if PR_fom > PR_fom_best

5673

PR_fom_best=PR_fom;

6045

PR_fom_best=PR_fom;

5674

best_ki=ki;

6046

best_ki=ki;

5675

end

6047

end

5676

if ~OP.DC_norm_test

6048

if ~OP.DC_norm_test

5677

results.DCn=PR_fom_best;

6049

results.DCn=PR_fom_best;

5678

results.DCn_pdf=testpdf;

6050

results.DCn_pdf=testpdf;

5679

results.DCn_cdf=cdf_test;

6051

results.DCn_cdf=cdf_test;

5680

else

6052

else

5681

results.DCn=PR_fom_best;

6053

results.DCn=PR_fom_best;

5682

end

6054

end

5683

results.DCn_p2p=max(PR)-min(PR);

6055

results.DCn_p2p=max(PR)-min(PR);

5684

end

6056

end

5685

6057

5686

6058

5687

6059

5688

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

6060

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

5689

SBR=chdata.eq_pulse_response(:)'; % row vector

6061

SBR=chdata.eq_pulse_response(:)'; % row vector

5690

type=chdata.type;

6062

type=chdata.type;

5691

samp_UI=param.samples_per_ui;

6063

samp_UI=param.samples_per_ui;

5692

residual_response = SBR;

6064

residual_response = SBR;

5693

6065

5694

if isequal(type, 'THRU')

6066

if isequal(type, 'THRU')

5695

% for thru pulse response:

6067

% for thru pulse response:

5696

% remove the cursor and the DFE postcursors (up to their limit), since

6068

% remove the cursor and the DFE postcursors (up to their limit), since

5697

% we only care about the residuals.

6069

% we only care about the residuals.

5698

6070

5699

if ~param.Floating_DFE

6071

if ~param.Floating_DFE

5700

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

6072

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

5701

else

6073

else

5702

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

6074

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

5703

end

6075

end

5704

if param.dfe_delta ~= 0

6076

if param.dfe_delta ~= 0

5705

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

6077

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

5706

else

6078

else

5707

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

6079

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5708

end

6080

end

5709

6081

5710

%AJG021820

6082

%AJG021820

5711

if ~param.Floating_DFE

6083

if ~param.Floating_DFE

5712

bmax_vec=residual_response(t_s)*[1,param.bmax];

6084

bmax_vec=residual_response(t_s)*[1,param.bmax];

5713

bmin_vec=residual_response(t_s)*[1,param.bmin];

6085

bmin_vec=residual_response(t_s)*[1,param.bmin];

5714

else

6086

else

5715

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

6087

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

5716

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

6088

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

5717

end

6089

end

5718

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6090

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5719

6091

5720

6092

5721

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

6093

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

5722

dfetaps=effective_cancelled_cursors/SBR(t_s);

6094

dfetaps=effective_cancelled_cursors/SBR(t_s);

5723

6095

5724

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6096

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5725

% really needed for COM, but helps debugging. May be factored out in future revisions.

6097

% really needed for COM, but helps debugging. May be factored out in future revisions.

5726

start_cancel = t_s-param.samples_per_ui/2;

6098

start_cancel = t_s-param.samples_per_ui/2;

5727

if ~param.Floating_DFE

6099

if ~param.Floating_DFE

5728

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

6100

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

5729

else

6101

else

5730

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

6102

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

5731

end

6103

end

5732

residual_response(start_cancel:end_cancel) = ...

6104

residual_response(start_cancel:end_cancel) = ...

5733

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6105

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5734

%else

6106

%else

5735

% for crosstalk pulse responses, nothing is cancelled, and all phases

6107

% for crosstalk pulse responses, nothing is cancelled, and all phases

5736

% are equally important.

6108

% are equally important.

5737

end

6109

end

5738

6110

5739

nui=round(length(residual_response)/param.samples_per_ui);

6111

nui=round(length(residual_response)/param.samples_per_ui);

5740

6112

5741

vs=zeros(nui-2, param.samples_per_ui);

6113

vs=zeros(nui-2, param.samples_per_ui);

5742

for i=1:param.samples_per_ui

6114

for i=1:param.samples_per_ui

5743

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

6115

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

5744

end

6116

end

5745

6117

5746

if OP.DISPLAY_WINDOW,

6118

if OP.DISPLAY_WINDOW,

5747

hwaitbar=waitbar(0);

6119

hwaitbar=waitbar(0);

5748

end

6120

end

5749

6121

5750

% determine which pdf to use

6122

% determine which pdf to use

5751

if isequal(type, 'THRU')

6123

if isequal(type, 'THRU')

5752

% one phase is interesting for thru

6124

% one phase is interesting for thru

5753

phases = mod(t_s,param.samples_per_ui);

6125

phases = mod(t_s,param.samples_per_ui);

5754

if phases==0, phases = param.samples_per_ui; end

6126

if phases==0, phases = param.samples_per_ui; end

5755

else

6127

else

5756

phases=1:samp_UI;

6128

phases=1:samp_UI;

5757

end

6129

end

5758

6130

5759

mxV = zeros(size(phases));

6131

mxV = zeros(size(phases));

5760

% we already found the phase in the PSD process for MMSE

6132

% we already found the phase in the PSD process for MMSE

5761

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

6133

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

5762

if isequal(type, 'THRU')

6134

if isequal(type, 'THRU')

5763

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

6135

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

5764

else

6136

else

5765

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

6137

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

5766

end

6138

end

5767

else

6139

else

5768

for k=phases

6140

for k=phases

5769

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

6141

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

5770

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6142

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

5771

progress = k/length(phases);

6143

progress = k/length(phases);

5772

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6144

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

5773

end

6145

end

5774

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

6146

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

5775

pdf=pdf_samples(pxi);

6147

pdf=pdf_samples(pxi);

5776

end

6148

end

5777

6149

5778

6150

5779

6151

5780

if OP.DISPLAY_WINDOW

6152

if OP.DISPLAY_WINDOW

5781

close(hwaitbar);

6153

close(hwaitbar);

5782

end

6154

end

5783

6155

5784

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

6156

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

5785

% Create PDF from interference vector using successive delta-set convolutions.

6157

% Create PDF from interference vector using successive delta-set convolutions.

5786

% input_vector = list of values of samples

6158

% input_vector = list of values of samples

5787

% return

6159

% return

5788

% pdf.x

6160

% pdf.x

5789

% pdf.y

6161

% pdf.y

5790

% pdf.vec

6162

% pdf.vec

5791

% pdf.bin

6163

% pdf.bin

5792

if ~exist('FAST_NOISE_CONV','var')

6164

if ~exist('FAST_NOISE_CONV','var')

5793

FAST_NOISE_CONV=0;

6165

FAST_NOISE_CONV=0;

5794

end

6166

end

5795

if max(input_vector) > BinSize

6167

if max(input_vector) > BinSize

5796

input_vector=input_vector(abs(input_vector)>BinSize);

6168

input_vector=input_vector(abs(input_vector)>BinSize);

5797

end

6169

end

5798

% for i = 1:length(input_vector)

6170

% for i = 1:length(input_vector)

5799

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

6171

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

5800

%end

6172

%end

5801

6173

5802

input_vector(abs(input_vector)<BinSize) = 0;

6174

input_vector(abs(input_vector)<BinSize) = 0;

5803

b=sign(input_vector);

6175

b=sign(input_vector);

5804

[input_vector,index]=sort(abs(input_vector),'descend');

6176

[input_vector,index]=sort(abs(input_vector),'descend');

5805

input_vector=input_vector.*b(index);

6177

input_vector=input_vector.*b(index);

5806

if FAST_NOISE_CONV

6178

if FAST_NOISE_CONV

5807

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

6179

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

5808

res_pdf= normal_dist(sig_res,5,BinSize);

6180

res_pdf= normal_dist(sig_res,5,BinSize);

5809

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

6181

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

5810

end

6182

end

5811

%% Equation 93A-39 %%

6183

%% Equation 93A-39 %%

5812

values = 2*(0:L-1)/(L-1)-1;

6184

values = 2*(0:L-1)/(L-1)-1;

5813

prob = ones(1,L)/L;

6185

prob = ones(1,L)/L;

5814

6186

5815

%% Initialize pdf to delta at 0

6187

%% Initialize pdf to delta at 0

5816

pdf=d_cpdf(BinSize, 0, 1);

6188

pdf=d_cpdf(BinSize, 0, 1);

5817

empty_pdf=pdf;

6189

empty_pdf=pdf;

5818

for k = 1:length(input_vector)

6190

for k = 1:length(input_vector)

5819

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

6191

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

5820

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

6192

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

5821

pdf=conv_fct(pdf, pdfn);

6193

pdf=conv_fct(pdf, pdfn);

5822

end

6194

end

5823

if FAST_NOISE_CONV

6195

if FAST_NOISE_CONV

5824

% pdf=conv_fct(pdf,res_pdf);

6196

% pdf=conv_fct(pdf,res_pdf);

5825

pdf=conv_fct_TEST(pdf,res_pdf);

6197

pdf=conv_fct_TEST(pdf,res_pdf);

5826

end

6198

end

5827

6199

5828

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

6200

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

5829

t_s_orig=t_s;

6201

t_s_orig=t_s;

5830

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

6202

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

5831

type=chdata.type;

6203

type=chdata.type;

5832

6204

5833

pulse_orig=chdata.eq_pulse_response(:)';

6205

pulse_orig=chdata.eq_pulse_response(:)';

5834

%build arbitrary time axis with step size = 1/samples per ui

6206

%build arbitrary time axis with step size = 1/samples per ui

5835

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

6207

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

5836

%force t_s at time =0 (makes the other things below easy)

6208

%force t_s at time =0 (makes the other things below easy)

5837

original_sample_time=old_time(t_s_orig);

6209

original_sample_time=old_time(t_s_orig);

5838

old_time=old_time-original_sample_time;

6210

old_time=old_time-original_sample_time;

5839

%build new time axis that forces time=0 to be in the axis

6211

%build new time axis that forces time=0 to be in the axis

5840

%unless the new/old samples per UI are integer ratios, time 0 will not be

6212

%unless the new/old samples per UI are integer ratios, time 0 will not be

5841

%there by default

6213

%there by default

5842

samp_UI=param.samples_for_C2M;

6214

samp_UI=param.samples_for_C2M;

5843

new_timea=[0:-1/samp_UI:min(old_time)];

6215

new_timea=[0:-1/samp_UI:min(old_time)];

5844

new_timeb=[0:1/samp_UI:max(old_time)];

6216

new_timeb=[0:1/samp_UI:max(old_time)];

5845

new_time=[fliplr(new_timea) new_timeb(2:end)];

6217

new_time=[fliplr(new_timea) new_timeb(2:end)];

5846

SBR=interp1(old_time,pulse_orig,new_time);

6218

SBR=interp1(old_time,pulse_orig,new_time);

5847

%new sample time is simply the point where new_time = 0

6219

%new sample time is simply the point where new_time = 0

5848

[tmp,t_s]=min(abs(new_time));

6220

[tmp,t_s]=min(abs(new_time));

5849

6221

5850

residual_response = SBR;

6222

residual_response = SBR;

5851

6223

5852

half_UI=get_center_of_UI(samp_UI);

6224

half_UI=get_center_of_UI(samp_UI);

5853

6225

5854

if isequal(type, 'THRU')

6226

if isequal(type, 'THRU')

5855

% for thru pulse response:

6227

% for thru pulse response:

5856

% remove the cursor and the DFE postcursors (up to their limit), since

6228

% remove the cursor and the DFE postcursors (up to their limit), since

5857

% we only care about the residuals.

6229

% we only care about the residuals.

5858

6230

5859

%AJG021820

6231

%AJG021820

5860

if ~param.Floating_DFE

6232

if ~param.Floating_DFE

5861

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

6233

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

5862

else

6234

else

5863

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

6235

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

5864

end

6236

end

5865

if param.dfe_delta ~= 0

6237

if param.dfe_delta ~= 0

5866

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

6238

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

5867

else

6239

else

5868

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

6240

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5869

end

6241

end

5870

6242

5871

if ~param.Floating_DFE

6243

if ~param.Floating_DFE

5872

bmax_vec=residual_response(t_s)*[param.bmax];

6244

bmax_vec=residual_response(t_s)*[param.bmax];

5873

bmin_vec=residual_response(t_s)*[param.bmin];

6245

bmin_vec=residual_response(t_s)*[param.bmin];

5874

else

6246

else

5875

bmax_vec=residual_response(t_s)*[param.use_bmax];

6247

bmax_vec=residual_response(t_s)*[param.use_bmax];

5876

bmin_vec=residual_response(t_s)*[param.use_bmin];

6248

bmin_vec=residual_response(t_s)*[param.use_bmin];

5877

end

6249

end

5878

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6250

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5879

6251

5880

6252

5881

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

6253

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

5882

dfetaps=effective_cancelled_cursors/SBR(t_s);

6254

dfetaps=effective_cancelled_cursors/SBR(t_s);

5883

6255

5884

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6256

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5885

% really needed for COM, but helps debugging. May be factored out in future revisions.

6257

% really needed for COM, but helps debugging. May be factored out in future revisions.

5886

6258

5887

%avoid dividing samp_UI by 2 in case it is not even

6259

%avoid dividing samp_UI by 2 in case it is not even

5888

start_cancel=t_s-half_UI+1+samp_UI;

6260

start_cancel=t_s-half_UI+1+samp_UI;

5889

%AJG021820

6261

%AJG021820

5890

if ~param.Floating_DFE

6262

if ~param.Floating_DFE

5891

end_cancel=start_cancel+param.ndfe*samp_UI-1;

6263

end_cancel=start_cancel+param.ndfe*samp_UI-1;

5892

else

6264

else

5893

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

6265

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

5894

end

6266

end

5895

residual_response(start_cancel:end_cancel) = ...

6267

residual_response(start_cancel:end_cancel) = ...

5896

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6268

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5897

%else

6269

%else

5898

% for crosstalk pulse responses, nothing is cancelled, and all phases

6270

% for crosstalk pulse responses, nothing is cancelled, and all phases

5899

% are equally important.

6271

% are equally important.

5900

6272

5901

%remove entire cursor UI

6273

%remove entire cursor UI

5902

uiv_start=start_cancel-samp_UI;

6274

uiv_start=start_cancel-samp_UI;

5903

uiv_end=uiv_start+samp_UI-1;

6275

uiv_end=uiv_start+samp_UI-1;

5904

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

6276

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

5905

residual_response(uiv_start:uiv_end)=0;

6277

residual_response(uiv_start:uiv_end)=0;

5906

end

6278

end

5907

6279

5908

nui=round(length(residual_response)/samp_UI);

6280

nui=round(length(residual_response)/samp_UI);

5909

6281

5910

6282

5911

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6283

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5912

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

6284

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

5913

%response without DFE included. (Can't include DFE for jitter calc)

6285

%response without DFE included. (Can't include DFE for jitter calc)

5914

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6286

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5915

6287

5916

% if OP.DISPLAY_WINDOW,

6288

% if OP.DISPLAY_WINDOW,

5917

% hwaitbar=waitbar(0);

6289

% hwaitbar=waitbar(0);

5918

% end

6290

% end

5919

6291

5920

% determine which pdf to use

6292

% determine which pdf to use

5921

if isequal(type, 'THRU')

6293

if isequal(type, 'THRU')

5922

% one phase is interesting for thru

6294

% one phase is interesting for thru

5923

phases = mod(t_s,samp_UI);

6295

phases = mod(t_s,samp_UI);

5924

if phases==0, phases = samp_UI; end

6296

if phases==0, phases = samp_UI; end

5925

else

6297

else

5926

phases=1:samp_UI;

6298

phases=1:samp_UI;

5927

end

6299

end

5928

6300

5929

mxV = zeros(size(phases));

6301

mxV = zeros(size(phases));

5930

6302

5931

%phases reveals the raw position in the UI window of the cursor.

6303

%phases reveals the raw position in the UI window of the cursor.

5932

%shift_amount is the amount to shift so that it aligns with half_UI

6304

%shift_amount is the amount to shift so that it aligns with half_UI

5933

shift_amount=half_UI-phases;

6305

shift_amount=half_UI-phases;

5934

%vs_shift puts the cursor at the center

6306

%vs_shift puts the cursor at the center

5935

vs_shift=circshift(vs,[0 shift_amount]);

6307

vs_shift=circshift(vs,[0 shift_amount]);

5936

L=size(vs_raw,1);

6308

L=size(vs_raw,1);

5937

%allow partial UI computation through pdf_range

6309

%allow partial UI computation through pdf_range

5938

%if pdf_range is empty, do full UI

6310

%if pdf_range is empty, do full UI

5939

if isempty(pdf_range)

6311

if isempty(pdf_range)

5940

pdf_range=1:samp_UI;

6312

pdf_range=1:samp_UI;

5941

else

6313

else

5942

pdf_range=min(pdf_range):max(pdf_range);

6314

pdf_range=min(pdf_range):max(pdf_range);

5943

end

6315

end

5944

h_j_full=zeros(L,samp_UI);

6316

h_j_full=zeros(L,samp_UI);

5945

for k=pdf_range

6317

for k=pdf_range

5946

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6318

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

5947

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6319

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

5948

%progress = k/length(phases);

6320

%progress = k/length(phases);

5949

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6321

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

5950

6322

5951

%build the circshift of h_j_full into the loop to support a reduced

6323

%build the circshift of h_j_full into the loop to support a reduced

5952

%range of sampling points. circshift at the end only works if doing the

6324

%range of sampling points. circshift at the end only works if doing the

5953

%full range of sampling points. And shifting before the loop will

6325

%full range of sampling points. And shifting before the loop will

5954

%yield the wrong answer at the edges of the UI

6326

%yield the wrong answer at the edges of the UI

5955

hk=k-shift_amount;

6327

hk=k-shift_amount;

5956

if hk<1

6328

if hk<1

5957

hk=hk+samp_UI;

6329

hk=hk+samp_UI;

5958

elseif hk>samp_UI

6330

elseif hk>samp_UI

5959

hk=hk-samp_UI;

6331

hk=hk-samp_UI;

5960

end

6332

end

5961

if hk==1

6333

if hk==1

5962

%when hk=1, the early UI is the last column

6334

%when hk=1, the early UI is the last column

5963

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6335

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

5964

elseif hk==samp_UI

6336

elseif hk==samp_UI

5965

%when hk=samp_UI, the late UI is the first column

6337

%when hk=samp_UI, the late UI is the first column

5966

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6338

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

5967

else

6339

else

5968

%for all other cases, do the normal late=+1, early = -1

6340

%for all other cases, do the normal late=+1, early = -1

5969

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6341

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

5970

end

6342

end

5971

end

6343

end

5972

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6344

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

5973

% filename parsing and acquisition

6345

% filename parsing and acquisition

5974

%------------------------------------------------------------------

6346

%------------------------------------------------------------------

5975

%----------put files names into chdata structure ---------

6347

%----------put files names into chdata structure ---------

5976

% The thru file has the index of 1

6348

% The thru file has the index of 1

5977

% crosstalk file are indexed from 2

6349

% crosstalk file are indexed from 2

5978

% nxi is incremented each time a file is read in so that nxi will end

6350

% nxi is incremented each time a file is read in so that nxi will end

5979

filepath=[]; % path name for file

6351

filepath=[]; % path name for file

5980

nxi=0; % file index

6352

nxi=0; % file index

5981

% get the THRU file

6353

% get the THRU file

5982

if size(file_list,2) ~= 0

6354

if size(file_list,2) ~= 0

5983

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6355

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5984

[filepath, basename, fileext]=fileparts(file_list{1});

6356

[filepath, basename, fileext]=fileparts(file_list{1});

5985

6357

5986

else

6358

else

5987

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6359

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5988

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6360

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5989

movegui(h,'northeast')

6361

movegui(h,'northeast')

5990

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6362

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

5991

end

6363

end

5992

if OP.ERL == 2

6364

if OP.ERL == 2

5993

dir=fullfile(filepath, '*.s2p');

6365

dir=fullfile(filepath, '*.s2p');

5994

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6366

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

5995

if filepath == 0

6367

if filepath == 0

5996

error('No RL measurement file')

6368

error('No RL measurement file')

5997

end

6369

end

5998

else

6370

else

5999

dir=fullfile(filepath, '*.s4p');

6371

dir=fullfile(filepath, '*.s4p');

6000

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6372

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6001

if filepath == 0

6373

if filepath == 0

6002

error('No Thru file')

6374

error('No Thru file')

6003

end

6375

end

6004

end

6376

end

6005

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6377

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6006

end

6378

end

6007

nxi=nxi+1;

6379

nxi=nxi+1;

6008

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6380

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6009

chdata(nxi).ext = fileext;

6381

chdata(nxi).ext = fileext;

6010

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6382

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6011

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6383

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6012

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6384

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6013

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6385

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6014

chdata(nxi).type='THRU';

6386

chdata(nxi).type='THRU';

6015

chdata(nxi).ftr=param.fb*param.f_v;

6387

chdata(nxi).ftr=param.fb*param.f_v;

6016

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6388

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6017

6389

6018

% now get FEXT file names into chdata structure

6390

% now get FEXT file names into chdata structure

6019

kxi=nxi;

6391

kxi=nxi;

6020

for nxi=kxi+1:num_fext+kxi

6392

for nxi=kxi+1:num_fext+kxi

6021

lastfilepath=filepath;

6393

lastfilepath=filepath;

6022

if size(file_list,2) ~= 0

6394

if size(file_list,2) ~= 0

6023

[filepath, basename, fileext]=fileparts(file_list{nxi});

6395

[filepath, basename, fileext]=fileparts(file_list{nxi});

6024

else

6396

else

6025

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6397

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6026

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6398

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6027

movegui(h,'northeast')

6399

movegui(h,'northeast')

6028

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6400

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6029

end

6401

end

6030

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6402

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6031

dir=fullfile(filepath, '*.s4p');

6403

dir=fullfile(filepath, '*.s4p');

6032

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6404

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6033

if filepath==0

6405

if filepath==0

6034

error('Not enough NEXT files')

6406

error('Not enough NEXT files')

6035

end

6407

end

6036

else

6408

else

6037

dir=fullfile(filepath, '*.s4p');

6409

dir=fullfile(filepath, '*.s4p');

6038

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6410

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6039

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6411

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6040

else

6412

else

6041

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6413

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6042

end

6414

end

6043

if filepath==0

6415

if filepath==0

6044

error('Not enough NEXT files')

6416

error('Not enough NEXT files')

6045

end

6417

end

6046

end

6418

end

6047

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6419

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6048

end

6420

end

6049

if isempty( filepath), filepath=lastfilepath; end

6421

if isempty( filepath), filepath=lastfilepath; end

6050

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6422

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6051

chdata(nxi).ext = fileext;

6423

chdata(nxi).ext = fileext;

6052

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6424

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6053

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6425

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6054

% chdata(nxi).A=param.a_fext;

6426

% chdata(nxi).A=param.a_fext;

6055

chdata(nxi).ftr=param.fb*param.f_f;

6427

chdata(nxi).ftr=param.fb*param.f_f;

6056

chdata(nxi).type='FEXT';

6428

chdata(nxi).type='FEXT';

6057

end

6429

end

6058

% now get NEXT file names into chdata structure

6430

% now get NEXT file names into chdata structure

6059

kxi=num_fext+kxi;

6431

kxi=num_fext+kxi;

6060

for nxi=kxi+1:num_next+kxi

6432

for nxi=kxi+1:num_next+kxi

6061

lastfilepath=filepath;

6433

lastfilepath=filepath;

6062

if size(file_list,2) ~= 0

6434

if size(file_list,2) ~= 0

6063

[filepath, basename, fileext]=fileparts(file_list{nxi});

6435

[filepath, basename, fileext]=fileparts(file_list{nxi});

6064

else

6436

else

6065

dir=fullfile(filepath, '*.s4p');

6437

dir=fullfile(filepath, '*.s4p');

6066

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6438

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6067

if filepath==0

6439

if filepath==0

6068

error('Not enough NEXT files')

6440

error('Not enough NEXT files')

6069

end

6441

end

6070

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6442

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6071

end

6443

end

6072

if isempty( filepath), filepath=lastfilepath; end

6444

if isempty( filepath), filepath=lastfilepath; end

6073

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6445

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6074

chdata(nxi).ext = fileext;

6446

chdata(nxi).ext = fileext;

6075

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6447

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6076

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6448

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6077

% chdata(nxi).A=param.A_next;

6449

% chdata(nxi).A=param.A_next;

6078

chdata(nxi).ftr=param.fb*param.f_n;

6450

chdata(nxi).ftr=param.fb*param.f_n;

6079

chdata(nxi).type='NEXT';

6451

chdata(nxi).type='NEXT';

6080

end

6452

end

6081

6453

6082

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6454

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6083

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6455

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6084

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6456

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6085

% H_r - receiver filter, Butterworth

6457

% H_r - receiver filter, Butterworth

6086

% H_ctf - total gain of CTLE and low freq filtering

6458

% H_ctf - total gain of CTLE and low freq filtering

6087

% H_dc - the common mode channel gain

6459

% H_dc - the common mode channel gain

6088

% param.eta_0 -input referred Rx noise

6460

% param.eta_0 -input referred Rx noise

6089

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6461

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6090

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6462

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6091

%% Equation 93A-35 - independent of FFE setting %%

6463

%% Equation 93A-35 - independent of FFE setting %%

6092

sigma_N1 = sqrt(param.eta_0*sum( abs(H_sy(2:end) .* H_r(2:end) .* H_ctf(2:end) ).^2 .* diff(chdata(1).faxis)/1e9));% eta_0 is V^2/Ghz i.e. /1

6464

sigma_N1 = sqrt(param.eta_0*sum( abs(H_sy(2:end) .* H_r(2:end) .* H_ctf(2:end) ).^2 .* diff(chdata(1).faxis)/1e9));% eta_0 is V^2/Ghz i.e. /1

6093

if sum(param.AC_CM_RMS) ~= 0

6465

if sum(param.AC_CM_RMS) ~= 0

6094

sigma_ACCM=0;

6466

sigma_ACCM=0;

6095

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6467

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6096

for i=1:length(chdata)

6468

for i=1:length(chdata)

6097

H_dc=abs(squeeze(chdata(i).sdc21));

6469

H_dc=abs(squeeze(chdata(i).sdc21));

6098

sigma_ACCM_acc= sqrt( 2*param.AC_CM_RMS_TX^2.*sum( abs(H_sy(2:length(f_int)) .* H_r(2:length(f_int)) .* H_ctf(2:length(f_int)).*H_dc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end) );

6470

sigma_ACCM_acc= sqrt( 2*param.AC_CM_RMS_TX^2.*sum( abs(H_sy(2:length(f_int)) .* H_r(2:length(f_int)) .* H_ctf(2:length(f_int)).*H_dc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end) );

6099

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6471

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6100

end

6472

end

6101

sigma_N=norm([sigma_N1,sigma_ACCM]);

6473

sigma_N=norm([sigma_N1,sigma_ACCM]);

6102

else

6474

else

6103

sigma_N=sigma_N1;

6475

sigma_N=sigma_N1;

6104

end

6476

end

6105

%%

6477

%%

6106

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6478

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6107

% for Rx calibratrion only

6479

% for Rx calibratrion only

6108

% the FEXT channel for calibration basically a DC connection unlike normal

6480

% the FEXT channel for calibration basically a DC connection unlike normal

6109

% FEXT channels which are nearly open at DC channels

6481

% FEXT channels which are nearly open at DC channels

6110

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6482

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6111

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6483

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6112

if size(chdata,2) >= 2

6484

if size(chdata,2) >= 2

6113

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6485

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6114

else

6486

else

6115

Hnoise_channel=1;

6487

Hnoise_channel=1;

6116

end

6488

end

6117

f=chdata(2).faxis;

6489

f=chdata(2).faxis;

6118

f_hp=param.f_hp;

6490

f_hp=param.f_hp;

6119

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6491

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6120

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6492

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6121

else

6493

else

6122

H_hp=ones(1,length(f));

6494

H_hp=ones(1,length(f));

6123

end

6495

end

6124

%% Equation 93A-47 or 162-12

6496

%% Equation 93A-47 or 162-12

6125

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6497

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6126

6498

6127

%% Equation 93A-48 or 162-14%%

6499

%% Equation 93A-48 or 162-14%%

6128

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6500

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6129

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6501

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6130

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6502

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6131

% Modified not to double count crosstalk: John Ewen 13/12/2018

6503

% Modified not to double count crosstalk: John Ewen 13/12/2018

6132

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6504

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6133

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6505

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6134

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6506

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6135

f=chdata(1).faxis;

6507

f=chdata(1).faxis;

6136

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6508

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6137

if(f(1)==0)

6509

if(f(1)==0)

6138

temp_angle(1)=1e-20;% we don't want to divide by zero

6510

temp_angle(1)=1e-20;% we don't want to divide by zero

6139

end

6511

end

6140

PWF_tx=ones(1,length(f));

6512

PWF_tx=ones(1,length(f));

6141

if max(upsampled_txffe) > 0

6513

if max(upsampled_txffe) > 0

6142

PWF_tx=zeros(1,length(f));

6514

PWF_tx=zeros(1,length(f));

6143

[mcur,icur] = max(upsampled_txffe);

6515

[mcur,icur] = max(upsampled_txffe);

6144

if exist('phase_memory','var') && ~isempty(phase_memory)

6516

if exist('phase_memory','var') && ~isempty(phase_memory)

6145

pre_calc=1;

6517

pre_calc=1;

6146

else

6518

else

6147

pre_calc=0;

6519

pre_calc=0;

6148

end

6520

end

6149

for ii=1:length(upsampled_txffe)

6521

for ii=1:length(upsampled_txffe)

6150

if upsampled_txffe(ii)==0

6522

if upsampled_txffe(ii)==0

6151

%speed up: skip cases when txffe=0

6523

%speed up: skip cases when txffe=0

6152

continue;

6524

continue;

6153

end

6525

end

6154

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6526

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6155

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6527

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6156

% that is needed

6528

% that is needed

6157

if ii==icur

6529

if ii==icur

6158

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6530

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6159

PWF_tx = PWF_tx + upsampled_txffe(ii);

6531

PWF_tx = PWF_tx + upsampled_txffe(ii);

6160

else

6532

else

6161

if pre_calc

6533

if pre_calc

6162

%speed up: avoid vector exp calculation by externally pre-calculating it

6534

%speed up: avoid vector exp calculation by externally pre-calculating it

6163

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6535

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6164

else

6536

else

6165

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6537

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6166

end

6538

end

6167

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6539

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6168

PWF_tx = PWF_tx + transpose(term_ii(:));

6540

PWF_tx = PWF_tx + transpose(term_ii(:));

6169

end

6541

end

6170

% /Adee

6542

% /Adee

6171

end

6543

end

6172

end

6544

end

6173

PWF_rx=ones(1,length(f));

6545

PWF_rx=ones(1,length(f));

6174

if exist('C','var')

6546

if exist('C','var')

6175

PWF_rx=zeros(1,length(f));

6547

PWF_rx=zeros(1,length(f));

6176

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6548

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6177

if C(ii+param.RxFFE_cmx+1)==0

6549

if C(ii+param.RxFFE_cmx+1)==0

6178

%speed up: skip cases when rxffe=0

6550

%speed up: skip cases when rxffe=0

6179

continue;

6551

continue;

6180

end

6552

end

6181

if ii+1==0

6553

if ii+1==0

6182

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6554

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6183

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6555

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6184

else

6556

else

6185

if pre_calc

6557

if pre_calc

6186

%speed up: avoid vector exp calculation by externally pre-calculating it

6558

%speed up: avoid vector exp calculation by externally pre-calculating it

6187

%The latter columns of phase_memory hold RXFFE shift vectors

6559

%The latter columns of phase_memory hold RXFFE shift vectors

6188

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6560

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6189

term_ii=transpose(term_ii);

6561

term_ii=transpose(term_ii);

6190

else

6562

else

6191

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6563

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6192

end

6564

end

6193

PWF_rx=PWF_rx+term_ii;

6565

PWF_rx=PWF_rx+term_ii;

6194

end

6566

end

6195

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6567

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6196

end

6568

end

6197

end

6569

end

6198

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6570

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6199

for ii=2:size(chdata,2)

6571

for ii=2:size(chdata,2)

6200

SINC = sin(temp_angle)./temp_angle;

6572

SINC = sin(temp_angle)./temp_angle;

6201

PWF_data=SINC.^2;

6573

PWF_data=SINC.^2;

6202

PWF=PWF_data.*PWF_rx; % power weight function

6574

PWF=PWF_data.*PWF_rx; % power weight function

6203

PWFnext=abs(PWF);

6575

PWFnext=abs(PWF);

6204

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6576

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6205

PWFfext=abs(PWF);

6577

PWFfext=abs(PWF);

6206

if isequal(chdata(ii).type, 'FEXT')

6578

if isequal(chdata(ii).type, 'FEXT')

6207

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6579

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6208

MDFEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFfext(1:index_f2).*abs(MDFEXT(1:index_f2)).^2)); %eq 46

6580

MDFEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFfext(1:index_f2).*abs(MDFEXT(1:index_f2)).^2)); %eq 46

6209

elseif isequal(chdata(ii).type, 'NEXT')

6581

elseif isequal(chdata(ii).type, 'NEXT')

6210

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6582

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6211

MDNEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFnext(1:index_f2).*abs(MDNEXT(1:index_f2)).^2)); %eq 47

6583

MDNEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFnext(1:index_f2).*abs(MDNEXT(1:index_f2)).^2)); %eq 47

6212

end

6584

end

6213

end

6585

end

6214

if nargout == 1 && isequal(type,'NEXT')

6586

if nargout == 1 && isequal(type,'NEXT')

6215

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6587

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6216

elseif nargout == 1 && isequal(type,'FEXT')

6588

elseif nargout == 1 && isequal(type,'FEXT')

6217

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6589

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6218

elseif nargout == 3

6590

elseif nargout == 3

6219

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6591

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6220

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6592

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6221

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6593

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6222

end

6594

end

6223

6595

6224

function out=hrem(h,index,N_bf,bmaxg)

6596

function out=hrem(h,index,N_bf,bmaxg)

6225

6597

6226

out=[ h(1:index-1) h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) h(index+N_bf:end) ];

6598

out=[ h(1:index-1) h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) h(index+N_bf:end) ];

6227

% faster than single line function

6599

% faster than single line function

6228

% hrem =@(h,index,N_bf,bmaxg) ...

6600

% hrem =@(h,index,N_bf,bmaxg) ...

6229

% [ h(1:index-1) ...

6601

% [ h(1:index-1) ...

6230

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6602

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6231

% h(index+N_bf:end) ]...

6603

% h(index+N_bf:end) ]...

6232

% ;

6604

% ;

6233

6605

6234

%% floating DFE taps

6606

%% floating DFE taps

6235

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6607

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6236

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6608

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6237

% Sout = interp_Sparam(Sin,fin,fout)

6609

% Sout = interp_Sparam(Sin,fin,fout)

6238

%

6610

%

6239

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6611

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6240

% fout.

6612

% fout.

6241

6613

6242

if ( fin(end)<fout(end) )

6614

if ( fin(end)<fout(end) )

6243

% warning('Channel high frequencies extrapolation might be inaccurate!');

6615

% warning('Channel high frequencies extrapolation might be inaccurate!');

6244

end

6616

end

6245

6617

6246

H_mag = abs(Sin);

6618

H_mag = abs(Sin);

6247

H_mag(H_mag<eps)=eps; % handle ill cases...

6619

H_mag(H_mag<eps)=eps; % handle ill cases...

6248

H_ph = unwrap(angle(Sin));

6620

H_ph = unwrap(angle(Sin));

6249

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6621

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6250

% user ignore that.

6622

% user ignore that.

6251

if mean(diff(H_ph))>0

6623

if mean(diff(H_ph))>0

6252

if OP.DEBUG

6624

if OP.DEBUG

6253

warning('Anti-causal response found. Finer frequency step is required for this channel');

6625

warning('Anti-causal response found. Finer frequency step is required for this channel');

6254

else

6626

else

6255

error('Anti-causal response found. Finer frequency step is required for this channel');

6627

error('Anti-causal response found. Finer frequency step is required for this channel');

6256

end

6628

end

6257

end

6629

end

6258

6630

6259

%opt_interp_Sparam_mag='linear_trend_to_DC';

6631

%opt_interp_Sparam_mag='linear_trend_to_DC';

6260

switch opt_interp_Sparam_mag

6632

switch opt_interp_Sparam_mag

6261

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6633

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6262

if -iscolumn(H_mag), H_mag=H_mag.';end

6634

if -iscolumn(H_mag), H_mag=H_mag.';end

6263

if -iscolumn(fin), fin=fin.';end

6635

if -iscolumn(fin), fin=fin.';end

6264

fin_x=fin;

6636

fin_x=fin;

6265

H_mag_x=H_mag(:);

6637

H_mag_x=H_mag(:);

6266

if fin(1)>0

6638

if fin(1)>0

6267

p=polyfit(fin(1:10), H_mag(1:10), 1);

6639

p=polyfit(fin(1:10), H_mag(1:10), 1);

6268

dc_trend_val=polyval(p, 0);

6640

dc_trend_val=polyval(p, 0);

6269

fin_x=[0, fin_x];

6641

fin_x=[0, fin_x];

6270

H_mag_x = [dc_trend_val; H_mag_x];

6642

H_mag_x = [dc_trend_val; H_mag_x];

6271

end

6643

end

6272

if fin(end)<fout(end)

6644

if fin(end)<fout(end)

6273

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6645

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6274

mid_freq_ind=round(length(fin)/2);

6646

mid_freq_ind=round(length(fin)/2);

6275

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6647

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6276

warning(warn_state);

6648

warning(warn_state);

6277

hf_trend_val=polyval(p, fout(end));

6649

hf_trend_val=polyval(p, fout(end));

6278

if hf_trend_val>H_mag(end)

6650

if hf_trend_val>H_mag(end)

6279

hf_trend_val=H_mag(end);

6651

hf_trend_val=H_mag(end);

6280

hf_logtrend_val = H_mag(end);

6652

hf_logtrend_val = H_mag(end);

6281

elseif hf_trend_val<eps

6653

elseif hf_trend_val<eps

6282

hf_trend_val=eps;

6654

hf_trend_val=eps;

6283

hf_logtrend_val = realmin;

6655

hf_logtrend_val = realmin;

6284

end

6656

end

6285

fin_x=[fin_x, fout(end)];

6657

fin_x=[fin_x, fout(end)];

6286

H_mag_x = [H_mag_x; hf_trend_val];

6658

H_mag_x = [H_mag_x; hf_trend_val];

6287

end

6659

end

6288

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6660

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6289

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6661

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6290

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6662

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6291

indx = find(fout > fin(end),1,'first');

6663

indx = find(fout > fin(end),1,'first');

6292

H_mag_i(indx:end) = H_logmag_i(indx:end);

6664

H_mag_i(indx:end) = H_logmag_i(indx:end);

6293

end

6665

end

6294

case 'trend_to_DC'

6666

case 'trend_to_DC'

6295

% extrapolate to trend value at DC.

6667

% extrapolate to trend value at DC.

6296

if -iscolumn(H_mag), H_mag=H_mag.';end

6668

if -iscolumn(H_mag), H_mag=H_mag.';end

6297

if -iscolumn(fin), fin=fin.';end

6669

if -iscolumn(fin), fin=fin.';end

6298

fin_x=fin;

6670

fin_x=fin;

6299

H_mag_x=H_mag;

6671

H_mag_x=H_mag;

6300

if fin(1)>0

6672

if fin(1)>0

6301

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6673

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6302

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6674

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6303

dc_trend_val=10^polyval(p, 0);

6675

dc_trend_val=10^polyval(p, 0);

6304

fin_x=[0, fin_x];

6676

fin_x=[0, fin_x];

6305

H_mag_x = [dc_trend_val H_mag_x];

6677

H_mag_x = [dc_trend_val H_mag_x];

6306

end

6678

end

6307

if fin(end)<fout(end)

6679

if fin(end)<fout(end)

6308

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6680

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6309

mid_freq_ind=round(length(fin)/2);

6681

mid_freq_ind=round(length(fin)/2);

6310

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6682

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6311

warning(warn_state);

6683

warning(warn_state);

6312

hf_trend_val=10^polyval(p, fout(end));

6684

hf_trend_val=10^polyval(p, fout(end));

6313

if hf_trend_val>H_mag(end)

6685

if hf_trend_val>H_mag(end)

6314

hf_trend_val=H_mag(end);

6686

hf_trend_val=H_mag(end);

6315

end

6687

end

6316

fin_x=[fin_x, fout(end)];

6688

fin_x=[fin_x, fout(end)];

6317

H_mag_x = [H_mag_x hf_trend_val];

6689

H_mag_x = [H_mag_x hf_trend_val];

6318

end

6690

end

6319

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6691

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6320

case 'extrap_to_DC_or_zero'

6692

case 'extrap_to_DC_or_zero'

6321

% same as extrap_to_DC but detect AC-coupled channels and

6693

% same as extrap_to_DC but detect AC-coupled channels and

6322

% extrapolate them to 0.

6694

% extrapolate them to 0.

6323

if fin(1)>0 && 20*log10(H_mag(1))<-20

6695

if fin(1)>0 && 20*log10(H_mag(1))<-20

6324

% assume AC coupling, with 0 at DC

6696

% assume AC coupling, with 0 at DC

6325

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6697

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6326

else

6698

else

6327

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6699

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6328

end

6700

end

6329

H_mag_i(fout>fin(end)) = H_mag(end);

6701

H_mag_i(fout>fin(end)) = H_mag(end);

6330

case 'extrap_to_DC'

6702

case 'extrap_to_DC'

6331

% first extrapolate down to DC, then use highest available frequency

6703

% first extrapolate down to DC, then use highest available frequency

6332

% for higher frequencies

6704

% for higher frequencies

6333

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6705

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6334

H_mag_i(fout>fin(end)) = H_mag(end);

6706

H_mag_i(fout>fin(end)) = H_mag(end);

6335

case 'old'

6707

case 'old'

6336

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6708

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6337

otherwise

6709

otherwise

6338

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6710

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6339

end

6711

end

6340

6712

6341

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6713

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6342

6714

6343

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6715

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6344

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6716

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6345

switch opt_interp_Sparam_phase

6717

switch opt_interp_Sparam_phase

6346

case 'old'

6718

case 'old'

6347

H_ph_i = H_ph_i-H_ph_i(1);

6719

H_ph_i = H_ph_i-H_ph_i(1);

6348

case 'zero_DC'

6720

case 'zero_DC'

6349

H_ph_i(1) = 0;

6721

H_ph_i(1) = 0;

6350

case 'interp_to_DC'

6722

case 'interp_to_DC'

6351

if fin(1) ~= 0

6723

if fin(1) ~= 0

6352

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6724

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6353

end

6725

end

6354

case 'extrap_cubic_to_dc_linear_to_inf'

6726

case 'extrap_cubic_to_dc_linear_to_inf'

6355

if fin(1) ~= 0

6727

if fin(1) ~= 0

6356

% estimate low frequency group delay

6728

% estimate low frequency group delay

6357

group_delay = -diff(H_ph(:))./diff(fin(:));

6729

group_delay = -diff(H_ph(:))./diff(fin(:));

6358

low_freq_gd = group_delay(1:50);

6730

low_freq_gd = group_delay(1:50);

6359

% calculate trend, throwing away outliers

6731

% calculate trend, throwing away outliers

6360

m = median(low_freq_gd); sigma = std(low_freq_gd);

6732

m = median(low_freq_gd); sigma = std(low_freq_gd);

6361

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6733

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6362

% correct outliers in first 10 phase samples

6734

% correct outliers in first 10 phase samples

6363

for k=10:-1:1

6735

for k=10:-1:1

6364

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6736

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6365

end

6737

end

6366

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6738

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6367

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6739

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6368

% modification - trend to inf

6740

% modification - trend to inf

6369

if (1)

6741

if (1)

6370

high_freq_gd = group_delay(end-50:end);

6742

high_freq_gd = group_delay(end-50:end);

6371

% calculate trend, throwing away outliers

6743

% calculate trend, throwing away outliers

6372

m = median(high_freq_gd); sigma = std(high_freq_gd);

6744

m = median(high_freq_gd); sigma = std(high_freq_gd);

6373

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6745

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6374

hf_extrap_range = find(fout>fin(end));

6746

hf_extrap_range = find(fout>fin(end));

6375

last_data_sample = hf_extrap_range(1)-1;

6747

last_data_sample = hf_extrap_range(1)-1;

6376

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6748

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6377

% for k=hf_range

6749

% for k=hf_range

6378

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6750

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6379

% end

6751

% end

6380

end

6752

end

6381

6753

6382

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6754

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6383

H_ph_i=H_ph_cubic;

6755

H_ph_i=H_ph_cubic;

6384

H_ph_i(indx:end) = H_ph_linear(indx:end);

6756

H_ph_i(indx:end) = H_ph_linear(indx:end);

6385

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6757

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6386

end

6758

end

6387

case 'interp_and_shift_to_DC'

6759

case 'interp_and_shift_to_DC'

6388

if fin(1) ~= 0

6760

if fin(1) ~= 0

6389

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6761

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6390

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6762

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6391

end

6763

end

6392

case 'trend_and_shift_to_DC'

6764

case 'trend_and_shift_to_DC'

6393

% estimate low frequency group delay

6765

% estimate low frequency group delay

6394

group_delay = -diff(H_ph(:))./diff(fin(:));

6766

group_delay = -diff(H_ph(:))./diff(fin(:));

6395

low_freq_gd = group_delay(1:50);

6767

low_freq_gd = group_delay(1:50);

6396

% calculate trend, throwing away outliers

6768

% calculate trend, throwing away outliers

6397

m = median(low_freq_gd); sigma = std(low_freq_gd);

6769

m = median(low_freq_gd); sigma = std(low_freq_gd);

6398

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6770

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6399

fin_x=fin;

6771

fin_x=fin;

6400

H_ph_x=H_ph(:);

6772

H_ph_x=H_ph(:);

6401

if fin(1) ~= 0

6773

if fin(1) ~= 0

6402

% correct outliers in first 10 phase samples

6774

% correct outliers in first 10 phase samples

6403

for k=10:-1:1

6775

for k=10:-1:1

6404

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6776

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6405

end

6777

end

6406

6778

6407

% shift all phase data so that DC extrapolation to 0 follows trend

6779

% shift all phase data so that DC extrapolation to 0 follows trend

6408

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6780

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6409

fin_x=[0, fin_x];

6781

fin_x=[0, fin_x];

6410

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6782

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6411

end

6783

end

6412

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6784

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6413

% the last two samples, so noise can create an inverted slope and

6785

% the last two samples, so noise can create an inverted slope and

6414

% non-causal response).

6786

% non-causal response).

6415

if fout(end)>fin(end)

6787

if fout(end)>fin(end)

6416

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6788

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6417

% p=polyfit(fin_x', H_ph_x, 1);

6789

% p=polyfit(fin_x', H_ph_x, 1);

6418

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6790

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6419

% hf_phase_trend=polyval(p,max(fout));

6791

% hf_phase_trend=polyval(p,max(fout));

6420

fin_x=[fin_x, fout(end)];

6792

fin_x=[fin_x, fout(end)];

6421

H_ph_x=[H_ph_x; hf_phase_trend];

6793

H_ph_x=[H_ph_x; hf_phase_trend];

6422

end

6794

end

6423

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6795

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6424

6796

6425

otherwise

6797

otherwise

6426

error('COM:Extrap:InvalidOption', ...

6798

error('COM:Extrap:InvalidOption', ...

6427

'debug_interp_Sparam valid values are "old", "zero_DC", "interp_to_DC", "interp_and_shift_to_DC", "trend_and_shift_to_DC", "interp_cubic_to_dc_linear_to_inf"');

6799

'debug_interp_Sparam valid values are "old", "zero_DC", "interp_to_DC", "interp_and_shift_to_DC", "trend_and_shift_to_DC", "interp_cubic_to_dc_linear_to_inf"');

6428

end

6800

end

6429

H_i = H_mag_i.*exp(1j*H_ph_i);

6801

H_i = H_mag_i.*exp(1j*H_ph_i);

6430

Sout=H_i;

6802

Sout=H_i;

6431

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6803

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6432

6804

6433

%This function makes the TX or RX package. The type input must be

6805

%This function makes the TX or RX package. The type input must be

6434

%'TX' or 'RX'

6806

%'TX' or 'RX'

6435

%If the mode argument is omitted, mode='dd' is assumed. Currently

6807

%If the mode argument is omitted, mode='dd' is assumed. Currently

6436

%mode='dc' is only used when making the TX package for AC CM noise

6808

%mode='dc' is only used when making the TX package for AC CM noise

6437

%inclusion. The Rx package for 'dc' mode is still generated using

6809

%inclusion. The Rx package for 'dc' mode is still generated using

6438

%the same parameters as 'dd' mode

6810

%the same parameters as 'dd' mode

6439

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6811

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6440

%

6812

%

6441

%One instance of package block looks like this (if no elements are set to 0):

6813

%One instance of package block looks like this (if no elements are set to 0):

6442

%-------------Lcomp----------Tline---------------

6814

%-------------Lcomp----------Tline---------------

6443

% | | |

6815

% | | |

6444

% Cpad Cbump Cball

6816

% Cpad Cbump Cball

6445

% | | |

6817

% | | |

6446

%------------------------------------------------

6818

%------------------------------------------------

6447

6819

6448

if nargin<6

6820

if nargin<6

6449

%optional input "include_die"=0 allows die parameters to be forced to 0

6821

%optional input "include_die"=0 allows die parameters to be forced to 0

6450

%this includes Cpad, Lcomp, and Cbump

6822

%this includes Cpad, Lcomp, and Cbump

6451

include_die=1;

6823

include_die=1;

6452

end

6824

end

6453

if nargin<5

6825

if nargin<5

6454

mode='dd';

6826

mode='dd';

6455

end

6827

end

6456

6828

6457

6829

6458

if ~isempty(param.PKG_NAME)

6830

if ~isempty(param.PKG_NAME)

6459

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6831

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6460

%so they are swapped in depending on if Tx or Rx is set for type

6832

%so they are swapped in depending on if Tx or Rx is set for type

6461

%Note that param is not returned from this function, so the swap does not persist

6833

%Note that param is not returned from this function, so the swap does not persist

6462

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6834

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6463

if strcmpi(type,'tx')

6835

if strcmpi(type,'tx')

6464

pkg_name = param.PKG_NAME{1};

6836

pkg_name = param.PKG_NAME{1};

6465

elseif strcmpi(type,'rx')

6837

elseif strcmpi(type,'rx')

6466

pkg_name = param.PKG_NAME{2};

6838

pkg_name = param.PKG_NAME{2};

6467

else

6839

else

6468

error('Pkg type must be Tx or Rx');

6840

error('Pkg type must be Tx or Rx');

6469

end

6841

end

6470

pkg_parameter_struct = param.PKG.(pkg_name);

6842

pkg_parameter_struct = param.PKG.(pkg_name);

6471

6843

6472

6844

6473

for j=1:length(swap_fields)

6845

for j=1:length(swap_fields)

6474

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6846

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6475

end

6847

end

6476

6848

6477

end

6849

end

6478

6850

6479

C_diepad = param.C_diepad;

6851

C_diepad = param.C_diepad;

6480

C_pkg_board = param.C_pkg_board;

6852

C_pkg_board = param.C_pkg_board;

6481

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6853

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6482

L_comp = param.L_comp;

6854

L_comp = param.L_comp;

6483

C_bump = param.C_bump;

6855

C_bump = param.C_bump;

6484

if ~include_die

6856

if ~include_die

6485

%best to multiply by 0. that way vectors maintain original size

6857

%best to multiply by 0. that way vectors maintain original size

6486

C_diepad=C_diepad*0;

6858

C_diepad=C_diepad*0;

6487

L_comp=L_comp*0;

6859

L_comp=L_comp*0;

6488

C_bump=C_bump*0;

6860

C_bump=C_bump*0;

6489

end

6861

end

6490

% [ahealey] End of modifications.

6862

% [ahealey] End of modifications.

6491

% generate TX package according to channel type.

6863

% generate TX package according to channel type.

6492

[ncases, mele]=size(param.z_p_next_cases);

6864

[ncases, mele]=size(param.z_p_next_cases);

6493

6865

6494

%Syntax update for C_diepad and L_comp

6866

%Syntax update for C_diepad and L_comp

6495

%Allow a chain of values to be entered as a matrix:

6867

%Allow a chain of values to be entered as a matrix:

6496

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6868

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6497

if isvector(C_diepad)

6869

if isvector(C_diepad)

6498

Cd_Tx=C_diepad(1);

6870

Cd_Tx=C_diepad(1);

6499

Cd_Rx=C_diepad(2);

6871

Cd_Rx=C_diepad(2);

6500

L_comp_Tx=L_comp(1);

6872

L_comp_Tx=L_comp(1);

6501

L_comp_Rx=L_comp(2);

6873

L_comp_Rx=L_comp(2);

6502

num_blocks=mele;

6874

num_blocks=mele;

6503

else

6875

else

6504

Cd_Tx=C_diepad(1,:);

6876

Cd_Tx=C_diepad(1,:);

6505

Cd_Rx=C_diepad(2,:);

6877

Cd_Rx=C_diepad(2,:);

6506

L_comp_Tx=L_comp(1,:);

6878

L_comp_Tx=L_comp(1,:);

6507

L_comp_Rx=L_comp(2,:);

6879

L_comp_Rx=L_comp(2,:);

6508

num_blocks=mele+length(Cd_Tx)-1;

6880

num_blocks=mele+length(Cd_Tx)-1;

6509

end

6881

end

6510

extra_LC=length(Cd_Tx)-1;

6882

extra_LC=length(Cd_Tx)-1;

6511

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6883

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6512

insert_zeros=zeros([1 extra_LC]);

6884

insert_zeros=zeros([1 extra_LC]);

6513

6885

6514

%Updated technique of building Tx/Rx packages

6886

%Updated technique of building Tx/Rx packages

6515

%each index corresponds to the package segment

6887

%each index corresponds to the package segment

6516

switch type

6888

switch type

6517

case 'TX'

6889

case 'TX'

6518

switch mele

6890

switch mele

6519

case 1

6891

case 1

6520

Cpad=Cd_Tx;

6892

Cpad=Cd_Tx;

6521

Lcomp=L_comp_Tx;

6893

Lcomp=L_comp_Tx;

6522

Cbump=C_bump(1);

6894

Cbump=C_bump(1);

6523

Cball=C_pkg_board(1);

6895

Cball=C_pkg_board(1);

6524

Zpkg=param.pkg_Z_c(1);

6896

Zpkg=param.pkg_Z_c(1);

6525

case 4

6897

case 4

6526

Cpad=[Cd_Tx 0 0 0];

6898

Cpad=[Cd_Tx 0 0 0];

6527

Lcomp=[L_comp_Tx 0 0 0];

6899

Lcomp=[L_comp_Tx 0 0 0];

6528

Cbump=[C_bump(1) 0 0 0];

6900

Cbump=[C_bump(1) 0 0 0];

6529

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6901

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6530

Zpkg=param.pkg_Z_c(1,:);

6902

Zpkg=param.pkg_Z_c(1,:);

6531

otherwise

6903

otherwise

6532

error('package syntax error')

6904

error('package syntax error')

6533

end

6905

end

6534

switch upper(channel_type)

6906

switch upper(channel_type)

6535

case 'THRU'

6907

case 'THRU'

6536

Len=param.Pkg_len_TX;

6908

Len=param.Pkg_len_TX;

6537

case 'NEXT'

6909

case 'NEXT'

6538

Len=param.Pkg_len_NEXT;

6910

Len=param.Pkg_len_NEXT;

6539

case 'FEXT'

6911

case 'FEXT'

6540

Len=param.Pkg_len_FEXT;

6912

Len=param.Pkg_len_FEXT;

6541

end

6913

end

6542

case 'RX'

6914

case 'RX'

6543

switch mele

6915

switch mele

6544

case 1

6916

case 1

6545

Cpad=Cd_Rx;

6917

Cpad=Cd_Rx;

6546

Lcomp=L_comp_Rx;

6918

Lcomp=L_comp_Rx;

6547

Cbump=C_bump(2);

6919

Cbump=C_bump(2);

6548

Cball=C_pkg_board(2);

6920

Cball=C_pkg_board(2);

6549

Zpkg=param.pkg_Z_c(2);

6921

Zpkg=param.pkg_Z_c(2);

6550

case 4

6922

case 4

6551

Cpad=[Cd_Rx 0 0 0];

6923

Cpad=[Cd_Rx 0 0 0];

6552

Lcomp=[L_comp_Rx 0 0 0];

6924

Lcomp=[L_comp_Rx 0 0 0];

6553

Cbump=[C_bump(2) 0 0 0];

6925

Cbump=[C_bump(2) 0 0 0];

6554

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6926

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6555

Zpkg=param.pkg_Z_c(2,:);

6927

Zpkg=param.pkg_Z_c(2,:);

6556

otherwise

6928

otherwise

6557

error('package syntax error')

6929

error('package syntax error')

6558

end

6930

end

6559

switch upper(channel_type)

6931

switch upper(channel_type)

6560

case 'THRU'

6932

case 'THRU'

6561

Len=param.Pkg_len_RX;

6933

Len=param.Pkg_len_RX;

6562

case 'NEXT'

6934

case 'NEXT'

6563

Len=param.Pkg_len_RX;

6935

Len=param.Pkg_len_RX;

6564

case 'FEXT'

6936

case 'FEXT'

6565

Len=param.Pkg_len_RX;

6937

Len=param.Pkg_len_RX;

6566

end

6938

end

6567

end

6939

end

6568

6940

6569

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6941

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6570

Cball=[insert_zeros Cball];

6942

Cball=[insert_zeros Cball];

6571

Cbump=[insert_zeros Cbump];

6943

Cbump=[insert_zeros Cbump];

6572

Len=[insert_zeros Len];

6944

Len=[insert_zeros Len];

6573

Zpkg=[insert_zeros Zpkg];

6945

Zpkg=[insert_zeros Zpkg];

6574

6946

6575

% debug_string='';

6947

% debug_string='';

6576

% for j=1:length(Zpkg)

6948

% for j=1:length(Zpkg)

6577

% if Cpad(j)~=0

6949

% if Cpad(j)~=0

6578

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6950

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6579

% end

6951

% end

6580

% if Lcomp(j)~=0

6952

% if Lcomp(j)~=0

6581

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6953

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6582

% end

6954

% end

6583

% if Cbump(j)~=0

6955

% if Cbump(j)~=0

6584

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6956

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6585

% end

6957

% end

6586

% if Len(j)~=0

6958

% if Len(j)~=0

6587

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6959

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6588

% end

6960

% end

6589

% if Cball(j)~=0

6961

% if Cball(j)~=0

6590

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6962

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6591

% end

6963

% end

6592

% end

6964

% end

6593

% if length(debug_string)>2

6965

% if length(debug_string)>2

6594

% debug_string=debug_string(3:end);

6966

% debug_string=debug_string(3:end);

6595

% end

6967

% end

6596

6968

6597

% tx package

6969

% tx package

6598

pkg_param=param;

6970

pkg_param=param;

6599

if strcmpi(mode,'dc')

6971

if strcmpi(mode,'dc')

6600

% change tx package to CC mode

6972

% change tx package to CC mode

6601

pkg_param.Z0=pkg_param.Z0/2;

6973

pkg_param.Z0=pkg_param.Z0/2;

6602

Cpad=Cpad*2;

6974

Cpad=Cpad*2;

6603

Cball=Cball*2;

6975

Cball=Cball*2;

6604

Zpkg=Zpkg*2;

6976

Zpkg=Zpkg*2;

6605

Lcomp=Lcomp/2;

6977

Lcomp=Lcomp/2;

6606

Cbump=Cbump*2;

6978

Cbump=Cbump*2;

6607

end

6979

end

6608

switch num_blocks

6980

switch num_blocks

6609

case 1

6981

case 1

6610

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6982

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6611

otherwise

6983

otherwise

6612

for j=1:num_blocks

6984

for j=1:num_blocks

6613

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6985

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6614

if j==1

6986

if j==1

6615

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6987

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6616

else

6988

else

6617

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6989

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6618

end

6990

end

6619

end

6991

end

6620

end

6992

end

6621

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6993

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6622

f(f<eps)=eps;

6994

f(f<eps)=eps;

6623

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6995

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6624

%% Equation 93A-8

6996

%% Equation 93A-8

6625

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6997

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6626

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6998

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6627

6999

6628

% [ahealey] Add compensating L and shunt C (bump) when requested.

7000

% [ahealey] Add compensating L and shunt C (bump) when requested.

6629

s12pad = s21pad;

7001

s12pad = s21pad;

6630

s22pad = s11pad;

7002

s22pad = s11pad;

6631

if nargin > 6

7003

if nargin > 6

6632

lcomp = varargin{1};

7004

lcomp = varargin{1};

6633

if lcomp>0

7005

if lcomp>0

6634

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

7006

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6635

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

7007

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6636

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

7008

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6637

s11pad, s12pad, s21pad, s22pad, ...

7009

s11pad, s12pad, s21pad, s22pad, ...

6638

s11comp, s21comp, s21comp, s11comp);

7010

s11comp, s21comp, s21comp, s11comp);

6639

end

7011

end

6640

end

7012

end

6641

if nargin > 7

7013

if nargin > 7

6642

cbump = varargin{2};

7014

cbump = varargin{2};

6643

if cbump>0

7015

if cbump>0

6644

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

7016

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

6645

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

7017

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

6646

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

7018

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6647

s11pad, s12pad, s21pad, s22pad, ...

7019

s11pad, s12pad, s21pad, s22pad, ...

6648

s11bump, s21bump, s21bump, s11bump);

7020

s11bump, s21bump, s21bump, s11bump);

6649

end

7021

end

6650

end

7022

end

6651

% [ahealey] End of modifications.

7023

% [ahealey] End of modifications.

6652

7024

6653

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

7025

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

6654

% [ahealey] Symmetry cannot be assumed with more complex termination models.

7026

% [ahealey] Symmetry cannot be assumed with more complex termination models.

6655

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

7027

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

6656

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

7028

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

6657

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

7029

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

6658

s11pad, s12pad, s21pad, s22pad, ...

7030

s11pad, s12pad, s21pad, s22pad, ...

6659

S11, S21, S21, S11);

7031

S11, S21, S21, S11);

6660

% [ahealey] End of modifications.

7032

% [ahealey] End of modifications.

6661

7033

6662

%% Equation 93A-8

7034

%% Equation 93A-8

6663

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

7035

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

6664

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

7036

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

6665

[ s11out, s12out, s21out, s22out ]= ...

7037

[ s11out, s12out, s21out, s22out ]= ...

6666

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

7038

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

6667

7039

6668

function missingParameter (parameterName)

7040

function missingParameter (parameterName)

6669

error( 'error:badParameterInformation', ...

7041

error( 'error:badParameterInformation', ...

6670

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

7042

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

6671

7043

6672

function pdf = normal_dist(sigma,nsigma,binsize)

7044

function pdf = normal_dist(sigma,nsigma,binsize)

6673

pdf.BinSize=binsize;

7045

pdf.BinSize=binsize;

6674

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

7046

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

6675

pdf.x=(pdf.Min:-pdf.Min)*binsize;

7047

pdf.x=(pdf.Min:-pdf.Min)*binsize;

6676

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

7048

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

6677

pdf.y=pdf.y/sum(pdf.y);

7049

pdf.y=pdf.y/sum(pdf.y);

6678

7050

6679

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

7051

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

6680

%% input

7052

%% input

6681

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

7053

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

6682

% baud_rate - baud rate in seconds

7054

% baud_rate - baud rate in seconds

6683

% param.samples_per_ui = samples per UI of IR

7055

% param.samples_per_ui = samples per UI of IR

6684

% param.max_ctle - maximum ac to dc gain in dB

7056

% param.max_ctle - maximum ac to dc gain in dB

6685

% param.tx_ffe(1) - maximum pre cursor (positive value)

7057

% param.tx_ffe(1) - maximum pre cursor (positive value)

6686

% param.tx_ffe(2) - maximum post cursor (positive value)

7058

% param.tx_ffe(2) - maximum post cursor (positive value)

6687

% param.tx_ffe_step - sweep step size for tx pre and post taps

7059

% param.tx_ffe_step - sweep step size for tx pre and post taps

6688

% param.ndfe - number of reference dfe taps

7060

% param.ndfe - number of reference dfe taps

6689

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

7061

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

6690

% output

7062

% output

6691

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

7063

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

6692

% result.eq.ctle - index of CTLE parameters in table

7064

% result.eq.ctle - index of CTLE parameters in table

6693

% result.IR - impulse response

7065

% result.IR - impulse response

6694

% result.avail_signal - maximum signal after equalization

7066

% result.avail_signal - maximum signal after equalization

6695

% result.avail_sig_index - index in result.IR of max signal

7067

% result.avail_sig_index - index in result.IR of max signal

6696

% result.best_FOM - best raw ISI

7068

% result.best_FOM - best raw ISI

6697

7069

6698

min_number_of_UI_in_response=40;

7070

min_number_of_UI_in_response=40;

6699

baud_rate=1/param.ui;

7071

baud_rate=1/param.ui;

6700

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

7072

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

6701

f=chdata(1).faxis;

7073

f=chdata(1).faxis;

6702

7074

6703

%Read user input of ts_sample_adj_range

7075

%Read user input of ts_sample_adj_range

6704

%if one value was entered, go from 0 to that value

7076

%if one value was entered, go from 0 to that value

6705

%if 2 values were entered, go from the 1st value to the 2nd value

7077

%if 2 values were entered, go from the 1st value to the 2nd value

6706

if length(param.ts_sample_adj_range)==1

7078

if length(param.ts_sample_adj_range)==1

6707

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

7079

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

6708

param.ts_sample_adj_range(1)=0;

7080

param.ts_sample_adj_range(1)=0;

6709

end

7081

end

6710

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

7082

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

6711

7083

6712

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

7084

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

6713

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

7085

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

6714

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7086

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

6715

% need to include H_RCos in noise and when computing the system ir for thru

7087

% need to include H_RCos in noise and when computing the system ir for thru

6716

% and crosstalk

7088

% and crosstalk

6717

H_r=H_bw.*H_bt.*H_RCos;

7089

H_r=H_bw.*H_bt.*H_RCos;

6718

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

7090

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

6719

% Get f vector from 0 to Fs/2-delta_f.

7091

% Get f vector from 0 to Fs/2-delta_f.

6720

N_fft_by2 = 512;

7092

N_fft_by2 = 512;

6721

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

7093

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

6722

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

7094

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

6723

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

7095

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

6724

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

7096

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

6725

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

7097

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

6726

%%

7098

%%

6727

7099

6728

% system noise H_sy PSD

7100

% system noise H_sy PSD

6729

if OP.USE_ETA0_PSD

7101

if OP.USE_ETA0_PSD

6730

fspike=1e9;

7102

fspike=1e9;

6731

% requires communication tool box if used

7103

% requires communication tool box if used

6732

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

7104

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

6733

else

7105

else

6734

H_sy=ones(1,length(chdata(1).faxis));

7106

H_sy=ones(1,length(chdata(1).faxis));

6735

end

7107

end

6736

7108

6737

%Build txffe values dynamically

7109

%Build txffe values dynamically

6738

%any param field that is "tx_ffe_cm<X>_values" is a precursor

7110

%any param field that is "tx_ffe_cm<X>_values" is a precursor

6739

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

7111

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

6740

%where <X> is any integer

7112

%where <X> is any integer

6741

param_fields=fieldnames(param);

7113

param_fields=fieldnames(param);

6742

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

7114

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

6743

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

7115

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

6744

num_taps=num_pre+num_post;

7116

num_taps=num_pre+num_post;

6745

cur=num_pre+1;

7117

cur=num_pre+1;

6746

%txffe_cell combines all the txffe values into a single cell array

7118

%txffe_cell combines all the txffe values into a single cell array

6747

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

7119

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

6748

txffe_cell=cell(1,num_taps);

7120

txffe_cell=cell(1,num_taps);

6749

for k=num_pre:-1:1

7121

for k=num_pre:-1:1

6750

idx=num_pre-k+1;

7122

idx=num_pre-k+1;

6751

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

7123

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

6752

txffe_cell{idx}=param.(this_tx_field);

7124

txffe_cell{idx}=param.(this_tx_field);

6753

end

7125

end

6754

for k=1:num_post

7126

for k=1:num_post

6755

idx=k+num_pre;

7127

idx=k+num_pre;

6756

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

7128

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

6757

txffe_cell{idx}=param.(this_tx_field);

7129

txffe_cell{idx}=param.(this_tx_field);

6758

end

7130

end

6759

%total number of txffe runs is the product of the lengths of each tap

7131

%total number of txffe runs is the product of the lengths of each tap

6760

txffe_lengths=cellfun('length',txffe_cell);

7132

txffe_lengths=cellfun('length',txffe_cell);

6761

if isempty(txffe_cell)

7133

if isempty(txffe_cell)

6762

num_txffe_runs=1;

7134

num_txffe_runs=1;

6763

else

7135

else

6764

num_txffe_runs=prod(txffe_lengths);

7136

num_txffe_runs=prod(txffe_lengths);

6765

end

7137

end

6766

%txffe_sweep_indices are used in the LOCAL_SEARCH block

7138

%txffe_sweep_indices are used in the LOCAL_SEARCH block

6767

%any tap with length=1 can be ignored

7139

%any tap with length=1 can be ignored

6768

%Also is statistically likely that taps with greater number of values

7140

%Also is statistically likely that taps with greater number of values

6769

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

7141

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

6770

txffe_sweep_indices=find(txffe_lengths>1);

7142

txffe_sweep_indices=find(txffe_lengths>1);

6771

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

7143

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

6772

txffe_sweep_indices=txffe_sweep_indices(length_sort);

7144

txffe_sweep_indices=txffe_sweep_indices(length_sort);

6773

num_txffe_sweep_indices=length(txffe_sweep_indices);

7145

num_txffe_sweep_indices=length(txffe_sweep_indices);

6774

7146

6775

gdc_values = param.ctle_gdc_values;

7147

gdc_values = param.ctle_gdc_values;

6776

Gffe_values = param.cursor_gain;

7148

Gffe_values = param.cursor_gain;

6777

switch param.CTLE_type

7149

switch param.CTLE_type

6778

case 'CL93'

7150

case 'CL93'

6779

case 'CL120d'

7151

case 'CL120d'

6780

g_DC_HP_values =param.g_DC_HP_values;

7152

g_DC_HP_values =param.g_DC_HP_values;

6781

case 'CL120e'

7153

case 'CL120e'

6782

f_HP_Z=param.f_HP_Z;

7154

f_HP_Z=param.f_HP_Z;

6783

f_HP_P=param.f_HP_P;

7155

f_HP_P=param.f_HP_P;

6784

7156

6785

end

7157

end

6786

best_ctle = [];

7158

best_ctle = [];

6787

best_FOM = -inf;

7159

best_FOM = -inf;

6788

best_txffe = [];

7160

best_txffe = [];

6789

delta_sbr = [];

7161

delta_sbr = [];

6790

PSD_results=[];

7162

PSD_results=[];

6791

MMSE_results=[];

7163

MMSE_results=[];

6792

best_bmax=param.bmax;

7164

best_bmax=param.bmax;

6793

%AJG021820

7165

%AJG021820

6794

best_bmin=param.bmin;

7166

best_bmin=param.bmin;

6795

h_J=[];

7167

h_J=[];

6796

pxi=0;

7168

pxi=0;

6797

if OP.DISPLAY_WINDOW

7169

if OP.DISPLAY_WINDOW

6798

hwaitbar=waitbar(0);

7170

hwaitbar=waitbar(0);

6799

else

7171

else

6800

fprintf('FOM search ');

7172

fprintf('FOM search ');

6801

end

7173

end

6802

FOM=0;

7174

FOM=0;

6803

if ~OP.RxFFE

7175

if ~OP.RxFFE

6804

Gffe_values=0;

7176

Gffe_values=0;

6805

end

7177

end

6806

param.ndfe_passed=param.ndfe;

7178

param.ndfe_passed=param.ndfe;

6807

old_loops=0;

7179

old_loops=0;

6808

new_loops=0;

7180

new_loops=0;

6809

7181

6810

%GDC Qual construction

7182

%GDC Qual construction

6811

gqual= param.gqual;

7183

gqual= param.gqual;

6812

g2qual=param.g2qual;

7184

g2qual=param.g2qual;

6813

if ~strcmp(param.CTLE_type,'CL120d')

7185

if ~strcmp(param.CTLE_type,'CL120d')

6814

qual=ones(1,length(gdc_values));

7186

qual=ones(1,length(gdc_values));

6815

else

7187

else

6816

if isempty(gqual) && isempty(g2qual)

7188

if isempty(gqual) && isempty(g2qual)

6817

qual=ones(length(g_DC_HP_values),length(gdc_values));

7189

qual=ones(length(g_DC_HP_values),length(gdc_values));

6818

else

7190

else

6819

qual=zeros(length(g_DC_HP_values),length(gdc_values));

7191

qual=zeros(length(g_DC_HP_values),length(gdc_values));

6820

7192

6821

%prepare gqual and g2qual

7193

%prepare gqual and g2qual

6822

[g2qual,si]=sort(g2qual,'descend');

7194

[g2qual,si]=sort(g2qual,'descend');

6823

gqual=gqual(si,:);

7195

gqual=gqual(si,:);

6824

tmp=g2qual;

7196

tmp=g2qual;

6825

g2qual=zeros(length(tmp),2);

7197

g2qual=zeros(length(tmp),2);

6826

for kk=1:length(tmp)

7198

for kk=1:length(tmp)

6827

if kk==1

7199

if kk==1

6828

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

7200

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

6829

else

7201

else

6830

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

7202

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

6831

end

7203

end

6832

gqual(kk,:)=sort(gqual(kk,:),'descend');

7204

gqual(kk,:)=sort(gqual(kk,:),'descend');

6833

end

7205

end

6834

7206

6835

%Qual Construction

7207

%Qual Construction

6836

for jj=1:length(g_DC_HP_values)

7208

for jj=1:length(g_DC_HP_values)

6837

for ii=1:length(gdc_values)

7209

for ii=1:length(gdc_values)

6838

for kk=1:size(gqual,1)

7210

for kk=1:size(gqual,1)

6839

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

7211

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

6840

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

7212

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

6841

qual(jj,ii)=1;

7213

qual(jj,ii)=1;

6842

break;

7214

break;

6843

end

7215

end

6844

end

7216

end

6845

end

7217

end

6846

end

7218

end

6847

end

7219

end

6848

end

7220

end

6849

end

7221

end

6850

7222

6851

progress_interval=0.025;

7223

progress_interval=0.025;

6852

if do_C2M

7224

if do_C2M

6853

loop_count=[1 2];

7225

loop_count=[1 2];

6854

T_O=floor((param.T_O/1000)*param.samples_per_ui);

7226

T_O=floor((param.T_O/1000)*param.samples_per_ui);

6855

T_O=max(0,T_O);

7227

T_O=max(0,T_O);

6856

else

7228

else

6857

loop_count=1;

7229

loop_count=1;

6858

T_O=0;

7230

T_O=0;

6859

end

7231

end

6860

switch param.CTLE_type

7232

switch param.CTLE_type

6861

case 'CL93'

7233

case 'CL93'

6862

lf_indx=1;

7234

lf_indx=1;

6863

case 'CL120d'

7235

case 'CL120d'

6864

lf_indx=length(g_DC_HP_values);

7236

lf_indx=length(g_DC_HP_values);

6865

case 'CL120e'

7237

case 'CL120e'

6866

lf_indx=1;

7238

lf_indx=1;

6867

end

7239

end

6868

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

7240

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

6869

if OP.Optimize_loop_speed_up == 1

7241

if OP.Optimize_loop_speed_up == 1

6870

OP.BinSize = 1e-4;

7242

OP.BinSize = 1e-4;

6871

OP.impulse_response_truncation_threshold = 1e-3;

7243

OP.impulse_response_truncation_threshold = 1e-3;

6872

end

7244

end

6873

7245

6874

%Used to speed up FFE by only performing circshift when necessary

7246

%Used to speed up FFE by only performing circshift when necessary

6875

pulse_struc(1).pulse_ctle_circshift=[];

7247

pulse_struc(1).pulse_ctle_circshift=[];

6876

ctle_response_updated=1;

7248

ctle_response_updated=1;

6877

7249

6878

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

7250

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

6879

calc_exp_phase=0;

7251

calc_exp_phase=0;

6880

7252

6881

%calculate cur index and pre/post indices outside of the loop

7253

%calculate cur index and pre/post indices outside of the loop

6882

cur_start=cur;

7254

cur_start=cur;

6883

precursor_indices=[];

7255

precursor_indices=[];

6884

postcursor_indices=[];

7256

postcursor_indices=[];

6885

auto_count_trigger=0;

7257

auto_count_trigger=0;

6886

for kv=1:num_taps

7258

for kv=1:num_taps

6887

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

7259

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

6888

%precursor values fill the beginning of the vector. Any empty precursor means

7260

%precursor values fill the beginning of the vector. Any empty precursor means

6889

%cursor position must be subtracted by 1

7261

%cursor position must be subtracted by 1

6890

if kv<cur_start

7262

if kv<cur_start

6891

cur=cur-1;

7263

cur=cur-1;

6892

end

7264

end

6893

else

7265

else

6894

%non empty value: add to precursor or postcursor indices depending on position

7266

%non empty value: add to precursor or postcursor indices depending on position

6895

%in the vector

7267

%in the vector

6896

if kv<cur_start

7268

if kv<cur_start

6897

auto_count_trigger=1;

7269

auto_count_trigger=1;

6898

precursor_indices=[precursor_indices kv];

7270

precursor_indices=[precursor_indices kv];

6899

else

7271

else

6900

auto_count_trigger=0;

7272

auto_count_trigger=0;

6901

postcursor_indices=[postcursor_indices kv];

7273

postcursor_indices=[postcursor_indices kv];

6902

end

7274

end

6903

end

7275

end

6904

end

7276

end

6905

if ~isempty(postcursor_indices)

7277

if ~isempty(postcursor_indices)

6906

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

7278

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

6907

end

7279

end

6908

7280

6909

%Calculate the full grid matrix of all txffe combinations

7281

%Calculate the full grid matrix of all txffe combinations

6910

if isempty(txffe_cell)

7282

if isempty(txffe_cell)

6911

TXFFE_grid=0;

7283

TXFFE_grid=0;

6912

FULL_tx_index_vector=1;

7284

FULL_tx_index_vector=1;

6913

else

7285

else

6914

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

7286

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

6915

%Also calculate the full grid matrix for the index used in each txffe combination

7287

%Also calculate the full grid matrix for the index used in each txffe combination

6916

%(the index is used in the LOCAL SEARCH block)

7288

%(the index is used in the LOCAL SEARCH block)

6917

for k=1:num_taps

7289

for k=1:num_taps

6918

txffe_index_cell{k}=1:txffe_lengths(k);

7290

txffe_index_cell{k}=1:txffe_lengths(k);

6919

end

7291

end

6920

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

7292

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

6921

end

7293

end

6922

7294

6923

%pre-calculate cursor to save time

7295

%pre-calculate cursor to save time

6924

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

7296

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

6925

7297

6926

%pre-calculate full txffe for each iteration to save time

7298

%pre-calculate full txffe for each iteration to save time

6927

precursor_matrix=TXFFE_grid(:,precursor_indices);

7299

precursor_matrix=TXFFE_grid(:,precursor_indices);

6928

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7300

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

6929

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7301

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

6930

7302

6931

if OP.TDMODE

7303

if OP.TDMODE

6932

uneq_field='uneq_pulse_response';

7304

uneq_field='uneq_pulse_response';

6933

ctle_field='ctle_pulse_response';

7305

ctle_field='ctle_pulse_response';

6934

else

7306

else

6935

uneq_field='uneq_imp_response';

7307

uneq_field='uneq_imp_response';

6936

ctle_field='ctle_imp_response';

7308

ctle_field='ctle_imp_response';

6937

end

7309

end

6938

7310

6939

%Speed up search for max(sbr)

7311

%Speed up search for max(sbr)

6940

if OP.TDMODE

7312

if OP.TDMODE

6941

[~,init_max]=max(chdata(1).uneq_pulse_response);

7313

[~,init_max]=max(chdata(1).uneq_pulse_response);

6942

else

7314

else

6943

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7315

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

6944

end

7316

end

6945

UI_max_window=20;

7317

UI_max_window=20;

6946

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7318

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

6947

if start_max_idx<1

7319

if start_max_idx<1

6948

start_max_idx=1;

7320

start_max_idx=1;

6949

end

7321

end

6950

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7322

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

6951

if end_max_idx>length(chdata(1).(uneq_field))

7323

if end_max_idx>length(chdata(1).(uneq_field))

6952

end_max_idx=length(chdata(1).(uneq_field));

7324

end_max_idx=length(chdata(1).(uneq_field));

6953

end

7325

end

6954

7326

6955

itick_skips=0;

7327

itick_skips=0;

6956

itick_cases=0;

7328

itick_cases=0;

6957

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7329

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

6958

for i=loop_count

7330

for i=loop_count

6959

7331

6960

for Gffe_index=1:length(Gffe_values)

7332

for Gffe_index=1:length(Gffe_values)

6961

param.current_ffegain=Gffe_values(Gffe_index);

7333

param.current_ffegain=Gffe_values(Gffe_index);

6962

for ctle_index=1:length(gdc_values)

7334

for ctle_index=1:length(gdc_values)

6963

g_dc = gdc_values(ctle_index);

7335

g_dc = gdc_values(ctle_index);

6964

kacdc = 10^(g_dc/20);

7336

kacdc = 10^(g_dc/20);

6965

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7337

CTLE_fp1 = param.CTLE_fp1(ctle_index);

6966

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7338

CTLE_fp2 = param.CTLE_fp2(ctle_index);

6967

CTLE_fz = param.CTLE_fz(ctle_index);

7339

CTLE_fz = param.CTLE_fz(ctle_index);

6968

switch param.CTLE_type

7340

switch param.CTLE_type

6969

case 'CL93'

7341

case 'CL93'

6970

%

7342

%

6971

case 'CL120d'

7343

case 'CL120d'

6972

%

7344

%

6973

case 'CL120e'

7345

case 'CL120e'

6974

HP_Z = param.f_HP_Z(ctle_index);

7346

HP_Z = param.f_HP_Z(ctle_index);

6975

HP_P = param.f_HP_P(ctle_index);

7347

HP_P = param.f_HP_P(ctle_index);

6976

end

7348

end

6977

%% HF Boost

7349

%% HF Boost

6978

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7350

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

6979

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7351

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

6980

%% Mid Frequency Boost

7352

%% Mid Frequency Boost

6981

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7353

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

6982

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7354

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

6983

for g_LP_index=1:lf_indx

7355

for g_LP_index=1:lf_indx

6984

7356

6985

%GDC Qual Check

7357

%GDC Qual Check

6986

if qual(g_LP_index,ctle_index)==0

7358

if qual(g_LP_index,ctle_index)==0

6987

pxi=pxi+num_txffe_runs;

7359

pxi=pxi+num_txffe_runs;

6988

continue;

7360

continue;

6989

end

7361

end

6990

7362

6991

switch param.CTLE_type

7363

switch param.CTLE_type

6992

case 'CL93'

7364

case 'CL93'

6993

H_low=1;

7365

H_low=1;

6994

kacde_DC_low=1;

7366

kacde_DC_low=1;

6995

case 'CL120d'

7367

case 'CL120d'

6996

g_DC_low = g_DC_HP_values(g_LP_index);

7368

g_DC_low = g_DC_HP_values(g_LP_index);

6997

f_HP=param.f_HP(g_LP_index);

7369

f_HP=param.f_HP(g_LP_index);

6998

kacde_DC_low = 10^(g_DC_low/20);

7370

kacde_DC_low = 10^(g_DC_low/20);

6999

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7371

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7000

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7372

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7001

case 'CL120e' % z1 has been adusted on read in

7373

case 'CL120e' % z1 has been adusted on read in

7002

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7374

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7003

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7375

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7004

end

7376

end

7005

H_ctf=H_low.*ctle_gain;

7377

H_ctf=H_low.*ctle_gain;

7006

switch upper(OP.FFE_OPT_METHOD)

7378

switch upper(OP.FFE_OPT_METHOD)

7007

case 'WIENER-HOPF'

7379

case 'WIENER-HOPF'

7008

%% Bill Kirkland

7380

%% Bill Kirkland

7009

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7381

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7010

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7382

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7011

% use Fourier Transform pair for correlation as we have to

7383

% use Fourier Transform pair for correlation as we have to

7012

% take ifft of H_r anyways.

7384

% take ifft of H_r anyways.

7013

% onesided and two sided responses - tricky, tricky, tricky

7385

% onesided and two sided responses - tricky, tricky, tricky

7014

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7386

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7015

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7387

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7016

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7388

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7017

7389

7018

if OP.Do_White_Noise

7390

if OP.Do_White_Noise

7019

Noise_XC = Noise_XC(1);

7391

Noise_XC = Noise_XC(1);

7020

end

7392

end

7021

otherwise

7393

otherwise

7022

Noise_XC=[];

7394

Noise_XC=[];

7023

end

7395

end

7024

7396

7025

7397

7026

7398

7027

if OP.INCLUDE_CTLE==1

7399

if OP.INCLUDE_CTLE==1

7028

for k=1:param.num_s4p_files

7400

for k=1:param.num_s4p_files

7029

ir_peak = max(abs(chdata(k).(uneq_field)));

7401

ir_peak = max(abs(chdata(k).(uneq_field)));

7030

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7402

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7031

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7403

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7032

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7404

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7033

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7405

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7034

switch param.CTLE_type

7406

switch param.CTLE_type

7035

case 'CL93'

7407

case 'CL93'

7036

case 'CL120d'

7408

case 'CL120d'

7037

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7409

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7038

case 'CL120e' % z1 has been adusted on read in

7410

case 'CL120e' % z1 has been adusted on read in

7039

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7411

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7040

end

7412

end

7041

end

7413

end

7042

%set the flag to show ctle response was updated

7414

%set the flag to show ctle response was updated

7043

ctle_response_updated=1;

7415

ctle_response_updated=1;

7044

else

7416

else

7045

for k=1:param.num_s4p_files

7417

for k=1:param.num_s4p_files

7046

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7418

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7047

end

7419

end

7048

end

7420

end

7049

for k=1:param.num_s4p_files

7421

for k=1:param.num_s4p_files

7050

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7422

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7051

end

7423

end

7052

%% Equation 93A-22 %%

7424

%% Equation 93A-22 %%

7053

% figure(1000)

7425

% figure(1000)

7054

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7426

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7055

% hold on

7427

% hold on

7056

if OP.RX_CALIBRATION

7428

if OP.RX_CALIBRATION

7057

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7429

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7058

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7430

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7059

switch param.CTLE_type

7431

switch param.CTLE_type

7060

case 'CL93'

7432

case 'CL93'

7061

H_low2=1;

7433

H_low2=1;

7062

case 'CL120d'

7434

case 'CL120d'

7063

g_DC_low = g_DC_HP_values(g_LP_index);

7435

g_DC_low = g_DC_HP_values(g_LP_index);

7064

f_HP=param.f_HP(g_LP_index);

7436

f_HP=param.f_HP(g_LP_index);

7065

kacde_DC_low = 10^(g_DC_low/20);

7437

kacde_DC_low = 10^(g_DC_low/20);

7066

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7438

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7067

case 'CL120e' % z1 has been adusted on read in

7439

case 'CL120e' % z1 has been adusted on read in

7068

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7440

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7069

end

7441

end

7070

H_ctf2=H_low2.*ctle_gain2;

7442

H_ctf2=H_low2.*ctle_gain2;

7071

end

7443

end

7072

% RIM 11-30-2020 moved to a subfunction

7444

% RIM 11-30-2020 moved to a subfunction

7073

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7445

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7074

if OP.RX_CALIBRATION

7446

if OP.RX_CALIBRATION

7075

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7447

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7076

sigma_NEXT=sqrt(param.eta_0*sum( abs(H_sy(2:end).^2 .* H_r(2:end).*2 .* H_ctf(2:end).^2 ) .* diff(chdata(1).faxis)/1e9));% changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7448

sigma_NEXT=sqrt(param.eta_0*sum( abs(H_sy(2:end).^2 .* H_r(2:end).*2 .* H_ctf(2:end).^2 ) .* diff(chdata(1).faxis)/1e9));% changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7077

else

7449

else

7078

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7450

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7079

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7451

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7080

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7452

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7081

sigma_ne=0;

7453

sigma_ne=0;

7082

end

7454

end

7083

7455

7084

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7456

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7085

pxi=pxi+num_txffe_runs;

7457

pxi=pxi+num_txffe_runs;

7086

continue; % change per 0.3k draft 2.3

7458

continue; % change per 0.3k draft 2.3

7087

end

7459

end

7088

%%

7460

%%

7089

PSD_results=[];

7461

PSD_results=[];

7090

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7462

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7091

OP.WO_TXFFE=1;

7463

OP.WO_TXFFE=1;

7092

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7464

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7093

end

7465

end

7094

%TXFFE Loop

7466

%TXFFE Loop

7095

%Originally this was a separate for loop for each tap, but it is now all contained in the TXFFE_grid matrix to use a single modular loop

7467

%Originally this was a separate for loop for each tap, but it is now all contained in the TXFFE_grid matrix to use a single modular loop

7096

for TK=1:size(TXFFE_grid,1)

7468

for TK=1:size(TXFFE_grid,1)

7097

7469

7098

pxi=pxi+1;

7470

pxi=pxi+1;

7099

progress = pxi/runs;

7471

progress = pxi/runs;

7100

if OP.DISPLAY_WINDOW

7472

if OP.DISPLAY_WINDOW

7101

if ~mod(pxi,floor(runs*progress_interval))

7473

if ~mod(pxi,floor(runs*progress_interval))

7102

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7474

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7103

end

7475

end

7104

else

7476

else

7105

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7477

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7106

end

7478

end

7107

7479

7108

%get the cursor for this iteration

7480

%get the cursor for this iteration

7109

txffe_cur=txffe_cursor_vector(TK);

7481

txffe_cur=txffe_cursor_vector(TK);

7110

7482

7111

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7483

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7112

if txffe_cur<param.tx_ffe_c0_min

7484

if txffe_cur<param.tx_ffe_c0_min

7113

continue;

7485

continue;

7114

end

7486

end

7115

old_loops=old_loops+1;

7487

old_loops=old_loops+1;

7116

7488

7117

%get the index used for each tap on this iteration

7489

%get the index used for each tap on this iteration

7118

%this is needed for the LOCAL SEARCH block

7490

%this is needed for the LOCAL SEARCH block

7119

tx_index_vector=FULL_tx_index_vector(TK,:);

7491

tx_index_vector=FULL_tx_index_vector(TK,:);

7120

7492

7121

%Original LOCAL SEARCH Block:

7493

%Original LOCAL SEARCH Block:

7122

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7494

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7123

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7495

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7124

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7496

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7125

% % skip configurations more than

7497

% % skip configurations more than

7126

% % 2 steps away from current "best" point on any grid direction

7498

% % 2 steps away from current "best" point on any grid direction

7127

% % Matt Brown 11/19/2021 for cp2 and cp3

7499

% % Matt Brown 11/19/2021 for cp2 and cp3

7128

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7500

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7129

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7501

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7130

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7502

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7131

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7503

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7132

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7504

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7133

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7505

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7134

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7506

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7135

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7507

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7136

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7508

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7137

%

7509

%

7138

% continue;

7510

% continue;

7139

% end

7511

% end

7140

7512

7141

%Modular LOCAL_SEARCH block:

7513

%Modular LOCAL_SEARCH block:

7142

% speedup "local search" heuristic - Adee Ran 03-17-2020

7514

% speedup "local search" heuristic - Adee Ran 03-17-2020

7143

% skip configurations more than 2 steps away from current "best" point on any grid direction

7515

% skip configurations more than 2 steps away from current "best" point on any grid direction

7144

skip_it=0;

7516

skip_it=0;

7145

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7517

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7146

%instead of looping across all taps, only loop across

7518

%instead of looping across all taps, only loop across

7147

%those with length>1 (txffe_sweep_indices).

7519

%those with length>1 (txffe_sweep_indices).

7148

%It saves time since this block is encountered so often

7520

%It saves time since this block is encountered so often

7149

for kj=1:num_txffe_sweep_indices

7521

for kj=1:num_txffe_sweep_indices

7150

kv=txffe_sweep_indices(kj);

7522

kv=txffe_sweep_indices(kj);

7151

if kv==1

7523

if kv==1

7152

previous_loop_val=g_LP_index;

7524

previous_loop_val=g_LP_index;

7153

else

7525

else

7154

previous_loop_val=tx_index_vector(kv-1);

7526

previous_loop_val=tx_index_vector(kv-1);

7155

end

7527

end

7156

if previous_loop_val>1

7528

if previous_loop_val>1

7157

best_index_this_tap=best_txffe_index(kv);

7529

best_index_this_tap=best_txffe_index(kv);

7158

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7530

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7159

skip_it=1;

7531

skip_it=1;

7160

break;

7532

break;

7161

end

7533

end

7162

end

7534

end

7163

end

7535

end

7164

7536

7165

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7537

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7166

skip_it=1;

7538

skip_it=1;

7167

end

7539

end

7168

end

7540

end

7169

if skip_it

7541

if skip_it

7170

continue;

7542

continue;

7171

end

7543

end

7172

%End Modular LOCAL SEARCH block

7544

%End Modular LOCAL SEARCH block

7173

7545

7174

new_loops=new_loops+1;

7546

new_loops=new_loops+1;

7175

7547

7176

%fetch txffe for this iteration

7548

%fetch txffe for this iteration

7177

txffe=txffe_matrix(TK,:);

7549

txffe=txffe_matrix(TK,:);

7178

7550

7179

%The phase shift exponentials used in get_xtlk_noise are independent of

7551

%The phase shift exponentials used in get_xtlk_noise are independent of

7180

%everything except number of taps and cursor position

7552

%everything except number of taps and cursor position

7181

%So it can be calculated 1 time here to avoid thousands of re-calcs

7553

%So it can be calculated 1 time here to avoid thousands of re-calcs

7182

if ~calc_exp_phase

7554

if ~calc_exp_phase

7183

calc_exp_phase=1;

7555

calc_exp_phase=1;

7184

for k=1:length(txffe)

7556

for k=1:length(txffe)

7185

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7557

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7186

end

7558

end

7187

if OP.RxFFE

7559

if OP.RxFFE

7188

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7560

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7189

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7561

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7190

end

7562

end

7191

phase_memory=[phase_memory phase_memoryRXFFE];

7563

phase_memory=[phase_memory phase_memoryRXFFE];

7192

end

7564

end

7193

end

7565

end

7194

7566

7195

%% Unequalized Pulse Reponse & circshift for FFE

7567

%% Unequalized Pulse Reponse & circshift for FFE

7196

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7568

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7197

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7569

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7198

if ctle_response_updated

7570

if ctle_response_updated

7199

ctle_response_updated=0;

7571

ctle_response_updated=0;

7200

num_pre=cur-1;

7572

num_pre=cur-1;

7201

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7573

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7202

%Calculating here reduces number of convolutions by thousands

7574

%Calculating here reduces number of convolutions by thousands

7203

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7575

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7204

ich=1;

7576

ich=1;

7205

else

7577

else

7206

ich=param.num_s4p_files;

7578

ich=param.num_s4p_files;

7207

end

7579

end

7208

for ii=1:ich

7580

for ii=1:ich

7209

if OP.TDMODE

7581

if OP.TDMODE

7210

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7582

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7211

else

7583

else

7212

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7584

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7213

%"conv2" is faster than filter. Just need to chop off extra points at the end

7585

%"conv2" is faster than filter. Just need to chop off extra points at the end

7214

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7586

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7215

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7587

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7216

end

7588

end

7217

for k=1:length(txffe)

7589

for k=1:length(txffe)

7218

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7590

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7219

end

7591

end

7220

end

7592

end

7221

end

7593

end

7222

7594

7223

%% Apply TXFFE to pre-shifted pulse response

7595

%% Apply TXFFE to pre-shifted pulse response

7224

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7596

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7225

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7597

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7226

sbr_from_txffe=sbr;

7598

sbr_from_txffe=sbr;

7227

for ii=1:ich

7599

for ii=1:ich

7228

% this is sbr when ii=1; to be used in get_PSDs

7600

% this is sbr when ii=1; to be used in get_PSDs

7229

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7601

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7230

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7602

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7231

else

7603

else

7232

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7604

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7233

end

7605

end

7234

end

7606

end

7235

7607

7236

%% Find Sample Location

7608

%% Find Sample Location

7237

% If RXFFE is included, the sample location will be found again below

7609

% If RXFFE is included, the sample location will be found again below

7238

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7610

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7239

if param.ts_anchor==0

7611

if param.ts_anchor==0

7240

%keep MM

7612

%keep MM

7241

elseif param.ts_anchor==1

7613

elseif param.ts_anchor==1

7242

%peak sample

7614

%peak sample

7243

cursor_i=sbr_peak_i;

7615

cursor_i=sbr_peak_i;

7244

no_zero_crossing=0;

7616

no_zero_crossing=0;

7245

elseif param.ts_anchor==2

7617

elseif param.ts_anchor==2

7246

%max DV

7618

%max DV

7247

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7619

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7248

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7620

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7249

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7621

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7250

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7622

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7251

no_zero_crossing=0;

7623

no_zero_crossing=0;

7252

else

7624

else

7253

error('ts_anchor parameter must be 0, 1, or 2');

7625

error('ts_anchor parameter must be 0, 1, or 2');

7254

end

7626

end

7255

if no_zero_crossing

7627

if no_zero_crossing

7256

continue;

7628

continue;

7257

end

7629

end

7258

raw_cursor_i=cursor_i;

7630

raw_cursor_i=cursor_i;

7259

7631

7260

%%%%%%%%%%

7632

%%%%%%%%%%

7261

%%%%%%%%%%

7633

%%%%%%%%%%

7262

%%%%%%%%%%

7634

%%%%%%%%%%

7263

%NEW ITICK LOOP (not indenting everything yet)

7635

%NEW ITICK LOOP (not indenting everything yet)

7264

[~,si]=sort(abs(full_sample_range));

7636

[~,si]=sort(abs(full_sample_range));

7265

best_positive_itick_FOM=-inf;

7637

best_positive_itick_FOM=-inf;

7266

best_negative_itick_FOM=-inf;

7638

best_negative_itick_FOM=-inf;

7267

best_positive_itick_in_loop=[];

7639

best_positive_itick_in_loop=[];

7268

best_negative_itick_in_loop=[];

7640

best_negative_itick_in_loop=[];

7269

best_itick_FOM=-inf;

7641

best_itick_FOM=-inf;

7270

best_itick_in_cluster=[];

7642

best_itick_in_cluster=[];

7271

best_cluster=[];

7643

best_cluster=[];

7272

7644

7273

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7645

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7274

%middle_search: start from itick=0 and work outwards in negative and positive direction. stop searching when FOM starts to go down (using LOCAL SEARCH)

7646

%middle_search: start from itick=0 and work outwards in negative and positive direction. stop searching when FOM starts to go down (using LOCAL SEARCH)

7275

% Commit request4p4_7 healey_3dj_COM_01_240416

7647

% Commit request4p4_7 healey_3dj_COM_01_240416

7276

%box_search=0;

7648

%box_search=0;

7277

%middle_search=1;% should set 0 so all Ts sample points are used

7649

%middle_search=1;% should set 0 so all Ts sample points are used

7278

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7650

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7279

case 'full-sweep'

7651

case 'full-sweep'

7280

box_search=0;

7652

box_search=0;

7281

middle_search=0;

7653

middle_search=0;

7282

case 'middle'

7654

case 'middle'

7283

box_search=0;

7655

box_search=0;

7284

middle_search=1;

7656

middle_search=1;

7285

otherwise

7657

otherwise

7286

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7658

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7287

end

7659

end

7288

if box_search

7660

if box_search

7289

box_size=5;

7661

box_size=5;

7290

box_mid=floor(box_size/2);

7662

box_mid=floor(box_size/2);

7291

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7663

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7292

CL=length(cluster);

7664

CL=length(cluster);

7293

loop_range=1:CL+box_mid*2;

7665

loop_range=1:CL+box_mid*2;

7294

elseif middle_search

7666

elseif middle_search

7295

loop_range=si;

7667

loop_range=si;

7296

else

7668

else

7297

loop_range=1:length(full_sample_range);

7669

loop_range=1:length(full_sample_range);

7298

end

7670

end

7299

7671

7300

for itickn=loop_range

7672

for itickn=loop_range

7301

if box_search

7673

if box_search

7302

if itickn<=CL

7674

if itickn<=CL

7303

itick=cluster(itickn);

7675

itick=cluster(itickn);

7304

else

7676

else

7305

if itickn==CL+1

7677

if itickn==CL+1

7306

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7678

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7307

end

7679

end

7308

if isempty(best_cluster)

7680

if isempty(best_cluster)

7309

continue;

7681

continue;

7310

end

7682

end

7311

itick=best_cluster(itickn-CL);

7683

itick=best_cluster(itickn-CL);

7312

end

7684

end

7313

else

7685

else

7314

itick=full_sample_range(itickn);

7686

itick=full_sample_range(itickn);

7315

end

7687

end

7316

7688

7317

itick_cases=itick_cases+1;

7689

itick_cases=itick_cases+1;

7318

7690

7319

sbr=sbr_from_txffe;

7691

sbr=sbr_from_txffe;

7320

cursor_i = raw_cursor_i+itick;

7692

cursor_i = raw_cursor_i+itick;

7321

7693

7322

%Local Search for +/- itick sweep

7694

%Local Search for +/- itick sweep

7323

if middle_search && param.LOCAL_SEARCH>0

7695

if middle_search && param.LOCAL_SEARCH>0

7324

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7696

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7325

itick_skips=itick_skips+1;

7697

itick_skips=itick_skips+1;

7326

continue;

7698

continue;

7327

end

7699

end

7328

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7700

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7329

itick_skips=itick_skips+1;

7701

itick_skips=itick_skips+1;

7330

continue;

7702

continue;

7331

end

7703

end

7332

end

7704

end

7333

7705

7334

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7706

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7335

if min_number_of_UI_in_response < triple_transit_time

7707

if min_number_of_UI_in_response < triple_transit_time

7336

min_number_of_UI_in_response = triple_transit_time;

7708

min_number_of_UI_in_response = triple_transit_time;

7337

end

7709

end

7338

7710

7339

cursor = sbr(cursor_i);

7711

cursor = sbr(cursor_i);

7340

7712

7341

%% RXFFE

7713

%% RXFFE

7342

if OP.RxFFE

7714

if OP.RxFFE

7343

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7715

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7344

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7716

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7345

%if isrow(sbr), sbr=sbr';end

7717

%if isrow(sbr), sbr=sbr';end

7346

7718

7347

%AJG: do not return sbr here (run time improvement)

7719

%AJG: do not return sbr here (run time improvement)

7348

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7720

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7349

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7721

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7350

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7722

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7351

% sbr at this point include the current setting

7723

% sbr at this point include the current setting

7352

% under consideration of txffe h21 ctf and fr

7724

% under consideration of txffe h21 ctf and fr

7353

switch upper(OP.FFE_OPT_METHOD)

7725

switch upper(OP.FFE_OPT_METHOD)

7354

case 'MMSE'

7726

case 'MMSE'

7355

OP.WO_TXFFE=0;

7727

OP.WO_TXFFE=0;

7356

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7728

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7357

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn;

7729

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn;

7358

if 0 % for debug

7730

if 0 % for debug

7359

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7731

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7360

hold on

7732

hold on

7361

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7733

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7362

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7734

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7363

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7735

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7364

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7736

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7365

xlim([0 0.5])

7737

xlim([0 0.5])

7366

% ylim([-190 -160])

7738

% ylim([-190 -160])

7367

set(gcf,'defaulttextinterpreter','none')

7739

set(gcf,'defaulttextinterpreter','none')

7368

xlabel('Normalized Frequency')

7740

xlabel('Normalized Frequency')

7369

ylabel('PSD dBm/Hz')

7741

ylabel('PSD dBm/Hz')

7370

hold on

7742

hold on

7371

grid on

7743

grid on

7372

legend show

7744

legend show

7373

title('PSD')

7745

title('PSD')

7374

end

7746

end

7375

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7747

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7376

% floating_tap_locations=MMSE_results.MLSE_results;

7748

% floating_tap_locations=MMSE_results.MLSE_results;

7377

C=MMSE_results.C;

7749

C=MMSE_results.C;

7378

FOM=MMSE_results.FOM;

7750

FOM=MMSE_results.FOM;

7379

floating_tap_locations=MMSE_results.floating_tap_locations;

7751

floating_tap_locations=MMSE_results.floating_tap_locations;

7380

otherwise

7752

otherwise

7381

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7753

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7382

end

7754

end

7383

%Now there is a stand alone function for determining if RXFFE taps are illegal

7755

%Now there is a stand alone function for determining if RXFFE taps are illegal

7384

%This is because the "force" function will also do a legality check when "backoff" is enabled

7756

%This is because the "force" function will also do a legality check when "backoff" is enabled

7385

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7757

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7386

if RXFFE_Illegal(C,param)

7758

if RXFFE_Illegal(C,param)

7387

continue;

7759

continue;

7388

end

7760

end

7389

end

7761

end

7390

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7762

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7391

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7763

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7392

if isrow(sbr), sbr=sbr';end

7764

if isrow(sbr), sbr=sbr';end

7393

7765

7394

%% second guess at cursor location (t_s) - based on approximate zero crossing

7766

%% second guess at cursor location (t_s) - based on approximate zero crossing

7395

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7767

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7396

%UPDATE: NOT RESAMPLING AFTER RXFFE

7768

%UPDATE: NOT RESAMPLING AFTER RXFFE

7397

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7769

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7398

% if no_zero_crossing

7770

% if no_zero_crossing

7399

% continue;

7771

% continue;

7400

% end

7772

% end

7401

7773

7402

cursor = sbr(cursor_i);

7774

cursor = sbr(cursor_i);

7403

end

7775

end

7404

A_p=sbr(sbr_peak_i);

7776

A_p=sbr(sbr_peak_i);

7405

%% 93A.1.6 step c defines A_s %%

7777

%% 93A.1.6 step c defines A_s %%

7406

A_s = param.R_LM*cursor/(param.levels-1);

7778

A_s = param.R_LM*cursor/(param.levels-1);

7407

if isempty(delta_sbr)

7779

if isempty(delta_sbr)

7408

delta_sbr = sbr;

7780

delta_sbr = sbr;

7409

end

7781

end

7410

sbr=sbr(:);

7782

sbr=sbr(:);

7411

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7783

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7412

7784

7413

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7785

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7414

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7786

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7415

t=((cursor_i+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:length(sbr))-(cursor_i+param.samples_per_ui*(param.ndfe+1)))*...

7787

t=((cursor_i+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:length(sbr))-(cursor_i+param.samples_per_ui*(param.ndfe+1)))*...

7416

param.ui/param.samples_per_ui;

7788

param.ui/param.samples_per_ui;

7417

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7789

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7418

precursors = precursors(end:-1:1);

7790

precursors = precursors(end:-1:1);

7419

7791

7420

% % Error message if the sbr is not long enough for the specified range of Nb

7792

% % Error message if the sbr is not long enough for the specified range of Nb

7421

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7793

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7422

% close(hwaitbar);

7794

% close(hwaitbar);

7423

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7795

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7424

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7796

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7425

% end

7797

% end

7426

7798

7427

7799

7428

7800

7429

%% skip this case if FOM has no chance of beating old FOM

7801

%% skip this case if FOM has no chance of beating old FOM

7430

%this is also done below but with excess_dfe_cursors included.

7802

%this is also done below but with excess_dfe_cursors included.

7431

%excess_dfe_cursors requires the floating DFE computation which is

7803

%excess_dfe_cursors requires the floating DFE computation which is

7432

%time consuming, so checking here can have significant run time improvements

7804

%time consuming, so checking here can have significant run time improvements

7433

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7805

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7434

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7806

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7435

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7807

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7436

continue

7808

continue

7437

end

7809

end

7438

end

7810

end

7439

7811

7440

%% Equation 93A-27, when 1<=n<=N_b

7812

%% Equation 93A-27, when 1<=n<=N_b

7441

%required length = cursor + all DFE UI + 1 additional UI

7813

%required length = cursor + all DFE UI + 1 additional UI

7442

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7814

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7443

if length(sbr)<sbr_required_length

7815

if length(sbr)<sbr_required_length

7444

sbr(end+1:sbr_required_length)=0;

7816

sbr(end+1:sbr_required_length)=0;

7445

end

7817

end

7446

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7818

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7447

if param.dfe_delta ~= 0

7819

if param.dfe_delta ~= 0

7448

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7820

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7449

7821

7450

else

7822

else

7451

dfecursors_q=dfecursors;

7823

dfecursors_q=dfecursors;

7452

end

7824

end

7453

if param.Floating_DFE

7825

if param.Floating_DFE

7454

%% floating taps

7826

%% floating taps

7455

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7827

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7456

7828

7457

[floating_tap_locations, floating_tap_coef, hisi, bmax]= floatingDFE( postcurors ,param.ndfe_passed,param.N_bf,param.N_bg,param.N_bmax, param.bmaxg, sbr(cursor_i), param.dfe_delta );

7829

[floating_tap_locations, floating_tap_coef, hisi, bmax]= floatingDFE( postcurors ,param.ndfe_passed,param.N_bf,param.N_bg,param.N_bmax, param.bmaxg, sbr(cursor_i), param.dfe_delta );

7458

7830

7459

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7831

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7460

param.use_bmax=newbmax;

7832

param.use_bmax=newbmax;

7461

%AJG021820

7833

%AJG021820

7462

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7834

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7463

else

7835

else

7464

param.use_bmax=param.bmax;

7836

param.use_bmax=param.bmax;

7465

%AJG021820

7837

%AJG021820

7466

param.use_bmin=param.bmin;

7838

param.use_bmin=param.bmin;

7467

end

7839

end

7468

7840

7469

%AJG021820

7841

%AJG021820

7470

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7842

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7471

if do_C2M

7843

if do_C2M

7472

dfecursors_windowed=sbr(cursor_i-T_O+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe)-T_O);

7844

dfecursors_windowed=sbr(cursor_i-T_O+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe)-T_O);

7473

% readjust SBR

7845

% readjust SBR

7474

if 0

7846

if 0

7475

%PR_DFE_center not currently used, so this is in "if 0" statement

7847

%PR_DFE_center not currently used, so this is in "if 0" statement

7476

PR_DFE_center=sbr;

7848

PR_DFE_center=sbr;

7477

for n=1:param.ndfe

7849

for n=1:param.ndfe

7478

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7850

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7479

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7851

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7480

% dper=sbr(i_sample)- actual_dfecursors(n);

7852

% dper=sbr(i_sample)- actual_dfecursors(n);

7481

% PR_DFE_center(i_sample)=dper;

7853

% PR_DFE_center(i_sample)=dper;

7482

% end

7854

% end

7483

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7855

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7484

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7856

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7485

end

7857

end

7486

end

7858

end

7487

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7859

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7488

else

7860

else

7489

excess_dfe_cursors=dfecursors-actual_dfecursors;

7861

excess_dfe_cursors=dfecursors-actual_dfecursors;

7490

end

7862

end

7491

dfetaps=actual_dfecursors/sbr(cursor_i);

7863

dfetaps=actual_dfecursors/sbr(cursor_i);

7492

7864

7493

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7865

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7494

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7866

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7495

if tail_RSS ~= 0

7867

if tail_RSS ~= 0

7496

if tail_RSS >= param.B_float_RSS_MAX

7868

if tail_RSS >= param.B_float_RSS_MAX

7497

param.use_bmax(param.N_tail_start:end)= ...

7869

param.use_bmax(param.N_tail_start:end)= ...

7498

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7870

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7499

%AJG021820

7871

%AJG021820

7500

param.use_bmin(param.N_tail_start:end)= ...

7872

param.use_bmin(param.N_tail_start:end)= ...

7501

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7873

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7502

end

7874

end

7503

end

7875

end

7504

7876

7505

%AJG021820

7877

%AJG021820

7506

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7878

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7507

if do_C2M

7879

if do_C2M

7508

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7880

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7509

else

7881

else

7510

excess_dfe_cursors=dfecursors-actual_dfecursors;

7882

excess_dfe_cursors=dfecursors-actual_dfecursors;

7511

end

7883

end

7512

dfetaps=actual_dfecursors/sbr(cursor_i);

7884

dfetaps=actual_dfecursors/sbr(cursor_i);

7513

7885

7514

else

7886

else

7515

tail_RSS=0;

7887

tail_RSS=0;

7516

end

7888

end

7517

%% Eq. 93A-28 %%

7889

%% Eq. 93A-28 %%

7518

sampling_offset = mod(cursor_i, param.samples_per_ui);

7890

sampling_offset = mod(cursor_i, param.samples_per_ui);

7519

%ensure we can take early sample

7891

%ensure we can take early sample

7520

if sampling_offset<=1

7892

if sampling_offset<=1

7521

sampling_offset=sampling_offset+param.samples_per_ui;

7893

sampling_offset=sampling_offset+param.samples_per_ui;

7522

end

7894

end

7523

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7895

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7524

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7896

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7525

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7897

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7526

else

7898

else

7527

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7899

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7528

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7900

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7529

end

7901

end

7530

% ensure lengths are equal

7902

% ensure lengths are equal

7531

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7903

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7532

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7904

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7533

if ~OP.SNR_TXwC0

7905

if ~OP.SNR_TXwC0

7534

%% Equation 93A-30 %%

7906

%% Equation 93A-30 %%

7535

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7907

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7536

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7908

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7537

else

7909

else

7538

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7910

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7539

end

7911

end

7540

%% Equation 93A-31 %%

7912

%% Equation 93A-31 %%

7541

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7913

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7542

ISI_N=param.sigma_X*norm( far_cursors);

7914

ISI_N=param.sigma_X*norm( far_cursors);

7543

%% break if FOM has no chance of beating old e

7915

%% break if FOM has no chance of beating old e

7544

OP.exe_mode=1;

7916

OP.exe_mode=1;

7545

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7917

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7546

switch OP.EXE_MODE

7918

switch OP.EXE_MODE

7547

case 0

7919

case 0

7548

case 1

7920

case 1

7549

if (20*log10(A_s/sigma_ISI) < best_FOM)

7921

if (20*log10(A_s/sigma_ISI) < best_FOM)

7550

continue

7922

continue

7551

end

7923

end

7552

case 2

7924

case 2

7553

if (20*log10(A_s/sigma_ISI) < best_FOM)

7925

if (20*log10(A_s/sigma_ISI) < best_FOM)

7554

break

7926

break

7555

end

7927

end

7556

end

7928

end

7557

end

7929

end

7558

%% Equation 93A-32 %%

7930

%% Equation 93A-32 %%

7559

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7931

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7560

7932

7561

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7933

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7562

if OP.RX_CALIBRATION

7934

if OP.RX_CALIBRATION

7563

sigma_XT=0;

7935

sigma_XT=0;

7564

else

7936

else

7565

if ~OP.RxFFE

7937

if ~OP.RxFFE

7566

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata,phase_memory); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7938

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata,phase_memory); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7567

%% Equation 93A-36 denominator (actually its sqrt)

7939

%% Equation 93A-36 denominator (actually its sqrt)

7568

else % John Ewen: 13/12/20018

7940

else % John Ewen: 13/12/20018

7569

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7941

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7570

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata, phase_memory,C); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7942

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata, phase_memory,C); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7571

else % use results from get_PSDs RIM 3/28/2024

7943

else % use results from get_PSDs RIM 3/28/2024

7572

sigma_XT=PSD_results.S_xn_rms;

7944

sigma_XT=PSD_results.S_xn_rms;

7573

end

7945

end

7574

end

7946

end

7575

end

7947

end

7576

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7948

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7577

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7949

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7578

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7950

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7579

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7951

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7580

f=chdata(1).faxis;

7952

f=chdata(1).faxis;

7581

H_Rx_FFE=zeros(1,length(f));

7953

H_Rx_FFE=zeros(1,length(f));

7582

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7954

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7583

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7955

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7584

if C(ii+param.RxFFE_cmx+1)==0

7956

if C(ii+param.RxFFE_cmx+1)==0

7585

%speed up: skip cases when rxffe=0

7957

%speed up: skip cases when rxffe=0

7586

continue;

7958

continue;

7587

end

7959

end

7588

if ii+1==0

7960

if ii+1==0

7589

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7961

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7590

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7962

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7591

else

7963

else

7592

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7964

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7593

end

7965

end

7594

end

7966

end

7595

sigma_N =sqrt(param.eta_0*sum(H_sy(2:end) .* abs(H_r(2:end) .* H_ctf(2:end) .*H_Rx_FFE(2:end)).^2 .* diff(chdata(1).faxis)/1e9)); % changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7967

sigma_N =sqrt(param.eta_0*sum(H_sy(2:end) .* abs(H_r(2:end) .* H_ctf(2:end) .*H_Rx_FFE(2:end)).^2 .* diff(chdata(1).faxis)/1e9)); % changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7596

end

7968

end

7597

end

7969

end

7598

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7970

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7599

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7971

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7600

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7972

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7601

else

7973

else

7602

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7974

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7603

end

7975

end

7604

if do_C2M

7976

if do_C2M

7605

if param.Noise_Crest_Factor == 0

7977

if param.Noise_Crest_Factor == 0

7606

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7978

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7607

else

7979

else

7608

ber_q=param.Noise_Crest_Factor;

7980

ber_q=param.Noise_Crest_Factor;

7609

end

7981

end

7610

if OP.force_pdf_bin_size

7982

if OP.force_pdf_bin_size

7611

delta_y = OP.BinSize;

7983

delta_y = OP.BinSize;

7612

else

7984

else

7613

delta_y = min(A_s/1000, OP.BinSize);

7985

delta_y = min(A_s/1000, OP.BinSize);

7614

end

7986

end

7615

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7987

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7616

cci_pdf = normal_dist(0, ber_q, delta_y);

7988

cci_pdf = normal_dist(0, ber_q, delta_y);

7617

chdata(1).eq_pulse_response=sbr;

7989

chdata(1).eq_pulse_response=sbr;

7618

tmp_result.t_s= cursor_i;

7990

tmp_result.t_s= cursor_i;

7619

tmp_result.A_s=A_s;

7991

tmp_result.A_s=A_s;

7620

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7992

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7621

if EH_1st <= param.Min_VEO_Test/1000 -.001

7993

if EH_1st <= param.Min_VEO_Test/1000 -.001

7622

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7994

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7623

continue

7995

continue

7624

else

7996

else

7625

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7997

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7626

end

7998

end

7627

Struct_Noise.sigma_N=sigma_N;

7999

Struct_Noise.sigma_N=sigma_N;

7628

Struct_Noise.sigma_TX=sigma_TX;

8000

Struct_Noise.sigma_TX=sigma_TX;

7629

Struct_Noise.cci_pdf=cci_pdf;

8001

Struct_Noise.cci_pdf=cci_pdf;

7630

Struct_Noise.ber_q=ber_q;

8002

Struct_Noise.ber_q=ber_q;

7631

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

8003

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7632

[Left_EW,Right_EW,eye_contour,EH_T_C2M,EH_B_C2M]=COM_eye_width(chdata,delta_y,tmp_result,param,OP,Struct_Noise,1);

8004

[Left_EW,Right_EW,eye_contour,EH_T_C2M,EH_B_C2M]=COM_eye_width(chdata,delta_y,tmp_result,param,OP,Struct_Noise,1);

7633

EH=EH_T_C2M-EH_B_C2M;

8005

EH=EH_T_C2M-EH_B_C2M;

7634

N_i=(A_s*2-EH)/2;

8006

N_i=(A_s*2-EH)/2;

7635

if EH <= param.Min_VEO_Test/1000

8007

if EH <= param.Min_VEO_Test/1000

7636

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

8008

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7637

continue

8009

continue

7638

else

8010

else

7639

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

8011

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

7640

end

8012

end

7641

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

8013

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7642

FOM =20*log10(A_s/N_i);

8014

FOM =20*log10(A_s/N_i);

7643

end

8015

end

7644

else

8016

else

7645

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

8017

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7646

FOM = 20*log10(A_s/total_noise_rms);

8018

FOM = 20*log10(A_s/total_noise_rms);

7647

end

8019

end

7648

% if strfind(param.CTLE_type,'CL120e')

8020

% if strfind(param.CTLE_type,'CL120e')

7649

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

8021

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

7650

end

8022

end

7651

if 0 % for loop analysis

8023

if 0 % for loop analysis

7652

result.FOM_array(new_loops)=FOM;

8024

result.FOM_array(new_loops)=FOM;

7653

end

8025

end

7654

8026

7655

if FOM>best_itick_FOM

8027

if FOM>best_itick_FOM

7656

best_itick_FOM=FOM;

8028

best_itick_FOM=FOM;

7657

best_itick_in_cluster=itick;

8029

best_itick_in_cluster=itick;

7658

end

8030

end

7659

8031

7660

if itick>=0 && FOM>best_positive_itick_FOM

8032

if itick>=0 && FOM>best_positive_itick_FOM

7661

best_positive_itick_FOM=FOM;

8033

best_positive_itick_FOM=FOM;

7662

best_positive_itick_in_loop=itick;

8034

best_positive_itick_in_loop=itick;

7663

end

8035

end

7664

if itick<=0 && FOM>best_negative_itick_FOM

8036

if itick<=0 && FOM>best_negative_itick_FOM

7665

best_negative_itick_FOM=FOM;

8037

best_negative_itick_FOM=FOM;

7666

best_negative_itick_in_loop=itick;

8038

best_negative_itick_in_loop=itick;

7667

end

8039

end

7668

8040

7669

itick_index=find(itick==full_sample_range);

8041

itick_index=find(itick==full_sample_range);

7670

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

8042

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

7671

8043

7672

if (FOM > best_FOM)

8044

if (FOM > best_FOM)

7673

best_current_ffegain=param.current_ffegain;

8045

best_current_ffegain=param.current_ffegain;

7674

best_txffe = txffe;

8046

best_txffe = txffe;

7675

%along with best_txffe, save the indices of the best_txffe

8047

%along with best_txffe, save the indices of the best_txffe

7676

%(saves time in LOCAL SEARCH block)

8048

%(saves time in LOCAL SEARCH block)

7677

best_txffe_index=tx_index_vector;

8049

best_txffe_index=tx_index_vector;

7678

best_sbr = sbr;

8050

best_sbr = sbr;

7679

best_ctle = ctle_index;

8051

best_ctle = ctle_index;

7680

best_G_high_pass =g_LP_index;

8052

best_G_high_pass =g_LP_index;

7681

best_FOM = FOM;

8053

best_FOM = FOM;

7682

best_cursor_i = cursor_i;

8054

best_cursor_i = cursor_i;

7683

best_itick = itick;

8055

best_itick = itick;

7684

if ~OP.TDMODE

8056

if ~OP.TDMODE

7685

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

8057

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7686

best_IR=effective_channel;

8058

best_IR=effective_channel;

7687

end

8059

end

7688

best_sigma_N = sigma_N;

8060

best_sigma_N = sigma_N;

7689

best_h_J = h_J;

8061

best_h_J = h_J;

7690

best_A_s=A_s;

8062

best_A_s=A_s;

7691

best_A_p=A_p;

8063

best_A_p=A_p;

7692

best_ISI=ISI_N;

8064

best_ISI=ISI_N;

7693

best_bmax=param.use_bmax;

8065

best_bmax=param.use_bmax;

7694

%AJG021820

8066

%AJG021820

7695

best_bmin=param.use_bmin;

8067

best_bmin=param.use_bmin;

7696

best_tail_RSS=tail_RSS;

8068

best_tail_RSS=tail_RSS;

7697

best_dfetaps=dfetaps;

8069

best_dfetaps=dfetaps;

7698

if param.Floating_DFE

8070

if param.Floating_DFE

7699

best_floating_tap_locations=floating_tap_locations;

8071

best_floating_tap_locations=floating_tap_locations;

7700

best_floating_tap_coef=floating_tap_coef;

8072

best_floating_tap_coef=floating_tap_coef;

7701

end

8073

end

7702

if param.Floating_RXFFE

8074

if param.Floating_RXFFE

7703

best_floating_tap_locations=floating_tap_locations;

8075

best_floating_tap_locations=floating_tap_locations;

7704

% best_floating_tap_coef=floating_tap_coef;

8076

% best_floating_tap_coef=floating_tap_coef;

7705

end

8077

end

7706

if OP.RxFFE

8078

if OP.RxFFE

7707

best_RxFFE=C;

8079

best_RxFFE=C;

7708

best_PSD_results=PSD_results;

8080

best_PSD_results=PSD_results;

7709

best_MMSE_results=MMSE_results;

8081

best_MMSE_results=MMSE_results;

7710

end

8082

end

7711

end

8083

end

7712

end

8084

end

7713

end

8085

end

7714

8086

7715

end

8087

end

7716

end

8088

end

7717

end

8089

end

7718

if do_C2M

8090

if do_C2M

7719

if best_FOM == -inf

8091

if best_FOM == -inf

7720

param.Min_VEO_Test=0;

8092

param.Min_VEO_Test=0;

7721

else

8093

else

7722

break

8094

break

7723

end

8095

end

7724

end

8096

end

7725

end

8097

end

7726

if 0

8098

if 0

7727

fprintf('old loops = %d\n',old_loops);

8099

fprintf('old loops = %d\n',old_loops);

7728

fprintf('new loops = %d\n',new_loops);

8100

fprintf('new loops = %d\n',new_loops);

7729

display(sprintf('\n :loops = %g',pxi))

8101

display(sprintf('\n :loops = %g',pxi))

7730

end

8102

end

7731

8103

7732

%turn this on to review if FOM changes sign more than once in an itick loop

8104

%turn this on to review if FOM changes sign more than once in an itick loop

7733

if 0

8105

if 0

7734

DIR_CHANGE={};

8106

DIR_CHANGE={};

7735

for m=1:length(Gffe_values)

8107

for m=1:length(Gffe_values)

7736

for n=1:length(gdc_values)

8108

for n=1:length(gdc_values)

7737

for k=1:lf_indx

8109

for k=1:lf_indx

7738

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

8110

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

7739

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

8111

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

7740

%1 = goes up, -1=goes down

8112

%1 = goes up, -1=goes down

7741

x=sign(diff(FOM_this_mat')');

8113

x=sign(diff(FOM_this_mat')');

7742

%y = change in sign on x. the location of a "2" is where FOM changes direction

8114

%y = change in sign on x. the location of a "2" is where FOM changes direction

7743

y=abs(diff(x'))';

8115

y=abs(diff(x'))';

7744

%the goal is the FOM only changes direction once. so count the occurences of the 2

8116

%the goal is the FOM only changes direction once. so count the occurences of the 2

7745

for j=1:size(FOM_this_mat,1)

8117

for j=1:size(FOM_this_mat,1)

7746

z{j}=find(y(j,:)==2);

8118

z{j}=find(y(j,:)==2);

7747

end

8119

end

7748

zL=cellfun('length',z);

8120

zL=cellfun('length',z);

7749

%return any row where FOM changed direction more than once

8121

%return any row where FOM changed direction more than once

7750

DIR_CHANGE{j,k}=find(zL>1);

8122

DIR_CHANGE{j,k}=find(zL>1);

7751

end

8123

end

7752

end

8124

end

7753

end

8125

end

7754

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

8126

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

7755

end

8127

end

7756

8128

7757

if ~exist('best_cursor_i', 'var')% take last setting

8129

if ~exist('best_cursor_i', 'var')% take last setting

7758

result.eq_failed=true;

8130

result.eq_failed=true;

7759

display('equalization failed')

8131

display('equalization failed')

7760

best_bmax=param.bmax;

8132

best_bmax=param.bmax;

7761

%AJG021820

8133

%AJG021820

7762

best_bmin=param.bmin;

8134

best_bmin=param.bmin;

7763

best_tail_RSS=0;

8135

best_tail_RSS=0;

7764

best_current_ffegain=0;

8136

best_current_ffegain=0;

7765

best_txffe = txffe;

8137

best_txffe = txffe;

7766

best_sbr = sbr;

8138

best_sbr = sbr;

7767

best_ctle = ctle_index;

8139

best_ctle = ctle_index;

7768

if OP.RxFFE

8140

if OP.RxFFE

7769

best_PSD_results=PSD_results;

8141

best_PSD_results=PSD_results;

7770

best_MMSE_results=MMSE_results;

8142

best_MMSE_results=MMSE_results;

7771

best_RxFFE=C;

8143

best_RxFFE=C;

7772

end

8144

end

7773

best_G_high_pass =g_LP_index;

8145

best_G_high_pass =g_LP_index;

7774

best_FOM = FOM;

8146

best_FOM = FOM;

7775

%if this block is reached, the last encountered EQ parameters are used

8147

%if this block is reached, the last encountered EQ parameters are used

7776

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

8148

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

7777

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

8149

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

7778

if isempty(cursor_i)

8150

if isempty(cursor_i)

7779

[~,cursor_i]=max(sbr);

8151

[~,cursor_i]=max(sbr);

7780

end

8152

end

7781

best_cursor_i = cursor_i;

8153

best_cursor_i = cursor_i;

7782

best_itick = itick;

8154

best_itick = itick;

7783

if ~OP.TDMODE

8155

if ~OP.TDMODE

7784

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

8156

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7785

best_IR=effective_channel;

8157

best_IR=effective_channel;

7786

end

8158

end

7787

best_sigma_N = sigma_N;

8159

best_sigma_N = sigma_N;

7788

best_h_J = h_J;

8160

best_h_J = h_J;

7789

best_A_p=max(sbr);

8161

best_A_p=max(sbr);

7790

best_ISI=1;

8162

best_ISI=1;

7791

best_dfetaps= sbr( cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe))/sbr(cursor_i) ;

8163

best_dfetaps= sbr( cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe))/sbr(cursor_i) ;

7792

best_A_s= sbr( cursor_i);

8164

best_A_s= sbr( cursor_i);

7793

if param.Floating_DFE

8165

if param.Floating_DFE

7794

best_floating_tap_locations=[];

8166

best_floating_tap_locations=[];

7795

best_floating_tap_coef=[];

8167

best_floating_tap_coef=[];

7796

end

8168

end

7797

if do_C2M

8169

if do_C2M

7798

return

8170

return

7799

end

8171

end

7800

% return

8172

% return

7801

else

8173

else

7802

result.eq_failed=false; % RIM 12/30/2023

8174

result.eq_failed=false; % RIM 12/30/2023

7803

end

8175

end

7804

8176

7805

best_cursor = best_sbr(best_cursor_i);

8177

best_cursor = best_sbr(best_cursor_i);

7806

% report during debug

8178

% report during debug

7807

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

8179

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

7808

%If sbr was zero padded, then PRin needs to do so as well)

8180

%If sbr was zero padded, then PRin needs to do so as well)

7809

if length(PRin)<length(best_sbr)

8181

if length(PRin)<length(best_sbr)

7810

PRin(end+1:length(best_sbr))=0;

8182

PRin(end+1:length(best_sbr))=0;

7811

end

8183

end

7812

f=1e8:1e8:100e9;

8184

f=1e8:1e8:100e9;

7813

8185

7814

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

8186

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

7815

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

8187

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

7816

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

8188

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7817

% need to include H_RCos in noise and when computing the system ir for thru

8189

% need to include H_RCos in noise and when computing the system ir for thru

7818

% and crosstalk

8190

% and crosstalk

7819

H_r=H_bw.*H_bt.*H_RCos;

8191

H_r=H_bw.*H_bt.*H_RCos;

7820

8192

7821

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

8193

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

7822

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

8194

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

7823

8195

7824

switch param.CTLE_type

8196

switch param.CTLE_type

7825

case 'CL93'

8197

case 'CL93'

7826

H_low=1;

8198

H_low=1;

7827

case 'CL120d'

8199

case 'CL120d'

7828

H_low=(10^(param.g_DC_HP_values(best_G_high_pass)/20) + 1i*f/param.f_HP(best_G_high_pass))./(1 + 1i*f/param.f_HP(best_G_high_pass));

8200

H_low=(10^(param.g_DC_HP_values(best_G_high_pass)/20) + 1i*f/param.f_HP(best_G_high_pass))./(1 + 1i*f/param.f_HP(best_G_high_pass));

7829

case 'CL120e'

8201

case 'CL120e'

7830

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

8202

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

7831

end

8203

end

7832

ctle_gain=H_low.*ctle_gain1.*H_r;

8204

ctle_gain=H_low.*ctle_gain1.*H_r;

7833

8205

7834

8206

7835

8207

7836

%lsbr=length(sbr);

8208

%lsbr=length(sbr);

7837

%use length of best_sbr in case zero padding was performed

8209

%use length of best_sbr in case zero padding was performed

7838

%check "sbr_required_length" variable

8210

%check "sbr_required_length" variable

7839

lsbr=length(best_sbr);

8211

lsbr=length(best_sbr);

7840

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

8212

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

7841

8213

7842

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 = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

7843

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

8215

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

7844

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

8216

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

7845

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

8217

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

7846

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

8218

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

7847

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

8219

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

7848

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

8220

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

7849

if param.Floating_DFE

8221

if param.Floating_DFE

7850

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

8222

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

7851

end

8223

end

7852

% apply max tap value constraint

8224

% apply max tap value constraint

7853

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

8225

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

7854

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

8226

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

7855

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

8227

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

7856

8228

7857

%AJG021820

8229

%AJG021820

7858

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

8230

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

7859

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

8231

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

7860

if param.Floating_DFE

8232

if param.Floating_DFE

7861

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

8233

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

7862

end

8234

end

7863

8235

7864

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

8236

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

7865

Symbol_Adj = (param.levels-1);% 3A.1.6

8237

Symbol_Adj = (param.levels-1);% 3A.1.6

7866

if OP.DEBUG ~=0

8238

if OP.DEBUG ~=0

7867

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

8239

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

7868

% display pulse responses in one axis per test case.

8240

% display pulse responses in one axis per test case.

7869

switch upper(OP.TIME_AXIS)

8241

switch upper(OP.TIME_AXIS)

7870

case 'S' % RIM 11-13-2023 added user selectable xaxis

8242

case 'S' % RIM 11-13-2023 added user selectable xaxis

7871

xnorm=1;

8243

xnorm=1;

7872

xaxis_label='seconds';

8244

xaxis_label='seconds';

7873

offset=0;

8245

offset=0;

7874

case 'UI'

8246

case 'UI'

7875

xnorm=param.ui;

8247

xnorm=param.ui;

7876

xaxis_label='UI';

8248

xaxis_label='UI';

7877

offset=t(best_cursor_i)/xnorm;

8249

offset=t(best_cursor_i)/xnorm;

7878

otherwise

8250

otherwise

7879

xnorm=1;

8251

xnorm=1;

7880

xaxis_label='seconds';

8252

xaxis_label='seconds';

7881

offset=0;

8253

offset=0;

7882

end

8254

end

7883

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

8255

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

7884

fig=findobj('Name', figure_name);

8256

fig=findobj('Name', figure_name);

7885

if isempty(fig), fig=figure('Name', figure_name); end

8257

if isempty(fig), fig=figure('Name', figure_name); end

7886

figure(fig);set(gcf,'Tag','COM');

8258

figure(fig);set(gcf,'Tag','COM');

7887

movegui(fig,'north')

8259

movegui(fig,'north')

7888

%figure(fig.Number);

8260

%figure(fig.Number);

7889

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

8261

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

7890

if OP.RxFFE

8262

if OP.RxFFE

7891

ax1=subplot(2,1,1);

8263

ax1=subplot(2,1,1);

7892

end

8264

end

7893

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

8265

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

7894

hold on

8266

hold on

7895

8267

7896

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

8268

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

7897

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

8269

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

7898

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

8270

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

7899

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

8271

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

7900

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

8272

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

7901

ylabel('volts')

8273

ylabel('volts')

7902

xlabel(xaxis_label)

8274

xlabel(xaxis_label)

7903

grid on

8275

grid on

7904

legend show

8276

legend show

7905

legend( 'Location', 'best')

8277

legend( 'Location', 'best')

7906

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

8278

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

7907

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

8279

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

7908

if param.ndfe_passed ~=0

8280

if param.ndfe_passed ~=0

7909

stem((sampled_best_sbr_dfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,DFE_taps_mV(1:param.ndfe_passed)/Symbol_Adj','m', 'LineWidth',2,'disp','DFE-canceled cursors');

8281

stem((sampled_best_sbr_dfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,DFE_taps_mV(1:param.ndfe_passed)/Symbol_Adj','m', 'LineWidth',2,'disp','DFE-canceled cursors');

7910

end

8282

end

7911

if param.Floating_DFE

8283

if param.Floating_DFE

7912

stem((sampled_best_sbr_fdfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,FDFE_taps_mV/Symbol_Adj, 'MarkerFaceColor','red','MarkerEdgeColor','m','LineWidth',1,'disp','FDFE-canceled cursors');

8284

stem((sampled_best_sbr_fdfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,FDFE_taps_mV/Symbol_Adj, 'MarkerFaceColor','red','MarkerEdgeColor','m','LineWidth',1,'disp','FDFE-canceled cursors');

7913

end

8285

end

7914

if OP.RxFFE

8286

if OP.RxFFE

7915

ax2=subplot(2,1,2);

8287

ax2=subplot(2,1,2);

7916

if param.Floating_RXFFE

8288

if param.Floating_RXFFE

7917

%AJG: floating tap x-axis location needs offset by -(RxFFE_cmx+1) because the floating tap indices include precursor indices

8289

%AJG: floating tap x-axis location needs offset by -(RxFFE_cmx+1) because the floating tap indices include precursor indices

7918

stem((t(best_cursor_i+(best_floating_tap_locations-param.RxFFE_cmx-1)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

8290

stem((t(best_cursor_i+(best_floating_tap_locations-param.RxFFE_cmx-1)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

7919

,'filled','disp','RxFFE floating FFE taps')

8291

,'filled','disp','RxFFE floating FFE taps')

7920

hold on

8292

hold on

7921

end

8293

end

7922

stem((t(best_cursor_i+param.samples_per_ui*(-param.RxFFE_cmx:param.RxFFE_cpx)))/xnorm-offset,best_RxFFE(1:param.RxFFE_cmx+param.RxFFE_cpx+1)...

8294

stem((t(best_cursor_i+param.samples_per_ui*(-param.RxFFE_cmx:param.RxFFE_cpx)))/xnorm-offset,best_RxFFE(1:param.RxFFE_cmx+param.RxFFE_cpx+1)...

7923

,'filled','disp','RxFFE fixted FFE taps')

8295

,'filled','disp','RxFFE fixted FFE taps')

7924

legend show

8296

legend show

7925

zoom xon

8297

zoom xon

7926

linkaxes([ax1 ax2],'x')

8298

linkaxes([ax1 ax2],'x')

7927

end

8299

end

7928

8300

7929

8301

7930

grid on

8302

grid on

7931

legend show

8303

legend show

7932

legend( 'Location', 'best')

8304

legend( 'Location', 'best')

7933

zoom xon

8305

zoom xon

7934

% set(hax, 'tag', 'EQE');

8306

% set(hax, 'tag', 'EQE');

7935

%

8307

%

7936

figure(110);set(gcf,'Tag','COM');

8308

figure(110);set(gcf,'Tag','COM');

7937

set(gcf, 'Name', 'CTLE selection');

8309

set(gcf, 'Name', 'CTLE selection');

7938

movegui(gcf, 'southeast');

8310

movegui(gcf, 'southeast');

7939

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8311

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

7940

hold on

8312

hold on

7941

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8313

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

7942

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8314

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

7943

fbaud_tick=find(f >= baud_rate, 1);

8315

fbaud_tick=find(f >= baud_rate, 1);

7944

fnq_tick=find(f >= baud_rate/2, 1);

8316

fnq_tick=find(f >= baud_rate/2, 1);

7945

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8317

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

7946

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8318

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

7947

recolor_plots(gca);

8319

recolor_plots(gca);

7948

title('CTF/w Rx Filter Response')

8320

title('CTF/w Rx Filter Response')

7949

ylabel('dB')

8321

ylabel('dB')

7950

xlabel('Hz')

8322

xlabel('Hz')

7951

legend show

8323

legend show

7952

end

8324

end

7953

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8325

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

7954

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8326

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

7955

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8327

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

7956

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8328

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

7957

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8329

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

7958

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8330

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

7959

end

8331

end

7960

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

8332

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

7961

eqe_axes = findobj('tag', 'EQE');

8333

eqe_axes = findobj('tag', 'EQE');

7962

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8334

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

7963

end

8335

end

7964

if OP.DISPLAY_WINDOW

8336

if OP.DISPLAY_WINDOW

7965

close(hwaitbar);

8337

close(hwaitbar);

7966

else

8338

else

7967

fprintf('\n');

8339

fprintf('\n');

7968

end

8340

end

7969

8341

7970

% % eq_data

8342

% % eq_data

7971

result.cur=cur;

8343

result.cur=cur;

7972

result.txffe = best_txffe;

8344

result.txffe = best_txffe;

7973

result.ctle = best_ctle;

8345

result.ctle = best_ctle;

7974

result.best_G_high_pass=best_G_high_pass;

8346

result.best_G_high_pass=best_G_high_pass;

7975

result.DFE_taps = best_dfetaps; %relative

8347

result.DFE_taps = best_dfetaps; %relative

7976

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8348

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

7977

if param.Floating_DFE

8349

if param.Floating_DFE

7978

result.floating_tap_locations=best_floating_tap_locations;

8350

result.floating_tap_locations=best_floating_tap_locations;

7979

result.floating_tap_coef=best_floating_tap_coef;

8351

result.floating_tap_coef=best_floating_tap_coef;

7980

end

8352

end

7981

if param.Floating_RXFFE

8353

if param.Floating_RXFFE

7982

result.floating_tap_locations=best_floating_tap_locations;

8354

result.floating_tap_locations=best_floating_tap_locations;

7983

end

8355

end

7984

result.A_s = best_A_s;

8356

result.A_s = best_A_s;

7985

result.t_s = best_cursor_i;

8357

result.t_s = best_cursor_i;

7986

result.itick = best_itick;

8358

result.itick = best_itick;

7987

result.sigma_N = best_sigma_N;

8359

result.sigma_N = best_sigma_N;

7988

result.h_J = best_h_J;

8360

result.h_J = best_h_J;

7989

result.FOM = best_FOM;

8361

result.FOM = best_FOM;

7990

if ~OP.TDMODE

8362

if ~OP.TDMODE

7991

%If sbr was zero padded, then best_IR needs to do so as well)

8363

%If sbr was zero padded, then best_IR needs to do so as well)

7992

if length(best_IR)<length(best_sbr)

8364

if length(best_IR)<length(best_sbr)

7993

best_IR(end+1:length(best_sbr))=0;

8365

best_IR(end+1:length(best_sbr))=0;

7994

end

8366

end

7995

result.IR = best_IR;

8367

result.IR = best_IR;

7996

end

8368

end

7997

result.t=t;

8369

result.t=t;

7998

result.sbr=best_sbr;

8370

result.sbr=best_sbr;

7999

if OP.RxFFE

8371

if OP.RxFFE

8000

result.RxFFE=best_RxFFE;

8372

result.RxFFE=best_RxFFE;

8001

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8373

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8002

result.PSD_results=best_PSD_results;

8374

result.PSD_results=best_PSD_results;

8003

result.MMSE_results=best_MMSE_results;

8375

result.MMSE_results=best_MMSE_results;

8004

end

8376

end

8005

end

8377

end

8006

8378

8007

8379

8008

8380

8009

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8381

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8010

% updated RIM 12/17/2021

8382

% updated RIM 12/17/2021

8011

result.A_p = max(chdata(1).uneq_pulse_response);

8383

result.A_p = max(chdata(1).uneq_pulse_response);

8012

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8384

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8013

PR=chdata(1).uneq_pulse_response;

8385

PR=chdata(1).uneq_pulse_response;

8014

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8386

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8015

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8387

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8016

if iend >= length(PR)

8388

if iend >= length(PR)

8017

iend = length (PR);

8389

iend = length (PR);

8018

end

8390

end

8019

if ibeg < 1

8391

if ibeg < 1

8020

ibeg = 1;

8392

ibeg = 1;

8021

end

8393

end

8022

PR=PR(ibeg:iend);

8394

PR=PR(ibeg:iend);

8023

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8395

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8024

SRn=PR;

8396

SRn=PR;

8025

for ik=1:floor(length(PR)/param.samples_per_ui)

8397

for ik=1:floor(length(PR)/param.samples_per_ui)

8026

SPR=circshift(PR,param.samples_per_ui*ik);

8398

SPR=circshift(PR,param.samples_per_ui*ik);

8027

SPR(1:ik*param.samples_per_ui)=0;

8399

SPR(1:ik*param.samples_per_ui)=0;

8028

SRn=SRn+ SPR;

8400

SRn=SRn+ SPR;

8029

end

8401

end

8030

codedebug=0;

8402

codedebug=0;

8031

if codedebug

8403

if codedebug

8032

fig=figure('Name', 'step and pulse response for code debug');

8404

fig=figure('Name', 'step and pulse response for code debug');

8033

figure(fig);set(gcf,'Tag','COM');

8405

figure(fig);set(gcf,'Tag','COM');

8034

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8406

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8035

plot(UI,SRn)

8407

plot(UI,SRn)

8036

hold on

8408

hold on

8037

plot(UI,PR)

8409

plot(UI,PR)

8038

xlim([-param.D_p param.N_v])

8410

xlim([-param.D_p param.N_v])

8039

grid on;hold off;

8411

grid on;hold off;

8040

result.step=SRn;

8412

result.step=SRn;

8041

end

8413

end

8042

i20=find(SRn>=0.20*result.A_f,1,'first');

8414

i20=find(SRn>=0.20*result.A_f,1,'first');

8043

i80=find(SRn>=0.80*result.A_f,1,'first');

8415

i80=find(SRn>=0.80*result.A_f,1,'first');

8044

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8416

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8045

result.Pmax_by_Vf=result.A_p/result.A_f;

8417

result.Pmax_by_Vf=result.A_p/result.A_f;

8046

result.ISI =best_ISI;

8418

result.ISI =best_ISI;

8047

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8419

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8048

result.best_current_ffegain=best_current_ffegain;

8420

result.best_current_ffegain=best_current_ffegain;

8049

result.best_bmax=best_bmax;

8421

result.best_bmax=best_bmax;

8050

%AJG021820

8422

%AJG021820

8051

result.best_bmin=best_bmin;

8423

result.best_bmin=best_bmin;

8052

result.tail_RSS=best_tail_RSS;

8424

result.tail_RSS=best_tail_RSS;

8053

function param=parameter_size_adjustment(param,OP)

8425

function param=parameter_size_adjustment(param,OP)

8054

8426

8055

make_length2={'C_pkg_board' 'C_diepad' 'L_comp' 'C_bump' 'tfx' 'C_v' 'C_0' 'C_1' 'pkg_Z_c' 'brd_Z_c' 'R_diepad'};

8427

make_length2={'C_pkg_board' 'C_diepad' 'L_comp' 'C_bump' 'tfx' 'C_v' 'C_0' 'C_1' 'pkg_Z_c' 'brd_Z_c' 'R_diepad'};

8056

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8428

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8057

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8429

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8058

make_length_DCHP={'f_HP'};

8430

make_length_DCHP={'f_HP'};

8059

make_length_ncases={'AC_CM_RMS'};

8431

make_length_ncases={'AC_CM_RMS'};

8060

8432

8061

%ncases used by make_length_ncases fields

8433

%ncases used by make_length_ncases fields

8062

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8434

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8063

8435

8064

%PORTZ_mult used by make_length_WCPORTZ fields

8436

%PORTZ_mult used by make_length_WCPORTZ fields

8065

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8437

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8066

if OP.WC_PORTZ

8438

if OP.WC_PORTZ

8067

PORTZ_mult=[1 1];

8439

PORTZ_mult=[1 1];

8068

else

8440

else

8069

PORTZ_mult=pkg_sel_vec;

8441

PORTZ_mult=pkg_sel_vec;

8070

end

8442

end

8071

8443

8072

%Parameters that have length = 2

8444

%Parameters that have length = 2

8073

for j=1:length(make_length2)

8445

for j=1:length(make_length2)

8074

if numel(param.(make_length2{j}))==1

8446

if numel(param.(make_length2{j}))==1

8075

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8447

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8076

end

8448

end

8077

end

8449

end

8078

8450

8079

%Parameters that have length = ncases

8451

%Parameters that have length = ncases

8080

for j=1:length(make_length_ncases)

8452

for j=1:length(make_length_ncases)

8081

if numel(param.(make_length_ncases{j}))==1

8453

if numel(param.(make_length_ncases{j}))==1

8082

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8454

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8083

end

8455

end

8084

end

8456

end

8085

8457

8086

%Parameters that have length = length(ctle_gdc_values)

8458

%Parameters that have length = length(ctle_gdc_values)

8087

for j=1:length(make_length_GDC)

8459

for j=1:length(make_length_GDC)

8088

if numel(param.(make_length_GDC{j}))==1

8460

if numel(param.(make_length_GDC{j}))==1

8089

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8461

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8090

end

8462

end

8091

end

8463

end

8092

8464

8093

%Parameters that have length = length(g_DC_HP_values)

8465

%Parameters that have length = length(g_DC_HP_values)

8094

for j=1:length(make_length_DCHP)

8466

for j=1:length(make_length_DCHP)

8095

if numel(param.(make_length_DCHP{j}))==1

8467

if numel(param.(make_length_DCHP{j}))==1

8096

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8468

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8097

end

8469

end

8098

end

8470

end

8099

8471

8100

%Parameters that have length associated with PORTZ_mult

8472

%Parameters that have length associated with PORTZ_mult

8101

for j=1:length(make_length_WCPORTZ)

8473

for j=1:length(make_length_WCPORTZ)

8102

if numel(param.(make_length_WCPORTZ{j}))==1

8474

if numel(param.(make_length_WCPORTZ{j}))==1

8103

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8475

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8104

end

8476

end

8105

end

8477

end

8106

function sgm = pdf2sgm(pdf)

8478

function sgm = pdf2sgm(pdf)

8107

avg = sum(pdf.x .* pdf.y);

8479

avg = sum(pdf.x .* pdf.y);

8108

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8480

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8109

% end yasuo patch

8481

% end yasuo patch

8110

8482

8111

8483

8112

%% adding tx packgage

8484

%% adding tx packgage

8113

function cdf=pdf_to_cdf(pdf)

8485

function cdf=pdf_to_cdf(pdf)

8114

8486

8115

%Transform PDF to CDF

8487

%Transform PDF to CDF

8116

%The CDF is natively calculated from negative-to-positive voltage.

8488

%The CDF is natively calculated from negative-to-positive voltage.

8117

%This only gives BER calculation for bottom eye. Need to also

8489

%This only gives BER calculation for bottom eye. Need to also

8118

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8490

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8119

%min of top and bottom CDF values.

8491

%min of top and bottom CDF values.

8120

%If only interested in one side, a simple cumsum on y is all that is needed.

8492

%If only interested in one side, a simple cumsum on y is all that is needed.

8121

8493

8122

cdf.yB=cumsum(pdf.y);

8494

cdf.yB=cumsum(pdf.y);

8123

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8495

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8124

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8496

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8125

cdf.x=pdf.x;

8497

cdf.x=pdf.x;

8126

function plot_bathtub_curves(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf,jitt_pdf, combined_interference_and_noise_pdf, bin_size)

8498

function plot_bathtub_curves(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf,jitt_pdf, combined_interference_and_noise_pdf, bin_size)

8127

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8499

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8128

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8500

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8129

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8501

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8130

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8502

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8131

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8503

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8132

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8504

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8133

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8505

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8134

%% Added by Bill Kirkland, June 14, 2017

8506

%% Added by Bill Kirkland, June 14, 2017

8135

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8507

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8136

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8508

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8137

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8509

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8138

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8510

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8139

8511

8140

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8512

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8141

hold on

8513

hold on

8142

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8514

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8143

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8515

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8144

semilogy(signal_and_system_noise_pdf.x, abs(cumsum(signal_and_system_noise_pdf.y)-0.5) ,'m','Disp','Jitter, SNR_TX,RL_M, eta_0 noise', 'parent', hax)

8516

semilogy(signal_and_system_noise_pdf.x, abs(cumsum(signal_and_system_noise_pdf.y)-0.5) ,'m','Disp','Jitter, SNR_TX,RL_M, eta_0 noise', 'parent', hax)

8145

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8517

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8146

8518

8147

%% Added by Bill Kirkland, June 14, 2017

8519

%% Added by Bill Kirkland, June 14, 2017

8148

% modification allows bathtub curves to cross over and hence one can

8520

% modification allows bathtub curves to cross over and hence one can

8149

% directly read the noise component.

8521

% directly read the noise component.

8150

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8522

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8151

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8523

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8152

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8524

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8153

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8525

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8154

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8526

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8155

8527

8156

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8528

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8157

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8529

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8158

8530

8159

ylabel(hax, 'Probability')

8531

ylabel(hax, 'Probability')

8160

xlabel(hax, 'volts')

8532

xlabel(hax, 'volts')

8161

legend(hax, 'show')

8533

legend(hax, 'show')

8162

% testing code

8534

% testing code

8163

if 0

8535

if 0

8164

figure_name = 'COM curves';

8536

figure_name = 'COM curves';

8165

fig=findobj('Name', figure_name);

8537

fig=findobj('Name', figure_name);

8166

if isempty(fig), fig=figure('Name', figure_name); end

8538

if isempty(fig), fig=figure('Name', figure_name); end

8167

figure(fig);set(gcf,'Tag','COM');

8539

figure(fig);set(gcf,'Tag','COM');

8168

grid on

8540

grid on

8169

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8541

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8170

hold on

8542

hold on

8171

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8543

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8172

ylim([ 1e-6 0.25])

8544

ylim([ 1e-6 0.25])

8173

xlim([0 30])

8545

xlim([0 30])

8174

grid on

8546

grid on

8175

end

8547

end

8176

function plot_pie_com(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf, combined_interference_and_noise_pdf, bin_size,param)

8548

function plot_pie_com(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf, combined_interference_and_noise_pdf, bin_size,param)

8177

BER=param.specBER;

8549

BER=param.specBER;

8178

delta_dB=param.delta_IL;

8550

delta_dB=param.delta_IL;

8179

8551

8180

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8552

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8181

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8553

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8182

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8554

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8183

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8555

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8184

8556

8185

8557

8186

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8558

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8187

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8559

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8188

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8560

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8189

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8561

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8190

8562

8191

COM=20*log10(max_signal/maxn_tot);

8563

COM=20*log10(max_signal/maxn_tot);

8192

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8564

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8193

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8565

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8194

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8566

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8195

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8567

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8196

8568

8197

pfctr=exp(-0.09054*delta_dB);% less loss

8569

pfctr=exp(-0.09054*delta_dB);% less loss

8198

mfctr=exp(0.09054*delta_dB); % more loss

8570

mfctr=exp(0.09054*delta_dB); % more loss

8199

8571

8200

%less loss

8572

%less loss

8201

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8573

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8202

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8574

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8203

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8575

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8204

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8576

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8205

plus_maxn_tot=norm(plus_maxn);

8577

plus_maxn_tot=norm(plus_maxn);

8206

8578

8207

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8579

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8208

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8580

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8209

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8581

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8210

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8582

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8211

minus_maxn_tot=norm(minus_maxn);

8583

minus_maxn_tot=norm(minus_maxn);

8212

8584

8213

% more loss

8585

% more loss

8214

COMp=20*log10(max_signal*pfctr/maxn_tot);

8586

COMp=20*log10(max_signal*pfctr/maxn_tot);

8215

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8587

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8216

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8588

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8217

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8589

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8218

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8590

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8219

% less loss

8591

% less loss

8220

COMm=20*log10(max_signal*mfctr/maxn_tot);

8592

COMm=20*log10(max_signal*mfctr/maxn_tot);

8221

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8593

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8222

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8594

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8223

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8595

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8224

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8596

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8225

8597

8226

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8598

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8227

8599

8228

8600

8229

if(COM<0)

8601

if(COM<0)

8230

return

8602

return

8231

end

8603

end

8232

8604

8233

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8605

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8234

8606

8235

% pie(COM_per_noise,labels)

8607

% pie(COM_per_noise,labels)

8236

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8608

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8237

% legend('show','Location','bestoutside')

8609

% legend('show','Location','bestoutside')

8238

nullbar= [ 0 0 0 ];

8610

nullbar= [ 0 0 0 ];

8239

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8611

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8240

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8612

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8241

hold on

8613

hold on

8242

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8614

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8243

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8615

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8244

8616

8245

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8617

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8246

% ax=gca;

8618

% ax=gca;

8247

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8619

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8248

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8620

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8249

grid on

8621

grid on

8250

legend(labels,'Location','north')

8622

legend(labels,'Location','north')

8251

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8623

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8252

ylabel('COM (dB)')

8624

ylabel('COM (dB)')

8253

hold off

8625

hold off

8254

8626

8255

8627

8256

8628

8257

8629

8258

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8630

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8259

num_files=length(chdata);

8631

num_files=length(chdata);

8260

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8632

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8261

for i=1:num_files

8633

for i=1:num_files

8262

if param.package_testcase_i==1 && i==1

8634

if param.package_testcase_i==1 && i==1

8263

if OP.TDR && i==1

8635

if OP.TDR && i==1

8264

S.Frequencies=chdata(i).faxis;

8636

S.Frequencies=chdata(i).faxis;

8265

S.Impedance=100;

8637

S.Impedance=100;

8266

if ~OP.SHOW_BRD

8638

if ~OP.SHOW_BRD

8267

Sfield='_orig';

8639

Sfield='_orig';

8268

else

8640

else

8269

Sfield='_raw';

8641

Sfield='_raw';

8270

end

8642

end

8271

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8643

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8272

if ~param.FLAG.S2P

8644

if ~param.FLAG.S2P

8273

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8645

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8274

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8646

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8275

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8647

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8276

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8648

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8277

else

8649

else

8278

S.NumPorts=1;

8650

S.NumPorts=1;

8279

end

8651

end

8280

if OP.TDR_W_TXPKG

8652

if OP.TDR_W_TXPKG

8281

if OP.ERL == 2

8653

if OP.ERL == 2

8282

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8654

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8283

end

8655

end

8284

R_diepad = param.R_diepad;

8656

R_diepad = param.R_diepad;

8285

% RX package length is assumed to be the same for all

8657

% RX package length is assumed to be the same for all

8286

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8658

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8287

% for Rx pkg

8659

% for Rx pkg

8288

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8660

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8289

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8661

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8290

combines4p( s11in, s12in, s21in, s22in, ...

8662

combines4p( s11in, s12in, s21in, s22in, ...

8291

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8663

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8292

% S=sparameters(S.Parameters,S.Frequencies,100);

8664

% S=sparameters(S.Parameters,S.Frequencies,100);

8293

S=SL(S,S.Frequencies,R_diepad(1)*2);

8665

S=SL(S,S.Frequencies,R_diepad(1)*2);

8294

chdata(i).TX_RL=S.Parameters(2,2,:);

8666

chdata(i).TX_RL=S.Parameters(2,2,:);

8295

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8667

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8296

end

8668

end

8297

8669

8298

% need to combine S wiht is page and channel

8670

% need to combine S wiht is page and channel

8299

if param.FLAG.S2P

8671

if param.FLAG.S2P

8300

port_sel=1;

8672

port_sel=1;

8301

else

8673

else

8302

port_sel=[1 2];

8674

port_sel=[1 2];

8303

if OP.AUTO_TFX

8675

if OP.AUTO_TFX

8304

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8676

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8305

pix=find(fir4del==max(fir4del),1);

8677

pix=find(fir4del==max(fir4del),1);

8306

param.tfx(2)=2*tu(pix);

8678

param.tfx(2)=2*tu(pix);

8307

end

8679

end

8308

end

8680

end

8309

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8681

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8310

for ipsl=1:length(port_sel) % do for both port if s4p

8682

for ipsl=1:length(port_sel) % do for both port if s4p

8311

for izt=1:length(param.Z_t) % do for all tdr impedances

8683

for izt=1:length(param.Z_t) % do for all tdr impedances

8312

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8684

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8313

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8685

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8314

% OP.interp_sparam_mag='trend_to_DC';

8686

% OP.interp_sparam_mag='trend_to_DC';

8315

OP.interp_sparam_mag='linear_trend_to_DC';

8687

OP.interp_sparam_mag='linear_trend_to_DC';

8316

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8688

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8317

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8689

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8318

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8690

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8319

if ipsl ==1

8691

if ipsl ==1

8320

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8692

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8321

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8693

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8322

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8694

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8323

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8695

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8324

else

8696

else

8325

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8697

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8326

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8698

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8327

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8699

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8328

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8700

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8329

end

8701

end

8330

if OP.PTDR && i==1

8702

if OP.PTDR && i==1

8331

if ipsl ==1

8703

if ipsl ==1

8332

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8704

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8333

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8705

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8334

else

8706

else

8335

if ~param.FLAG.S2P

8707

if ~param.FLAG.S2P

8336

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8708

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8337

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8709

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8338

else

8710

else

8339

chdata(i).TDR22(izt).ERL=[];

8711

chdata(i).TDR22(izt).ERL=[];

8340

chdata(i).TDR22(izt).ERLRMS=[];

8712

chdata(i).TDR22(izt).ERLRMS=[];

8341

end

8713

end

8342

end

8714

end

8343

else

8715

else

8344

chdata(i).TDR11(izt).ERL=[];

8716

chdata(i).TDR11(izt).ERL=[];

8345

chdata(i).TDR22(izt).ERL=[];

8717

chdata(i).TDR22(izt).ERL=[];

8346

chdata(i).TDR11(izt).ERLRMS=[];

8718

chdata(i).TDR11(izt).ERLRMS=[];

8347

chdata(i).TDR22(izt).ERLRMS=[];

8719

chdata(i).TDR22(izt).ERLRMS=[];

8348

end

8720

end

8349

end

8721

end

8350

end

8722

end

8351

end

8723

end

8352

8724

8353

end

8725

end

8354

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8726

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8355

h=figure(180);set(gcf,'Tag','COM');

8727

h=figure(180);set(gcf,'Tag','COM');

8356

if param.package_testcase_i==1 && i == 1

8728

if param.package_testcase_i==1 && i == 1

8357

if i==1

8729

if i==1

8358

htabgroup = uitabgroup(h);

8730

htabgroup = uitabgroup(h);

8359

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8731

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8360

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8732

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8361

hax1 = axes('Parent', htab1);

8733

hax1 = axes('Parent', htab1);

8362

hax3 = axes('Parent', htab3);

8734

hax3 = axes('Parent', htab3);

8363

if ~param.FLAG.S2P

8735

if ~param.FLAG.S2P

8364

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8736

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8365

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8737

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8366

hax2 = axes('Parent', htab2);

8738

hax2 = axes('Parent', htab2);

8367

hax4 = axes('Parent', htab4);

8739

hax4 = axes('Parent', htab4);

8368

end

8740

end

8369

end

8741

end

8370

set(h,'CurrentAxes',hax1)

8742

set(h,'CurrentAxes',hax1)

8371

hold on

8743

hold on

8372

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8744

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8373

hold off

8745

hold off

8374

legend (hax1, 'off');grid on;zoom xon;

8746

legend (hax1, 'off');grid on;zoom xon;

8375

set(legend (hax1, 'show'), 'interp', 'none');

8747

set(legend (hax1, 'show'), 'interp', 'none');

8376

8748

8377

if ~param.FLAG.S2P

8749

if ~param.FLAG.S2P

8378

set(h,'CurrentAxes',hax2)

8750

set(h,'CurrentAxes',hax2)

8379

hold on

8751

hold on

8380

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8752

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8381

hold off

8753

hold off

8382

legend (hax2, 'off');grid on;zoom xon;

8754

legend (hax2, 'off');grid on;zoom xon;

8383

set(legend (hax2, 'show'), 'interp', 'none');

8755

set(legend (hax2, 'show'), 'interp', 'none');

8384

end

8756

end

8385

8757

8386

set(h,'CurrentAxes',hax3)

8758

set(h,'CurrentAxes',hax3)

8387

hold on

8759

hold on

8388

if OP.PTDR

8760

if OP.PTDR

8389

for izt=1:length(param.Z_t)

8761

for izt=1:length(param.Z_t)

8390

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8762

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8391

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8763

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8392

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8764

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8393

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8765

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8394

end

8766

end

8395

end

8767

end

8396

hold off

8768

hold off

8397

legend (hax3, 'off');grid on;zoom xon;

8769

legend (hax3, 'off');grid on;zoom xon;

8398

set(legend (hax3, 'show'), 'interp', 'none');

8770

set(legend (hax3, 'show'), 'interp', 'none');

8399

if ~param.FLAG.S2P

8771

if ~param.FLAG.S2P

8400

set(h,'CurrentAxes',hax4)

8772

set(h,'CurrentAxes',hax4)

8401

hold on

8773

hold on

8402

if OP.PTDR

8774

if OP.PTDR

8403

for izt=1:length(param.Z_t)

8775

for izt=1:length(param.Z_t)

8404

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8776

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8405

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8777

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8406

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8778

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8407

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8779

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8408

end

8780

end

8409

end

8781

end

8410

hold off

8782

hold off

8411

legend (hax4, 'off');grid on;zoom xon;

8783

legend (hax4, 'off');grid on;zoom xon;

8412

set(legend (hax4, 'show'), 'interp', 'none');

8784

set(legend (hax4, 'show'), 'interp', 'none');

8413

end

8785

end

8414

end

8786

end

8415

end

8787

end

8416

if param.FLAG.S2P, return; end

8788

if param.FLAG.S2P, return; end

8417

end

8789

end

8418

function S =r_parrelell2(zref,f,rpad)

8790

function S =r_parrelell2(zref,f,rpad)

8419

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8791

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8420

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8792

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8421

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8793

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8422

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8794

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8423

% Sm=sparameters(S.Parameters,f,zref);

8795

% Sm=sparameters(S.Parameters,f,zref);

8424

8796

8425

8797

8426

8798

8427

8799

8428

8800

8429

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8801

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8430

8802

8431

%touchstone_file: .sNp touchstone file to read

8803

%touchstone_file: .sNp touchstone file to read

8432

%port_order: port reorder vector

8804

%port_order: port reorder vector

8433

%

8805

%

8434

%sch: sparameter matrix

8806

%sch: sparameter matrix

8435

%schFreqAxis: frequency axis

8807

%schFreqAxis: frequency axis

8436

8808

8437

[file_path,root_name,extension]=fileparts(touchstone_file);

8809

[file_path,root_name,extension]=fileparts(touchstone_file);

8438

fid=fopen(touchstone_file);

8810

fid=fopen(touchstone_file);

8439

8811

8440

%fetch number of ports from extension

8812

%fetch number of ports from extension

8441

num_ports=str2num(char(regexp(extension,'\d*','match')));

8813

num_ports=str2num(char(regexp(extension,'\d*','match')));

8442

8814

8443

%Get option line

8815

%Get option line

8444

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8816

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8445

optcell=textscan(optstr{1}{1},'%s');

8817

optcell=textscan(optstr{1}{1},'%s');

8446

optcell=optcell{1};

8818

optcell=optcell{1};

8447

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8819

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8448

%Some touchstone files need this. can't remember why now. maybe lines

8820

%Some touchstone files need this. can't remember why now. maybe lines

8449

%with whitespace but not empty but not commented

8821

%with whitespace but not empty but not commented

8450

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8822

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8451

optcell=textscan(optstr{1}{1},'%s');

8823

optcell=textscan(optstr{1}{1},'%s');

8452

optcell=optcell{1};

8824

optcell=optcell{1};

8453

end

8825

end

8454

8826

8455

%read the entire file

8827

%read the entire file

8456

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8828

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8457

raw_column_data=raw_read_data{1};

8829

raw_column_data=raw_read_data{1};

8458

fclose(fid);

8830

fclose(fid);

8459

8831

8460

%number of columns for 2D matrix

8832

%number of columns for 2D matrix

8461

columns=num_ports*num_ports*2+1;

8833

columns=num_ports*num_ports*2+1;

8462

8834

8463

%find the frequency lines by searching for the right number of NaN

8835

%find the frequency lines by searching for the right number of NaN

8464

a=sum(isnan(raw_column_data),2);

8836

a=sum(isnan(raw_column_data),2);

8465

if num_ports==3

8837

if num_ports==3

8466

b=find(a==2);

8838

b=find(a==2);

8467

elseif num_ports==1

8839

elseif num_ports==1

8468

b=find(a==6);

8840

b=find(a==6);

8469

else

8841

else

8470

b=find(a==0);

8842

b=find(a==0);

8471

end

8843

end

8472

8844

8473

num_freq=length(b);

8845

num_freq=length(b);

8474

8846

8475

%toss out the NaN and reshape into a 2D matrix

8847

%toss out the NaN and reshape into a 2D matrix

8476

raw_input = raw_column_data.';

8848

raw_input = raw_column_data.';

8477

raw_input = raw_input(~isnan(raw_input));

8849

raw_input = raw_input(~isnan(raw_input));

8478

raw_input = reshape(raw_input,columns,num_freq).';

8850

raw_input = reshape(raw_input,columns,num_freq).';

8479

8851

8480

%get the frequency mult

8852

%get the frequency mult

8481

frequency_mult_text=optcell{2};

8853

frequency_mult_text=optcell{2};

8482

if(strcmpi(frequency_mult_text,'hz'))

8854

if(strcmpi(frequency_mult_text,'hz'))

8483

frequency_mult=1;

8855

frequency_mult=1;

8484

elseif(strcmpi(frequency_mult_text,'khz'))

8856

elseif(strcmpi(frequency_mult_text,'khz'))

8485

frequency_mult=1e3;

8857

frequency_mult=1e3;

8486

elseif(strcmpi(frequency_mult_text,'mhz'))

8858

elseif(strcmpi(frequency_mult_text,'mhz'))

8487

frequency_mult=1e6;

8859

frequency_mult=1e6;

8488

elseif(strcmpi(frequency_mult_text,'ghz'))

8860

elseif(strcmpi(frequency_mult_text,'ghz'))

8489

frequency_mult=1e9;

8861

frequency_mult=1e9;

8490

else

8862

else

8491

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8863

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8492

end

8864

end

8493

8865

8494

%get the RI/MA/DB format

8866

%get the RI/MA/DB format

8495

format=optcell{4};

8867

format=optcell{4};

8496

%get Z0

8868

%get Z0

8497

port_impedance=str2double(optcell(6:end))';

8869

port_impedance=str2double(optcell(6:end))';

8498

8870

8499

8871

8500

%grab frequency

8872

%grab frequency

8501

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8873

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8502

Spar.F=raw_input(:,1);

8874

Spar.F=raw_input(:,1);

8503

Spar.F=transpose(Spar.F(:));

8875

Spar.F=transpose(Spar.F(:));

8504

8876

8505

8877

8506

%transform data to real imaginary

8878

%transform data to real imaginary

8507

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8879

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8508

if(strcmpi(format,'ri'))

8880

if(strcmpi(format,'ri'))

8509

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8881

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8510

elseif(strcmpi(format,'ma'))

8882

elseif(strcmpi(format,'ma'))

8511

mag_data=raw_input(:,2:2:end);

8883

mag_data=raw_input(:,2:2:end);

8512

rad_data=raw_input(:,3:2:end)*pi/180;

8884

rad_data=raw_input(:,3:2:end)*pi/180;

8513

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8885

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8514

elseif(strcmpi(format,'db'))

8886

elseif(strcmpi(format,'db'))

8515

mag_data=10.^(raw_input(:,2:2:end)/20);

8887

mag_data=10.^(raw_input(:,2:2:end)/20);

8516

rad_data=raw_input(:,3:2:end)*pi/180;

8888

rad_data=raw_input(:,3:2:end)*pi/180;

8517

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8889

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8518

else

8890

else

8519

error('Format %s is not supported. Use RI MA or DB',format);

8891

error('Format %s is not supported. Use RI MA or DB',format);

8520

end

8892

end

8521

8893

8522

8894

8523

8895

8524

%transform to 3D

8896

%transform to 3D

8525

%allow for upper/lower matrix specification for touchstone 2.0 support

8897

%allow for upper/lower matrix specification for touchstone 2.0 support

8526

matrix_format=0;

8898

matrix_format=0;

8527

if(matrix_format==0)

8899

if(matrix_format==0)

8528

%full

8900

%full

8529

for j=1:num_ports

8901

for j=1:num_ports

8530

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8902

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8531

end

8903

end

8532

elseif(matrix_format==1)

8904

elseif(matrix_format==1)

8533

%upper

8905

%upper

8534

used_ports=0;

8906

used_ports=0;

8535

for j=1:num_ports

8907

for j=1:num_ports

8536

stated_ports=num_ports-j+1;

8908

stated_ports=num_ports-j+1;

8537

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8909

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8538

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8910

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8539

used_ports=used_ports+stated_ports;

8911

used_ports=used_ports+stated_ports;

8540

end

8912

end

8541

elseif(matrix_format==2)

8913

elseif(matrix_format==2)

8542

%lower

8914

%lower

8543

used_ports=0;

8915

used_ports=0;

8544

for j=1:num_ports

8916

for j=1:num_ports

8545

stated_ports=j;

8917

stated_ports=j;

8546

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8918

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8547

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8919

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8548

used_ports=used_ports+stated_ports;

8920

used_ports=used_ports+stated_ports;

8549

end

8921

end

8550

else

8922

else

8551

error('Matrix format is not supported. Use Full, Lower, or Upper');

8923

error('Matrix format is not supported. Use Full, Lower, or Upper');

8552

end

8924

end

8553

8925

8554

8926

8555

%check for swapping the 2 port matrix (required on 1.x spec)

8927

%check for swapping the 2 port matrix (required on 1.x spec)

8556

two_port_swap=1;

8928

two_port_swap=1;

8557

if(num_ports==2 && two_port_swap==1)

8929

if(num_ports==2 && two_port_swap==1)

8558

temp=pre_out.sp(1,2,:);

8930

temp=pre_out.sp(1,2,:);

8559

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8931

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8560

pre_out.sp(2,1,:)=temp;

8932

pre_out.sp(2,1,:)=temp;

8561

end

8933

end

8562

8934

8563

Spar.S=pre_out.sp;

8935

Spar.S=pre_out.sp;

8564

Spar.Z0=transpose(port_impedance(:));

8936

Spar.Z0=transpose(port_impedance(:));

8565

8937

8566

if length(Spar.Z0)>1

8938

if length(Spar.Z0)>1

8567

error('Each port must have the same reference impedance');

8939

error('Each port must have the same reference impedance');

8568

end

8940

end

8569

if ~isequal(Spar.Z0,50)

8941

if ~isequal(Spar.Z0,50)

8570

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8942

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8571

%Renormalize to 50 ohms

8943

%Renormalize to 50 ohms

8572

rho=(50-Spar.Z0)/(50+Spar.Z0);

8944

rho=(50-Spar.Z0)/(50+Spar.Z0);

8573

p=num_ports;

8945

p=num_ports;

8574

s_old=Spar.S;

8946

s_old=Spar.S;

8575

for k=1:num_freq

8947

for k=1:num_freq

8576

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8948

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8577

end

8949

end

8578

end

8950

end

8579

8951

8580

%These operations sync up with COM style Spar matrix

8952

%These operations sync up with COM style Spar matrix

8581

%1: put frequency as first dimension

8953

%1: put frequency as first dimension

8582

sch=shiftdim(Spar.S,2);

8954

sch=shiftdim(Spar.S,2);

8583

%2: reorder ports according to "ports" input

8955

%2: reorder ports according to "ports" input

8584

sch=sch(:,port_order,port_order);

8956

sch=sch(:,port_order,port_order);

8585

schFreqAxis=Spar.F;

8957

schFreqAxis=Spar.F;

8586

function [chdata, param] = read_PR_files(param, OP, chdata)

8958

function [chdata, param] = read_PR_files(param, OP, chdata)

8587

%% Read in pulse response

8959

%% Read in pulse response

8588

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8960

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8589

num_files=length(chdata);

8961

num_files=length(chdata);

8590

M=param.samples_per_ui;

8962

M=param.samples_per_ui;

8591

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8963

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8592

for i=1:num_files

8964

for i=1:num_files

8593

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8965

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8594

progress = i/num_files;

8966

progress = i/num_files;

8595

if OP.DISPLAY_WINDOW

8967

if OP.DISPLAY_WINDOW

8596

[~,a]=fileparts(chdata(i).filename);

8968

[~,a]=fileparts(chdata(i).filename);

8597

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8969

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8598

else

8970

else

8599

fprintf('%i ',i);

8971

fprintf('%i ',i);

8600

end

8972

end

8601

switch chdata(i).ext

8973

switch chdata(i).ext

8602

case '.csv'

8974

case '.csv'

8603

vt=load(chdata(i).filename);

8975

vt=load(chdata(i).filename);

8604

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8976

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8605

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8977

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8606

dt=vt(2,1)-vt(1,1);

8978

dt=vt(2,1)-vt(1,1);

8607

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8979

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8608

8980

8609

8981

8610

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8982

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8611

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8983

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8612

Vf=step_response(end);

8984

Vf=step_response(end);

8613

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8985

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8614

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8986

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8615

8987

8616

end

8988

end

8617

end

8989

end

8618

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8990

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8619

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8991

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8620

[filepath,name,ext] = fileparts(paramFile);

8992

[filepath,name,ext] = fileparts(paramFile);

8621

if ~isempty(filepath)

8993

if ~isempty(filepath)

8622

filepath=[filepath '\'];

8994

filepath=[filepath '\'];

8623

end

8995

end

8624

matcongfile=[filepath name '.mat'];

8996

matcongfile=[filepath name '.mat'];

8625

try

8997

try

8626

switch upper(ext)

8998

switch upper(ext)

8627

case upper('.mat')

8999

case upper('.mat')

8628

load(matcongfile)

9000

load(matcongfile)

8629

case upper('.csv')

9001

case upper('.csv')

8630

[na1, na2, parameter] = xlsread(paramFile);

9002

[na1, na2, parameter] = xlsread(paramFile);

8631

otherwise

9003

otherwise

8632

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

9004

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8633

end

9005

end

8634

9006

8635

catch ME %#ok<NASGU>

9007

catch ME %#ok<NASGU>

8636

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

9008

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8637

switch upper(ext)

9009

switch upper(ext)

8638

case upper('.mat')

9010

case upper('.mat')

8639

load(matcongfile)

9011

load(matcongfile)

8640

case upper('.csv')

9012

case upper('.csv')

8641

[na1, na2, parameter] = xlsread(paramFile);

9013

[na1, na2, parameter] = xlsread(paramFile);

8642

otherwise

9014

otherwise

8643

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

9015

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8644

end

9016

end

8645

end

9017

end

8646

9018

8647

%% New section to parse .START package data

9019

%% New section to parse .START package data

8648

first_column_data = parameter(:,1);

9020

first_column_data = parameter(:,1);

8649

start_data_rows = find(strcmp(first_column_data,'.START'));

9021

start_data_rows = find(strcmp(first_column_data,'.START'));

8650

if ~isempty(start_data_rows)

9022

if ~isempty(start_data_rows)

8651

end_data_rows = find(strcmp(first_column_data,'.END'));

9023

end_data_rows = find(strcmp(first_column_data,'.END'));

8652

if length(start_data_rows) ~= length(end_data_rows)

9024

if length(start_data_rows) ~= length(end_data_rows)

8653

error('Number of .START and .END must be the same');

9025

error('Number of .START and .END must be the same');

8654

end

9026

end

8655

first_start_row = start_data_rows(1);

9027

first_start_row = start_data_rows(1);

8656

special_parameter = parameter;

9028

special_parameter = parameter;

8657

parameter = parameter(1:first_start_row-1,:);

9029

parameter = parameter(1:first_start_row-1,:);

8658

for j=1:length(start_data_rows)

9030

for j=1:length(start_data_rows)

8659

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

9031

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

8660

pkg_name = special_parameter{start_data_rows(j),2};

9032

pkg_name = special_parameter{start_data_rows(j),2};

8661

9033

8662

%Read all the parameters that make up a package

9034

%Read all the parameters that make up a package

8663

PKG_param = read_package_parameters(this_block);

9035

PKG_param = read_package_parameters(this_block);

8664

9036

8665

%save the data in a field revealed by pkg_name

9037

%save the data in a field revealed by pkg_name

8666

param.PKG.(pkg_name) = PKG_param;

9038

param.PKG.(pkg_name) = PKG_param;

8667

9039

8668

9040

8669

end

9041

end

8670

end

9042

end

8671

%Allow specification of TX and RX package section through PKG_NAME keyword

9043

%Allow specification of TX and RX package section through PKG_NAME keyword

8672

%the values must match package blocks specified in .START sections

9044

%the values must match package blocks specified in .START sections

8673

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

9045

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

8674

if isnan(param.PKG_NAME)

9046

if isnan(param.PKG_NAME)

8675

param.PKG_NAME = '';

9047

param.PKG_NAME = '';

8676

end

9048

end

8677

if isempty(param.PKG_NAME)

9049

if isempty(param.PKG_NAME)

8678

param.PKG_NAME = {};

9050

param.PKG_NAME = {};

8679

else

9051

else

8680

param.PKG_NAME = strsplit(param.PKG_NAME);

9052

param.PKG_NAME = strsplit(param.PKG_NAME);

8681

end

9053

end

8682

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

9054

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

8683

error('PKG_NAME can only be used if .START blocks for package parameters are used');

9055

error('PKG_NAME can only be used if .START blocks for package parameters are used');

8684

end

9056

end

8685

for j=1:length(param.PKG_NAME)

9057

for j=1:length(param.PKG_NAME)

8686

if ~isfield(param.PKG,param.PKG_NAME{j})

9058

if ~isfield(param.PKG,param.PKG_NAME{j})

8687

error('Package Block "%s" not found',param.PKG_NAME{j});

9059

error('Package Block "%s" not found',param.PKG_NAME{j});

8688

end

9060

end

8689

end

9061

end

8690

9062

8691

%%

9063

%%

8692

% just need to define so we can pass

9064

% just need to define so we can pass

8693

param.c=[.4e-12 .4e-12];

9065

param.c=[.4e-12 .4e-12];

8694

param.alen=[ 20 30 550 ];

9066

param.alen=[ 20 30 550 ];

8695

param.az=[100 120 100];

9067

param.az=[100 120 100];

8696

9068

8697

% make control for package/channel reflection control

9069

% make control for package/channel reflection control

8698

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

9070

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

8699

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

9071

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

+9072

8700

9073

8701

% make compatible with presentation of kappa

9074

% make compatible with presentation of kappa

+9075

8702

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

9076

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

8703

9077

8704

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

9078

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

8705

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

9079

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

8706

9080

8707

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

9081

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

8708

param.f2 = xls_parameter(parameter, 'f_2', true, param.fb/1e9 )*1e9; % frequency in GHz for intergration compuation of ICN or FOM_Ild in GHz

9082

param.f2 = xls_parameter(parameter, 'f_2', true, param.fb/1e9 )*1e9; % frequency in GHz for intergration compuation of ICN or FOM_Ild in GHz

8709

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

9083

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

8710

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

9084

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

8711

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

9085

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

8712

param.tx_ffe_c0_min = xls_parameter(parameter, 'c(0)', false); % TX equalizer cursor minimum value (actual value is calculated as 1-sum(abs(tap)), Grid seat ingored for when C(0) is below this value

9086

param.tx_ffe_c0_min = xls_parameter(parameter, 'c(0)', false); % TX equalizer cursor minimum value (actual value is calculated as 1-sum(abs(tap)), Grid seat ingored for when C(0) is below this value

8713

9087

8714

if OP.dynamic_txffe

9088

if OP.dynamic_txffe

8715

found_pre=1;

9089

found_pre=1;

8716

pre_count=1;

9090

pre_count=1;

8717

while found_pre

9091

while found_pre

8718

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

9092

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

8719

if found_pre

9093

if found_pre

8720

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

9094

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

8721

param.(field_name)=p;

9095

param.(field_name)=p;

8722

pre_count=pre_count+1;

9096

pre_count=pre_count+1;

8723

end

9097

end

8724

end

9098

end

8725

found_post=1;

9099

found_post=1;

8726

post_count=1;

9100

post_count=1;

8727

while found_post

9101

while found_post

8728

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

9102

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

8729

if found_post

9103

if found_post

8730

field_name=sprintf('tx_ffe_cp%d_values',post_count);

9104

field_name=sprintf('tx_ffe_cp%d_values',post_count);

8731

param.(field_name)=p;

9105

param.(field_name)=p;

8732

post_count=post_count+1;

9106

post_count=post_count+1;

8733

end

9107

end

8734

end

9108

end

8735

else

9109

else

8736

param.tx_ffe_cm4_values = xls_parameter(parameter, 'c(-4)', true,0); % TX equalizer pre cursor tap -4 individual settings or range. If not present ignored

9110

param.tx_ffe_cm4_values = xls_parameter(parameter, 'c(-4)', true,0); % TX equalizer pre cursor tap -4 individual settings or range. If not present ignored

8737

param.tx_ffe_cm3_values = xls_parameter(parameter, 'c(-3)', true,0); % TX equalizer pre cursor tap -3 individual settings or range. If not present ignored

9111

param.tx_ffe_cm3_values = xls_parameter(parameter, 'c(-3)', true,0); % TX equalizer pre cursor tap -3 individual settings or range. If not present ignored

8738

param.tx_ffe_cm2_values = xls_parameter(parameter, 'c(-2)', true,0); % TX equalizer pre cursor tap -2 individual settings or range. If not present ignored

9112

param.tx_ffe_cm2_values = xls_parameter(parameter, 'c(-2)', true,0); % TX equalizer pre cursor tap -2 individual settings or range. If not present ignored

8739

param.tx_ffe_cm1_values = xls_parameter(parameter, 'c(-1)', true,0); % TX equalizer pre cursor tap -1 individual settings or range. If not present ignored

9113

param.tx_ffe_cm1_values = xls_parameter(parameter, 'c(-1)', true,0); % TX equalizer pre cursor tap -1 individual settings or range. If not present ignored

8740

param.tx_ffe_cp1_values = xls_parameter(parameter, 'c(1)', true,0); % TX equalizer post cursor tap 1 individual settings or range. If not present ignored

9114

param.tx_ffe_cp1_values = xls_parameter(parameter, 'c(1)', true,0); % TX equalizer post cursor tap 1 individual settings or range. If not present ignored

8741

param.tx_ffe_cp2_values = xls_parameter(parameter, 'c(2)', true,0); % TX equalizer post cursor tap 2 individual settings or range. If not present ignored

9115

param.tx_ffe_cp2_values = xls_parameter(parameter, 'c(2)', true,0); % TX equalizer post cursor tap 2 individual settings or range. If not present ignored

8742

param.tx_ffe_cp3_values = xls_parameter(parameter, 'c(3)', true,0); % TX equalizer post cursor tap 3 individual settings or range. If not present ignored

9116

param.tx_ffe_cp3_values = xls_parameter(parameter, 'c(3)', true,0); % TX equalizer post cursor tap 3 individual settings or range. If not present ignored

8743

end

9117

end

8744

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

9118

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

8745

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

9119

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

8746

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

9120

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

8747

param.N_bx = xls_parameter(parameter, 'N_bx', true, param.ndfe ); % Used for ERL to Compensate for a number of Ui assoicated with the DFE

9121

param.N_bx = xls_parameter(parameter, 'N_bx', true, param.ndfe ); % Used for ERL to Compensate for a number of Ui assoicated with the DFE

8748

% support for floating taps

9122

% support for floating taps

8749

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

9123

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

8750

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

9124

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

8751

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

9125

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

8752

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

9126

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

8753

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

9127

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

8754

if param.N_bg == 0, param.N_bmax=param.ndfe; end

9128

if param.N_bg == 0, param.N_bmax=param.ndfe; end

8755

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

9129

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

8756

9130

8757

% support for tail tap power limitations

9131

% support for tail tap power limitations

8758

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

9132

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

8759

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

9133

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

8760

%

9134

%

8761

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

9135

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

8762

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

9136

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

8763

param.RxFFE_cmx=param.ffe_pre_tap_len;

9137

param.RxFFE_cmx=param.ffe_pre_tap_len;

8764

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

9138

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

8765

param.RxFFE_cpx=param.ffe_post_tap_len;

9139

param.RxFFE_cpx=param.ffe_post_tap_len;

8766

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

9140

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

8767

param.RxFFE_stepz=param.ffe_tap_step_size;

9141

param.RxFFE_stepz=param.ffe_tap_step_size;

8768

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

9142

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

8769

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

9143

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

8770

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

9144

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

8771

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

9145

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

8772

param.ffe_backoff=xls_parameter(parameter, 'ffe_backoff', true,0); % see if better zero foreced solution is better by backing off the number specified FFE taps one at at time

9146

param.ffe_backoff=xls_parameter(parameter, 'ffe_backoff', true,0); % see if better zero foreced solution is better by backing off the number specified FFE taps one at at time

8773

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

9147

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

8774

OP.RxFFE= true;

9148

OP.RxFFE= true;

8775

else

9149

else

8776

OP.RxFFE=false;

9150

OP.RxFFE=false;

8777

end

9151

end

8778

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

9152

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

8779

9153

8780

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

9154

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

8781

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

9155

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

8782

param.f_HP_Z = 1e9*xls_parameter(parameter, 'f_HP_Z', true, []); % CFT zero fz1 is in GHz. Normally a list for 120e. Not normally use elsewise

9156

param.f_HP_Z = 1e9*xls_parameter(parameter, 'f_HP_Z', true, []); % CFT zero fz1 is in GHz. Normally a list for 120e. Not normally use elsewise

8783

param.f_HP_P = 1e9*xls_parameter(parameter, 'f_HP_P', true, []); % CFT pole fp2 is in GHz. Normally a list for 120e. Not normally use elsewise

9157

param.f_HP_P = 1e9*xls_parameter(parameter, 'f_HP_P', true, []); % CFT pole fp2 is in GHz. Normally a list for 120e. Not normally use elsewise

8784

9158

8785

9159

8786

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

9160

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

8787

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

9161

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

8788

param.Min_VEO_Test= xls_parameter(parameter, 'EH_min_test', true,0); % Older syntax. Used when PMD_type is C2M. This allow EH to go below EH_min. If set to zero it is ignored (same as Min_VEO_test)

9162

param.Min_VEO_Test= xls_parameter(parameter, 'EH_min_test', true,0); % Older syntax. Used when PMD_type is C2M. This allow EH to go below EH_min. If set to zero it is ignored (same as Min_VEO_test)

8789

param.Min_VEO_Test= xls_parameter(parameter, 'Min_VEO_Test', true,param.Min_VEO_Test); % used when PMD_type is C2M. This allow EH to go blow EH_min. If set to Zero it is ignored

9163

param.Min_VEO_Test= xls_parameter(parameter, 'Min_VEO_Test', true,param.Min_VEO_Test); % used when PMD_type is C2M. This allow EH to go blow EH_min. If set to Zero it is ignored

8790

9164

8791

param.CTLE_type= xls_parameter(parameter, 'CTLE_type', false,'CL93'); % Sets the CTLE type default is poles and zeros (i.e. not a list of poles as in 120e)

9165

param.CTLE_type= xls_parameter(parameter, 'CTLE_type', false,'CL93'); % Sets the CTLE type default is poles and zeros (i.e. not a list of poles as in 120e)

8792

if ~isempty(param.g_DC_HP_values) ; param.CTLE_type='CL120d';end % overrides CL93 if g_DC_HP_values are a spreadsheet entry. Mostly used when baud rare is >= 50Gbps

9166

if ~isempty(param.g_DC_HP_values) ; param.CTLE_type='CL120d';end % overrides CL93 if g_DC_HP_values are a spreadsheet entry. Mostly used when baud rare is >= 50Gbps

8793

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

9167

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

8794

% always read in main ctle values. They would be interpreted different baseed

9168

% always read in main ctle values. They would be interpreted different baseed

8795

% on the clause they apply because of different CTF equations

9169

% on the clause they apply because of different CTF equations

8796

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

9170

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

8797

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9171

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8798

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9172

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8799

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9173

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8800

% the contex of the poles an zeros are determined by the clause

9174

% the contex of the poles an zeros are determined by the clause

8801

switch param.CTLE_type

9175

switch param.CTLE_type

8802

case 'CL93'

9176

case 'CL93'

8803

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % Continuous time filter DC gain settings (G_DC) or range as specified in Annex 93A

9177

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % Continuous time filter DC gain settings (G_DC) or range as specified in Annex 93A

8804

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9178

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8805

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9179

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8806

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9180

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8807

case 'CL120d'

9181

case 'CL120d'

8808

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

9182

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

8809

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

9183

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

8810

case 'CL120e'

9184

case 'CL120e'

8811

% re adjust to get TD_CTLE to work with C:120e equation without

9185

% re adjust to get TD_CTLE to work with C:120e equation without

8812

% changing TD_CTLE code

9186

% changing TD_CTLE code

8813

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

9187

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

8814

end

9188

end

8815

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

9189

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

8816

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

9190

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

8817

%% addd default to support multiple packages

8818

param.a_thru = xls_parameter(parameter, 'A_v', true, 0.5); % Victim differential peak source output voltage (half of peak to peak)

9191

param.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

8819

param.a_fext = xls_parameter(parameter, 'A_fe', true,0.5); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9192

param.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

8820

param.a_next = xls_parameter(parameter, 'A_ne', true,0.5); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9193

param.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

8821

param.a_icn_fext = xls_parameter(parameter, 'A_ft', true, param.a_fext); % FEXT aggressor amplitude for ICN. Defaults to A_fe if not specified

9194

param.a_icn_fext = xls_parameter(parameter, 'A_ft', true, param.a_fext); % FEXT aggressor amplitude for ICN. Defaults to A_fe if not specified

8822

param.a_icn_next = xls_parameter(parameter, 'A_nt', true, param.a_next );% NEXT aggressor amplitude for ICN. Defaults to A_ne if not specified

9195

param.a_icn_next = xls_parameter(parameter, 'A_nt', true, param.a_next );% NEXT aggressor amplitude for ICN. Defaults to A_ne if not specified

8823

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

9196

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

8824

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

9197

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

8825

param.DER_CDR = xls_parameter(parameter, 'DER_CDR',true,1e-2); % min DER required for a CDR

9198

param.DER_CDR = xls_parameter(parameter, 'DER_CDR',true,1e-2); % min DER required for a CDR

8826

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

9199

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

8827

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

9200

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

8828

param.VEC_pass_threshold = xls_parameter(parameter, 'VEC Pass threshold',false,0);% the pass fail threshold for VEC in dB only used when PMD_type is C2M

9201

param.VEC_pass_threshold = xls_parameter(parameter, 'VEC Pass threshold',false,0);% the pass fail threshold for VEC in dB only used when PMD_type is C2M

8829

9202

8830

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

9203

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

8831

param.A_DD = xls_parameter(parameter, 'A_DD'); % Normalized peak dual-Dirac noise, this is half of the total bound uncorrelated jitter (BUJ) in UI

9204

param.A_DD = xls_parameter(parameter, 'A_DD'); % Normalized peak dual-Dirac noise, this is half of the total bound uncorrelated jitter (BUJ) in UI

8832

param.eta_0 = xls_parameter(parameter, 'eta_0'); % One-sided noise spectral density (V^2/GHz).Input refered noise at TP5. Input referred noise at TP5

9205

param.eta_0 = xls_parameter(parameter, 'eta_0'); % One-sided noise spectral density (V^2/GHz).Input refered noise at TP5. Input referred noise at TP5

8833

% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

8834

param.trunc = xls_parameter(parameter, 'trunc', true, 128); % MLSE sequence truncation length

8835

param.trunc = xls_parameter(parameter, 'N_tc', true, param.trunc); % MLSE sequence truncation length

8836

8837

% healey_3dj_01a_2407 adjust MLSE for COM_DFE

8838

param.Q_budget_adj = xls_parameter(parameter, 'Q_budget_adj', true, 0); % MLSE sequence truncation length

8839

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

9206

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

8840

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

9207

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

8841

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

9208

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

8842

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

9209

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

8843

param.ts_anchor = xls_parameter(parameter, 'ts_anchor', true, 0); %choice of sampling routine. 0=MM, 1=Peak, 2=max DV (max cursor minus precursor)

9210

param.ts_anchor = xls_parameter(parameter, 'ts_anchor', true, 0); %choice of sampling routine. 0=MM, 1=Peak, 2=max DV (max cursor minus precursor)

8844

% This will keep bmax length 0 if Nb=0

9211

% This will keep bmax length 0 if Nb=0

8845

9212

8846

%AJG021820

9213

%AJG021820

8847

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

9214

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

8848

if isempty(param.bmax)

9215

if isempty(param.bmax)

8849

param.bmin=param.bmax;

9216

param.bmin=param.bmax;

8850

else

9217

else

8851

param.bmin(1:param.ndfe) =xls_parameter(parameter, 'b_min(1)', true,-param.bmax(1) ); % DFE negative magnitude limit. If not specified it defaults to -bmax.

9218

param.bmin(1:param.ndfe) =xls_parameter(parameter, 'b_min(1)', true,-param.bmax(1) ); % DFE negative magnitude limit. If not specified it defaults to -bmax.

8852

9219

8853

end

9220

end

8854

if param.ndfe >= 2

9221

if param.ndfe >= 2

8855

param.bmax(2:param.ndfe) = xls_parameter(parameter, 'b_max(2..N_b)', true, .2); % DFE magnitude limit, second coefficient and on (ignored if Nb<2). Can be a regualar expression

9222

param.bmax(2:param.ndfe) = xls_parameter(parameter, 'b_max(2..N_b)', true, .2); % DFE magnitude limit, second coefficient and on (ignored if Nb<2). Can be a regualar expression

8856

param.bmin(2:param.ndfe) = xls_parameter(parameter, 'b_min(2..N_b)', true, -1*param.bmax(2:param.ndfe) ); % DFE negative magnitude limit, if not specified it defaults to -b_max(2..N_b)

9223

param.bmin(2:param.ndfe) = xls_parameter(parameter, 'b_min(2..N_b)', true, -1*param.bmax(2:param.ndfe) ); % DFE negative magnitude limit, if not specified it defaults to -b_max(2..N_b)

8857

end

9224

end

8858

9225

8859

param.gqual=xls_parameter(parameter, 'G_Qual', true,[]);% G_Qual are the dB ranges of g_DC g DC )which correspond tog_DC_HP (g DC2)

9226

param.gqual=xls_parameter(parameter, 'G_Qual', true,[]);% G_Qual are the dB ranges of g_DC g DC )which correspond tog_DC_HP (g DC2)

8860

param.g2qual=xls_parameter(parameter, 'G2_Qual', true,[]); % G2_Qual limit values of g_DC_HP (g DC2 ) which corresponds to ranges of g_DC g DC specified with G_QUAL

9227

param.g2qual=xls_parameter(parameter, 'G2_Qual', true,[]); % G2_Qual limit values of g_DC_HP (g DC2 ) which corresponds to ranges of g_DC g DC specified with G_QUAL

8861

%verify gqual and gqual2 input

9228

%verify gqual and gqual2 input

8862

if ~isempty(param.gqual) || ~isempty(param.g2qual)

9229

if ~isempty(param.gqual) || ~isempty(param.g2qual)

8863

if size(param.gqual,1)~=length(param.g2qual)

9230

if size(param.gqual,1)~=length(param.g2qual)

8864

error('gqual and g2qual size mismatch');

9231

error('gqual and g2qual size mismatch');

8865

end

9232

end

8866

if size(param.gqual,2)~=2

9233

if size(param.gqual,2)~=2

8867

error('gqual must be Nx2 matrix');

9234

error('gqual must be Nx2 matrix');

8868

end

9235

end

8869

end

9236

end

8870

9237

8871

9238

8872

% eval if string for all three - can use different for TX and RX

9239

% eval if string for all three - can use different for TX and RX

8873

param.C_pkg_board = xls_parameter(parameter, 'C_p', true,0)*1e-9; % C_p in nF (single sided)

9240

param.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

8874

param.C_diepad = xls_parameter(parameter, 'C_d', true,0)*1e-9; % C_d in nF (single sided)

9241

param.C_diepad = xls_parameter(parameter, 'C_d', true)*1e-9; % C_d in nF (single sided)

8875

% [ahealey] Read values for optional compensating L and "bump" C

9242

% [ahealey] Read values for optional compensating L and "bump" C

8876

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

9243

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

8877

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

9244

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

8878

% [ahealey] End of modification

9245

% [ahealey] End of modifications.

8879

% added default to support multiple packages

8880

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

9246

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

8881

param.R_diepad = xls_parameter(parameter, 'R_d', true, [50,50]); % Die source termination resistance (single sided)

9247

param.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

8882

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

9248

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

8883

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

9249

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

8884

9250

8885

9251

8886

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

9252

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

8887

% added default to support multiple packages

8888

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of victim transmitter package trace lengths in mm, one per case

9253

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

8889

[ncases, mele]=size(param.z_p_tx_cases);

9254

[ncases, mele]=size(param.z_p_tx_cases);

8890

if mele ==2

9255

if mele ==2

8891

param.flex=2;

9256

param.flex=2;

8892

elseif mele==4

9257

elseif mele==4

8893

param.flex=4;

9258

param.flex=4;

8894

elseif mele==1

9259

elseif mele==1

8895

param.flex=1;

9260

param.flex=1;

8896

else

9261

else

8897

error(sprintf('config file syntax error'))

9262

error(sprintf('config file syntax error'))

8898

end

9263

end

8899

9264

8900

% board parameters

9265

% board parameters

8901

param.C_0 = xls_parameter(parameter, 'C_0', true,0)*1e-9; % If Include PCB is set to 1, near device single ended capacitance C0 in nF is added

9266

param.C_0 = xls_parameter(parameter, 'C_0', true,0)*1e-9; % If Include PCB is set to 1, near device single ended capacitance C0 in nF is added

8902

param.C_1 = xls_parameter(parameter, 'C_1', true,0)*1e-9; % if Include PCB is set to 1, connector side single ended capacitance C1 in nF is added

9267

param.C_1 = xls_parameter(parameter, 'C_1', true,0)*1e-9; % if Include PCB is set to 1, connector side single ended capacitance C1 in nF is added

8903

% added default to support multiple packages

9268

%

8904

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of NEXT transmitter package trace lengths in mm, one per case

9269

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

8905

[ncases1, mele1]=size(param.z_p_next_cases);

9270

[ncases1, mele1]=size(param.z_p_next_cases);

8906

if ncases ~= ncases1 || mele ~= mele1

9271

if ncases ~= ncases1 || mele ~= mele1

8907

error('All TX, NEXT, FEXT, Rx cases must agree');

9272

error('All TX, NEXT, FEXT, Rx cases must agree');

8908

else

9273

else

8909

end

9274

end

8910

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of FEXT transmitter package trace lengths in mm, one per case

9275

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

8911

[ncases1, mele1]=size(param.z_p_fext_cases);

9276

[ncases1, mele1]=size(param.z_p_fext_cases);

8912

if ncases ~= ncases1 || mele ~= mele1

9277

if ncases ~= ncases1 || mele ~= mele1

8913

error('All TX, NEXT, FEXT, Rx cases must agree');

9278

error('All TX, NEXT, FEXT, Rx cases must agree');

8914

else

9279

else

8915

end

9280

end

8916

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of FEXT receiver package trace lengths in mm, one per case

9281

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

8917

[ncases1, mele1]=size(param.z_p_rx_cases);

9282

[ncases1, mele1]=size(param.z_p_rx_cases);

8918

if ncases ~= ncases1 || mele ~= mele1

9283

if ncases ~= ncases1 || mele ~= mele1

8919

error('All TX, NEXT, FEXT, Rx cases must agree');

9284

error('All TX, NEXT, FEXT, Rx cases must agree');

8920

else

9285

else

8921

end

9286

end

8922

% Table 93A-3 parameters

9287

% Table 93A-3 parameters

8923

param.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9288

param.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

8924

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9289

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

8925

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, '[92 92 ; 70 70; 80 80; 100 100]').';% Package model transmission line characteristic impedance [ Tx , Rx ]

9290

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

8926

[ ncases1, mele1]=size(param.pkg_Z_c);%

9291

[ ncases1, mele1]=size(param.pkg_Z_c);%

8927

if mele ~= mele1

9292

if mele ~= mele1

8928

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9293

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

8929

else

9294

else

8930

end

9295

end

8931

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9296

if mele1==2 % fuill in a array if only a 2 element flex package is specified

8932

for ii=1:ncases

9297

for ii=1:ncases

8933

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9298

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

8934

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9299

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

8935

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9300

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

8936

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9301

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

8937

end

9302

end

8938

param.z_p_fext_cases = param.z_p_fext_casesx;

9303

param.z_p_fext_cases = param.z_p_fext_casesx;

8939

param.z_p_next_cases= param.z_p_next_casesx;

9304

param.z_p_next_cases= param.z_p_next_casesx;

8940

param.z_p_tx_cases= param.z_p_tx_casesx;

9305

param.z_p_tx_cases= param.z_p_tx_casesx;

8941

param.z_p_rx_cases= param.z_p_rx_casesx;

9306

param.z_p_rx_cases= param.z_p_rx_casesx;

8942

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9307

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

8943

end

9308

end

8944

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9309

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

8945

9310

8946

% Table 92-12 parameters

9311

% Table 92-12 parameters

8947

param.brd_gamma0_a1_a2 = xls_parameter(parameter, 'board_tl_gamma0_a1_a2', true, [0 4.114e-4 2.547e-4]); % Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9312

param.brd_gamma0_a1_a2 = xls_parameter(parameter, 'board_tl_gamma0_a1_a2', true, [0 4.114e-4 2.547e-4]); % Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

8948

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9313

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

8949

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9314

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

8950

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9315

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

8951

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9316

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

8952

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9317

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

8953

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9318

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

8954

9319

8955

% Unofficial parameters

9320

% Unofficial parameters

8956

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9321

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

8957

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9322

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

8958

% Deprecated parameters - affect only frequency domain analysis.

9323

% Deprecated parameters - affect only frequency domain analysis.

8959

param.f_v = xls_parameter(parameter, 'f_v', true, 4); % For FOM_ILD: Transiton rate cut off frequency for ICN/ILD calc in terms of fb

9324

param.f_v = xls_parameter(parameter, 'f_v', true, 4); % For FOM_ILD: Transiton rate cut off frequency for ICN/ILD calc in terms of fb

8960

param.f_f = xls_parameter(parameter, 'f_f', true, 4); % For ICN: Fext transiton rate cut off frequency for ICN calc in terms of fb

9325

param.f_f = xls_parameter(parameter, 'f_f', true, 4); % For ICN: Fext transiton rate cut off frequency for ICN calc in terms of fb

8961

param.f_n = xls_parameter(parameter, 'f_n', true, 4); % For ICN: Next transiton rate cut off frequency for ICN calc in terms of fb

9326

param.f_n = xls_parameter(parameter, 'f_n', true, 4); % For ICN: Next transiton rate cut off frequency for ICN calc in terms of fb

8962

param.f_r = xls_parameter(parameter, 'f_r', true, 4); % reference receive filter in COM and in ICN/FOM_ILD calcs in terms of fb

9327

param.f_r = xls_parameter(parameter, 'f_r', true, 4); % reference receive filter in COM and in ICN/FOM_ILD calcs in terms of fb

8963

param.fb_BT_cutoff= xls_parameter(parameter, 'TDR_f_BT_3db', true, 0.4730); % Bessel-Thomson 3 dB cut off freqeuncy in terms of fb

9328

param.fb_BT_cutoff= xls_parameter(parameter, 'TDR_f_BT_3db', true, 0.4730); % Bessel-Thomson 3 dB cut off freqeuncy in terms of fb

8964

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9329

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

8965

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9330

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

8966

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9331

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

8967

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9332

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

8968

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9333

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

8969

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9334

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

8970

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9335

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

8971

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9336

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

8972

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9337

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

8973

switch param.Gx

9338

switch param.Gx

8974

case 0

9339

case 0

8975

param.Grr=param.Grr; % just use older Grr ir gx not specified

9340

param.Grr=param.Grr; % just use older Grr ir gx not specified

8976

case 1

9341

case 1

8977

param.Grr=2; % use newer Grr

9342

param.Grr=2; % use newer Grr

8978

end

9343

end

8979

9344

8980

param.LOCAL_SEARCH=xls_parameter(parameter,'Local Search',true,0); % Decreases COM compute time. Aetting to 2 seems ok ,if 0 search is full grid

9345

param.LOCAL_SEARCH=xls_parameter(parameter,'Local Search',true,0); % Decreases COM compute time. Aetting to 2 seems ok ,if 0 search is full grid

8981

% Operational control variables

9346

% Operational control variables

8982

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9347

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

8983

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9348

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

8984

param.Noise_Crest_Factor= xls_parameter(parameter, 'Noise_Crest_Factor', true, 0); % Normally not used. If set this is q factor used for quantized Gaussian PDFs

9349

param.Noise_Crest_Factor= xls_parameter(parameter, 'Noise_Crest_Factor', true, 0); % Normally not used. If set this is q factor used for quantized Gaussian PDFs

8985

param.AC_CM_RMS = xls_parameter(parameter, 'AC_CM_RMS', true, 0); % AC_CM_RMS is the CM BBN AWGN RMS at COM source point. Default is 0. Adds common mode noise source to the COM signal path for the through channel

9350

param.AC_CM_RMS = xls_parameter(parameter, 'AC_CM_RMS', true, 0); % AC_CM_RMS is the CM BBN AWGN RMS at COM source point. Default is 0. Adds common mode noise source to the COM signal path for the through channel

8986

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9351

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

8987

param.T_O = xls_parameter(parameter, 'T_O', true, 0 ); % Units are mUI. Histogram for VEC and VEO are computed over T_s +/- T_O.

9352

param.T_O = xls_parameter(parameter, 'T_O', true, 0 ); % Units are mUI. Histogram for VEC and VEO are computed over T_s +/- T_O.

8988

param.T_O = xls_parameter(parameter, 'T_h', true, param.T_O ); % superceded with T_O but is the internal values that is used. Do not use.

9353

param.T_O = xls_parameter(parameter, 'T_h', true, param.T_O ); % superceded with T_O but is the internal values that is used. Do not use.

8989

9354

8990

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9355

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

8991

9356

8992

OP.Histogram_Window_Weight=xls_parameter(parameter, 'Histogram_Window_Weight', false, 'rectangle' ); %Weighting for VEC and VEO are histogram processing. Type are Gaussian,Dual Rayleigh,Triangle, and Rectangle (default)

9357

OP.Histogram_Window_Weight=xls_parameter(parameter, 'Histogram_Window_Weight', false, 'rectangle' ); %Weighting for VEC and VEO are histogram processing. Type are Gaussian,Dual Rayleigh,Triangle, and Rectangle (default)

8993

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9358

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

8994

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9359

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

8995

param.QL=xls_parameter(parameter, 'QL', true, param.T_O/param.Qr/1000 ); % superceded with sigma_r but is the internal values that is used

9360

param.QL=xls_parameter(parameter, 'QL', true, param.T_O/param.Qr/1000 ); % superceded with sigma_r but is the internal values that is used

8996

9361

8997

%%

9362

%%

8998

9363

8999

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9364

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9000

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9365

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9001

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9366

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9002

param.awgn_mv=param.AC_CM_RMS;

9367

param.awgn_mv=param.AC_CM_RMS;

9003

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9368

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9004

param.f_hp=xls_parameter(parameter, 'f_hp', true, 0 ); % for rx testing for eq 162-12 if 0 (default) then rx test using rx bbn

9369

param.f_hp=xls_parameter(parameter, 'f_hp', true, 0 ); % for rx testing for eq 162-12 if 0 (default) then rx test using rx bbn

9005

param.Q=xls_parameter(parameter, 'Q', true, 0 ); % Implementation penalty for MLSE in EQ 178a-36

9370

param.Q=xls_parameter(parameter, 'Q', true, 0 ); % Implementation penalty for MLSE in EQ 178a-36

9006

9371

9007

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9372

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9008

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9373

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9009

param.Floating_RXFFE=false;

9374

param.Floating_RXFFE=false;

9010

param.Floating_DFE=false;

9375

param.Floating_DFE=false;

9011

if param.N_bg > 0

9376

if param.N_bg > 0

9012

param.Floating_DFE=true;

9377

param.Floating_DFE=true;

9013

end

9378

end

9014

if OP.RxFFE

9379

if OP.RxFFE

9015

param.Floating_DFE=false;

9380

param.Floating_DFE=false;

9016

if param.N_bg > 0

9381

if param.N_bg > 0

9017

param.Floating_RXFFE=true;

9382

param.Floating_RXFFE=true;

9018

end

9383

end

9019

end

9384

end

9020

%% for introducing Tx or Rx skew on p leg or n leg

9385

%% for introducing Tx or Rx skew on p leg or n leg

9021

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9386

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9022

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9387

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9023

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9388

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9024

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9389

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9025

9390

9026

%%

9391

%%

9027

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9392

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9028

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9393

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9029

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9394

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9030

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9395

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9031

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9396

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9032

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9397

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9033

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9398

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9034

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9399

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9035

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9400

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9036

OP.CSV_REPORT = xls_parameter(parameter, 'CSV_REPORT', false, true); % saves all the output parameters to a CSV file in the results directory, If DIAGNOSTICS is set then a mat file is also created

9401

OP.CSV_REPORT = xls_parameter(parameter, 'CSV_REPORT', false, true); % saves all the output parameters to a CSV file in the results directory, If DIAGNOSTICS is set then a mat file is also created

9037

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9402

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9038

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9403

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9039

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9404

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9040

OP.GET_FD = xls_parameter(parameter, 'Display frequency domain', false, OP.GET_FD); % Not normally set in the config file. It is normally just set to true to get FD plots

9405

OP.GET_FD = xls_parameter(parameter, 'Display frequency domain', false, OP.GET_FD); % Not normally set in the config file. It is normally just set to true to get FD plots

9041

OP.INC_PACKAGE = xls_parameter(parameter, 'INC_PACKAGE', false, true); % warning: INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1

9406

OP.INC_PACKAGE = xls_parameter(parameter, 'INC_PACKAGE', false, true); % warning: INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1

9042

if ~OP.INC_PACKAGE

9407

if ~OP.INC_PACKAGE

9043

fprintf('<strong> Warning!!! INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9408

fprintf('<strong> Warning!!! INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9044

end

9409

end

9045

9410

9046

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9411

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9047

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9412

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9048

if OP.IDEAL_TX_TERM

9413

if OP.IDEAL_TX_TERM

9049

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9414

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9050

end

9415

end

9051

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9416

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9052

if OP.IDEAL_RX_TERM

9417

if OP.IDEAL_RX_TERM

9053

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9418

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9054

end

9419

end

9055

9420

9056

OP.TDMODE = xls_parameter(parameter, 'TDMODE',false, OP.TDMODE); % Enables the the use of pulse response instead of s-parameters. Assumes no packages or the packages are included in the PR. Default is 0.

9421

OP.TDMODE = xls_parameter(parameter, 'TDMODE',false, OP.TDMODE); % Enables the the use of pulse response instead of s-parameters. Assumes no packages or the packages are included in the PR. Default is 0.

9057

9422

9058

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9423

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9059

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9424

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9060

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9425

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9061

OP.BREAD_CRUMBS = xls_parameter(parameter, 'BREAD_CRUMBS',false, false); % if DIAGNOSTICS is set then param, OP, and chdata are include in the output for each run

9426

OP.BREAD_CRUMBS = xls_parameter(parameter, 'BREAD_CRUMBS',false, false); % if DIAGNOSTICS is set then param, OP, and chdata are include in the output for each run

9062

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9427

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9063

OP.COM_CONTRIBUTION_CURVES = xls_parameter(parameter, 'COM_CONTRIBUTION',false,0); % Default is 0. If set to 1 then a bar graph of COM contributors is produce instead of bathtub curves

9428

OP.COM_CONTRIBUTION_CURVES = xls_parameter(parameter, 'COM_CONTRIBUTION',false,0); % Default is 0. If set to 1 then a bar graph of COM contributors is produce instead of bathtub curves

9064

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9429

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9065

OP.EC_REL_TOL = xls_parameter(parameter, 'Enforce Causality REL_TOL', false, 1e-2); % Relative Tolerance parameter for causality, Hard enforcement, 1e-3, Soft enforcement, 1e-2

9430

OP.EC_REL_TOL = xls_parameter(parameter, 'Enforce Causality REL_TOL', false, 1e-2); % Relative Tolerance parameter for causality, Hard enforcement, 1e-3, Soft enforcement, 1e-2

9066

OP.EC_DIFF_TOL = xls_parameter(parameter, 'Enforce Causality DIFF_TOL', false, 1e-3); % Difference Tolerance parameter for causality, Hard enforcement, 1e-4,Soft enforcement, 1e-3

9431

OP.EC_DIFF_TOL = xls_parameter(parameter, 'Enforce Causality DIFF_TOL', false, 1e-3); % Difference Tolerance parameter for causality, Hard enforcement, 1e-4,Soft enforcement, 1e-3

9067

OP.EC_PULSE_TOL = xls_parameter(parameter, 'Enforce Causality pulse start tolerance', false, 0.01); % Tolerance parameter for causality, Hard enforcement, 0.05, Soft enforcement, .01

9432

OP.EC_PULSE_TOL = xls_parameter(parameter, 'Enforce Causality pulse start tolerance', false, 0.01); % Tolerance parameter for causality, Hard enforcement, 0.05, Soft enforcement, .01

9068

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9433

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9069

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9434

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9070

OP.sigma_bn_STEP = xls_parameter(parameter, 'Sigma BBN step', false, 5e-3); % BBN step for Rx Calibration in volts. Defaults is 0.5e-3

9435

OP.sigma_bn_STEP = xls_parameter(parameter, 'Sigma BBN step', false, 5e-3); % BBN step for Rx Calibration in volts. Defaults is 0.5e-3

9071

OP.BBN_Q_factor = xls_parameter(parameter, 'BBN Q factor', false, 5); % Overrides NEXT/FEXT noise Qfactor for 'Force BBN Q factor' used for reporting. does not affect COM.

9436

OP.BBN_Q_factor = xls_parameter(parameter, 'BBN Q factor', false, 5); % Overrides NEXT/FEXT noise Qfactor for 'Force BBN Q factor' used for reporting. does not affect COM.

9072

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9437

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9073

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9438

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9074

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9439

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9075

9440

9076

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_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9077

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9442

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9078

OP.FORCE_TR = xls_parameter(parameter, 'FORCE_TR', false, false);% Included for earlier version support but should be set to 1 in most later config sheets.

9443

OP.FORCE_TR = xls_parameter(parameter, 'FORCE_TR', false, false);% Included for earlier version support but should be set to 1 in most later config sheets.

9079

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9444

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9080

% compatibility

9445

% compatibility

9081

if OP.FORCE_TR

9446

if OP.FORCE_TR

9082

OP.T_r_meas_point=0;

9447

OP.T_r_meas_point=0;

9083

OP.T_r_filter_type=1;

9448

OP.T_r_filter_type=1;

9084

end

9449

end

9085

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9450

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9086

OP.TDR_duration= xls_parameter(parameter, 'TDR_duration', false, 5); % only used if N*UI is longer than the TDR duration time. Default is 5 times the raw s-parameter transit time.

9451

OP.TDR_duration= xls_parameter(parameter, 'TDR_duration', false, 5); % only used if N*UI is longer than the TDR duration time. Default is 5 times the raw s-parameter transit time.

9087

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9452

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9088

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9453

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9089

OP.T_k= xls_parameter(parameter, 'T_k', false, .6)*1e-9; % Time span (ns) for which the impedance of port is determined using TDR.

9454

OP.T_k= xls_parameter(parameter, 'T_k', false, .6)*1e-9; % Time span (ns) for which the impedance of port is determined using TDR.

9090

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9455

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9091

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9456

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9092

if OP.ERL

9457

if OP.ERL

9093

OP.PTDR=1;

9458

OP.PTDR=1;

9094

else

9459

else

9095

OP.PTDR=0;

9460

OP.PTDR=0;

9096

end % ERL needs to do a TDR

9461

end % ERL needs to do a TDR

9097

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9462

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9098

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9463

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9099

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9464

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9100

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9465

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9101

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9466

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9102

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9467

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9103

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9468

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9104

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9469

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9105

OP.AUTO_TFX=xls_parameter(parameter, 'AUTO_TFX', false,0); % Mostly used for device ERL. If sent to 1 the fixture tfx will be estimated.

9470

OP.AUTO_TFX=xls_parameter(parameter, 'AUTO_TFX', false,0); % Mostly used for device ERL. If sent to 1 the fixture tfx will be estimated.

9106

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9471

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9107

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9472

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9108

OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncation threshold', false, 1e-3); % zero padding threshold in fraction of IR peak for the impulse response. Effectively controls the length of time for the PR. Larger values decrease run time and accuracy. Default is 1e-3.

9473

OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncation threshold', false, 1e-3); % zero padding threshold in fraction of IR peak for the impulse response. Effectively controls the length of time for the PR. Larger values decrease run time and accuracy. Default is 1e-3.

9109

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9474

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9110

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9475

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9111

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9476

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9112

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9477

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9113

if strcmpi(OP.PHY,'C2M')

9478

if strcmpi(OP.PHY,'C2M')

9114

OP.EW=true;

9479

OP.EW=true;

9115

else

9480

else

9116

param.T_O=0; % make sure when c2c that sample is at Ts

9481

param.T_O=0; % make sure when c2c that sample is at Ts

9117

end

9482

end

9118

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9483

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9119

OP.PHY='C2Mcom';

9484

OP.PHY='C2Mcom';

9120

end

9485

end

9121

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9486

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9122

switch lower(OP.TDECQ)

9487

switch lower(OP.TDECQ)

9123

case {false 'none' 'vma'}

9488

case {false 'none' 'vma'}

9124

otherwise

9489

otherwise

9125

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9490

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9126

end

9491

end

9127

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9492

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9128

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9493

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9129

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9494

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9130

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9495

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9131

OP.Optimize_loop_speed_up =xls_parameter(parameter, 'Optimize_loop_speed_up', true , 0);% If set to 0 (or default) normal looping, If set to 1 loop speedup by slightly reducing PD Fbin and FIR_threshold for optimize looping only

9496

OP.Optimize_loop_speed_up =xls_parameter(parameter, 'Optimize_loop_speed_up', true , 0);% If set to 0 (or default) normal looping, If set to 1 loop speedup by slightly reducing PD Fbin and FIR_threshold for optimize looping only

9132

% Parameters for error burst probability calculation. Not officially used

9497

% Parameters for error burst probability calculation. Not officially used

9133

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9498

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9134

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9499

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9135

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9500

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9136

OP.USE_ETA0_PSD = xls_parameter(parameter, 'USE_ETA0_PSD', false, 0); % Used eta_0 PSD equaiton for sigma_n. Default is 0. Do not use.

9501

OP.USE_ETA0_PSD = xls_parameter(parameter, 'USE_ETA0_PSD', false, 0); % Used eta_0 PSD equaiton for sigma_n. Default is 0. Do not use.

9137

OP.SAVE_CONFIG2MAT = xls_parameter(parameter, 'SAVE_CONFIG2MAT', false, 0); % If set to 1 (default) saves parameters in mat file. Requires DIAGNOSTICS to be set.

9502

OP.SAVE_CONFIG2MAT = xls_parameter(parameter, 'SAVE_CONFIG2MAT', false, 0); % If set to 1 (default) saves parameters in mat file. Requires DIAGNOSTICS to be set.

9138

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9503

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9139

OP.fraction_of_F_range_start_extrap_from= xls_parameter(parameter, 'fraction_of_F_range_start_extrap_from', true, 0.75); % Frequency (fb) where high frequency extropolation begins for computing IR. Helps control Gibbs phenomena. defualt is 0.75.

9504

OP.fraction_of_F_range_start_extrap_from= xls_parameter(parameter, 'fraction_of_F_range_start_extrap_from', true, 0.75); % Frequency (fb) where high frequency extropolation begins for computing IR. Helps control Gibbs phenomena. defualt is 0.75.

9140

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9505

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9141

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9506

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9142

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9507

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9143

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9508

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9144

OP.MLSD = xls_parameter(parameter, 'MLSD', false, 0); % not 0 or missing means use MLSD

9509

OP.MLSE = xls_parameter(parameter, 'MLSE', false, 0); % MLSE 0,1,2, 3 (no MLSE, U1 MLSE, experimetal MLSE, U3 MLSE)

9145

OP.MLSE = xls_parameter(parameter, 'MLSE', false, OP.MLSD ); % MSLD Synonym support

9146

if OP.MLSE ~=0

9147

if param.T_O ~= 0

9148

error('MLSD nnot presently no supported for VEC')

9149

end

9150

if OP.COM_CONTRIBUTION_CURVES ~=0

9151

warning("COM_CONTRIBUTION_CURVES not functional yet with MLSE")

9152

OP.COM_CONTRIBUTION_CURVES=0;

9153

end

9154

end

9155

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9510

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9156

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9511

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9157

if OP.MLSE && param.ndfe==0

9512

if OP.MLSE && param.ndfe==0

9158

error('At least DFE 1 must be set to use MLSE');

9513

error('At least DFE 1 must be set to use MLSE');

9159

end

9514

end

9160

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9515

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9161

% MNSE parameters

9516

% MNSE parameters

9162

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9517

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9163

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9518

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9164

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9519

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9165

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9520

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9166

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9521

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9167

% Commit request 4p4_7, healey_3dj_COM_01_240416

9522

% Commit request 4p4_7, healey_3dj_COM_01_240416

9168

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

9523

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

9169

% need to make sure TD mode does not invoke FD operations

9524

% need to make sure TD mode does not invoke FD operations

9170

if OP.TDMODE % need to set GET_FD false of TDMODE

9525

if OP.TDMODE % need to set GET_FD false of TDMODE

9171

OP.GET_FD=false;

9526

OP.GET_FD=false;

9172

OP.ERL_ONLY=0;

9527

OP.ERL_ONLY=0;

9173

OP.ERL=0;

9528

OP.ERL=0;

9174

OP.PTDR=0;

9529

OP.PTDR=0;

9175

OP.TDR=0;

9530

OP.TDR=0;

9176

OP.RX_CALIBRATION=0;

9531

OP.RX_CALIBRATION=0;

9177

end

9532

end

9178

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9533

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9179

save(matcongfile ,'parameter');

9534

save(matcongfile ,'parameter');

9180

end

9535

end

9181

9536

9182

9537

9183

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9538

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9184

if ~isempty(param.PKG_NAME)

9539

if ~isempty(param.PKG_NAME)

9185

if length(param.PKG_NAME) == 1

9540

if length(param.PKG_NAME) == 1

9186

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9541

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9187

end

9542

end

9188

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9543

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9189

tx_rx_fields_matrix = {'pkg_Z_c'};

9544

tx_rx_fields_matrix = {'pkg_Z_c'};

9190

tx_fields = {'z_p_tx_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9545

tx_fields = {'z_p_tx_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9191

rx_fields = {'z_p_rx_cases' 'a_next' 'z_p_next_cases'};

9546

rx_fields = {'z_p_rx_cases' 'a_next' 'z_p_next_cases'};

9192

tx_pkg_name=param.PKG_NAME{1};

9547

tx_pkg_name=param.PKG_NAME{1};

9193

rx_pkg_name=param.PKG_NAME{2};

9548

rx_pkg_name=param.PKG_NAME{2};

9194

tx_pkg_struct=param.PKG.(tx_pkg_name);

9549

tx_pkg_struct=param.PKG.(tx_pkg_name);

9195

rx_pkg_struct=param.PKG.(rx_pkg_name);

9550

rx_pkg_struct=param.PKG.(rx_pkg_name);

9196

9551

9197

%tx_rx_fields: put the value from the tx package in the Tx position and the value from the rx package in the RX position

9552

%tx_rx_fields: put the value from the tx package in the Tx position and the value from the rx package in the RX position

9198

for j=1:length(tx_rx_fields)

9553

for j=1:length(tx_rx_fields)

9199

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9554

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9200

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9555

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9201

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9556

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9202

end

9557

end

9203

9558

9204

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9559

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9205

for j=1:length(tx_rx_fields_matrix)

9560

for j=1:length(tx_rx_fields_matrix)

9206

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9561

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9207

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9562

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9208

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9563

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9209

end

9564

end

9210

9565

9211

%tx_fields: use only the tx package values

9566

%tx_fields: use only the tx package values

9212

for j=1:length(tx_fields)

9567

for j=1:length(tx_fields)

9213

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9568

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9214

end

9569

end

9215

9570

9216

%rx_fields: use only the rx package values

9571

%rx_fields: use only the rx package values

9217

for j=1:length(rx_fields)

9572

for j=1:length(rx_fields)

9218

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9573

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9219

end

9574

end

9220

9575

9221

end

9576

end

9222

9577

9223

9578

9224

%%

9579

%%

9225

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9580

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9226

%% FUNCTION :: read_sp4_sparams

9581

%% FUNCTION :: read_sp4_sparams

9227

%

9582

%

9228

% Description

9583

% Description

9229

% Read the fid of single-ended 4-port complex S-parameters

9584

% Read the fid of single-ended 4-port complex S-parameters

9230

% in Touchstone format 'file' and convert to the internal

9585

% in Touchstone format 'file' and convert to the internal

9231

% format using the port transform 'ports'

9586

% format using the port transform 'ports'

9232

%

9587

%

9233

% Created by Mike Y. He

9588

% Created by Mike Y. He

9234

% April 22, 2005

9589

% April 22, 2005

9235

%

9590

%

9236

% Reused some code from

9591

% Reused some code from

9237

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9592

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9238

% for touchstone 4-port S-matrix import.

9593

% for touchstone 4-port S-matrix import.

9239

%

9594

%

9240

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9595

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9241

% optimized for quicker parameter matching and parsing. also, separated out

9596

% optimized for quicker parameter matching and parsing. also, separated out

9242

% the plotting algorithms into their own sub-function routines

9597

% the plotting algorithms into their own sub-function routines

9243

%

9598

%

9244

% Modified December 2021 to use read_Nport_touchstone

9599

% Modified December 2021 to use read_Nport_touchstone

9245

% This is faster reader that is capable of reading touchstone with any number of ports

9600

% This is faster reader that is capable of reading touchstone with any number of ports

9246

%

9601

%

9247

% Input Variables (required)

9602

% Input Variables (required)

9248

% infile -- The s4p file to be read and converted

9603

% infile -- The s4p file to be read and converted

9249

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9604

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9250

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9605

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9251

% ports -- Re-order the port layout

9606

% ports -- Re-order the port layout

9252

%

9607

%

9253

% Output/Return Variables

9608

% Output/Return Variables

9254

% data -- structure containing network parameter data points and frequency axis

9609

% data -- structure containing network parameter data points and frequency axis

9255

% sdc -- the differential in/common-mode out s-parameter data matrix

9610

% sdc -- the differential in/common-mode out s-parameter data matrix

9256

% sdd -- the differential in/differential out s-parameter data matrix

9611

% sdd -- the differential in/differential out s-parameter data matrix

9257

%

9612

%

9258

9613

9259

9614

9260

% backwards compatibility settings. can be removed in updated code.

9615

% backwards compatibility settings. can be removed in updated code.

9261

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9616

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9262

if isempty(ports); ports = [1 2]; end % default order normally used.

9617

if isempty(ports); ports = [1 2]; end % default order normally used.

9263

ports = [1 2];

9618

ports = [1 2];

9264

9619

9265

9620

9266

if OP.DISPLAY_WINDOW

9621

if OP.DISPLAY_WINDOW

9267

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9622

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9268

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9623

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9269

end

9624

end

9270

9625

9271

%AJG: fast touchstone read for any number of ports

9626

%AJG: fast touchstone read for any number of ports

9272

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9627

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9273

9628

9274

9629

9275

9630

9276

D=NaN(size(sch));

9631

D=NaN(size(sch));

9277

% calculate differential s parameter matrix from single ended

9632

% calculate differential s parameter matrix from single ended

9278

for i=1:size(sch,1)

9633

for i=1:size(sch,1)

9279

S(:,:) = sch(i,:,:);

9634

S(:,:) = sch(i,:,:);

9280

T = [1 1 ; 1 -1 ];

9635

T = [1 1 ; 1 -1 ];

9281

W = T * (S / T);

9636

W = T * (S / T);

9282

D(i,:,:) = W(:,:);

9637

D(i,:,:) = W(:,:);

9283

end

9638

end

9284

9639

9285

% D matrix should be

9640

% D matrix should be

9286

% Scc11 Scd11 Scc12 Scd21

9641

% Scc11 Scd11 Scc12 Scd21

9287

% Sdc11 Sdd11 Sdc12 Sdd12

9642

% Sdc11 Sdd11 Sdc12 Sdd12

9288

% Scc21 Scd21 Scc22 Scd22

9643

% Scc21 Scd21 Scc22 Scd22

9289

% Sdc21 Sdd21 Sdc22 Sdd22

9644

% Sdc21 Sdd21 Sdc22 Sdd22

9290

9645

9291

% proper values

9646

% proper values

9292

%AJG: matrix can be properly referenced after fixing mapping

9647

%AJG: matrix can be properly referenced after fixing mapping

9293

SDD(:,1,1) = D(:,2,2);

9648

SDD(:,1,1) = D(:,2,2);

9294

SDC(:,1,1)= D(:,2,1);

9649

SDC(:,1,1)= D(:,2,1);

9295

SCC(:,1,1)= D(:,1,1);

9650

SCC(:,1,1)= D(:,1,1);

9296

SCD(:,1,1)= D(:,1,2);

9651

SCD(:,1,1)= D(:,1,2);

9297

9652

9298

9653

9299

9654

9300

% backwards compatibility output variables

9655

% backwards compatibility output variables

9301

data.m = sch;

9656

data.m = sch;

9302

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9657

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9303

data.freq = schFreqAxis;

9658

data.freq = schFreqAxis;

9304

colors = 'rgbk';

9659

colors = 'rgbk';

9305

9660

9306

if (plot_ini_s_params == 1)

9661

if (plot_ini_s_params == 1)

9307

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9662

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9308

for mj=1:4

9663

for mj=1:4

9309

% subplot(2,2,mj);

9664

% subplot(2,2,mj);

9310

for mi=1:4

9665

for mi=1:4

9311

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9666

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9312

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9667

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9313

hold on

9668

hold on

9314

end

9669

end

9315

xlabel('Frequency (Hz)');

9670

xlabel('Frequency (Hz)');

9316

ylabel('Magnitude (dB)');

9671

ylabel('Magnitude (dB)');

9317

legend show

9672

legend show

9318

grid on

9673

grid on

9319

title(sprintf('Output port %d', mj));

9674

title(sprintf('Output port %d', mj));

9320

end

9675

end

9321

end

9676

end

9322

plot_dif_s_params =0;

9677

plot_dif_s_params =0;

9323

if (plot_dif_s_params == 1)

9678

if (plot_dif_s_params == 1)

9324

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9679

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9325

% subplot(2,1,1);

9680

% subplot(2,1,1);

9326

for mj=1:1

9681

for mj=1:1

9327

for mi=1:1

9682

for mi=1:1

9328

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9683

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9329

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9684

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9330

hold on

9685

hold on

9331

end

9686

end

9332

end

9687

end

9333

xlabel('Frequency (Hz)');

9688

xlabel('Frequency (Hz)');

9334

ylabel('Magnitude (dB)');

9689

ylabel('Magnitude (dB)');

9335

legend show

9690

legend show

9336

grid on

9691

grid on

9337

title(infile);

9692

title(infile);

9338

9693

9339

% subplot(2,1,2);

9694

% subplot(2,1,2);

9340

% for mj=1:2

9695

% for mj=1:2

9341

% for mi=1:2

9696

% for mi=1:2

9342

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9697

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9343

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9698

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9344

% hold on

9699

% hold on

9345

% end

9700

% end

9346

% end

9701

% end

9347

% xlabel('Frequency (Hz)');

9702

% xlabel('Frequency (Hz)');

9348

% ylabel('Magnitude (dB)');

9703

% ylabel('Magnitude (dB)');

9349

% legend show

9704

% legend show

9350

% grid on

9705

% grid on

9351

end

9706

end

9352

9707

9353

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9708

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9354

% end read_sp2_sparam

9709

% end read_sp2_sparam

9355

9710

9356

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9711

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9357

%% FUNCTION :: read_sp4_sparams

9712

%% FUNCTION :: read_sp4_sparams

9358

%

9713

%

9359

% Description

9714

% Description

9360

% Read the fid of single-ended 4-port complex S-parameters

9715

% Read the fid of single-ended 4-port complex S-parameters

9361

% in Touchstone format 'file' and convert to the internal

9716

% in Touchstone format 'file' and convert to the internal

9362

% format using the port transform 'ports'

9717

% format using the port transform 'ports'

9363

%

9718

%

9364

% Created by Mike Y. He

9719

% Created by Mike Y. He

9365

% April 22, 2005

9720

% April 22, 2005

9366

%

9721

%

9367

% Reused some code from

9722

% Reused some code from

9368

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9723

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9369

% for touchstone 4-port S-matrix import.

9724

% for touchstone 4-port S-matrix import.

9370

%

9725

%

9371

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9726

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9372

% optimized for quicker parameter matching and parsing. also, separated out

9727

% optimized for quicker parameter matching and parsing. also, separated out

9373

% the plotting algorithms into their own sub-function routines

9728

% the plotting algorithms into their own sub-function routines

9374

%

9729

%

9375

% Modified December 2021 to use read_Nport_touchstone

9730

% Modified December 2021 to use read_Nport_touchstone

9376

% This is faster reader that is capable of reading touchstone with any number of ports

9731

% This is faster reader that is capable of reading touchstone with any number of ports

9377

%

9732

%

9378

% Input Variables (required)

9733

% Input Variables (required)

9379

% infile -- The s4p file to be read and converted

9734

% infile -- The s4p file to be read and converted

9380

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9735

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9381

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9736

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9382

% ports -- Re-order the port layout

9737

% ports -- Re-order the port layout

9383

% OP

9738

% OP

9384

% param

9739

% param

9385

% Output/Return Variables

9740

% Output/Return Variables

9386

% data -- structure containing network parameter data points and frequency axis

9741

% data -- structure containing network parameter data points and frequency axis

9387

% sdd -- the differential in/differential out s-parameter data matrix

9742

% sdd -- the differential in/differential out s-parameter data matrix

9388

% sdc -- the differential in/common-mode out s-parameter data matrix

9743

% sdc -- the differential in/common-mode out s-parameter data matrix

9389

% scc -- the common mode in/common-mode out s-parameter data matrix

9744

% scc -- the common mode in/common-mode out s-parameter data matrix

9390

%

9745

%

9391

%

9746

%

9392

9747

9393

9748

9394

% backwards compatibility settings. can be removed in updated code.

9749

% backwards compatibility settings. can be removed in updated code.

9395

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9750

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9396

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9751

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9397

9752

9398

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9753

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9399

% pair is reversed.

9754

% pair is reversed.

9400

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9755

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9401

9756

9402

if OP.DISPLAY_WINDOW

9757

if OP.DISPLAY_WINDOW

9403

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9758

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9404

end

9759

end

9405

9760

9406

%AJG: fast touchstone read for any number of ports

9761

%AJG: fast touchstone read for any number of ports

9407

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9762

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9408

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9763

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9409

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9764

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9410

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9765

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9411

Sigfct = ...

9766

Sigfct = ...

9412

@(sigma2,sigma1,sigma4,sigma3)reshape([sigma1.^2,sigma1.*sigma2,sigma1.*sigma3,sigma1.*sigma4,sigma1.*sigma2,sigma2.^2,sigma2.*sigma3,sigma2.*sigma4,sigma1.*sigma3,sigma2.*sigma3,sigma3.^2,sigma3.*sigma4,sigma1.*sigma4,sigma2.*sigma4,sigma3.*sigma4,sigma4.^2],[4,4]);

9767

@(sigma2,sigma1,sigma4,sigma3)reshape([sigma1.^2,sigma1.*sigma2,sigma1.*sigma3,sigma1.*sigma4,sigma1.*sigma2,sigma2.^2,sigma2.*sigma3,sigma2.*sigma4,sigma1.*sigma3,sigma2.*sigma3,sigma3.^2,sigma3.*sigma4,sigma1.*sigma4,sigma2.*sigma4,sigma3.*sigma4,sigma4.^2],[4,4]);

9413

D=NaN(size(sch));

9768

D=NaN(size(sch));

9414

% calculate differential s parameter matrix from single ended

9769

% calculate differential s parameter matrix from single ended

9415

% skew added RIM 12/29/2023

9770

% skew added RIM 12/29/2023

9416

for i=1:size(sch,1)

9771

for i=1:size(sch,1)

9417

f=schFreqAxis(i);

9772

f=schFreqAxis(i);

9418

sigma_matrix=Sigfct(exp(2i*pi*f*param.Txpskew*1e-12),exp(2i*pi*f*param.Txnskew*1e-12),exp(2i*pi*f*param.Rxpskew*1e-12),exp(2i*pi*f*param.Rxnskew*1e-12) );

9773

sigma_matrix=Sigfct(exp(2i*pi*f*param.Txpskew*1e-12),exp(2i*pi*f*param.Txnskew*1e-12),exp(2i*pi*f*param.Rxpskew*1e-12),exp(2i*pi*f*param.Rxnskew*1e-12) );

9419

S(:,:) = sch(i,:,:);

9774

S(:,:) = sch(i,:,:);

9420

Snew=sigma_matrix.*S;

9775

Snew=sigma_matrix.*S;

9421

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9776

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9422

W = T * (Snew / T);

9777

W = T * (Snew / T);

9423

D(i,:,:) = W(:,:);

9778

D(i,:,:) = W(:,:);

9424

end

9779

end

9425

9780

9426

% D matrix should be

9781

% D matrix should be

9427

% Scc11 Scd11 Scc12 Scd21

9782

% Scc11 Scd11 Scc12 Scd21

9428

% Sdc11 Sdd11 Sdc12 Sdd12

9783

% Sdc11 Sdd11 Sdc12 Sdd12

9429

% Scc21 Scd21 Scc22 Scd22

9784

% Scc21 Scd21 Scc22 Scd22

9430

% Sdc21 Sdd21 Sdc22 Sdd22

9785

% Sdc21 Sdd21 Sdc22 Sdd22

9431

9786

9432

% proper values

9787

% proper values

9433

SDD(:,1,1) = D(:,2,2);

9788

SDD(:,1,1) = D(:,2,2);

9434

SDD(:,2,2) = D(:,4,4);

9789

SDD(:,2,2) = D(:,4,4);

9435

SDD(:,1,2) = D(:,2,4);

9790

SDD(:,1,2) = D(:,2,4);

9436

SDD(:,2,1) = D(:,4,2);

9791

SDD(:,2,1) = D(:,4,2);

9437

9792

9438

SDC(:,1,1) = D(:,2,1);

9793

SDC(:,1,1) = D(:,2,1);

9439

SDC(:,2,2) = D(:,4,3);

9794

SDC(:,2,2) = D(:,4,3);

9440

SDC(:,1,2) = D(:,2,3);

9795

SDC(:,1,2) = D(:,2,3);

9441

SDC(:,2,1) = D(:,4,1);

9796

SDC(:,2,1) = D(:,4,1);

9442

9797

9443

SCC(:,1,1) = D(:,1,1);

9798

SCC(:,1,1) = D(:,1,1);

9444

SCC(:,2,2) = D(:,3,3);

9799

SCC(:,2,2) = D(:,3,3);

9445

SCC(:,1,2) = D(:,1,3);

9800

SCC(:,1,2) = D(:,1,3);

9446

SCC(:,2,1) = D(:,3,1);

9801

SCC(:,2,1) = D(:,3,1);

9447

9802

9448

% backwards compatibility output variables

9803

% backwards compatibility output variables

9449

data.m = sch;

9804

data.m = sch;

9450

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9805

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9451

data.freq = schFreqAxis;

9806

data.freq = schFreqAxis;

9452

colors = 'rgbk';

9807

colors = 'rgbk';

9453

9808

9454

if (plot_ini_s_params == 1)

9809

if (plot_ini_s_params == 1)

9455

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9810

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9456

for mj=1:4

9811

for mj=1:4

9457

subplot(2,2,mj);

9812

subplot(2,2,mj);

9458

for mi=1:4

9813

for mi=1:4

9459

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9814

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9460

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9815

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9461

hold on

9816

hold on

9462

end

9817

end

9463

xlabel('Frequency (Hz)');

9818

xlabel('Frequency (Hz)');

9464

ylabel('Magnitude (dB)');

9819

ylabel('Magnitude (dB)');

9465

legend show

9820

legend show

9466

grid on

9821

grid on

9467

title(sprintf('Output port %d', mj));

9822

title(sprintf('Output port %d', mj));

9468

end

9823

end

9469

end

9824

end

9470

plot_dif_s_params =0;

9825

plot_dif_s_params =0;

9471

if (plot_dif_s_params == 1)

9826

if (plot_dif_s_params == 1)

9472

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9827

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9473

% subplot(2,1,1);

9828

% subplot(2,1,1);

9474

for mj=1:2

9829

for mj=1:2

9475

for mi=1:2

9830

for mi=1:2

9476

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9831

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9477

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9832

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9478

hold on

9833

hold on

9479

end

9834

end

9480

end

9835

end

9481

xlabel('Frequency (Hz)');

9836

xlabel('Frequency (Hz)');

9482

ylabel('Magnitude (dB)');

9837

ylabel('Magnitude (dB)');

9483

legend show

9838

legend show

9484

grid on

9839

grid on

9485

title(infile);

9840

title(infile);

9486

%

9841

%

9487

% subplot(2,1,2);

9842

% subplot(2,1,2);

9488

% for mj=1:2

9843

% for mj=1:2

9489

% for mi=1:2

9844

% for mi=1:2

9490

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9845

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9491

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9846

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9492

% hold on

9847

% hold on

9493

% end

9848

% end

9494

% end

9849

% end

9495

% xlabel('Frequency (Hz)');

9850

% xlabel('Frequency (Hz)');

9496

% ylabel('Magnitude (dB)');

9851

% ylabel('Magnitude (dB)');

9497

% legend show

9852

% legend show

9498

% grid on

9853

% grid on

9499

end

9854

end

9500

9855

9501

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9856

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9502

% end read_sp4_sparam

9857

% end read_sp4_sparam

9503

function param_struct = read_package_parameters(parameter,param_struct)

9858

function param_struct = read_package_parameters(parameter,param_struct)

9504

9859

9505

%With the introduction of Package sections in COM spreadsheet, it makes sense to have a single function that grabs all package parameters from a parameter block

9860

%With the introduction of Package sections in COM spreadsheet, it makes sense to have a single function that grabs all package parameters from a parameter block

9506

%This block should eventually replace what is in read_ParamConfigFile

9861

%This block should eventually replace what is in read_ParamConfigFile

9507

%It can be called as: param = read_package_parameters(parameter, param)

9862

%It can be called as: param = read_package_parameters(parameter, param)

9508

9863

9509

if nargin<2

9864

if nargin<2

9510

%param_struct doesn't need to be passed when building a new package structure

9865

%param_struct doesn't need to be passed when building a new package structure

9511

%it is only needed when appending to regular param structure

9866

%it is only needed when appending to regular param structure

9512

param_struct=struct;

9867

param_struct=struct;

9513

end

9868

end

9514

9869

9515

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9870

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9516

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9871

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9517

9872

9518

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_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9519

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9874

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9520

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9875

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9521

9876

9522

param_struct.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9877

param_struct.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9523

[ncases, mele]=size(param_struct.z_p_tx_cases);

9878

[ncases, mele]=size(param_struct.z_p_tx_cases);

9524

if mele ==2

9879

if mele ==2

9525

param_struct.flex=2;

9880

param_struct.flex=2;

9526

elseif mele==4

9881

elseif mele==4

9527

param_struct.flex=4;

9882

param_struct.flex=4;

9528

elseif mele==1

9883

elseif mele==1

9529

param_struct.flex=1;

9884

param_struct.flex=1;

9530

else

9885

else

9531

error('config file syntax error')

9886

error('config file syntax error')

9532

end

9887

end

9533

param_struct.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9888

param_struct.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9534

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9889

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9535

if ncases ~= ncases1 || mele ~= mele1

9890

if ncases ~= ncases1 || mele ~= mele1

9536

error('All TX, NEXT, FEXT, Rx cases must agree');

9891

error('All TX, NEXT, FEXT, Rx cases must agree');

9537

else

9892

else

9538

end

9893

end

9539

param_struct.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9894

param_struct.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9540

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9895

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9541

if ncases ~= ncases1 || mele ~= mele1

9896

if ncases ~= ncases1 || mele ~= mele1

9542

error('All TX, NEXT, FEXT, Rx cases must agree');

9897

error('All TX, NEXT, FEXT, Rx cases must agree');

9543

else

9898

else

9544

end

9899

end

9545

param_struct.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9900

param_struct.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9546

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9901

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9547

if ncases ~= ncases1 || mele ~= mele1

9902

if ncases ~= ncases1 || mele ~= mele1

9548

error('All TX, NEXT, FEXT, Rx cases must agree');

9903

error('All TX, NEXT, FEXT, Rx cases must agree');

9549

else

9904

else

9550

end

9905

end

9551

% Table 93A-3 parameters

9906

% Table 93A-3 parameters

9552

param_struct.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9907

param_struct.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9553

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9908

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9554

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9909

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9555

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9910

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9556

if mele ~= mele1

9911

if mele ~= mele1

9557

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9912

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9558

else

9913

else

9559

end

9914

end

9560

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9915

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9561

for ii=1:ncases

9916

for ii=1:ncases

9562

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9917

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9563

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9918

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9564

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9919

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9565

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9920

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9566

end

9921

end

9567

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9922

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9568

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9923

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9569

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9924

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9570

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9925

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9571

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9926

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9572

end

9927

end

9573

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9928

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9574

%% extract s-parameter and convert to differential mode

9929

%% extract s-parameter and convert to differential mode

9575

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9930

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9576

num_files=length(chdata);

9931

num_files=length(chdata);

9577

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9932

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9578

for i=1:num_files

9933

for i=1:num_files

9579

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9934

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9580

progress = i/num_files;

9935

progress = i/num_files;

9581

if OP.DISPLAY_WINDOW

9936

if OP.DISPLAY_WINDOW

9582

[~,a]=fileparts(chdata(i).filename);

9937

[~,a]=fileparts(chdata(i).filename);

9583

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9938

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9584

else

9939

else

9585

fprintf('%i ',i);

9940

fprintf('%i ',i);

9586

end

9941

end

9587

9942

9588

% Skip reading file if it was already read (multiple test cases)

9943

% Skip reading file if it was already read (multiple test cases)

9589

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9944

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9590

switch lower(chdata(i).ext)

9945

switch lower(chdata(i).ext)

9591

case '.s2p' % for differential return loss

9946

case '.s2p' % for differential return loss

9592

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9947

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9593

chdata(i).fmaxi = length(Sch.freq);

9948

chdata(i).fmaxi = length(Sch.freq);

9594

chdata(i).faxis = Sch.freq;

9949

chdata(i).faxis = Sch.freq;

9595

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9950

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9596

SDDp2p(i)=NaN;

9951

SDDp2p(i)=NaN;

9597

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9952

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9598

chdata(i).sdd11=chdata(i).sdd11_raw;

9953

chdata(i).sdd11=chdata(i).sdd11_raw;

9599

case '.s4p'

9954

case '.s4p'

9600

if length(param.snpPortsOrder) ~= 4

9955

if length(param.snpPortsOrder) ~= 4

9601

error( 'warning:sNpFilePortMismatch', ...

9956

error( 'warning:sNpFilePortMismatch', ...

9602

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9957

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9603

length(param.snpPortsOrder), ...

9958

length(param.snpPortsOrder), ...

9604

chdata(i).ext ...

9959

chdata(i).ext ...

9605

);

9960

);

9606

end

9961

end

9607

% read function returns differnetial mode parameters

9962

% read function returns differnetial mode parameters

9608

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9963

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9609

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9964

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9610

% param.holdsdata(i).Sch= Sch;

9965

% param.holdsdata(i).Sch= Sch;

9611

% param.holdsdata(i).SDDch= SDDch;

9966

% param.holdsdata(i).SDDch= SDDch;

9612

% param.holdsdata(i).SDCch= SDCch;

9967

% param.holdsdata(i).SDCch= SDCch;

9613

else

9968

else

9614

error('If this line is reached, there is a logic error');

9969

error('If this line is reached, there is a logic error');

9615

% Sch=param.holdsdata(i).Sch;

9970

% Sch=param.holdsdata(i).Sch;

9616

% SDDch=param.holdsdata(i).SDDch;

9971

% SDDch=param.holdsdata(i).SDDch;

9617

% SDCch=param.holdsdata(i).SDCch;

9972

% SDCch=param.holdsdata(i).SDCch;

9618

end

9973

end

9619

chdata(i).fmaxi = length(Sch.freq);

9974

chdata(i).fmaxi = length(Sch.freq);

9620

9975

9621

9976

9622

if Sch.freq(chdata(i).fmaxi) < param.fb

9977

if Sch.freq(chdata(i).fmaxi) < param.fb

9623

warning('COM:read_s4p:MaxFreqTooLow', ...

9978

warning('COM:read_s4p:MaxFreqTooLow', ...

9624

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9979

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9625

chdata(i).filename, Sch.freq(end), param.fb);

9980

chdata(i).filename, Sch.freq(end), param.fb);

9626

end

9981

end

9627

if Sch.freq(1) > param.max_start_freq

9982

if Sch.freq(1) > param.max_start_freq

9628

warning('COM:read_s4p:StartFreqTooHigh', ...

9983

warning('COM:read_s4p:StartFreqTooHigh', ...

9629

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9984

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9630

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9985

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9631

end

9986

end

9632

freqstep=diff(Sch.freq);

9987

freqstep=diff(Sch.freq);

9633

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9988

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9634

if max(freqstep)-min(freqstep) > 1

9989

if max(freqstep)-min(freqstep) > 1

9635

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9990

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9636

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9991

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9637

end

9992

end

9638

if max(freqstep) - param.max_freq_step > 1

9993

if max(freqstep) - param.max_freq_step > 1

9639

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9994

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9640

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9995

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9641

end

9996

end

9642

9997

9643

chdata(i).faxis = Sch.freq;

9998

chdata(i).faxis = Sch.freq;

9644

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9999

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9645

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

10000

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9646

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

10001

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9647

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

10002

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9648

% mode conversion

10003

% mode conversion

9649

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

10004

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9650

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

10005

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9651

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

10006

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9652

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

10007

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9653

%save original and add board (if required)

10008

%save original and add board (if required)

9654

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

10009

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9655

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

10010

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

9656

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

10011

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

9657

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

10012

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

9658

if OP.include_pcb

10013

if OP.include_pcb

9659

% add boards to sdd

10014

% add boards to sdd

9660

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

10015

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

9661

10016

9662

end

10017

end

9663

%save final return loss (after the boards were included)

10018

%save final return loss (after the boards were included)

9664

chdata(i).sdd11=chdata(i).sdd11_raw;

10019

chdata(i).sdd11=chdata(i).sdd11_raw;

9665

chdata(i).sdd22=chdata(i).sdd22_raw;

10020

chdata(i).sdd22=chdata(i).sdd22_raw;

9666

otherwise

10021

otherwise

9667

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

10022

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

9668

end

10023

end

9669

10024

9670

%Crosstalk frequency axis must be the same as Thru

10025

%Crosstalk frequency axis must be the same as Thru

9671

if i>1

10026

if i>1

9672

%error on length difference

10027

%error on length difference

9673

if length(chdata(i).faxis)~=length(chdata(1).faxis)

10028

if length(chdata(i).faxis)~=length(chdata(1).faxis)

9674

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

10029

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

9675

end

10030

end

9676

%error if any value > 1Hz (don't want to check for exact

10031

%error if any value > 1Hz (don't want to check for exact

9677

%equality in case of floating point error)

10032

%equality in case of floating point error)

9678

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

10033

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

9679

if max(Fdiff)>1

10034

if max(Fdiff)>1

9680

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

10035

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

9681

end

10036

end

9682

end

10037

end

9683

else

10038

else

9684

SDDch(:,1,2)=chdata(i).sdd12_raw;

10039

SDDch(:,1,2)=chdata(i).sdd12_raw;

9685

SDDch(:,2,1)=chdata(i).sdd21_raw;

10040

SDDch(:,2,1)=chdata(i).sdd21_raw;

9686

SDDch(:,1,1)=chdata(i).sdd11_raw;

10041

SDDch(:,1,1)=chdata(i).sdd11_raw;

9687

SDDch(:,2,2)=chdata(i).sdd22_raw;

10042

SDDch(:,2,2)=chdata(i).sdd22_raw;

9688

end

10043

end

9689

chdata(i).sigma_ACCM_at_tp0=0;

10044

chdata(i).sigma_ACCM_at_tp0=0;

9690

if ~param.FLAG.S2P

10045

if ~param.FLAG.S2P

9691

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

10046

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

9692

if (OP.RX_CALIBRATION == 1 && i==2)

10047

if (OP.RX_CALIBRATION == 1 && i==2)

9693

chdata(i).sdd21=chdata(i).sdd21_raw;

10048

chdata(i).sdd21=chdata(i).sdd21_raw;

9694

else

10049

else

9695

%updated package construction with single function for both DD and DC

10050

%updated package construction with single function for both DD and DC

9696

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

10051

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

9697

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

10052

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

9698

chdata(i).sdd21=chdata(i).sdd21p;

10053

chdata(i).sdd21=chdata(i).sdd21p;

9699

if 1 % for AC CM noise inclusion

10054

if 1 % for AC CM noise inclusion

9700

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

10055

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

9701

chdata(i).sdc21=chdata(i).sdc21p;

10056

chdata(i).sdc21=chdata(i).sdc21p;

9702

end

10057

end

9703

end

10058

end

9704

else

10059

else

9705

chdata(i).sdd21=chdata(i).sdd21_raw;

10060

chdata(i).sdd21=chdata(i).sdd21_raw;

9706

end

10061

end

9707

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

10062

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

9708

end

10063

end

9709

end

10064

end

9710

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

10065

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

9711

10066

9712

function result = readdataSnPx(filename, nport)

10067

function result = readdataSnPx(filename, nport)

9713

%function [freq, cs] = readdataSnPx(filename, nport)

10068

%function [freq, cs] = readdataSnPx(filename, nport)

9714

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

10069

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

9715

%

10070

%

9716

% Read Touchstone file with frequencies in units of Hertz

10071

% Read Touchstone file with frequencies in units of Hertz

9717

%

10072

%

9718

% Input:

10073

% Input:

9719

% ======

10074

% ======

9720

% filename: Name of the Touchstone/SnP file

10075

% filename: Name of the Touchstone/SnP file

9721

% nport: Number of ports

10076

% nport: Number of ports

9722

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

10077

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

9723

% Touchstone file)

10078

% Touchstone file)

9724

% nheader: Number of header lines (comment lines plus option line in the

10079

% nheader: Number of header lines (comment lines plus option line in the

9725

% Touchstone file)

10080

% Touchstone file)

9726

%

10081

%

9727

% Output:

10082

% Output:

9728

% =======

10083

% =======

9729

% freq: Vector of frequencies [Hz]

10084

% freq: Vector of frequencies [Hz]

9730

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

10085

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

9731

% at frequency freq(k)

10086

% at frequency freq(k)

9732

%

10087

%

9733

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

10088

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

9734

% frequencies appropriately after reading the data.

10089

% frequencies appropriately after reading the data.

9735

%

10090

%

9736

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

10091

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

9737

% EIA/IBIS Open Forum, 2002.

10092

% EIA/IBIS Open Forum, 2002.

9738

%

10093

%

9739

% Written by Henning Braunisch, September 2004.

10094

% Written by Henning Braunisch, September 2004.

9740

% Updated by Steven Krooswyk, April 2006.

10095

% Updated by Steven Krooswyk, April 2006.

9741

10096

9742

10097

9743

fid = fopen(filename, 'r');

10098

fid = fopen(filename, 'r');

9744

10099

9745

10100

9746

% Skip header lines

10101

% Skip header lines

9747

str = ' ';

10102

str = ' ';

9748

n = 0;

10103

n = 0;

9749

while ~strcmp(str(1),'#')

10104

while ~strcmp(str(1),'#')

9750

str = fgetl(fid);

10105

str = fgetl(fid);

9751

if isempty(str)

10106

if isempty(str)

9752

str=' ' ;

10107

str=' ' ;

9753

if n > 1000

10108

if n > 1000

9754

display('error: could not find config line (#)')

10109

display('error: could not find config line (#)')

9755

break

10110

break

9756

end

10111

end

9757

end

10112

end

9758

n = n + 1;

10113

n = n + 1;

9759

end

10114

end

9760

10115

9761

% parse configuration line

10116

% parse configuration line

9762

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

10117

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

9763

p = find(A=='S'); %position of 'S'

10118

p = find(A=='S'); %position of 'S'

9764

units = lower(A(2:p-1)); %units before 'S'

10119

units = lower(A(2:p-1)); %units before 'S'

9765

format = A(p+1:p+2); %format after 'S'

10120

format = A(p+1:p+2); %format after 'S'

9766

10121

9767

% skip any more header lines

10122

% skip any more header lines

9768

%while ~str

10123

%while ~str

9769

10124

9770

nk = 0; % frequency counter

10125

nk = 0; % frequency counter

9771

while 1

10126

while 1

9772

10127

9773

[temp, count] = fscanf(fid, '%f', 1);

10128

[temp, count] = fscanf(fid, '%f', 1);

9774

if count == 0

10129

if count == 0

9775

temp2 = fscanf(fid, '%s', 1);

10130

temp2 = fscanf(fid, '%s', 1);

9776

if ~isempty(temp2), fgetl(fid); continue, end;

10131

if ~isempty(temp2), fgetl(fid); continue, end;

9777

break

10132

break

9778

end

10133

end

9779

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

10134

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

9780

for ni = 1:nport

10135

for ni = 1:nport

9781

for nj = 1:nport

10136

for nj = 1:nport

9782

switch lower(format)

10137

switch lower(format)

9783

case 'ma'

10138

case 'ma'

9784

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10139

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9785

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

10140

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

9786

case 'ri'

10141

case 'ri'

9787

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

10142

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

9788

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10143

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9789

case 'db'

10144

case 'db'

9790

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10145

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9791

M = 10^(db/20);

10146

M = 10^(db/20);

9792

%re = M*cos(ang);

10147

%re = M*cos(ang);

9793

%im = M*sin(ang);

10148

%im = M*sin(ang);

9794

re = M*cos(ang * pi / 180);

10149

re = M*cos(ang * pi / 180);

9795

im = M*sin(ang * pi / 180);

10150

im = M*sin(ang * pi / 180);

9796

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10151

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9797

otherwise

10152

otherwise

9798

error('readdataSnP: Unknown data format');

10153

error('readdataSnP: Unknown data format');

9799

end

10154

end

9800

end

10155

end

9801

end

10156

end

9802

end

10157

end

9803

10158

9804

fclose(fid);

10159

fclose(fid);

9805

10160

9806

% If 2-port then swap S_12 and S_21 per Touchstone spec

10161

% If 2-port then swap S_12 and S_21 per Touchstone spec

9807

if nport == 2

10162

if nport == 2

9808

temp = cs(2,1,:);

10163

temp = cs(2,1,:);

9809

cs(2,1,:) = cs(1,2,:);

10164

cs(2,1,:) = cs(1,2,:);

9810

cs(1,2,:) = temp;

10165

cs(1,2,:) = temp;

9811

end

10166

end

9812

10167

9813

% Update freq units to Hz

10168

% Update freq units to Hz

9814

switch lower(units)

10169

switch lower(units)

9815

case 'hz'

10170

case 'hz'

9816

10171

9817

case 'khz'

10172

case 'khz'

9818

freq=freq.*1e3;

10173

freq=freq.*1e3;

9819

case 'mhz'

10174

case 'mhz'

9820

freq=freq.*1e6;

10175

freq=freq.*1e6;

9821

case 'ghz'

10176

case 'ghz'

9822

freq=freq.*1e9;

10177

freq=freq.*1e9;

9823

end

10178

end

9824

10179

9825

% passivity check

10180

% passivity check

9826

result.freq = freq;

10181

result.freq = freq;

9827

result.cs = cs;

10182

result.cs = cs;

9828

10183

9829

function recolor_plots(ax)

10184

function recolor_plots(ax)

9830

10185

9831

if ~verLessThan('matlab', '8.4.0')

10186

if ~verLessThan('matlab', '8.4.0')

9832

return

10187

return

9833

end

10188

end

9834

colors='brgcmk';

10189

colors='brgcmk';

9835

ch=flipud(get(ax, 'children'));

10190

ch=flipud(get(ax, 'children'));

9836

10191

9837

for k=1:length(ch)

10192

for k=1:length(ch)

9838

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

10193

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

9839

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

10194

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

9840

end

10195

end

9841

legend (ax, 'off');

10196

legend (ax, 'off');

9842

warning('off', 'MATLAB:legend:PlotEmpty');

10197

warning('off', 'MATLAB:legend:PlotEmpty');

9843

set(legend (ax, 'show'), 'interp', 'none');

10198

set(legend (ax, 'show'), 'interp', 'none');

9844

10199

9845

function result = reduce(var1)

10200

function result = reduce(var1)

9846

% --- Reduce 1x1xn array to 1xn (aka squeeze)

10201

% --- Reduce 1x1xn array to 1xn (aka squeeze)

9847

out = zeros(1,length(var1));

10202

out = zeros(1,length(var1));

9848

out(1,:) = var1(1,1,:);

10203

out(1,:) = var1(1,1,:);

9849

result=out;

10204

result=out;

9850

10205

9851

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

10206

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

9852

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

10207

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

9853

% faxis is the frequency array

10208

% faxis is the frequency array

9854

% s21, s11, s22 are the corresponding array of differential parameters

10209

% s21, s11, s22 are the corresponding array of differential parameters

9855

% s21p includes the VFT and Tx filter if include_die=1

10210

% s21p includes the VFT and Tx filter if include_die=1

9856

if nargin<6

10211

if nargin<6

9857

include_die=1;

10212

include_die=1;

9858

end

10213

end

9859

if nargin<5

10214

if nargin<5

9860

mode='dd';

10215

mode='dd';

9861

end

10216

end

9862

10217

9863

s21=chdata.(['s' mode '21_raw']);

10218

s21=chdata.(['s' mode '21_raw']);

9864

s12=chdata.(['s' mode '12_raw']);

10219

s12=chdata.(['s' mode '12_raw']);

9865

s11=chdata.(['s' mode '11_raw']);

10220

s11=chdata.(['s' mode '11_raw']);

9866

s22=chdata.(['s' mode '22_raw']);

10221

s22=chdata.(['s' mode '22_raw']);

9867

faxis=chdata.faxis;

10222

faxis=chdata.faxis;

9868

channel_type=chdata.type;

10223

channel_type=chdata.type;

9869

10224

9870

if strcmpi(mode,'dd')

10225

if strcmpi(mode,'dd')

9871

s11=s11*param.kappa1;

10226

s11=s11*param.kappa1;

9872

s22=s22*param.kappa2;

10227

s22=s22*param.kappa2;

9873

end

10228

end

9874

10229

9875

10230

9876

Z0=param.Z0;

10231

Z0=param.Z0;

9877

%sigma_ACCM_at_tp0 is only used when mode=DC

10232

%sigma_ACCM_at_tp0 is only used when mode=DC

9878

sigma_ACCM_at_tp0=0;

10233

sigma_ACCM_at_tp0=0;

9879

10234

9880

% The following three parameters have possibly different valuesF for TX and

10235

% The following three parameters have possibly different valuesF for TX and

9881

% RX (so can be 2-element vectors).

10236

% RX (so can be 2-element vectors).

9882

R_diepad = param.R_diepad;

10237

R_diepad = param.R_diepad;

9883

10238

9884

%Make TX Package

10239

%Make TX Package

9885

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

10240

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

9886

10241

9887

%Make RX Package

10242

%Make RX Package

9888

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

10243

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

9889

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

10244

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

9890

10245

9891

10246

9892

% p(1 ,1, :)=s11in;

10247

% p(1 ,1, :)=s11in;

9893

% p(2 ,2, :)=s22in;

10248

% p(2 ,2, :)=s22in;

9894

% p(1 ,2, :)=s12in;

10249

% p(1 ,2, :)=s12in;

9895

% p(2 ,1, :)=s21in;

10250

% p(2 ,1, :)=s21in;

9896

%

10251

%

9897

% S=sparameters(p,faxis);

10252

% S=sparameters(p,faxis);

9898

% rfwrite(S,'temp.s4p');

10253

% rfwrite(S,'temp.s4p');

9899

10254

9900

if strcmpi(mode,'dc')

10255

if strcmpi(mode,'dc')

9901

RTX=R_diepad(param.Tx_rd_sel)/2;

10256

RTX=R_diepad(param.Tx_rd_sel)/2;

9902

RRX=R_diepad(param.Rx_rd_sel)/2;

10257

RRX=R_diepad(param.Rx_rd_sel)/2;

9903

Z0gamma=Z0/2;

10258

Z0gamma=Z0/2;

9904

else

10259

else

9905

RTX=R_diepad(param.Tx_rd_sel);

10260

RTX=R_diepad(param.Tx_rd_sel);

9906

RRX=R_diepad(param.Rx_rd_sel);

10261

RRX=R_diepad(param.Rx_rd_sel);

9907

Z0gamma=Z0;

10262

Z0gamma=Z0;

9908

end

10263

end

9909

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

10264

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

9910

gamma_tx=0;

10265

gamma_tx=0;

9911

else

10266

else

9912

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

10267

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

9913

end

10268

end

9914

if OP.IDEAL_RX_TERM

10269

if OP.IDEAL_RX_TERM

9915

gamma_rx=0;

10270

gamma_rx=0;

9916

else

10271

else

9917

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

10272

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

9918

end

10273

end

9919

10274

9920

if OP.INC_PACKAGE==0

10275

if OP.INC_PACKAGE==0

9921

s21p= s21;

10276

s21p= s21;

9922

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

10277

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

9923

else

10278

else

9924

if OP.RX_CALIBRATION == 1 && channel_number == 2

10279

if OP.RX_CALIBRATION == 1 && channel_number == 2

9925

% for calibration do not include the transmitter package

10280

% for calibration do not include the transmitter package

9926

[s11out_rx, s12out_rx, s21out_rx, s22out_rx ] = combines4p( s11, s12, s21, s22, s22out, s12out, s21out, s11out ); %#ok<ASGLU> % s22 is ball side of package

10281

[s11out_rx, s12out_rx, s21out_rx, s22out_rx ] = combines4p( s11, s12, s21, s22, s22out, s12out, s21out, s11out ); %#ok<ASGLU> % s22 is ball side of package

9927

SCH.Frequencies=faxis;

10282

SCH.Frequencies=faxis;

9928

SCH.Parameters(1,1,:)=s11out_rx;

10283

SCH.Parameters(1,1,:)=s11out_rx;

9929

SCH.Parameters(2,2,:)=s22out_rx;

10284

SCH.Parameters(2,2,:)=s22out_rx;

9930

SCH.Parameters(1,2,:)=s12out_rx;

10285

SCH.Parameters(1,2,:)=s12out_rx;

9931

SCH.Parameters(2,1,:)=s21out_rx;

10286

SCH.Parameters(2,1,:)=s21out_rx;

9932

SCH.NumPorts=2;

10287

SCH.NumPorts=2;

9933

SCH.Impedance=100;

10288

SCH.Impedance=100;

9934

%% Equation 93A-18

10289

%% Equation 93A-18

9935

if include_die

10290

if include_die

9936

s21p= s21out_rx.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11out_rx.*gamma_tx - s22out_rx.*gamma_rx -s21out_rx.^2.*gamma_tx.*gamma_rx +s11out_rx.*s22out_rx.*gamma_tx.*gamma_rx);

10291

s21p= s21out_rx.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11out_rx.*gamma_tx - s22out_rx.*gamma_rx -s21out_rx.^2.*gamma_tx.*gamma_rx +s11out_rx.*s22out_rx.*gamma_tx.*gamma_rx);

9937

else

10292

else

9938

s21p=s21out_rx; % if no die we do not want a VTF

10293

s21p=s21out_rx; % if no die we do not want a VTF

9939

end

10294

end

9940

else

10295

else

9941

%% Equations 93A-4 to 93A-7

10296

%% Equations 93A-4 to 93A-7

9942

if ~OP.IDEAL_TX_TERM

10297

if ~OP.IDEAL_TX_TERM

9943

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10298

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

9944

end

10299

end

9945

H_t=ones(1,length(faxis)); % .3bj compatibility

10300

H_t=ones(1,length(faxis)); % .3bj compatibility

9946

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10301

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

9947

% for RITT testing with good termination as in some instruments

10302

% for RITT testing with good termination as in some instruments

9948

% and tx filter when required

10303

% and tx filter when required

9949

if OP.T_r_filter_type==0

10304

if OP.T_r_filter_type==0

9950

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10305

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

9951

else

10306

else

9952

tr=OP.transmitter_transition_time;

10307

tr=OP.transmitter_transition_time;

9953

f9=faxis/1e9;

10308

f9=faxis/1e9;

9954

if OP.T_r_meas_point == 1

10309

if OP.T_r_meas_point == 1

9955

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10310

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

9956

H_t=105./(f9.^4*(k*tr)^4 - f9.^3*(k*tr)^3*10i - 45*f9.^2*(k*tr)^2 + f9*(k*tr)*105i + 105);

10311

H_t=105./(f9.^4*(k*tr)^4 - f9.^3*(k*tr)^3*10i - 45*f9.^2*(k*tr)^2 + f9*(k*tr)*105i + 105);

9957

else

10312

else

9958

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10313

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

9959

end

10314

end

9960

10315

9961

end

10316

end

9962

end

10317

end

9963

if strcmpi(mode,'dc')

10318

if strcmpi(mode,'dc')

9964

% H_t=ones(1,length(faxis)); % not sure if we need a H_t or not. Is the CM noise correlated to the edge rate?

10319

% H_t=ones(1,length(faxis)); % not sure if we need a H_t or not. Is the CM noise correlated to the edge rate?

9965

end

10320

end

9966

if ~OP.IDEAL_RX_TERM

10321

if ~OP.IDEAL_RX_TERM

9967

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10322

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

9968

else

10323

else

9969

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10324

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

9970

end

10325

end

9971

%% Equation 93A-18 and part of 93A-1: Ht fix in V290 identified by Bill Kirkland and Ed Frlan ( s21^2 changed to s12*s21 )

10326

%% Equation 93A-18 and part of 93A-1: Ht fix in V290 identified by Bill Kirkland and Ed Frlan ( s21^2 changed to s12*s21 )

9972

if include_die

10327

if include_die

9973

s21p= H_t.*s21.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11.*gamma_tx - s22.*gamma_rx -s21.*s12.*gamma_tx.*gamma_rx +s11.*s22.*gamma_tx.*gamma_rx);

10328

s21p= H_t.*s21.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11.*gamma_tx - s22.*gamma_rx -s21.*s12.*gamma_tx.*gamma_rx +s11.*s22.*gamma_tx.*gamma_rx);

9974

else

10329

else

9975

s21p=s21; % if no die we do not want a VTF

10330

s21p=s21; % if no die we do not want a VTF

9976

end

10331

end

9977

end

10332

end

9978

10333

9979

if strcmpi(mode,'dc')

10334

if strcmpi(mode,'dc')

9980

% compute AC_CM_RMS at tp0

10335

% compute AC_CM_RMS at tp0

9981

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10336

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

9982

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10337

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

9983

if channel_number == 1

10338

if channel_number == 1

9984

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10339

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

9985

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10340

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

9986

sigma_ACCM_at_tp0= sqrt(2*param.AC_CM_RMS_TX^2*sum( abs( H_cc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end)) ;

10341

sigma_ACCM_at_tp0= sqrt(2*param.AC_CM_RMS_TX^2*sum( abs( H_cc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end)) ;

9987

% S=sparameters(p,faxis);

10342

% S=sparameters(p,faxis);

9988

% rfwrite(S,'temp.s4p');

10343

% rfwrite(S,'temp.s4p');

9989

end

10344

end

9990

end

10345

end

9991

10346

9992

SCH.Frequencies=faxis;

10347

SCH.Frequencies=faxis;

9993

SCH.Parameters(1,1,:)=s11;

10348

SCH.Parameters(1,1,:)=s11;

9994

SCH.Parameters(2,2,:)=s22;

10349

SCH.Parameters(2,2,:)=s22;

9995

SCH.Parameters(1,2,:)=s12;

10350

SCH.Parameters(1,2,:)=s12;

9996

SCH.Parameters(2,1,:)=s21;

10351

SCH.Parameters(2,1,:)=s21;

9997

SCH.NumPorts=2;

10352

SCH.NumPorts=2;

9998

if strcmpi(mode,'dc')

10353

if strcmpi(mode,'dc')

9999

SCH.Impedance=25;

10354

SCH.Impedance=25;

10000

else

10355

else

10001

SCH.Impedance=100;

10356

SCH.Impedance=100;

10002

end

10357

end

10003

10358

10004

end

10359

end

10005

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10360

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10006

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10361

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10007

% Creates a time-domain impulse response from frequency-domain IL data.

10362

% Creates a time-domain impulse response from frequency-domain IL data.

10008

% IL does not need to have DC but a corresponding frequency array

10363

% IL does not need to have DC but a corresponding frequency array

10009

% (freq_array) is required.

10364

% (freq_array) is required.

10010

%

10365

%

10011

% Causality is imposed using the Alternating Projections Method. See also:

10366

% Causality is imposed using the Alternating Projections Method. See also:

10012

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10367

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10013

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10368

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10014

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10369

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10015

10370

10016

ILin=IL;

10371

ILin=IL;

10017

fmax=1/time_step/2;

10372

fmax=1/time_step/2;

10018

freq_step=(freq_array(3)-freq_array(2))/1;

10373

freq_step=(freq_array(3)-freq_array(2))/1;

10019

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10374

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10020

if all(IL==0)

10375

if all(IL==0)

10021

%response with all zeros is problematic. set to all eps and avoid interp function

10376

%response with all zeros is problematic. set to all eps and avoid interp function

10022

IL=ones(1,length(fout))*eps;

10377

IL=ones(1,length(fout))*eps;

10023

else

10378

else

10024

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10379

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10025

IL_nan = find(isnan(IL));

10380

IL_nan = find(isnan(IL));

10026

for in=IL_nan

10381

for in=IL_nan

10027

IL(in)=IL(in-1);

10382

IL(in)=IL(in-1);

10028

end

10383

end

10029

end

10384

end

10030

IL = IL(:);

10385

IL = IL(:);

10031

% add padding for time steps

10386

% add padding for time steps

10032

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10387

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10033

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10388

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10034

impulse_response = real(ifft(IL_symmetric));

10389

impulse_response = real(ifft(IL_symmetric));

10035

L = length(impulse_response);

10390

L = length(impulse_response);

10036

t_base = (0:L-1)/(freq_step*L);

10391

t_base = (0:L-1)/(freq_step*L);

10037

10392

10038

original_impulse_response=impulse_response;

10393

original_impulse_response=impulse_response;

10039

% Correct non-causal effects frequently caused by extrapolation of IL

10394

% Correct non-causal effects frequently caused by extrapolation of IL

10040

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10395

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10041

abs_ir=abs(impulse_response);

10396

abs_ir=abs(impulse_response);

10042

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10397

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10043

start_ind = a(1);

10398

start_ind = a(1);

10044

10399

10045

err=inf;

10400

err=inf;

10046

while ~all(impulse_response==0)

10401

while ~all(impulse_response==0)

10047

impulse_response(1:start_ind)=0;

10402

impulse_response(1:start_ind)=0;

10048

impulse_response(floor(L/2):end)=0;

10403

impulse_response(floor(L/2):end)=0;

10049

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10404

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10050

ir_modified = real(ifft(IL_modified));

10405

ir_modified = real(ifft(IL_modified));

10051

delta = abs(impulse_response-ir_modified);

10406

delta = abs(impulse_response-ir_modified);

10052

10407

10053

err_prev = err;

10408

err_prev = err;

10054

err=max(delta)/max(impulse_response);

10409

err=max(delta)/max(impulse_response);

10055

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10410

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10056

break;

10411

break;

10057

end

10412

end

10058

10413

10059

impulse_response=ir_modified;

10414

impulse_response=ir_modified;

10060

end

10415

end

10061

10416

10062

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10417

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10063

10418

10064

if ~OP.ENFORCE_CAUSALITY

10419

if ~OP.ENFORCE_CAUSALITY

10065

impulse_response = original_impulse_response;

10420

impulse_response = original_impulse_response;

10066

end

10421

end

10067

% truncate final samples smaller than 1e-3 of the peak

10422

% truncate final samples smaller than 1e-3 of the peak

10068

ir_peak = max(abs(impulse_response));

10423

ir_peak = max(abs(impulse_response));

10069

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10424

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10070

10425

10071

voltage = impulse_response(1:ir_last);

10426

voltage = impulse_response(1:ir_last);

10072

t_base = t_base(1:ir_last);

10427

t_base = t_base(1:ir_last);

10073

10428

10074

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10429

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10075

10430

10076

function S =s_for_c2(zref,f,cpad)

10431

function S =s_for_c2(zref,f,cpad)

10077

% S is 2 port s parameters out

10432

% S is 2 port s parameters out

10078

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10433

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10079

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10434

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10080

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10435

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10081

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10436

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10082

S=sparameters(S_Parameters,f,zref);

10437

S=sparameters(S_Parameters,f,zref);

10083

10438

10084

function S =s_for_c4(zref,f,cpad)

10439

function S =s_for_c4(zref,f,cpad)

10085

10440

10086

S2 = s_for_c2(zref,f,cpad);

10441

S2 = s_for_c2(zref,f,cpad);

10087

S4P=s2_to_s4(S2.Parameters);

10442

S4P=s2_to_s4(S2.Parameters);

10088

S=sparameters(S4P,f,zref);

10443

S=sparameters(S4P,f,zref);

10089

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10444

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10090

10445

10091

10446

10092

10447

10093

10448

10094

%%

10449

%%

10095

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10450

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10096

% save commmend string

10451

% save commmend string

10097

% for saving from interactive queries

10452

% for saving from interactive queries

10098

10453

10099

10454

10100

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10455

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10101

for i=1:num_next+num_fext

10456

for i=1:num_next+num_fext

10102

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10457

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10103

end

10458

end

10104

cmd_str= [ cmd_str ')'];

10459

cmd_str= [ cmd_str ')'];

10105

10460

10106

10461

10107

%%%%% require the RF tool box

10462

%%%%% require the RF tool box

10108

%%

10463

%%

10109

function [ h ] = savefigs( param, OP )

10464

function [ h ] = savefigs( param, OP )

10110

10465

10111

%% find the figures

10466

%% find the figures

10112

hw = waitbar(0,'Saving figures...');

10467

hw = waitbar(0,'Saving figures...');

10113

h = findobj(0, 'Type', 'figure');

10468

h = findobj(0, 'Type', 'figure');

10114

for ii=1:length(h)

10469

for ii=1:length(h)

10115

10470

10116

figname= get(h(ii), 'Name'); % use the figure name as file name

10471

figname= get(h(ii), 'Name'); % use the figure name as file name

10117

if isempty(strfind(figname,param.base))

10472

if isempty(strfind(figname,param.base))

10118

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10473

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10119

end

10474

end

10120

if verLessThan('matlab', '8.4.0')

10475

if verLessThan('matlab', '8.4.0')

10121

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10476

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10122

else

10477

else

10123

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10478

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10124

end

10479

end

10125

figname = strrep(figname,':','-');

10480

figname = strrep(figname,':','-');

10126

figname = strrep(figname,' ','_');

10481

figname = strrep(figname,' ','_');

10127

if OP.SAVE_FIGURES==1

10482

if OP.SAVE_FIGURES==1

10128

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10483

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10129

end

10484

end

10130

%% get x y data

10485

%% get x y data

10131

if OP.SAVE_FIGURE_to_CSV==1

10486

if OP.SAVE_FIGURE_to_CSV==1

10132

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10487

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10133

M=[]; %ncol=1;

10488

M=[]; %ncol=1;

10134

for nk=1:length(h_L)

10489

for nk=1:length(h_L)

10135

% get x and data for a line.

10490

% get x and data for a line.

10136

x_data=get(h_L(nk),'xdata')';

10491

x_data=get(h_L(nk),'xdata')';

10137

y_data=get(h_L(nk),'ydata')';

10492

y_data=get(h_L(nk),'ydata')';

10138

% .........>> need to get data in the line structure (legend or label) for headers

10493

% .........>> need to get data in the line structure (legend or label) for headers

10139

M=[M; x_data; y_data]; %#ok<AGROW>

10494

M=[M; x_data; y_data]; %#ok<AGROW>

10140

end

10495

end

10141

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10496

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10142

% clear M y x header h_L

10497

% clear M y x header h_L

10143

end

10498

end

10144

waitbar(ii/length(h),hw)

10499

waitbar(ii/length(h),hw)

10145

10500

10146

end

10501

end

10147

10502

10148

close(hw)

10503

close(hw)

10149

10504

10150

%%

10505

%%

10151

function [ h ] = savefigs_png( param, OP )

10506

function [ h ] = savefigs_png( param, OP )

10152

10507

10153

%% find the figures

10508

%% find the figures

10154

hw = waitbar(0,'Saving figures...');

10509

hw = waitbar(0,'Saving figures...');

10155

h = findobj(0, 'Type', 'figure');

10510

h = findobj(0, 'Type', 'figure');

10156

for ii=1:length(h)

10511

for ii=1:length(h)

10157

10512

10158

figname= get(h(ii), 'Name'); % use the figure name as file name

10513

figname= get(h(ii), 'Name'); % use the figure name as file name

10159

if isempty(strfind(figname,param.base))

10514

if isempty(strfind(figname,param.base))

10160

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10515

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10161

end

10516

end

10162

if verLessThan('matlab', '8.4.0')

10517

if verLessThan('matlab', '8.4.0')

10163

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10518

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10164

else

10519

else

10165

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10520

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10166

end

10521

end

10167

figname = strrep(figname,':','-');

10522

figname = strrep(figname,':','-');

10168

figname = strrep(figname,' ','_');

10523

figname = strrep(figname,' ','_');

10169

if OP.SAVE_FIGURES==1

10524

if OP.SAVE_FIGURES==1

10170

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10525

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10171

end

10526

end

10172

%% get x y data

10527

%% get x y data

10173

if OP.SAVE_FIGURE_to_CSV==1

10528

if OP.SAVE_FIGURE_to_CSV==1

10174

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10529

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10175

M=[]; %ncol=1;

10530

M=[]; %ncol=1;

10176

for nk=1:length(h_L)

10531

for nk=1:length(h_L)

10177

% get x and data for a line.

10532

% get x and data for a line.

10178

x_data=get(h_L(nk),'xdata')';

10533

x_data=get(h_L(nk),'xdata')';

10179

y_data=get(h_L(nk),'ydata')';

10534

y_data=get(h_L(nk),'ydata')';

10180

% .........>> need to get data in the line structure (legend or label) for headers

10535

% .........>> need to get data in the line structure (legend or label) for headers

10181

M=[M; x_data; y_data]; %#ok<AGROW>

10536

M=[M; x_data; y_data]; %#ok<AGROW>

10182

end

10537

end

10183

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10538

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10184

% clear M y x header h_L

10539

% clear M y x header h_L

10185

end

10540

end

10186

waitbar(ii/length(h),hw)

10541

waitbar(ii/length(h),hw)

10187

10542

10188

end

10543

end

10189

10544

10190

close(hw)

10545

close(hw)

10191

10546

10192

%%

10547

%%

10193

function [pdf_out, cdf_out, scale_factor] = scaleCDF(pdf,delta_com,DER0,A_s)

10194

% scale CDF at DER0 to delta_com

10195

pdf_out=pdf;

10196

P=cumsum(pdf.y);

10197

ider0=find(P>=DER0,1,'first');

10198

anias=pdf.x(ider0)/A_s; % ani/as

10199

new_db = 20*log10(-1/anias)-delta_com;

10200

new_value = -1*1/10^(new_db/20);

10201

scale_factor=1/10^(-delta_com/20);

10202

pdf_out=scalePDF(pdf,scale_factor);

10203

cdf_out=cumsum(pdf_out.y);

10204

function pdf_out = scalePDF(pdf,scale_factor)

10548

function pdf_out = scalePDF(pdf,scale_factor)

10205

pdf_out=pdf;

10549

pdf_out=pdf;

10206

pdf_out.Min=floor(pdf.Min*scale_factor);

10550

pdf_out.Min=floor(pdf.Min*scale_factor);

10207

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10551

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10208

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10552

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10209

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10553

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10210

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10554

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10211

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10555

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10212

function t_params = stot(s_params)

10556

function t_params = stot(s_params)

10213

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10557

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10214

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10558

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10215

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10559

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10216

delta = (s11.*s22-s12.*s21);

10560

delta = (s11.*s22-s12.*s21);

10217

s21(s21==0)=eps;

10561

s21(s21==0)=eps;

10218

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10562

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10219

10563

10220

function csv_string = str2csv(c)

10564

function csv_string = str2csv(c)

10221

% convert a cell array of strings to a csv string

10565

% convert a cell array of strings to a csv string

10222

cell_tmp = cell(2, length(c));

10566

cell_tmp = cell(2, length(c));

10223

cell_tmp(1,:)=c;

10567

cell_tmp(1,:)=c;

10224

cell_tmp(2,:) = {','};

10568

cell_tmp(2,:) = {','};

10225

cell_tmp{2,end} = '';

10569

cell_tmp{2,end} = '';

10226

csv_string=strcat(cell_tmp{:});

10570

csv_string=strcat(cell_tmp{:});

10227

10571

10228

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10572

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10229

f_GHz=f/1e9;

10573

f_GHz=f/1e9;

10230

%% Equation 93A-10 %%

10574

%% Equation 93A-10 %%

10231

gamma_1 = gamma_coeff(2)*(1+1i);

10575

gamma_1 = gamma_coeff(2)*(1+1i);

10232

%% Equation 93A-11 %%

10576

%% Equation 93A-11 %%

10233

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10577

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10234

%% Equation 93A-9 %%

10578

%% Equation 93A-9 %%

10235

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10579

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10236

gamma(f_GHz==0) = gamma_coeff(1);

10580

gamma(f_GHz==0) = gamma_coeff(1);

10237

10581

10238

%% Equation 93A-12 %%

10582

%% Equation 93A-12 %%

10239

if d==0

10583

if d==0

10240

%force matched impedance if length is 0

10584

%force matched impedance if length is 0

10241

%otherwise divide by zero can occur if Z_c=0

10585

%otherwise divide by zero can occur if Z_c=0

10242

rho_rl=0;

10586

rho_rl=0;

10243

else

10587

else

10244

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10588

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10245

end

10589

end

10246

10590

10247

exp_gamma_d = exp(-d*gamma);

10591

exp_gamma_d = exp(-d*gamma);

10248

%% Equations 93A-13 and 93A-14 %%

10592

%% Equations 93A-13 and 93A-14 %%

10249

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10593

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10250

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10594

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10251

s12 = s21;

10595

s12 = s21;

10252

s22 = s11;

10596

s22 = s11;

10253

10597

10254

function s_params = ttos(t_params)

10598

function s_params = ttos(t_params)

10255

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10599

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10256

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10600

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10257

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10601

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10258

delta = t11.*t22-t21.*t12;

10602

delta = t11.*t22-t21.*t12;

10259

t11(t11==0)=eps;

10603

t11(t11==0)=eps;

10260

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10604

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10261

10605

10262

function [out_var,varg_out]=varargin_extractor(varargin)

10606

function [out_var,varg_out]=varargin_extractor(varargin)

10263

10607

10264

if isempty(varargin)

10608

if isempty(varargin)

10265

out_var=[];

10609

out_var=[];

10266

varg_out={};

10610

varg_out={};

10267

else

10611

else

10268

out_var=varargin{1};

10612

out_var=varargin{1};

10269

varg_out=varargin;

10613

varg_out=varargin;

10270

varg_out(1)=[];

10614

varg_out(1)=[];

10271

end

10615

end

10272

10616

10273

10617

10274

function results= vma(PR, M)

10618

function results= vma(PR, M)

10275

% PR=sbr.Data;

10619

% PR=sbr.Data;

10276

% M=32;

10620

% M=32;

10277

% PR is the pulse response

10621

% PR is the pulse response

10278

% M is samples per UI

10622

% M is samples per UI

10279

[ seq, syms, syms_nrz ] = PRBS13Q( );

10623

[ seq, syms, syms_nrz ] = PRBS13Q( );

10280

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10624

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10281

symbols=seq;

10625

symbols=seq;

10282

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10626

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10283

% start end symbols index for 7 3's and 6 0's

10627

% start end symbols index for 7 3's and 6 0's

10284

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10628

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10285

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10629

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10286

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10630

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10287

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10631

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10288

% superposition code

10632

% superposition code

10289

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10633

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10290

Bit_stream_response=filter(PR,1, shifting_vector);

10634

Bit_stream_response=filter(PR,1, shifting_vector);

10291

% find center of 3's and 0's

10635

% find center of 3's and 0's

10292

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10636

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10293

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10637

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10294

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10638

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10295

% hold on

10639

% hold on

10296

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10640

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10297

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10641

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10298

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10642

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10299

VMA= P_3 - P_0;

10643

VMA= P_3 - P_0;

10300

results.P_3=P_3;

10644

results.P_3=P_3;

10301

results.P_0=P_0;

10645

results.P_0=P_0;

10302

results.VMA=VMA;

10646

results.VMA=VMA;

10303

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10647

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10304

10648

10305

%slope of the 2 sample points around vref crossing

10649

%slope of the 2 sample points around vref crossing

10306

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10650

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10307

%x-intercept for the line

10651

%x-intercept for the line

10308

b1=eye_contour(x_in,1)-m1*x_in;

10652

b1=eye_contour(x_in,1)-m1*x_in;

10309

% drawing a horizontal line through vref so slope = 0

10653

% drawing a horizontal line through vref so slope = 0

10310

m2=0;

10654

m2=0;

10311

%special case for horizontal line, b=y

10655

%special case for horizontal line, b=y

10312

b2=vref;

10656

b2=vref;

10313

%the x-value of line intersection = (b2-b1)/(m1-m2)

10657

%the x-value of line intersection = (b2-b1)/(m1-m2)

10314

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10658

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10315

%And usually vref is 0, so it further reduces to -b1/m1

10659

%And usually vref is 0, so it further reduces to -b1/m1

10316

line_intersection=(b2-b1)/(m1-m2);

10660

line_intersection=(b2-b1)/(m1-m2);

10317

10661

10318

10662

10319

10663

10320

10664

10321

10665

10322

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10666

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10323

% helper function to read parameter values from XLS file. Uses names to find values.

10667

% helper function to read parameter values from XLS file. Uses names to find values.

10324

if nargin<3, eval_if_string=0; end

10668

if nargin<3, eval_if_string=0; end

10325

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10669

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10326

if numel(row)*numel(col)==0

10670

if numel(row)*numel(col)==0

10327

if nargin<4

10671

if nargin<4

10328

missingParameter(param_name);

10672

missingParameter(param_name);

10329

else

10673

else

10330

p = default_value;

10674

p = default_value;

10331

end

10675

end

10332

elseif numel(row)*numel(col)>1

10676

elseif numel(row)*numel(col)>1

10333

% if there are several occurrences, use the first, but warn

10677

% if there are several occurrences, use the first, but warn

10334

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10678

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10335

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10679

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10336

error('COM:XLS_parameter:MultipleOccurrence', ...

10680

error('COM:XLS_parameter:MultipleOccurrence', ...

10337

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10681

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10338

p=param_sheet{row(1), col(1)+1};

10682

p=param_sheet{row(1), col(1)+1};

10339

else

10683

else

10340

p=param_sheet{row, col+1};

10684

p=param_sheet{row, col+1};

10341

end

10685

end

10342

if ischar(p) && eval_if_string

10686

if ischar(p) && eval_if_string

10343

p=eval(p);

10687

p=eval(p);

10344

end

10688

end

10345

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10689

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10346

if OP.SAVE_KEYWORD_FILE

10690

if OP.SAVE_KEYWORD_FILE

10347

10691

10348

if nargin<3 || ~exist('default_value','var')

10692

if nargin<3 || ~exist('default_value','var')

10349

default_value=p;

10693

default_value=p;

10350

end

10694

end

10351

if isempty(default_value)

10695

if isempty(default_value)

10352

default_value='-';

10696

default_value='-';

10353

end

10697

end

10354

%%

10698

%%

10355

% Get call-stack info:

10699

% Get call-stack info:

10356

stDebug = dbstack;

10700

stDebug = dbstack;

10357

callerFileName = stDebug(2).file;

10701

callerFileName = stDebug(2).file;

10358

callerLineNumber = stDebug(2).line;

10702

callerLineNumber = stDebug(2).line;

10359

% Open caller file:

10703

% Open caller file:

10360

fCaller = fopen(callerFileName);

10704

fCaller = fopen(callerFileName);

10361

% Iterate through lines to get to desired line number:

10705

% Iterate through lines to get to desired line number:

10362

for iLine = 1 : callerLineNumber

10706

for iLine = 1 : callerLineNumber

10363

% Read current line of text:

10707

% Read current line of text:

10364

currLine = fgetl(fCaller);

10708

currLine = fgetl(fCaller);

10365

end

10709

end

10366

% (currLine) now reflects calling desired code: display this code:

10710

% (currLine) now reflects calling desired code: display this code:

10367

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10711

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10368

% Close caller file:

10712

% Close caller file:

10369

left_side=currLine(1:strfind(currLine,'=')-1);

10713

left_side=currLine(1:strfind(currLine,'=')-1);

10370

cmt_side=currLine(strfind(currLine,'%')+1:end);

10714

cmt_side=currLine(strfind(currLine,'%')+1:end);

10371

if isempty(cmt_side), cmt_side=' ';end

10715

if isempty(cmt_side), cmt_side=' ';end

10372

fclose(fCaller);

10716

fclose(fCaller);

10373

10717

10374

if ~ischar(default_value)

10718

if ~ischar(default_value)

10375

default_str=sprintf('%g ',default_value);

10719

default_str=sprintf('%g ',default_value);

10376

else

10720

else

10377

default_str=default_value;

10721

default_str=default_value;

10378

end

10722

end

10379

if ~isfile('keyworklog.mat')

10723

if ~isfile('keyworklog.mat')

10380

save_p=param_name;

10724

save_p=param_name;

10381

save_d=default_str;

10725

save_d=default_str;

10382

save_r=left_side;

10726

save_r=left_side;

10383

save_c=cmt_side;

10727

save_c=cmt_side;

10384

param_name = {'keyword'};

10728

param_name = {'keyword'};

10385

default_str = {'default'};

10729

default_str = {'default'};

10386

left_side={'matlab variable'};

10730

left_side={'matlab variable'};

10387

cmt_side={'info'};

10731

cmt_side={'info'};

10388

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10732

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10389

param_name=save_p;

10733

param_name=save_p;

10390

default_str=save_d;

10734

default_str=save_d;

10391

left_side=save_r;

10735

left_side=save_r;

10392

cmt_side=save_c;

10736

cmt_side=save_c;

10393

data=load('keyworklog.mat');

10737

data=load('keyworklog.mat');

10394

else

10738

else

10395

load('keyworklog.mat');

10739

load('keyworklog.mat');

10396

end

10740

end

10397

data.left_side = [ data.left_side; left_side];

10741

data.left_side = [ data.left_side; left_side];

10398

data.param_name = [data.param_name; param_name];

10742

data.param_name = [data.param_name; param_name];

10399

data.default_str = [data.default_str; default_str ];

10743

data.default_str = [data.default_str; default_str ];

10400

data.cmt_side = [ data.cmt_side; cmt_side];

10744

data.cmt_side = [ data.cmt_side; cmt_side];

10401

if length(data.default_str)~=length(data.default_str)

10745

if length(data.default_str)~=length(data.default_str)

10402

a=1;

10746

a=1;

10403

end

10747

end

10404

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10748

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10405

save('keyworklog.mat','data');

10749

save('keyworklog.mat','data');

10406

writetable(T,[ 'keywords_' date '.csv' ]);

10750

writetable(T,[ 'keywords_' date '.csv' ]);

10407

end

10751

end

10408

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10752

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10409

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10753

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10410

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10754

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10411

10755

10412

found=1;

10756

found=1;

10413

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10757

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10414

if numel(row)*numel(col)==0

10758

if numel(row)*numel(col)==0

10415

p = 0;

10759

p = 0;

10416

found=0;

10760

found=0;

10417

elseif numel(row)*numel(col)>1

10761

elseif numel(row)*numel(col)>1

10418

% if there are several occurrences, use the first, but warn

10762

% if there are several occurrences, use the first, but warn

10419

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10763

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10420

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10764

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10421

error('COM:XLS_parameter:MultipleOccurrence', ...

10765

error('COM:XLS_parameter:MultipleOccurrence', ...

10422

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10766

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10423

p=param_sheet{row(1), col(1)+1};

10767

p=param_sheet{row(1), col(1)+1};

10424

else

10768

else

10425

p=param_sheet{row, col+1};

10769

p=param_sheet{row, col+1};

10426

end

10770

end

10427

if ischar(p)

10771

if ischar(p)

10428

p=eval(p);

10772

p=eval(p);

10429

end

10773

end

10430

function zzz_list_of_changes

10774

function zzz_list_of_changes

10431

% structures:

10775

% structures:

10432

% chdata(i)

10776

% chdata(i)

10433

% i= 1 --> THRU index

10777

% i= 1 --> THRU index

10434

% i= 2, num_fext+1 --> FEXT channel index

10778

% i= 2, num_fext+1 --> FEXT channel index

10435

% i= num_fext+2, num_next+num_fext+1

10779

% i= num_fext+2, num_next+num_fext+1

10436

% base: name of THRU file

10780

% base: name of THRU file

10437

% A: amplitude

10781

% A: amplitude

10438

% type: 'THRU', 'NEXT', or 'FEXT'

10782

% type: 'THRU', 'NEXT', or 'FEXT'

10439

% ftr: Rise time frequency

10783

% ftr: Rise time frequency

10440

% fmaxi: max number of frequency points

10784

% fmaxi: max number of frequency points

10441

% faxis: frequency array [Hz]

10785

% faxis: frequency array [Hz]

10442

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10786

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10443

% sdd22: differential RL

10787

% sdd22: differential RL

10444

% sdd11: differential RL

10788

% sdd11: differential RL

10445

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10789

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10446

% sdd21f: raw differential IL not filtered use for FD plots

10790

% sdd21f: raw differential IL not filtered use for FD plots

10447

% added output_args.peak_uneq_pulse_mV

10791

% added output_args.peak_uneq_pulse_mV

10448

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10792

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10449

% added: tap c(-2) c(2) and c(3)

10793

% added: tap c(-2) c(2) and c(3)

10450

% added: g_DC_HP and f_HP_PZ

10794

% added: g_DC_HP and f_HP_PZ

10451

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10795

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10452

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10796

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10453

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10797

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10454

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10798

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10455

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10799

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10456

% fixed INCLUDE_CTLE=0 to really remove from computation

10800

% fixed INCLUDE_CTLE=0 to really remove from computation

10457

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10801

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10458

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10802

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10459

% r162 tx and rx package impedance {Zc)

10803

% r162 tx and rx package impedance {Zc)

10460

% r162a Gaussian equation corrected

10804

% r162a Gaussian equation corrected

10461

% r163 cast snr_tx with package test case

10805

% r163 cast snr_tx with package test case

10462

% r164 fix pdf for very low noise and lo pass filter enhancements

10806

% r164 fix pdf for very low noise and lo pass filter enhancements

10463

% r164 add zero gain at nqyist CTLE as in CL12e

10807

% r164 add zero gain at nqyist CTLE as in CL12e

10464

% r165 add simpler congfig command called FORCE_TR (force risetime)

10808

% r165 add simpler congfig command called FORCE_TR (force risetime)

10465

% r200 cm3 and cm4 added cp3 removed

10809

% r200 cm3 and cm4 added cp3 removed

10466

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10810

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10467

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10811

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10468

% r200 improved phase interpolation for return loss time conversion

10812

% r200 improved phase interpolation for return loss time conversion

10469

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10813

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10470

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10814

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10471

% r200c missed on fix for interpolation

10815

% r200c missed on fix for interpolation

10472

% r210 new ERL with time gating function

10816

% r210 new ERL with time gating function

10473

% r224 update ERL with from D3.1

10817

% r224 update ERL with from D3.1

10474

% r226 fix s2p reading problem

10818

% r226 fix s2p reading problem

10475

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10819

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10476

% Fix Rx calibration issue

10820

% Fix Rx calibration issue

10477

% added ERL limit and Nd

10821

% added ERL limit and Nd

10478

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10822

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10479

% INC_PACKAGE=0 not fully supported message

10823

% INC_PACKAGE=0 not fully supported message

10480

% if N=0 use TDR_duration

10824

% if N=0 use TDR_duration

10481

% red display text for fail ERL and COM

10825

% red display text for fail ERL and COM

10482

% r228 fixed ERL pass fail report, default Grr_limit to 1

10826

% r228 fixed ERL pass fail report, default Grr_limit to 1

10483

% r230 add rx ffe

10827

% r230 add rx ffe

10484

% r231 change crosstalk noise to icn like to speed things up

10828

% r231 change crosstalk noise to icn like to speed things up

10485

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10829

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10486

% 1e-5mof-

10830

% 1e-5mof-

10487

% r232 fix default for Rx eq so old spead sheets work

10831

% r232 fix default for Rx eq so old spead sheets work

10488

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10832

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10489

% r235 adding dfe quantization changed to normalized DFE taps reported

10833

% r235 adding dfe quantization changed to normalized DFE taps reported

10490

% r236 adding ffe gain loop and resample after RxFFE

10834

% r236 adding ffe gain loop and resample after RxFFE

10491

% r240 added output for C2M and setting defaults for some FFE eq

10835

% r240 added output for C2M and setting defaults for some FFE eq

10492

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10836

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10493

% r250 adding more complex package

10837

% r250 adding more complex package

10494

% r251 post cursor fix for DFE in force() and ffe backoff

10838

% r251 post cursor fix for DFE in force() and ffe backoff

10495

% r251 remove TDR threshold noise filter

10839

% r251 remove TDR threshold noise filter

10496

% r252 add rx FFE filter to receiver noise filter

10840

% r252 add rx FFE filter to receiver noise filter

10497

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10841

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10498

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10842

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10499

% r254 precursor check fix in optimize_fom % mod fix in force

10843

% r254 precursor check fix in optimize_fom % mod fix in force

10500

% r254 help to align columns in csv file

10844

% r254 help to align columns in csv file

10501

% r254 accept syntax for 2 tline flex package model

10845

% r254 accept syntax for 2 tline flex package model

10502

% r256 speed up optimize FOM

10846

% r256 speed up optimize FOM

10503

% r256 fix problem reading in config file from q/a

10847

% r256 fix problem reading in config file from q/a

10504

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10848

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10505

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10849

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10506

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10850

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10507

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10851

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10508

% r258 CDR switch 'MM' or 'mod-MM'

10852

% r258 CDR switch 'MM' or 'mod-MM'

10509

% r258 correction for asymentirc tx/Rx packages

10853

% r258 correction for asymentirc tx/Rx packages

10510

% r258 revamped display results display window

10854

% r258 revamped display results display window

10511

% r259 fix problem if Min_VEO is set in spreadsheet.

10855

% r259 fix problem if Min_VEO is set in spreadsheet.

10512

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10856

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10513

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10857

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10514

% r259 putting COM_db and IL last in output to terminal

10858

% r259 putting COM_db and IL last in output to terminal

10515

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10859

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10516

% r259 use N_bx for ERL rather than Nb (ndfe))

10860

% r259 use N_bx for ERL rather than Nb (ndfe))

10517

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10861

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10518

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10862

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10519

% r260 used eta_0 PSD equation for sigma_n

10863

% r260 used eta_0 PSD equation for sigma_n

10520

% r260 fix IL graph legend to w/pkg and Tr

10864

% r260 fix IL graph legend to w/pkg and Tr

10521

% r260 define tfx for each port

10865

% r260 define tfx for each port

10522

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10866

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10523

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10867

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10524

% r262 reset on exit default text interpreter to tex

10868

% r262 reset on exit default text interpreter to tex

10525

% r262 localize run timer (John Buck 1/17/19)

10869

% r262 localize run timer (John Buck 1/17/19)

10526

% r262 set db as internal function in force to avoid tool box

10870

% r262 set db as internal function in force to avoid tool box

10527

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10871

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10528

% r263 added to output_args RL structure and report "struct" in csv file

10872

% r263 added to output_args RL structure and report "struct" in csv file

10529

% r264 added EW estimate

10873

% r264 added EW estimate

10530

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10874

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10531

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10875

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10532

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10876

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10533

% r269 changed param.N_bmax to param.N_f

10877

% r269 changed param.N_bmax to param.N_f

10534

% r270 implement JingBo Li's and Howard Heck's floating tap method

10878

% r270 implement JingBo Li's and Howard Heck's floating tap method

10535

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10879

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10536

% r270 added c_0 and c_1 for CA in add_brd

10880

% r270 added c_0 and c_1 for CA in add_brd

10537

% r272 fixed version syntax problem in output_args RL report

10881

% r272 fixed version syntax problem in output_args RL report

10538

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10882

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10539

% r272 removed eye width report if doing a Rx calibration

10883

% r272 removed eye width report if doing a Rx calibration

10540

% r273 better alignment and control for ICN reporting

10884

% r273 better alignment and control for ICN reporting

10541

% r273 fixed PSXTK graph

10885

% r273 fixed PSXTK graph

10542

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10886

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10543

% r276 go back to reporting channel IL results (output_args.IL_dB_channel_only_at_Fnq) with board added read_s4p_files (as in r270)

10887

% r276 go back to reporting channel IL results (output_args.IL_dB_channel_only_at_Fnq) with board added read_s4p_files (as in r270)

10544

% r276 chdata(i).Aicn=param.a_icn_fext should have been chdata(i).Aicn=param.a_icn_next for the next selection. Since in most spec's they are the same there is little no impact in results

10888

% r276 chdata(i).Aicn=param.a_icn_fext should have been chdata(i).Aicn=param.a_icn_next for the next selection. Since in most spec's they are the same there is little no impact in results

10545

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10889

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10546

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10890

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10547

% r276 C_1 was instantiated as C_0. This was fixed

10891

% r276 C_1 was instantiated as C_0. This was fixed

10548

% r276 fixed rounding problem in reporting of loss at f_nq

10892

% r276 fixed rounding problem in reporting of loss at f_nq

10549

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10893

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10550

% r277 added nv for deterining steady state voltage for fitting compatibility

10894

% r277 added nv for deterining steady state voltage for fitting compatibility

10551

% r278 added b_min to support asymmetric bmax

10895

% r278 added b_min to support asymmetric bmax

10552

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10896

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10553

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10897

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10554

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10898

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10555

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10899

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10556

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10900

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10557

% r292 eq. 93A-19 and 93-20 code implementation bug when include .3by change% to fix edge rate equation 93A-46 (h_T). no effect if Rd=50 or IL > 5 dB

10901

% r292 eq. 93A-19 and 93-20 code implementation bug when include .3by change% to fix edge rate equation 93A-46 (h_T). no effect if Rd=50 or IL > 5 dB

10558

% r292 H_t implemented in s21_pkg

10902

% r292 H_t implemented in s21_pkg

10559

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10903

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10560

% r292 add GDC_MIN to optimize_FOM

10904

% r292 add GDC_MIN to optimize_FOM

10561

% r293 fix if ndfe-0 and ERL only and s2p issue

10905

% r293 fix if ndfe-0 and ERL only and s2p issue

10562

% r293a investigate the Tukey filtering

10906

% r293a investigate the Tukey filtering

10563

% r293a if fix if bmin is missing

10907

% r293a if fix if bmin is missing

10564

% r294 fix problems reading s2p files for ERL computation

10908

% r294 fix problems reading s2p files for ERL computation

10565

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10909

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10566

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10910

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10567

% r294 add gdc and gdc2 range limitations

10911

% r294 add gdc and gdc2 range limitations

10568

% r295 add VEC Pass threshold

10912

% r295 add VEC Pass threshold

10569

% r295 removed close force all. Tagged all figures with "COM"

10913

% r295 removed close force all. Tagged all figures with "COM"

10570

% r295 consolidated print in new function "end_display_control"

10914

% r295 consolidated print in new function "end_display_control"

10571

% r295 report pre/pmax for Txffe

10915

% r295 report pre/pmax for Txffe

10572

% r295 speed up test cases by not re-reading in s4p files

10916

% r295 speed up test cases by not re-reading in s4p files

10573

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10917

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10574

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10918

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10575

% r310 refine VEC and EH for C2M from Adam Gregory in

10919

% r310 refine VEC and EH for C2M from Adam Gregory in

10576

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10920

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10577

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10921

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10578

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10922

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10579

% r311 added RILN

10923

% r311 added RILN

10580

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10924

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10581

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10925

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10582

% r316 remove DC computation for RX Calibration loops

10926

% r316 remove DC computation for RX Calibration loops

10583

% r317 for SAVE_TD to include EQ and unEQ FIR

10927

% r317 for SAVE_TD to include EQ and unEQ FIR

10584

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10928

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10585

% r318 if min_VEO_test fails to find a solution the loop is restarted with min_VEO_test to near zero. Makes sure COM returns results

10929

% r318 if min_VEO_test fails to find a solution the loop is restarted with min_VEO_test to near zero. Makes sure COM returns results

10586

% r320 fixed RX_CALIBRATION which was broken in r310

10930

% r320 fixed RX_CALIBRATION which was broken in r310

10587

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10931

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10588

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10932

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10589

% r320 removed external feature and replace with TDMODE

10933

% r320 removed external feature and replace with TDMODE

10590

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10934

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10591

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10935

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10592

% r335 fixed typo in when processing the bessel thompson filter option

10936

% r335 fixed typo in when processing the bessel thompson filter option

10593

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10937

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10594

% r335 compute and report CD_CM_RMS

10938

% r335 compute and report CD_CM_RMS

10595

% r335 fixed where output_arg is save i.e. move to end

10939

% r335 fixed where output_arg is save i.e. move to end

10596

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10940

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10597

% r335 change raw IL plot to not include boards

10941

% r335 change raw IL plot to not include boards

10598

% r335 set T_0 to zero if not C2M

10942

% r335 set T_0 to zero if not C2M

10599

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10943

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10600

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10944

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10601

% r335 TD_RILN changes from Hansel Dsilva

10945

% r335 TD_RILN changes from Hansel Dsilva

10602

% r335 Fixed sigma_N for RxFFE

10946

% r335 Fixed sigma_N for RxFFE

10603

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10947

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10604

% r335 added c(2) and C(3) back to read_ParamConfigFile

10948

% r335 added c(2) and C(3) back to read_ParamConfigFile

10605

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10949

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10606

% r335 corrected GDC_MIN per 0.3ck D2.3

10950

% r335 corrected GDC_MIN per 0.3ck D2.3

10607

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10951

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10608

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10952

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10609

% r370 speed up

10953

% r370 speed up

10610

% r370 fix for floating tap missing locations

10954

% r370 fix for floating tap missing locations

10611

% r370 variable Tx FFE taps

10955

% r370 variable Tx FFE taps

10612

% r370 package die load with ladder circuit

10956

% r370 package die load with ladder circuit

10613

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10957

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10614

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10958

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10615

% r380 added capabablity to enable a raised cosine Rx filter0

10959

% r380 added capabablity to enable a raised cosine Rx filter0

10616

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10960

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10617

% r380 added plot for VTF

10961

% r380 added plot for VTF

10618

% r385 added capability for additional Tx FFE per package

10962

% r385 added capability for additional Tx FFE per package

10619

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10963

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10620

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10964

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10621

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10965

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10622

% r389 Improvement by A. Ran for reporting loss at Nq

10966

% r389 Improvement by A. Ran for reporting loss at Nq

10623

% r389 Fixed typo: changed VIM to VMP

10967

% r389 Fixed typo: changed VIM to VMP

10624

% r400 fixed PR with zero pad extension

10968

% r400 fixed PR with zero pad extension

10625

% r400 keyword MLSE and SNRADJ_EQUA for future work

10969

% r400 keyword MLSE and SNRADJ_EQUA for future work

10626

% r400 replaced function db with instances of 20*log10(abs(...))

10970

% r400 replaced function db with instances of 20*log10(abs(...))

10627

% r410 widen voltage distriution for normal_dist doubled max Q

10971

% r410 widen voltage distriution for normal_dist doubled max Q

10628

% r410 improve reading in of config files

10972

% r410 improve reading in of config files

10629

% r410 renormalize s-parameter if not 50 ohm ref

10973

% r410 renormalize s-parameter if not 50 ohm ref

10630

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10974

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10631

% r410 remove RL from output_args bc not need and too much storage allocation

10975

% r410 remove RL from output_args bc not need and too much storage allocation

10632

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10976

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10633

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10977

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10634

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10978

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10635

% r420 updade force to account for pulse responces with short delays in force

10979

% r420 updade force to account for pulse responces with short delays in force

10636

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10980

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10637

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10981

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10638

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10982

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10639

% r420 Wiener-Kofp MMSE optimization for RxFFE

10983

% r420 Wiener-Kofp MMSE optimization for RxFFE

10640

% r430 first pass at healey_3dj_01_2401

10984

% r430 first pass at healey_3dj_01_2401

10641

% r430 RxFFE fixed taps

10985

% r430 RxFFE fixed taps

10642

% r440 RxffE fixed tap index corrections and floating taps

10986

% r440 RxffE fixed tap index corrections and floating taps

10643

% r440 first pass implemenation of MLSE U3

10987

% r440 first pass implemenation of MLSE U3

10644

% r450 fix MLSE_FOM typos, sigma_e,and FOM.

10988

% r450 fix MLSE_FOM typos, sigma_e,and FOM.

10645

% r450 incude Hisi in PSD in get_PSDs

10989

% r450 incude Hisi in PSD in get_PSDs

10646

% r460 is working out reporting bug from RxFFE and package A,B invocations

10990

% r460 is working out reporting bug from RxFFE and package A,B invocations

10647

% r460 align package config Tx and Rx cases with selected casting 4p5_3

10991

% r460 align package config Tx and Rx cases with selected casting 4p5_3

10648

% r460 fix RxFFE floating taps display (indexing error) 4p5_4

10992

% r460 fix RxFFE floating taps display (indexing error) 4p5_4

10649

% r470 beta1 added MLSE truncation inclusion using N_tc

10650

% r470 beta1 add MLSE Q_budget_adj

10651

% r470 added parameter defaults to support multiple packages

10652

% r470 beta2 added MLSD proposal from healey_3dj_01_2409

10653

10993