File Comparison Report

C:\Users\richardm\OneDrive - Samtec\COM\COM\src\com_ieee8023_480beta3.m vs. C:\Users\richardm\OneDrive - Samtec\COM\COM\src\com_ieee8023_93a_480beta2.m

richardm

12-Feb-2025

Files

Left FileRight File
File namecom_ieee8023_480beta3com_ieee8023_93a_480beta2
File pathC:\Users\richardm\OneDrive - Samtec\COM\COM\srcC:\Users\richardm\OneDrive - Samtec\COM\COM\src
Last modified12-Feb-2025 12:53:0812-Feb-2025 10:49:18

Environment

MATLAB9.14 (R2023a)

Comparison Results

+

Insertion

Deletion

Modification
1

function results=com_ieee8023_(varargin)

1

function results=com_ieee8023_93a(varargin)

2

% This is NOT an official IEEE document.

2

% This is NOT an official IEEE document.

3

%% Implementation example of annex 93A and/or 178A IEEE Std 802.3

3

%% Implementation example of annex 93A IEEE Std 802.3

4

%% This the main calling program

4

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

5

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

5

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

6

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

6

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

7

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

7

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

8

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

8

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

9

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

9

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

10

% will ask for each of the files interactively.opupu

10

% will ask for each of the files interactively.opupu

11

%

11

%

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 which may be related to

14

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

13

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

15

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

14

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

16

% The original proposal for COM may be found at

15

% original proposal for COM may be found at

17

% 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

18

% from the following authors and affiliations in 2012.

17

% from the following authors and affiliations in 2012.

19

% Richard Mellitz, Intel Corporation

18

% Richard Mellitz, Intel Corporation

20

% Charles Moore, Avago Technologies

19

% Charles Moore, Avago Technologies

21

% Mike Dudek, QLogic Corporation

20

% Mike Dudek, QLogic Corporation

22

% Mike Peng Li, Altera Corporation

21

% Mike Peng Li, Altera Corporation

23

% Adee Ran, Intel Corporation

22

% Adee Ran, Intel Corporation

+23

%

24

% Some of the authors and Contributors:

25

% Adee Ran

26

% Richard Mellitz

27

% Yasuo Hidaka

28

% John Ewen

29

% Bill Kirkland

30

% Adam Gregory

31

% Howard Heck

32

% Jingbo Li

33

% Adam Healey

34

% Matt Brown

35

% Sameh Elnagar

36

% Hossein Shakiba

24

zzz_list_of_changes()

37

zzz_list_of_changes()

25

38

26

%% Opening Preface

39

%% Opening Preface

27

% 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

28

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

41

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

29

try % version number at end of call string

42

try % version number at end of call string

30

cmdfile=mfilename;

43

cmdfile=mfilename;

31

hindx=strfind(mfilename,'_');

44

hindx=strfind(mfilename,'_');

32

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

45

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

33

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

46

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

34

catch

47

catch

35

output_args.code_revision ='';

48

output_args.code_revision ='';

36

end

49

end

37

teststr='';

50

teststr='';

38

OP.TESTING=0;

51

OP.TESTING=0;

39

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

52

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

40

teststr='testing';

53

teststr='testing';

41

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

42

htest = msgbox(testmsg);

55

htest = msgbox(testmsg);

43

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

56

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

44

end

57

end

45

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

58

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

46

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

59

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

47

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

60

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

48

t0=tic;

61

t0=tic;

49

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

62

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

50

% reset to tex on exit

63

% reset to tex on exit

51

%% file_setup

64

%% file_setup

52

%%

65

%%

53

% need to see what happens for version 8

66

% need to see what happens for version 8

54

if verLessThan('matlab', '7.4.1')

67

if verLessThan('matlab', '7.4.1')

55

error('Matlab version 7.4 or higher required')

68

error('Matlab version 7.4 or higher required')

56

end

69

end

57

70

58

results=[];

71

results=[];

59

72

60

%% New Command Line parser

73

%% New Command Line parser

61

[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{:});

62

75

63

76

64

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

77

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

65

if isempty(config_file)

78

if isempty(config_file)

66

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

79

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

67

if isempty(config_file)

80

if isempty(config_file)

68

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

69

else

82

else

70

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

83

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

71

config_file=[cname cext];

84

config_file=[cname cext];

72

end

85

end

73

if config_file==0

86

if config_file==0

74

% cancel - exit gracefully

87

% cancel - exit gracefully

75

return;

88

return;

76

end

89

end

77

config_file = fullfile(config_file_path, config_file);

90

config_file = fullfile(config_file_path, config_file);

78

end

91

end

79

output_args.config_file = config_file;

92

output_args.config_file = config_file;

80

OP.SAVE_KEYWORD_FILE=0;

93

OP.SAVE_KEYWORD_FILE=0;

81

if OP.SAVE_KEYWORD_FILE

94

if OP.SAVE_KEYWORD_FILE

82

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

95

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

83

delete('keyworklog.mat');

96

delete('keyworklog.mat');

84

end

97

end

85

end

98

end

86

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

99

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

87

if OP.CONFIG2MAT_ONLY

100

if OP.CONFIG2MAT_ONLY

88

return;

101

return;

89

end

102

end

90

if isempty(num_fext)

103

if isempty(num_fext)

91

if OP.RX_CALIBRATION

104

if OP.RX_CALIBRATION

92

num_fext=1;

105

num_fext=1;

93

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

94

else

107

else

95

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

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

96

num_fext=1;

109

num_fext=1;

97

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

98

elseif ~OP.ERL_ONLY

111

elseif ~OP.ERL_ONLY

99

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

100

else

113

else

101

num_fext=0;

114

num_fext=0;

102

end

115

end

103

end

116

end

104

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

117

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

105

end

118

end

106

if isempty(num_next)

119

if isempty(num_next)

107

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

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

108

num_next=0;

121

num_next=0;

109

else

122

else

110

if OP.RX_CALIBRATION

123

if OP.RX_CALIBRATION

111

num_next=0;

124

num_next=0;

112

elseif ~OP.ERL_ONLY

125

elseif ~OP.ERL_ONLY

113

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

114

else

127

else

115

num_next=0;

128

num_next=0;

116

end

129

end

117

end

130

end

118

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

131

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

119

end

132

end

120

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

133

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

121

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

134

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

122

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

135

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

123

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

136

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

124

param.num_next=num_next;

137

param.num_next=num_next;

125

param.num_fext=num_fext;

138

param.num_fext=num_fext;

126

param.num_s4p_files=num_fext+num_next+1;

139

param.num_s4p_files=num_fext+num_next+1;

127

% checking for data when running for rx compliance BBN calibration

140

% checking for data when running for rx compliance BBN calibration

128

if OP.RX_CALIBRATION == 1

141

if OP.RX_CALIBRATION == 1

129

if num_fext ~=1

142

if num_fext ~=1

130

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

131

movegui(h,'northwest')

144

movegui(h,'northwest')

132

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

133

if OP.DEBUG ~= 1

146

if OP.DEBUG ~= 1

134

return

147

return

135

end

148

end

136

end

149

end

137

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

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

138

movegui(h,'southeast')

151

movegui(h,'southeast')

139

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

140

end

153

end

141

154

142

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

155

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

143

if num_fext ~=1

156

if num_fext ~=1

144

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

145

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

146

movegui(h,'northwest')

159

movegui(h,'northwest')

147

if OP.DEBUG ~= 1

160

if OP.DEBUG ~= 1

148

return

161

return

149

end

162

end

150

end

163

end

151

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

152

movegui(h,'southeast')

165

movegui(h,'southeast')

153

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

154

end

167

end

155

168

156

169

157

% create result directory if needed

170

% create result directory if needed

158

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

171

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

159

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

172

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

160

% 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

161

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

162

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

175

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

163

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

176

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

164

%OP.EXTERNAL = true;

177

%OP.EXTERNAL = true;

165

%OP.GET_FD = 0;

178

%OP.GET_FD = 0;

166

%ir1a= varargin(2);

179

%ir1a= varargin(2);

167

%ex_var = varargin(3);

180

%ex_var = varargin(3);

168

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

169

else

182

else

170

if OP.TDMODE

183

if OP.TDMODE

171

OP.GET_FD=false;

184

OP.GET_FD=false;

172

end

185

end

173

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)

174

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

187

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

175

end

188

end

176

%% eveluate any extra arguments as possible modifications of parameters

189

%% eveluate any extra arguments as possible modifications of parameters

177

extra_args = varargin(xtk+2:end);

190

extra_args = varargin(xtk+2:end);

178

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

191

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

179

try

192

try

180

orig_value_is_str = 1;

193

orig_value_is_str = 1;

181

orig_value=eval(extra_args{k});

194

orig_value=eval(extra_args{k});

182

if ~ischar(orig_value)

195

if ~ischar(orig_value)

183

orig_value_is_str = 0;

196

orig_value_is_str = 0;

184

orig_value=mat2str(orig_value);

197

orig_value=mat2str(orig_value);

185

end

198

end

186

catch eval_err

199

catch eval_err

187

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

200

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

188

% trying to modify a nonexistent parameter - probably a

201

% trying to modify a nonexistent parameter - probably a

189

% typo. save the user from his error.

202

% typo. save the user from his error.

190

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

191

else

204

else

192

% unexpected condition

205

% unexpected condition

193

rethrow(eval_err);

206

rethrow(eval_err);

194

end

207

end

195

end

208

end

196

try

209

try

197

if orig_value_is_str

210

if orig_value_is_str

198

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

199

else

212

else

200

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

201

end

214

end

202

eval(mod_string);

215

eval(mod_string);

203

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

216

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

204

% begin yasuo patch 2/11/2018

217

% begin yasuo patch 2/11/2018

205

% output_args.(fname)=mod_string;

218

% output_args.(fname)=mod_string;

206

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

219

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

207

220

208

% re-patch yasuo 3/18/2019

221

% re-patch yasuo 3/18/2019

209

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

222

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

210

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

223

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

211

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

212

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

225

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

213

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

226

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

214

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

227

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

215

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

228

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

216

else

229

else

217

output_args.(fname)=mod_string;

230

output_args.(fname)=mod_string;

218

end

231

end

219

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

220

catch eval_err

233

catch eval_err

221

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

234

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

222

end

235

end

223

end

236

end

224

end

237

end

225

end

238

end

226

%% Parameters computationally defined by values from the settings files

239

%% Parameters computationally defined by values from the settings files

227

param.ui=1/param.fb;

240

param.ui=1/param.fb;

228

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

241

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

229

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

230

factor_3db=0.473037;

243

factor_3db=0.473037;

231

param.fb_BT_cutoff=factor_3db*param.f_r;

244

param.fb_BT_cutoff=factor_3db*param.f_r;

232

param.fb_BW_cutoff=param.f_r;

245

param.fb_BW_cutoff=param.f_r;

233

param.Tx_rd_sel=1;

246

param.Tx_rd_sel=1;

234

param.Rx_rd_sel=2;

247

param.Rx_rd_sel=2;

235

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

248

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

236

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

249

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

237

end

250

end

238

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

251

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

239

param=parameter_size_adjustment(param,OP);

252

param=parameter_size_adjustment(param,OP);

240

253

241

%% get input models

254

%% get input models

242

param.FLAG.S2P=0;

255

param.FLAG.S2P=0;

243

if OP.TDMODE

256

if OP.TDMODE

244

OP.FIXTURE_CALIBRATION= 0;

257

OP.FIXTURE_CALIBRATION= 0;

245

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

246

else

259

else

247

OP.FIXTURE_CALIBRATION= 0;

260

OP.FIXTURE_CALIBRATION= 0;

248

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

249

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

262

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

250

param.FLAG.S2P=1;

263

param.FLAG.S2P=1;

251

end

264

end

252

end

265

end

253

266

254

OP.SAVE_CMD_STR=1;

267

OP.SAVE_CMD_STR=1;

255

if OP.SAVE_CMD_STR

268

if OP.SAVE_CMD_STR

256

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

257

setappdata(0,'cmd_str',cmd_str);

270

setappdata(0,'cmd_str',cmd_str);

258

end

271

end

259

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

260

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

273

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

261

COM = inf;

274

COM = inf;

262

min_COM=inf; % reset COM prior to calibration

275

min_COM=inf; % reset COM prior to calibration

263

% min_VEO = inf;

276

% min_VEO = inf;

264

min_VEO_mV = inf;

277

min_VEO_mV = inf;

265

max_VEC_dB = -inf;

278

max_VEC_dB = -inf;

266

threshold_DER=inf;

279

threshold_DER=inf;

267

% begin yasuo patch 3/18/2019

280

% begin yasuo patch 3/18/2019

268

threshold_DER_max = 0; % reset worst DER

281

threshold_DER_max = 0; % reset worst DER

269

% end yasuo patch

282

% end yasuo patch

270

sigma_bn=0;

283

sigma_bn=0;

271

DO_ONCE=true;

284

DO_ONCE=true;

272

low_COM_found = 0;

285

low_COM_found = 0;

273

% 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

274

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

287

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

275

if ~DO_ONCE

288

if ~DO_ONCE

276

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)

277

break;

290

break;

278

elseif min_COM > param.pass_threshold

291

elseif min_COM > param.pass_threshold

279

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

280

if low_COM_found

293

if low_COM_found

281

if OP.sigma_bn_STEP>0 % previous increase too small

294

if OP.sigma_bn_STEP>0 % previous increase too small

282

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

295

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

283

else % previously decrease too large

296

else % previously decrease too large

284

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

285

end

298

end

286

end

299

end

287

else % binary searchparam.Pkg_len_TX

300

else % binary searchparam.Pkg_len_TX

288

low_COM_found=1;

301

low_COM_found=1;

289

if OP.sigma_bn_STEP>0 % previous increase too large

302

if OP.sigma_bn_STEP>0 % previous increase too large

290

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

291

else % previously decrease too small

304

else % previously decrease too small

292

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

305

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

293

end

306

end

294

end

307

end

295

min_COM = inf; % ignore previous iterations

308

min_COM = inf; % ignore previous iterations

296

min_VEO_mV = inf;

309

min_VEO_mV = inf;

297

max_VEC_dB = -inf;

310

max_VEC_dB = -inf;

298

sigma_bn = sigma_bn + OP.sigma_bn_STEP;

311

sigma_bn = sigma_bn + OP.sigma_bn_STEP;

299

end

312

end

300

msgctr=1;

313

msgctr=1;

301

for package_testcase_i = 1:length(OP.pkg_len_select)

314

for package_testcase_i = 1:length(OP.pkg_len_select)

302

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

315

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

303

package_testcase=OP.pkg_len_select(package_testcase_i);

316

package_testcase=OP.pkg_len_select(package_testcase_i);

304

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

317

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

305

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

318

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

306

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

319

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

307

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

320

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

308

param.AC_CM_RMS_TX= param.AC_CM_RMS(package_testcase);

321

param.AC_CM_RMS_TX= param.AC_CM_RMS(package_testcase);

309

if param.PKG_Tx_FFE_preset ~=0

322

if param.PKG_Tx_FFE_preset ~=0

310

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

323

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

311

else

324

else

312

param.Pkg_TXFFE_preset=0;

325

param.Pkg_TXFFE_preset=0;

313

end

326

end

314

% ki=package_testcase;

327

% ki=package_testcase;

315

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

316

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

329

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

317

param.Pkg_Zc= param.pkg_Z_c;

330

param.Pkg_Zc= param.pkg_Z_c;

318

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

331

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

319

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

332

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

320

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

333

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

321

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

334

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

322

end

335

end

323

param.package_testcase_i = package_testcase_i;

336

param.package_testcase_i = package_testcase_i;

324

337

325

%% Fill in chdata

338

%% Fill in chdata

326

if OP.TDMODE

339

if OP.TDMODE

327

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

340

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

328

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

341

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

329

else

342

else

330

%fill in chada with s-parameters

343

%fill in chada with s-parameters

331

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

344

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

332

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

345

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

333

end

346

end

334

if OP.BREAD_CRUMBS

347

if OP.BREAD_CRUMBS

335

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

336

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

337

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

338

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

339

end

352

end

340

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

341

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

342

end

355

end

343

end

356

end

344

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

357

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

345

358

346

%% Process TDR & ERL

359

%% Process TDR & ERL

347

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

348

if OP.ERL_ONLY

361

if OP.ERL_ONLY

349

results = cell(1);

362

results = cell(1);

350

results{1} = output_args;

363

results{1} = output_args;

351

rt=toc(t0);

364

rt=toc(t0);

352

output_args.rtmin=rt/60;

365

output_args.rtmin=rt/60;

353

if 1

366

if 1

354

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

367

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

355

end

368

end

356

if OP.CSV_REPORT ==1

369

if OP.CSV_REPORT ==1

357

Write_CSV(output_args,CSV_FILE);

370

Write_CSV(output_args,CSV_FILE);

358

end

371

end

359

break;

372

break;

360

end

373

end

361

374

362

%% FD processing s-parameter

375

%% FD processing s-parameter

363

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

376

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

364

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

377

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

365

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

378

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

366

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

379

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

367

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

380

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

368

%most operations now wrapped into FD_Processing function

381

%most operations now wrapped into FD_Processing function

369

param.number_of_s4p_files=length(chdata);

382

param.number_of_s4p_files=length(chdata);

370

%ICN=0;

383

%ICN=0;

371

output_args.ICN_mV=0;

384

output_args.ICN_mV=0;

372

output_args.MDNEXT_ICN_92_46_mV=0;

385

output_args.MDNEXT_ICN_92_46_mV=0;

373

output_args.MDFEXT_ICN_92_47_mV=0;

386

output_args.MDFEXT_ICN_92_47_mV=0;

374

if OP.WC_PORTZ

387

if OP.WC_PORTZ

375

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

388

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

376

else

389

else

377

param.SNR_TX=param.SNDR(package_testcase);

390

param.SNR_TX=param.SNDR(package_testcase);

378

end

391

end

379

392

380

%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

381

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

382

395

383

%% Convert from Frequency Domain to Time Domain

396

%% Convert from Frequency Domain to Time Domain

384

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

397

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

385

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

398

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

386

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

399

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

387

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

400

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

388

if DO_ONCE

401

if DO_ONCE

389

if ~OP.TDMODE

402

if ~OP.TDMODE

390

chdata=COM_FD_to_TD(chdata,param,OP);

403

chdata=COM_FD_to_TD(chdata,param,OP);

391

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;

392

output_args.SCMR_dB=chdata(1).SCMR;

405

output_args.SCMR_dB=chdata(1).SCMR;

393

end

406

end

394

end

407

end

395

408

396

%% Determine equalization settings

409

%% Determine equalization settings

397

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

410

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

398

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

411

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

399

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

412

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

400

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

413

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

401

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

414

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

402

do_C2M=0;

415

do_C2M=0;

403

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

416

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

404

do_C2M=1;

417

do_C2M=1;

405

end

418

end

406

OP.COMPUTE_COM=false;

419

OP.COMPUTE_COM=false;

407

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

420

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

408

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

421

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

409

OP.COMPUTE_COM=true;

422

OP.COMPUTE_COM=true;

410

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

423

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

411

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

424

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

412

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

425

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

413

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

426

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

414

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

427

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

415

428

416

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

417

param.use_bmax=fom_result.best_bmax.';

430

param.use_bmax=fom_result.best_bmax.';

418

%AJG021820

431

%AJG021820

419

param.use_bmin=fom_result.best_bmin.';

432

param.use_bmin=fom_result.best_bmin.';

420

% 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

421

param.current_ffegain=fom_result.best_current_ffegain;

434

param.current_ffegain=fom_result.best_current_ffegain;

422

if OP.force_pdf_bin_size

435

if OP.force_pdf_bin_size

423

param.delta_y = OP.BinSize;

436

param.delta_y = OP.BinSize;

424

else

437

else

425

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

438

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

426

end

439

end

427

% 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

428

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

441

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

429

442

430

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

443

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

431

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

432

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

445

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

433

OP.WO_TXFFE=1;

446

OP.WO_TXFFE=1;

434

PSD_results.w=fom_result.RxFFE;

447

PSD_results.w=fom_result.RxFFE;

435

% 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

436

% well as CTLE (CTF) and tx FFE

449

% well as CTLE (CTF) and tx FFE

437

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

450

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

438

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

451

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

439

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

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

440

OP.WO_TXFFE=0;

453

OP.WO_TXFFE=0;

441

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

442

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

443

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

444

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

445

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

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

446

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

459

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

447

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

460

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

448

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

461

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

449

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

462

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

450

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

463

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

451

end

464

end

452

%% Create ISI PDF & Individual Crosstalk PDFs

465

%% Create ISI PDF & Individual Crosstalk PDFs

453

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

466

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

454

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

467

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

455

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

468

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

456

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

469

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

457

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

470

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

458

for i=1:param.number_of_s4p_files

471

for i=1:param.number_of_s4p_files

459

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

472

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

460

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

473

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

461

474

462

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

463

else

476

else

464

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

465

end

478

end

466

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

479

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

467

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

480

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

468

subplot(2,1,2);

481

subplot(2,1,2);

469

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

482

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

470

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

483

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

471

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

484

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

472

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

485

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

473

hold on; title('PDF')

486

hold on; title('PDF')

474

recolor_plots(gca);

487

recolor_plots(gca);

475

end

488

end

476

chdata(i).pdfr=pdf;

489

chdata(i).pdfr=pdf;

477

% reporting

490

% reporting

478

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

491

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

479

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

492

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

480

493

481

end

494

end

482

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

495

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

483

496

484

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

497

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

485

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

498

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

486

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

499

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

487

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

500

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

488

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

501

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

489

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

502

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

490

combined_interference_and_noise_pdf=PDF;

503

combined_interference_and_noise_pdf=PDF;

491

combined_interference_and_noise_cdf=CDF;

504

combined_interference_and_noise_cdf=CDF;

492

505

493

506

494

%% Calculate COM and other associated outputs

507

%% Calculate COM and other associated outputs

495

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

508

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

496

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

509

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

497

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

510

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

498

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

511

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

499

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

512

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

500

% that satisfies the relationship P(y0) = DER_0

513

% that satisfies the relationship P(y0) = DER_0

501

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

514

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

502

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

515

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

503

516

504

% begin yasuo patch 3/18/2019

517

% begin yasuo patch 3/18/2019

505

% estimate DER at threshold COM

518

% estimate DER at threshold COM

506

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

519

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

507

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

520

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

508

threshold_DER_max = max(threshold_DER_max, threshold_DER);

521

threshold_DER_max = max(threshold_DER_max, threshold_DER);

509

% end yasuo patch

522

% end yasuo patch

510

523

511

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

524

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

512

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

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

513

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

526

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

514

if OP.DISPLAY_WINDOW && OP.DEBUG

527

if OP.DISPLAY_WINDOW && OP.DEBUG

515

figure_name = 'Eye at DER0 estimate';

528

figure_name = 'Eye at DER0 estimate';

516

fig=findobj('Name', figure_name);

529

fig=findobj('Name', figure_name);

517

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

530

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

518

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

531

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

519

movegui(fig,'southwest')

532

movegui(fig,'southwest')

520

plot(eye_contour)

533

plot(eye_contour)

521

xlabel('UI %')

534

xlabel('UI %')

522

ylabel('V')

535

ylabel('V')

523

end

536

end

524

537

525

else

538

else

526

EW_UI=0;

539

EW_UI=0;

527

eye_contour=[];

540

eye_contour=[];

528

end

541

end

529

if OP.MLSE==0

542

if OP.MLSE==0

530

if param.T_O ~=0

543

if param.T_O ~=0

531

eye_opening=EH_T_C2M-EH_B_C2M;

544

eye_opening=EH_T_C2M-EH_B_C2M;

532

A_ni=2*A_s-eye_opening;

545

A_ni=2*A_s-eye_opening;

533

%eq 124E-4

546

%eq 124E-4

534

vec_arg=2*A_s/eye_opening;

547

vec_arg=2*A_s/eye_opening;

535

if vec_arg<eps

548

if vec_arg<eps

536

vec_arg=eps;

549

vec_arg=eps;

537

end

550

end

538

VEC_dB = 20*log10(vec_arg);

551

VEC_dB = 20*log10(vec_arg);

539

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

552

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

540

VEO_mV=eye_opening*1000;

553

VEO_mV=eye_opening*1000;

541

min_COM = min(min_COM, COM);

554

min_COM = min(min_COM, COM);

542

min_VEO_mV = min(min_VEO_mV,VEO_mV);

555

min_VEO_mV = min(min_VEO_mV,VEO_mV);

543

max_VEC_dB = max(max_VEC_dB, VEC_dB);

556

max_VEC_dB = max(max_VEC_dB, VEC_dB);

544

else

557

else

545

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

558

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

546

vec_arg=(A_s-A_ni)/A_s;

559

vec_arg=(A_s-A_ni)/A_s;

547

if vec_arg<eps

560

if vec_arg<eps

548

vec_arg=eps;

561

vec_arg=eps;

549

end

562

end

550

VEC_dB = -20*log10(vec_arg);

563

VEC_dB = -20*log10(vec_arg);

551

COM=20*log10(A_s/A_ni);

564

COM=20*log10(A_s/A_ni);

552

min_COM = min(min_COM, COM);

565

min_COM = min(min_COM, COM);

553

min_VEO_mV = min(min_VEO_mV,VEO_mV);

566

min_VEO_mV = min(min_VEO_mV,VEO_mV);

554

max_VEC_dB = max(max_VEC_dB, VEC_dB);

567

max_VEC_dB = max(max_VEC_dB, VEC_dB);

555

end

568

end

556

MLSE_results=struct;

569

MLSE_results=struct;

557

else

570

else

558

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

571

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

559

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

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)

560

if param.T_O ~=0

573

if param.T_O ~=0

561

eye_opening=EH_T_C2M-EH_B_C2M;

574

eye_opening=EH_T_C2M-EH_B_C2M;

562

A_ni=2*A_s-eye_opening;

575

A_ni=2*A_s-eye_opening;

563

%eq 124E-4

576

%eq 124E-4

564

vec_arg=2*A_s/eye_opening;

577

vec_arg=2*A_s/eye_opening;

565

if vec_arg<eps

578

if vec_arg<eps

566

vec_arg=eps;

579

vec_arg=eps;

567

end

580

end

568

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

569

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

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;

570

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

583

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

571

COM=MLSE_results.COM;

584

COM=MLSE_results.COM;

572

VEO_mV=eye_opening*1000;

585

VEO_mV=eye_opening*1000;

573

min_COM = min(min_COM, COM);

586

min_COM = min(min_COM, COM);

574

min_VEO_mV = min(min_VEO_mV,VEO_mV);

587

min_VEO_mV = min(min_VEO_mV,VEO_mV);

575

max_VEC_dB = max(max_VEC_dB, VEC_dB);

588

max_VEC_dB = max(max_VEC_dB, VEC_dB);

576

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

589

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

577

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

590

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

578

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

591

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

579

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

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

580

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

593

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

581

COM_SNR_Struct.VEC_dB=VEC_dB;

594

COM_SNR_Struct.VEC_dB=VEC_dB;

582

else

595

else

583

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

596

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

584

vec_arg=(A_s-A_ni)/A_s;

597

vec_arg=(A_s-A_ni)/A_s;

585

if vec_arg<eps

598

if vec_arg<eps

586

vec_arg=eps;

599

vec_arg=eps;

587

end

600

end

588

VEC_dB_orig = -20*log10(vec_arg);

601

VEC_dB_orig = -20*log10(vec_arg);

589

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

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;

590

COM_orig=20*log10(A_s/A_ni);

603

COM_orig=20*log10(A_s/A_ni);

591

COM=MLSE_results.COM;

604

COM=MLSE_results.COM;

592

min_COM = min(min_COM, COM);

605

min_COM = min(min_COM, COM);

593

min_VEO_mV = min(min_VEO_mV,VEO_mV);

606

min_VEO_mV = min(min_VEO_mV,VEO_mV);

594

max_VEC_dB = max(max_VEC_dB, VEC_dB);

607

max_VEC_dB = max(max_VEC_dB, VEC_dB);

595

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

608

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

596

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

609

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

597

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

610

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

598

COM_SNR_Struct.VEC_dB=VEC_dB;

611

COM_SNR_Struct.VEC_dB=VEC_dB;

599

end

612

end

600

end

613

end

601

614

602

%% Create COM_SNR_Struct to hold the main COM outputs

615

%% Create COM_SNR_Struct to hold the main COM outputs

603

COM_SNR_Struct.A_s=A_s;

616

COM_SNR_Struct.A_s=A_s;

604

COM_SNR_Struct.A_ni=A_ni;

617

COM_SNR_Struct.A_ni=A_ni;

605

COM_SNR_Struct.threshold_DER=threshold_DER;

618

COM_SNR_Struct.threshold_DER=threshold_DER;

606

COM_SNR_Struct.EW_UI=EW_UI;

619

COM_SNR_Struct.EW_UI=EW_UI;

607

COM_SNR_Struct.COM=COM;

620

COM_SNR_Struct.COM=COM;

608

COM_SNR_Struct.VEC_dB=VEC_dB;

621

COM_SNR_Struct.VEC_dB=VEC_dB;

609

if OP.MLSE == 0

622

if OP.MLSE == 0

610

COM_SNR_Struct.COM_orig=[];

623

COM_SNR_Struct.COM_orig=[];

611

COM_SNR_Struct.VEC_dB_orig=[];

624

COM_SNR_Struct.VEC_dB_orig=[];

612

else

625

else

613

COM_SNR_Struct.COM_orig=COM_orig;

626

COM_SNR_Struct.COM_orig=COM_orig;

614

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

627

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

615

end

628

end

616

COM_SNR_Struct.VEO_mV=VEO_mV;

629

COM_SNR_Struct.VEO_mV=VEO_mV;

617

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;

618

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;

619

COM_SNR_Struct.eye_contour=eye_contour;

632

COM_SNR_Struct.eye_contour=eye_contour;

620

633

621

634

622

%% Save TD

635

%% Save TD

623

if OP.SAVE_TD

636

if OP.SAVE_TD

624

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

637

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

625

if ~OP.TDMODE

638

if ~OP.TDMODE

626

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

639

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

627

end

640

end

628

for i=1:param.number_of_s4p_files

641

for i=1:param.number_of_s4p_files

629

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

642

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

630

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

643

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

631

if ~OP.TDMODE

644

if ~OP.TDMODE

632

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

645

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

633

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

646

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

634

end

647

end

635

end

648

end

636

if OP.TDMODE

649

if OP.TDMODE

637

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

650

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

638

else

651

else

639

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

652

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

640

end

653

end

641

end

654

end

642

655

643

%% Bathtub/Contribution Plot

656

%% Bathtub/Contribution Plot

644

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

657

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

645

if OP.MLSE ~= 0

658

if OP.MLSE ~= 0

646

COM_SNR_Struct.combined_interference_and_noise_pdf=MLSE_results.PDF;

659

COM_SNR_Struct.combined_interference_and_noise_pdf=MLSE_results.PDF;

647

COM_SNR_Struct.combined_interference_and_noise_cdf=MLSE_results.CDF;

660

COM_SNR_Struct.combined_interference_and_noise_cdf=MLSE_results.CDF;

648

end

661

end

649

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

662

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

650

end

663

end

651

664

652

%% Msg management

665

%% Msg management

653

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

666

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

654

msg=[];

667

msg=[];

655

end

668

end

656

if OP.DEBUG

669

if OP.DEBUG

657

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

670

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

658

switch param.flex

671

switch param.flex

659

case 4

672

case 4

660

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

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

661

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

674

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

662

);

675

);

663

case 2

676

case 2

664

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

677

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

665

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

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

666

);

679

);

667

otherwise

680

otherwise

668

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

681

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

669

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

682

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

670

);

683

);

671

684

672

end

685

end

673

else

686

else

674

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

687

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

675

end

688

end

676

689

677

if OP.TDMODE

690

if OP.TDMODE

678

min_ERL=inf;

691

min_ERL=inf;

679

ERL=[inf inf];

692

ERL=[inf inf];

680

end

693

end

681

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

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

682

695

683

696

684

%% Output Args

697

%% Output Args

685

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

698

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

686

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

699

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

687

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

700

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

688

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

701

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

689

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

702

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

690

rt=toc(t0);

703

rt=toc(t0);

691

output_args.rtmin=rt/60;

704

output_args.rtmin=rt/60;

692

705

693

if OP.BREAD_CRUMBS

706

if OP.BREAD_CRUMBS

694

output_args.OP=OP;

707

output_args.OP=OP;

695

output_args.param=param;

708

output_args.param=param;

696

output_args.chdata=chdata;

709

output_args.chdata=chdata;

697

output_args.fom_result = fom_result;

710

output_args.fom_result = fom_result;

698

output_args.PDF=PDF; % for exploration

711

output_args.PDF=PDF; % for exploration

699

output_args.CDF=CDF; % for exploration

712

output_args.CDF=CDF; % for exploration

700

output_args.MLSE_results=MLSE_results;

713

output_args.MLSE_results=MLSE_results;

701

output_args.PSD_results=PSD_results;

714

output_args.PSD_results=PSD_results;

702

end

715

end

703

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

716

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

704

717

705

%% making csv file

718

%% making csv file

706

if OP.CSV_REPORT ==1

719

if OP.CSV_REPORT ==1

707

Write_CSV(output_args,CSV_FILE);

720

Write_CSV(output_args,CSV_FILE);

708

end

721

end

709

%% making mat file

722

%% making mat file

710

if(OP.DEBUG)

723

if(OP.DEBUG)

711

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

724

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

712

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

725

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

713

end

726

end

714

if 1

727

if 1

715

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

728

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

716

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

729

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

717

end

730

end

718

731

719

if nargout==0

732

if nargout==0

720

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

733

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

721

disp(output_args)

734

disp(output_args)

722

end

735

end

723

736

724

if OP.BREAD_CRUMBS

737

if OP.BREAD_CRUMBS

725

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

738

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

726

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

739

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

727

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

740

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

728

try

741

try

729

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

742

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

730

catch

743

catch

731

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

744

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

732

end

745

end

733

end

746

end

734

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

747

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

735

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

748

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

736

end

749

end

737

750

738

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

751

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

739

end

752

end

740

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

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

741

%%

754

%%

742

755

743

if OP.RX_CALIBRATION ==1

756

if OP.RX_CALIBRATION ==1

744

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

757

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

745

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

758

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

746

end

759

end

747

DO_ONCE=false;

760

DO_ONCE=false;

748

end

761

end

749

762

750

%% Final cleanup

763

%% Final cleanup

751

if OP.DISPLAY_WINDOW

764

if OP.DISPLAY_WINDOW

752

savefigs(param, OP);

765

savefigs(param, OP);

753

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

766

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

754

end

767

end

755

768

756

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

769

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

757

if ~param.f_hp==0

770

if ~param.f_hp==0

758

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

771

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

759

if OP.DISPLAY_WINDOW

772

if OP.DISPLAY_WINDOW

760

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

773

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

761

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

774

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

762

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

775

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

763

end

776

end

764

else

777

else

765

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

778

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

766

if OP.DISPLAY_WINDOW

779

if OP.DISPLAY_WINDOW

767

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

780

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

768

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

781

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

769

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

782

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

770

end

783

end

771

end

784

end

772

end

785

end

773

786

774

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

787

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

775

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

788

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

776

disp(redo_cmd_str);

789

disp(redo_cmd_str);

777

if isdeployed

790

if isdeployed

778

if OP.exit_if_deployed

791

if OP.exit_if_deployed

779

quit

792

quit

780

end

793

end

781

end

794

end

782

%%

795

%%

783

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

796

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

784

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

797

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

785

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

798

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

786

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

799

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

787

800

788

FB=param.fb;

801

FB=param.fb;

789

FZ=param.CTLE_fz(fom_result.ctle);

802

FZ=param.CTLE_fz(fom_result.ctle);

790

FP1=param.CTLE_fp1(fom_result.ctle);

803

FP1=param.CTLE_fp1(fom_result.ctle);

791

FP2=param.CTLE_fp2(fom_result.ctle);

804

FP2=param.CTLE_fp2(fom_result.ctle);

792

GDC=param.ctle_gdc_values(fom_result.ctle);

805

GDC=param.ctle_gdc_values(fom_result.ctle);

793

if ~isempty(param.f_HP)

806

if ~isempty(param.f_HP)

794

FHP=param.f_HP(fom_result.best_G_high_pass);

807

FHP=param.f_HP(fom_result.best_G_high_pass);

795

end

808

end

796

if ~isempty(param.g_DC_HP_values)

809

if ~isempty(param.g_DC_HP_values)

797

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

810

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

798

end

811

end

799

if ~isempty(param.f_HP_Z)

812

if ~isempty(param.f_HP_Z)

800

FHPZ=param.f_HP_Z(fom_result.ctle);

813

FHPZ=param.f_HP_Z(fom_result.ctle);

801

end

814

end

802

if ~isempty(param.f_HP_P)

815

if ~isempty(param.f_HP_P)

803

FHPP=param.f_HP_P(fom_result.ctle);

816

FHPP=param.f_HP_P(fom_result.ctle);

804

end

817

end

805

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

818

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

806

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

819

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

807

%length

820

%length

808

SBR_Len=length(fom_result.sbr);

821

SBR_Len=length(fom_result.sbr);

809

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

822

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

810

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

823

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

811

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

824

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

812

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

825

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

813

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

826

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

814

end

827

end

815

for i=1:param.number_of_s4p_files

828

for i=1:param.number_of_s4p_files

816

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

829

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

817

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

830

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

818

if OP.INCLUDE_CTLE==1

831

if OP.INCLUDE_CTLE==1

819

switch param.CTLE_type

832

switch param.CTLE_type

820

case 'CL93'

833

case 'CL93'

821

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

834

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

822

case 'CL120d'

835

case 'CL120d'

823

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

824

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

837

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

825

case 'CL120e' % z has been adjusted for gain

838

case 'CL120e' % z has been adjusted for gain

826

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

839

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

827

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

840

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

828

end

841

end

829

else

842

else

830

eq_ir=uneq_ir;

843

eq_ir=uneq_ir;

831

end

844

end

832

chdata(i).eq_imp_response=eq_ir;

845

chdata(i).eq_imp_response=eq_ir;

833

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

846

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

834

847

835

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

848

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

836

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

849

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

837

end

850

end

838

851

839

% Next 4 lines determine a pulse response required quantization,

852

% Next 4 lines determine a pulse response required quantization,

840

% at the CTLE output with Tx_ffe

853

% at the CTLE output with Tx_ffe

841

chdata(i).ctle_pulse = eq_pulse;

854

chdata(i).ctle_pulse = eq_pulse;

842

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

855

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

843

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

856

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

844

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

857

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

845

858

846

% chdata(i).ctle_imp_response

859

% chdata(i).ctle_imp_response

847

if OP.RxFFE

860

if OP.RxFFE

848

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

861

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

849

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

862

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

850

end

863

end

851

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

864

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

852

end

865

end

853

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

866

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

854

end

867

end

855

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

868

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

856

869

857

% display bathtub curves in one axis per test case.

870

% display bathtub curves in one axis per test case.

858

case_number=param.package_testcase_i;

871

case_number=param.package_testcase_i;

859

if ~OP.COM_CONTRIBUTION_CURVES

872

if ~OP.COM_CONTRIBUTION_CURVES

860

figure_name = 'Voltage bathtub curves';

873

figure_name = 'Voltage bathtub curves';

861

fig=findobj('Name', figure_name);

874

fig=findobj('Name', figure_name);

862

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

875

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

863

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

876

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

864

movegui(fig,'south')

877

movegui(fig,'south')

865

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

878

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

866

plot_bathtub_curves( hax ...

879

plot_bathtub_curves( hax ...

867

, COM_SNR_Struct.A_s ...

880

, COM_SNR_Struct.A_s ...

868

, Noise_Struct.sci_pdf ...

881

, Noise_Struct.sci_pdf ...

869

, Noise_Struct.cci_pdf ...

882

, Noise_Struct.cci_pdf ...

870

, Noise_Struct.isi_and_xtalk_pdf ...

883

, Noise_Struct.isi_and_xtalk_pdf ...

871

, Noise_Struct.noise_pdf ...

884

, Noise_Struct.noise_pdf ...

872

, Noise_Struct.jitt_pdf ...

885

, Noise_Struct.jitt_pdf ...

873

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

886

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

874

, param.delta_y ...

887

, param.delta_y ...

875

);

888

);

876

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

889

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

877

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

890

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

878

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

891

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

879

% show BER target line

892

% show BER target line

880

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

893

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

881

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

894

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

882

else

895

else

883

figure_name = 'COM Contributions (Rough Allocations)';

896

figure_name = 'COM Contributions (Rough Allocations)';

884

fig=findobj('Name', figure_name);

897

fig=findobj('Name', figure_name);

885

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

898

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

886

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

899

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

887

movegui(fig,'south')

900

movegui(fig,'south')

888

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

901

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

889

902

890

plot_pie_com( hax ...

903

plot_pie_com( hax ...

891

, COM_SNR_Struct.A_s ...

904

, COM_SNR_Struct.A_s ...

892

, Noise_Struct.sci_pdf ...

905

, Noise_Struct.sci_pdf ...

893

, Noise_Struct.cci_pdf ...

906

, Noise_Struct.cci_pdf ...

894

, Noise_Struct.isi_and_xtalk_pdf ...

907

, Noise_Struct.isi_and_xtalk_pdf ...

895

, Noise_Struct.noise_pdf ...

908

, Noise_Struct.noise_pdf ...

896

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

909

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

897

, param.delta_y, param...

910

, param.delta_y, param...

898

);

911

);

899

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

912

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

900

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

913

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

901

end

914

end

902

915

903

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

916

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

904

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

917

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

905

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

918

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

906

end

919

end

907

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

920

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

908

921

909

if use_BT

922

if use_BT

910

a = bessel( param.BTorder );

923

a = bessel( param.BTorder );

911

acoef=fliplr( a );

924

acoef=fliplr( a );

912

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

925

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

913

else

926

else

914

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

927

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

915

end

928

end

916

929

917

930

918

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

931

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

919

932

920

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

933

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

921

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

934

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

922

%All subsequent lines are field names in chdata

935

%All subsequent lines are field names in chdata

923

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

936

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

924

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

937

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

925

%

938

%

926

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

939

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

927

%#reduce

940

%#reduce

928

%sdd12_raw

941

%sdd12_raw

929

%sdd21_raw

942

%sdd21_raw

930

%sdd22_raw

943

%sdd22_raw

931

%sdd11_raw

944

%sdd11_raw

932

%

945

%

933

946

934

fid=fopen(fields_file,'r');

947

fid=fopen(fields_file,'r');

935

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

948

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

936

949

937

file_data=file_data{1};

950

file_data=file_data{1};

938

fclose(fid);

951

fclose(fid);

939

952

940

%remove blank lines

953

%remove blank lines

941

L=cellfun('length',file_data);

954

L=cellfun('length',file_data);

942

file_data=file_data(L~=0);

955

file_data=file_data(L~=0);

943

956

944

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

957

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

945

type=file_data{1};

958

type=file_data{1};

946

field_names=file_data(2:end);

959

field_names=file_data(2:end);

947

switch lower(type)

960

switch lower(type)

948

case '#reduce'

961

case '#reduce'

949

remove_fields=field_names;

962

remove_fields=field_names;

950

case '#include'

963

case '#include'

951

all_fields=fieldnames(chdata);

964

all_fields=fieldnames(chdata);

952

remove_fields=setdiff(all_fields,field_names);

965

remove_fields=setdiff(all_fields,field_names);

953

otherwise

966

otherwise

954

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

967

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

955

end

968

end

956

969

957

%remove the "remove_fields" from chdata

970

%remove the "remove_fields" from chdata

958

for j=1:length(remove_fields)

971

for j=1:length(remove_fields)

959

this_field=remove_fields{j};

972

this_field=remove_fields{j};

960

if isfield(chdata,this_field)

973

if isfield(chdata,this_field)

961

chdata=rmfield(chdata,this_field);

974

chdata=rmfield(chdata,this_field);

962

end

975

end

963

end

976

end

964

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

977

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

965

978

966

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

979

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

967

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

980

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

968

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

981

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

969

982

970

A_s=COM_SNR_Struct.A_s;

983

A_s=COM_SNR_Struct.A_s;

971

% initialize loop with uncorrelated noise and BER

984

% initialize loop with uncorrelated noise and BER

972

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

985

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

973

986

974

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

987

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

975

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

988

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

976

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

989

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

977

% below target BER).

990

% below target BER).

978

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

991

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

979

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

992

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

980

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

993

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

981

if isempty(x_error_propagation)

994

if isempty(x_error_propagation)

982

p_error_propagation(1) = 1e-20;

995

p_error_propagation(1) = 1e-20;

983

else

996

else

984

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

997

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

985

end

998

end

986

999

987

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

1000

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

988

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

1001

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

989

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

1002

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

990

if OP.use_simple_EP_model

1003

if OP.use_simple_EP_model

991

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

1004

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

992

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

1005

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

993

else

1006

else

994

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

1007

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

995

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

1008

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

996

end

1009

end

997

1010

998

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

1011

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

999

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

1012

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

1000

if isempty(x_error_propagation)

1013

if isempty(x_error_propagation)

1001

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

1014

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

1002

else

1015

else

1003

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

1016

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

1004

end

1017

end

1005

end

1018

end

1006

1019

1007

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

1020

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

1008

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

1021

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

1009

% of this event by partial sum of the PDF.

1022

% of this event by partial sum of the PDF.

1010

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

1023

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

1011

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

1024

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

1012

1025

1013

% probability of bursts of different lengths

1026

% probability of bursts of different lengths

1014

p_burst = cumprod(p_error_propagation);

1027

p_burst = cumprod(p_error_propagation);

1015

function H_bw=Butterworth_Filter(param,f,use_BW)

1028

function H_bw=Butterworth_Filter(param,f,use_BW)

1016

1029

1017

if use_BW

1030

if use_BW

1018

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

1031

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

1019

else

1032

else

1020

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

1033

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

1021

end

1034

end

1022

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

1035

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

1023

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

1036

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

1024

CDF_ev=CDF(index);

1037

CDF_ev=CDF(index);

1025

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

1038

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

1026

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

1039

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

1027

if isempty(index)

1040

if isempty(index)

1028

CDF_inv_ev=PDF.x(end);

1041

CDF_inv_ev=PDF.x(end);

1029

else

1042

else

1030

CDF_inv_ev=PDF.x(index);

1043

CDF_inv_ev=PDF.x(index);

1031

end

1044

end

1032

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

1045

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

1033

1046

1034

1047

1035

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

1048

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

1036

Remember_keyword='Legacy';

1049

Remember_keyword='Legacy';

1037

OP.TDMODE=false;

1050

OP.TDMODE=false;

1038

OP.GET_FD=true;

1051

OP.GET_FD=true;

1039

OP.CONFIG2MAT_ONLY=false;

1052

OP.CONFIG2MAT_ONLY=false;

1040

config_file='';

1053

config_file='';

1041

num_fext=[];

1054

num_fext=[];

1042

num_next=[];

1055

num_next=[];

1043

if ~isempty(varargin)

1056

if ~isempty(varargin)

1044

if ~ischar(varargin{1})

1057

if ~ischar(varargin{1})

1045

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

1058

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

1046

end

1059

end

1047

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

1060

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

1048

if isempty(keyword_idx)

1061

if isempty(keyword_idx)

1049

%Legacy Mode

1062

%Legacy Mode

1050

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

1063

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

1051

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

1064

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

1052

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

1065

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

1053

else

1066

else

1054

%Keyword Mode

1067

%Keyword Mode

1055

my_keyword=varargin{1};

1068

my_keyword=varargin{1};

1056

Remember_keyword=my_keyword;

1069

Remember_keyword=my_keyword;

1057

varargin(1)=[];

1070

varargin(1)=[];

1058

switch my_keyword

1071

switch my_keyword

1059

1072

1060

case 'Legacy'

1073

case 'Legacy'

1061

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

1074

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

1062

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

1075

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

1063

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

1076

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

1064

case 'TD'

1077

case 'TD'

1065

OP.TDMODE=true;

1078

OP.TDMODE=true;

1066

OP.GET_FD=false;

1079

OP.GET_FD=false;

1067

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

1080

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

1068

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

1081

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

1069

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

1082

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

1070

case 'Config2Mat'

1083

case 'Config2Mat'

1071

OP.CONFIG2MAT_ONLY=true;

1084

OP.CONFIG2MAT_ONLY=true;

1072

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

1085

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

1073

end

1086

end

1074

end

1087

end

1075

end

1088

end

1076

function chdata=COM_FD_to_TD(chdata,param,OP)

1089

function chdata=COM_FD_to_TD(chdata,param,OP)

1077

1090

1078

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

1091

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

1079

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

1092

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

1080

case_number=param.package_testcase_i;

1093

case_number=param.package_testcase_i;

1081

for i=1:param.number_of_s4p_files

1094

for i=1:param.number_of_s4p_files

1082

% RIM 2-01-2023 moved to FD_Processing

1095

% RIM 2-01-2023 moved to FD_Processing

1083

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1096

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1084

% % Equation 93A-20 %%

1097

% % Equation 93A-20 %%

1085

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

1098

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

1086

% f=chdata(i).faxis;

1099

% f=chdata(i).faxis;

1087

% %

1100

% %

1088

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

1101

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

1089

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

1102

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

1090

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

1103

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

1091

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

1104

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

1092

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

1105

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

1093

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

1106

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

1094

% if OP.DISPLAY_WINDOW

1107

% if OP.DISPLAY_WINDOW

1095

% if i==1

1108

% if i==1

1096

% figure(300+param.package_testcase_i);

1109

% figure(300+param.package_testcase_i);

1097

% subplot(3,1,1)

1110

% subplot(3,1,1)

1098

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

1111

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

1099

% try

1112

% try

1100

% legend('NumColumns',2)

1113

% legend('NumColumns',2)

1101

% legend('location','south')

1114

% legend('location','south')

1102

% catch

1115

% catch

1103

% end

1116

% end

1104

% end

1117

% end

1105

% end

1118

% end

1106

% end

1119

% end

1107

[chdata(i).uneq_imp_response, ...

1120

[chdata(i).uneq_imp_response, ...

1108

chdata(i).t, ...

1121

chdata(i).t, ...

1109

chdata(i).causality_correction_dB, ...

1122

chdata(i).causality_correction_dB, ...

1110

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

1123

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

1111

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

1124

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

1112

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

1125

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

1113

[chdata(i).uneq_CD_imp_response, ...

1126

[chdata(i).uneq_CD_imp_response, ...

1114

chdata(i).t_DC, ...

1127

chdata(i).t_DC, ...

1115

chdata(i).causality_correction_DC_dB, ...

1128

chdata(i).causality_correction_DC_dB, ...

1116

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

1129

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

1117

end

1130

end

1118

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

1131

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

1119

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

1132

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

1120

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

1133

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

1121

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

1134

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

1122

1135

1123

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

1136

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

1124

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

1137

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

1125

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

1138

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

1126

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

1139

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

1127

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

1140

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

1128

rss=-inf;

1141

rss=-inf;

1129

for im=1:param.samples_per_ui

1142

for im=1:param.samples_per_ui

1130

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

1143

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

1131

end

1144

end

1132

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

1145

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

1133

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

1146

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

1134

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

1147

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

1135

end

1148

end

1136

if OP.DEBUG && OP.DISPLAY_WINDOW

1149

if OP.DEBUG && OP.DISPLAY_WINDOW

1137

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1150

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1138

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

1151

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

1139

screen_size=get(0,'ScreenSize');

1152

screen_size=get(0,'ScreenSize');

1140

pos = get(gcf, 'OuterPosition');

1153

pos = get(gcf, 'OuterPosition');

1141

set(gcf, 'OuterPosition', ...

1154

set(gcf, 'OuterPosition', ...

1142

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

1155

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

1143

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

1156

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

1144

%movegui(gcf,'northeast')

1157

%movegui(gcf,'northeast')

1145

1158

1146

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

1159

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

1147

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

1160

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

1148

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

1161

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

1149

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

1162

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

1150

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

1163

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

1151

end

1164

end

1152

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

1165

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

1153

% scale. thru is shown in another plot.

1166

% scale. thru is shown in another plot.

1154

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

1167

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

1155

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

1168

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

1156

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

1169

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

1157

end

1170

end

1158

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

1171

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

1159

ylabel('Volts')

1172

ylabel('Volts')

1160

xlabel('seconds')

1173

xlabel('seconds')

1161

1174

1162

recolor_plots(gca);

1175

recolor_plots(gca);

1163

else

1176

else

1164

if param.ndfe~=0

1177

if param.ndfe~=0

1165

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

1178

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

1166

end

1179

end

1167

end

1180

end

1168

1181

1169

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

1182

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

1170

if OP.ENFORCE_CAUSALITY

1183

if OP.ENFORCE_CAUSALITY

1171

fprintf('\n');

1184

fprintf('\n');

1172

else

1185

else

1173

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

1186

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

1174

end

1187

end

1175

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

1188

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

1176

1189

1177

end

1190

end

1178

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

1191

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

1179

1192

1180

1193

1181

debug_plot=0;

1194

debug_plot=0;

1182

1195

1183

1196

1184

samp_UI=param.samples_for_C2M;

1197

samp_UI=param.samples_for_C2M;

1185

half_UI=get_center_of_UI(samp_UI);

1198

half_UI=get_center_of_UI(samp_UI);

1186

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

1199

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

1187

start_sample=half_UI-T_O;

1200

start_sample=half_UI-T_O;

1188

end_sample=half_UI+T_O;

1201

end_sample=half_UI+T_O;

1189

1202

1190

1203

1191

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

1204

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

1192

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

1205

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

1193

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

1206

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

1194

if pdf_range_flag

1207

if pdf_range_flag

1195

pdf_range=[start_sample end_sample];

1208

pdf_range=[start_sample end_sample];

1196

else

1209

else

1197

pdf_range=[];

1210

pdf_range=[];

1198

end

1211

end

1199

1212

1200

%pdf_full is self ISI pdf for each sample point

1213

%pdf_full is self ISI pdf for each sample point

1201

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

1214

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

1202

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

1215

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

1203

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

1216

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

1204

1217

1205

1218

1206

1219

1207

if isempty(pdf_range)

1220

if isempty(pdf_range)

1208

pdf_range=1:samp_UI;

1221

pdf_range=1:samp_UI;

1209

else

1222

else

1210

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

1223

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

1211

end

1224

end

1212

1225

1213

%Test doing Level PDFs

1226

%Test doing Level PDFs

1214

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

1227

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

1215

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

1228

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

1216

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

1229

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

1217

1230

1218

%add signal vector into pdf

1231

%add signal vector into pdf

1219

for n=1:param.levels

1232

for n=1:param.levels

1220

pdf_full{n}=pdf_full_1;

1233

pdf_full{n}=pdf_full_1;

1221

for j=pdf_range

1234

for j=pdf_range

1222

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

1235

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

1223

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

1236

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

1224

end

1237

end

1225

end

1238

end

1226

1239

1227

1240

1228

% figure;

1241

% figure;

1229

% hold on;

1242

% hold on;

1230

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

1243

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

1231

%computed for every sample point

1244

%computed for every sample point

1232

for n=1:param.levels

1245

for n=1:param.levels

1233

for j=pdf_range

1246

for j=pdf_range

1234

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

1247

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

1235

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

1248

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

1236

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

1249

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

1237

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

1250

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

1238

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

1251

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

1239

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

1252

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

1240

% change from adam gregory to include crosstalk

1253

% change from adam gregory to include crosstalk

1241

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

1254

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

1242

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

1255

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

1243

1256

1244

%PDF to CDF

1257

%PDF to CDF

1245

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

1258

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

1246

1259

1247

end

1260

end

1248

end

1261

end

1249

%hold off;

1262

%hold off;

1250

1263

1251

1264

1252

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

1265

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

1253

for n=1:param.levels

1266

for n=1:param.levels

1254

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

1267

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

1255

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

1268

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

1256

for j=pdf_range

1269

for j=pdf_range

1257

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

1270

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

1258

end

1271

end

1259

end

1272

end

1260

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

1273

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

1261

1274

1262

for n=1:param.levels-1

1275

for n=1:param.levels-1

1263

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

1276

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

1264

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

1277

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

1265

end

1278

end

1266

1279

1267

1280

1268

for n=1:param.levels-1

1281

for n=1:param.levels-1

1269

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

1282

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

1270

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

1283

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

1271

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

1284

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

1272

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

1285

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

1273

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

1286

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

1274

EH=EH_top-EH_bot;

1287

EH=EH_top-EH_bot;

1275

vref=EH_top/2+EH_bot/2;

1288

vref=EH_top/2+EH_bot/2;

1276

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

1289

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

1277

%the top and bottom eye contours

1290

%the top and bottom eye contours

1278

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

1291

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

1279

end

1292

end

1280

1293

1281

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

1294

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

1282

eye_contour_tmp=eye_contour;

1295

eye_contour_tmp=eye_contour;

1283

eye_contour=[];

1296

eye_contour=[];

1284

for n=1:param.levels-1

1297

for n=1:param.levels-1

1285

eye_contour(:,(n-1)*2+1:n*2)=eye_contour_tmp{n};

1298

eye_contour(:,(n-1)*2+1:n*2)=eye_contour_tmp{n};

1286

end

1299

end

1287

1300

1288

1301

1289

%Find VEC eye height

1302

%Find VEC eye height

1290

out_VT=[];

1303

out_VT=[];

1291

out_VB=[];

1304

out_VB=[];

1292

if param.T_O ~=0

1305

if param.T_O ~=0

1293

1306

1294

switch lower(OP.Histogram_Window_Weight)

1307

switch lower(OP.Histogram_Window_Weight)

1295

case {'gaussian' 'norm' 'normal' 'guassian'}

1308

case {'gaussian' 'norm' 'normal' 'guassian'}

1296

%build a gaussian window of weights that are multiplied by each pdf in the T_O range

1309

%build a gaussian window of weights that are multiplied by each pdf in the T_O range

1297

%Sigma = T_O/QL. Default QL=2.5. This gives a nice descent to near 0 at the edge of the window

1310

%Sigma = T_O/QL. Default QL=2.5. This gives a nice descent to near 0 at the edge of the window

1298

QL_sigma=T_O/param.QL;

1311

QL_sigma=T_O/param.QL;

1299

weights=exp(-1/2 * ([-T_O:T_O]/QL_sigma).^2);

1312

weights=exp(-1/2 * ([-T_O:T_O]/QL_sigma).^2);

1300

case 'triangle'

1313

case 'triangle'

1301

%triangle window. linear slope from 0 to 1 and back down to 0

1314

%triangle window. linear slope from 0 to 1 and back down to 0

1302

%for the weights

1315

%for the weights

1303

t_slope=1/(T_O);

1316

t_slope=1/(T_O);

1304

weights=[0:t_slope:1 1-t_slope:-t_slope:0];

1317

weights=[0:t_slope:1 1-t_slope:-t_slope:0];

1305

case 'rectangle'

1318

case 'rectangle'

1306

%default = rectangle. all weights = 1

1319

%default = rectangle. all weights = 1

1307

weights(1:2*T_O+1)=1;

1320

weights(1:2*T_O+1)=1;

1308

case 'dual_rayleigh'

1321

case 'dual_rayleigh'

1309

QL_sigma=T_O/param.QL;

1322

QL_sigma=T_O/param.QL;

1310

X=-T_O:T_O;

1323

X=-T_O:T_O;

1311

weights=(X+T_O)/QL_sigma^2.*exp(-1/2 * ((X+T_O)/QL_sigma).^2)...

1324

weights=(X+T_O)/QL_sigma^2.*exp(-1/2 * ((X+T_O)/QL_sigma).^2)...

1312

-(X-T_O)/QL_sigma^2.*exp(-1/2 * ((X-T_O)/QL_sigma).^2);

1325

-(X-T_O)/QL_sigma^2.*exp(-1/2 * ((X-T_O)/QL_sigma).^2);

1313

weights=weights/max(weights);

1326

weights=weights/max(weights);

1314

otherwise

1327

otherwise

1315

error('%s not recognized for Histogram_Window_Weight',OP.Histogram_Window_Weight)

1328

error('%s not recognized for Histogram_Window_Weight',OP.Histogram_Window_Weight)

1316

end

1329

end

1317

1330

1318

for n=1:param.levels

1331

for n=1:param.levels

1319

out_pdf{n}=[];

1332

out_pdf{n}=[];

1320

for j=start_sample:end_sample

1333

for j=start_sample:end_sample

1321

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1334

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1322

target_pdf.y=target_pdf.y*weights(j-start_sample+1);

1335

target_pdf.y=target_pdf.y*weights(j-start_sample+1);

1323

if isempty(out_pdf{n})

1336

if isempty(out_pdf{n})

1324

out_pdf{n}=target_pdf;

1337

out_pdf{n}=target_pdf;

1325

else

1338

else

1326

out_pdf{n} = combine_pdf_same_voltage_axis(out_pdf{n}, target_pdf);

1339

out_pdf{n} = combine_pdf_same_voltage_axis(out_pdf{n}, target_pdf);

1327

end

1340

end

1328

end

1341

end

1329

out_pdf{n}.y=out_pdf{n}.y/sum(out_pdf{n}.y);

1342

out_pdf{n}.y=out_pdf{n}.y/sum(out_pdf{n}.y);

1330

end

1343

end

1331

1344

1332

for n=1:param.levels

1345

for n=1:param.levels

1333

out_cdf{n}=pdf_to_cdf(out_pdf{n});

1346

out_cdf{n}=pdf_to_cdf(out_pdf{n});

1334

end

1347

end

1335

1348

1336

for n=1:param.levels

1349

for n=1:param.levels

1337

[A_ni_top_O(n),A_ni_bottom_O(n)]=cdf_to_ber_contour(out_cdf{n},param.specBER);

1350

[A_ni_top_O(n),A_ni_bottom_O(n)]=cdf_to_ber_contour(out_cdf{n},param.specBER);

1338

end

1351

end

1339

1352

1340

for n=1:param.levels-1

1353

for n=1:param.levels-1

1341

OUT_VT_L(n,1)=A_ni_top_O(n+1);

1354

OUT_VT_L(n,1)=A_ni_top_O(n+1);

1342

OUT_VT_L(n,2)=A_ni_bottom_O(n);

1355

OUT_VT_L(n,2)=A_ni_bottom_O(n);

1343

end

1356

end

1344

1357

1345

%Report the top/bottom eye height of the worst eye

1358

%Report the top/bottom eye height of the worst eye

1346

EH_VT=OUT_VT_L(:,1)-OUT_VT_L(:,2);

1359

EH_VT=OUT_VT_L(:,1)-OUT_VT_L(:,2);

1347

[mineh,min_idx]=min(EH_VT);

1360

[mineh,min_idx]=min(EH_VT);

1348

out_VT=OUT_VT_L(min_idx,1);

1361

out_VT=OUT_VT_L(min_idx,1);

1349

out_VB=OUT_VT_L(min_idx,2);

1362

out_VB=OUT_VT_L(min_idx,2);

1350

1363

1351

% CDF_Mean=mean(A_s_vec(start_sample:end_sample));

1364

% CDF_Mean=mean(A_s_vec(start_sample:end_sample));

1352

% out_VT=2*CDF_Mean-A_ni_top_O;

1365

% out_VT=2*CDF_Mean-A_ni_top_O;

1353

% out_VB=-1*A_ni_bottom_O;

1366

% out_VB=-1*A_ni_bottom_O;

1354

1367

1355

if debug_plot

1368

if debug_plot

1356

figure;

1369

figure;

1357

hold on;

1370

hold on;

1358

for j=start_sample:end_sample

1371

for j=start_sample:end_sample

1359

plot(combined_interference_and_noise_pdf_full(j).x,combined_interference_and_noise_pdf_full(j).y);

1372

plot(combined_interference_and_noise_pdf_full(j).x,combined_interference_and_noise_pdf_full(j).y);

1360

end

1373

end

1361

plot(out_pdf.x,out_pdf.y,'color','k','LineWidth',2);

1374

plot(out_pdf.x,out_pdf.y,'color','k','LineWidth',2);

1362

hold off;

1375

hold off;

1363

end

1376

end

1364

end

1377

end

1365

1378

1366

1379

1367

1380

1368

1381

1369

function [PDF,CDF,NS]=Create_Noise_PDF(A_s,param,fom_result,chdata,OP,sigma_bn,PSD_results)

1382

function [PDF,CDF,NS]=Create_Noise_PDF(A_s,param,fom_result,chdata,OP,sigma_bn,PSD_results)

1370

1383

1371

%This block was originally in main COM function but was moved here for

1384

%This block was originally in main COM function but was moved here for

1372

%cleanup. It returns the combined interference and noise PDF & CDF as well

1385

%cleanup. It returns the combined interference and noise PDF & CDF as well

1373

%as a structure "NS" that contains all the noise parameters that are used

1386

%as a structure "NS" that contains all the noise parameters that are used

1374

%in other places in COM

1387

%in other places in COM

1375

1388

1376

if OP.RX_CALIBRATION

1389

if OP.RX_CALIBRATION

1377

ctle_gain2 = (10.^(param.ctle_gdc_values(fom_result.ctle)/20) + 1i*chdata(2).faxis/param.CTLE_fz(fom_result.ctle)) ./ ...

1390

ctle_gain2 = (10.^(param.ctle_gdc_values(fom_result.ctle)/20) + 1i*chdata(2).faxis/param.CTLE_fz(fom_result.ctle)) ./ ...

1378

((1+1i*chdata(2).faxis/param.CTLE_fp1(fom_result.ctle)).*(1+1i*chdata(2).faxis/param.CTLE_fp2(fom_result.ctle)));

1391

((1+1i*chdata(2).faxis/param.CTLE_fp1(fom_result.ctle)).*(1+1i*chdata(2).faxis/param.CTLE_fp2(fom_result.ctle)));

1379

switch param.CTLE_type

1392

switch param.CTLE_type

1380

case 'CL93'

1393

case 'CL93'

1381

H_low2=1;

1394

H_low2=1;

1382

case 'CL120d' % this clause uses two gain indexes

1395

case 'CL120d' % this clause uses two gain indexes

1383

H_low2=(10.^(param.g_DC_HP_values(fom_result.best_G_high_pass)/20) + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass))./(1 + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass));

1396

H_low2=(10.^(param.g_DC_HP_values(fom_result.best_G_high_pass)/20) + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass))./(1 + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass));

1384

case 'CL120e' % Z1 has been adjusted

1397

case 'CL120e' % Z1 has been adjusted

1385

H_low2=(1 + 1i*chdata(2).faxis/f_HP_P(fom_result.ctle))./(1 + 1i*chdata(2).faxis/f_HP_Z(fom_result.ctle));

1398

H_low2=(1 + 1i*chdata(2).faxis/f_HP_P(fom_result.ctle))./(1 + 1i*chdata(2).faxis/f_HP_Z(fom_result.ctle));

1386

end

1399

end

1387

H_ctf2=H_low2.*ctle_gain2;

1400

H_ctf2=H_low2.*ctle_gain2;

1388

[ sigma_ne, NS.sigma_hp] = get_sigma_noise( H_ctf2, param, chdata, sigma_bn );

1401

[ sigma_ne, NS.sigma_hp] = get_sigma_noise( H_ctf2, param, chdata, sigma_bn );

1389

else

1402

else

1390

sigma_ne=0;

1403

sigma_ne=0;

1391

end

1404

end

1392

1405

1393

NS.sigma_N = fom_result.sigma_N; % eta zero noise

1406

NS.sigma_N = fom_result.sigma_N; % eta zero noise

1394

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

1407

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

1395

if ~OP.SNR_TXwC0

1408

if ~OP.SNR_TXwC0

1396

% Equation 93A-30 %% h0(ts0)= A_s*R_lm/(L-1)

1409

% Equation 93A-30 %% h0(ts0)= A_s*R_lm/(L-1)

1397

NS.sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx and RLM

1410

NS.sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx and RLM

1398

else

1411

else

1399

NS.sigma_TX = (param.levels-1)*A_s/fom_result.txffe(fom_result.cur) /param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx from Adee

1412

NS.sigma_TX = (param.levels-1)*A_s/fom_result.txffe(fom_result.cur) /param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx from Adee

1400

end

1413

end

1401

NS.sigma_G = norm([param.sigma_RJ*param.sigma_X*norm(fom_result.h_J), NS.sigma_N, NS.sigma_TX]);

1414

NS.sigma_G = norm([param.sigma_RJ*param.sigma_X*norm(fom_result.h_J), NS.sigma_N, NS.sigma_TX]);

1402

NS.sigma_rjit= param.sigma_RJ*param.sigma_X*norm(fom_result.h_J);

1415

NS.sigma_rjit= param.sigma_RJ*param.sigma_X*norm(fom_result.h_J);

1403

else

1416

else

1404

NS.sigma_TX =PSD_results.S_tn_rms;

1417

NS.sigma_TX =PSD_results.S_tn_rms;

1405

NS.sigma_G = PSD_results.S_G_rms;

1418

NS.sigma_G = PSD_results.S_G_rms;

1406

NS.sigma_rjit=PSD_results.S_rj_rms ;

1419

NS.sigma_rjit=PSD_results.S_rj_rms ;

1407

NS.sigma_N=PSD_results.S_rn_rms ; % Commit request 4p4_8, healey_3dj_COM_01_240416

1420

NS.sigma_N=PSD_results.S_rn_rms ; % Commit request 4p4_8, healey_3dj_COM_01_240416

1408

end

1421

end

1409

% Equation 93A-41 %%

1422

% Equation 93A-41 %%

1410

1423

1411

1424

1412

% Equation 93A-42 %%

1425

% Equation 93A-42 %%

1413

% number of sigmas needed depends on the required BER.

1426

% number of sigmas needed depends on the required BER.

1414

if param.Noise_Crest_Factor == 0

1427

if param.Noise_Crest_Factor == 0

1415

NS.ber_q = sqrt(2)*erfcinv(2*param.specBER);

1428

NS.ber_q = sqrt(2)*erfcinv(2*param.specBER);

1416

else

1429

else

1417

NS.ber_q=param.Noise_Crest_Factor;

1430

NS.ber_q=param.Noise_Crest_Factor;

1418

end

1431

end

1419

NS.gaussian_noise_pdf = normal_dist(NS.sigma_G, NS.ber_q, param.delta_y);

1432

NS.gaussian_noise_pdf = normal_dist(NS.sigma_G, NS.ber_q, param.delta_y);

1420

% enable overriding the Q factor of the BBN instrument.

1433

% enable overriding the Q factor of the BBN instrument.

1421

if OP.force_BBN_Q_factor

1434

if OP.force_BBN_Q_factor

1422

NS.ne_noise_pdf = normal_dist(sigma_ne, OP.BBN_Q_factor, param.delta_y);

1435

NS.ne_noise_pdf = normal_dist(sigma_ne, OP.BBN_Q_factor, param.delta_y);

1423

else

1436

else

1424

NS.ne_noise_pdf = normal_dist(sigma_ne, NS.ber_q, param.delta_y);

1437

NS.ne_noise_pdf = normal_dist(sigma_ne, NS.ber_q, param.delta_y);

1425

end

1438

end

1426

NS.gaussian_noise_pdf = conv_fct(NS.gaussian_noise_pdf, NS.ne_noise_pdf);

1439

NS.gaussian_noise_pdf = conv_fct(NS.gaussian_noise_pdf, NS.ne_noise_pdf);

1427

1440

1428

% p_DD is computed using the procedure defined in 93A.1.7.1 with h(n)=A_DD*h_J(n)

1441

% p_DD is computed using the procedure defined in 93A.1.7.1 with h(n)=A_DD*h_J(n)

1429

NS.p_DD = get_pdf_from_sampled_signal(param.A_DD*fom_result.h_J, param.levels, param.delta_y);

1442

NS.p_DD = get_pdf_from_sampled_signal(param.A_DD*fom_result.h_J, param.levels, param.delta_y);

1430

1443

1431

% Equation 93A-43 % only used for reporting bathtub curves

1444

% Equation 93A-43 % only used for reporting bathtub curves

1432

NS.noise_pdf=conv_fct(NS.gaussian_noise_pdf, NS.p_DD);

1445

NS.noise_pdf=conv_fct(NS.gaussian_noise_pdf, NS.p_DD);

1433

gaussian_rjitt_pdf = normal_dist(NS.sigma_rjit, NS.ber_q, param.delta_y);

1446

gaussian_rjitt_pdf = normal_dist(NS.sigma_rjit, NS.ber_q, param.delta_y);

1434

NS.jitt_pdf=conv_fct(gaussian_rjitt_pdf, NS.p_DD);

1447

NS.jitt_pdf=conv_fct(gaussian_rjitt_pdf, NS.p_DD);

1435

1448

1436

% Implementation of 93A.1.7.3 combination procedure

1449

% Implementation of 93A.1.7.3 combination procedure

1437

% (effectively Equation 93A-44) %%

1450

% (effectively Equation 93A-44) %%

1438

1451

1439

% Self-Channel Interference is thru residual result

1452

% Self-Channel Interference is thru residual result

1440

NS.sci_pdf = chdata(1).pdfr;

1453

NS.sci_pdf = chdata(1).pdfr;

1441

sci_mxi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1454

sci_mxi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1442

NS.thru_peak_interference_at_BER=abs(NS.sci_pdf.x(sci_mxi));

1455

NS.thru_peak_interference_at_BER=abs(NS.sci_pdf.x(sci_mxi));

1443

sci_msi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1456

sci_msi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1444

NS.sci_sigma=abs(NS.sci_pdf.x(sci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1457

NS.sci_sigma=abs(NS.sci_pdf.x(sci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1445

if OP.RX_CALIBRATION ==0

1458

if OP.RX_CALIBRATION ==0

1446

% Co-Channel Interference PDFs (for information only):

1459

% Co-Channel Interference PDFs (for information only):

1447

% initialize to deltas

1460

% initialize to deltas

1448

MDNEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1461

MDNEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1449

MDFEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1462

MDFEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1450

% serially convolve FEXT/NEXT PDFs

1463

% serially convolve FEXT/NEXT PDFs

1451

for k=2:param.number_of_s4p_files

1464

for k=2:param.number_of_s4p_files

1452

if isequal(chdata(k).type, 'NEXT')

1465

if isequal(chdata(k).type, 'NEXT')

1453

MDNEXT_cci_pdf = conv_fct(MDNEXT_cci_pdf, chdata(k).pdfr);

1466

MDNEXT_cci_pdf = conv_fct(MDNEXT_cci_pdf, chdata(k).pdfr);

1454

else % ... must be FEXT

1467

else % ... must be FEXT

1455

MDFEXT_cci_pdf = conv_fct(MDFEXT_cci_pdf, chdata(k).pdfr);

1468

MDFEXT_cci_pdf = conv_fct(MDFEXT_cci_pdf, chdata(k).pdfr);

1456

end

1469

end

1457

end

1470

end

1458

1471

1459

% find "peaks" of MDNEXT/MDFEXT for reporting

1472

% find "peaks" of MDNEXT/MDFEXT for reporting

1460

mdnxi=find(cumsum(MDNEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1473

mdnxi=find(cumsum(MDNEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1461

NS.MDNEXT_peak_interference=abs(MDNEXT_cci_pdf.x(mdnxi));

1474

NS.MDNEXT_peak_interference=abs(MDNEXT_cci_pdf.x(mdnxi));

1462

mdfxi=find(cumsum(MDFEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1475

mdfxi=find(cumsum(MDFEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1463

NS.MDFEXT_peak_interference=abs(MDFEXT_cci_pdf.x(mdfxi));

1476

NS.MDFEXT_peak_interference=abs(MDFEXT_cci_pdf.x(mdfxi));

1464

1477

1465

% Combined crosstalk effect

1478

% Combined crosstalk effect

1466

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1479

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1467

cci_mxi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1480

cci_mxi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1468

cci_msi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1481

cci_msi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1469

NS.cci_sigma=abs(NS.cci_pdf.x(cci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1482

NS.cci_sigma=abs(NS.cci_pdf.x(cci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1470

NS.crosstalk_peak_interference_at_BER=abs(NS.cci_pdf.x(cci_mxi));

1483

NS.crosstalk_peak_interference_at_BER=abs(NS.cci_pdf.x(cci_mxi));

1471

% combine cci and sci

1484

% combine cci and sci

1472

NS.isi_and_xtalk_pdf = conv_fct(NS.sci_pdf, NS.cci_pdf);

1485

NS.isi_and_xtalk_pdf = conv_fct(NS.sci_pdf, NS.cci_pdf);

1473

else

1486

else

1474

% for calibration there is no cci

1487

% for calibration there is no cci

1475

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1488

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1476

end

1489

end

1477

1490

1478

mxi=find(cumsum(NS.isi_and_xtalk_pdf.y)>=param.specBER, 1, 'first');

1491

mxi=find(cumsum(NS.isi_and_xtalk_pdf.y)>=param.specBER, 1, 'first');

1479

NS.peak_interference_at_BER=abs(NS.isi_and_xtalk_pdf.x(mxi));

1492

NS.peak_interference_at_BER=abs(NS.isi_and_xtalk_pdf.x(mxi));

1480

1493

1481

1494

1482

% Equation 93A-45

1495

% Equation 93A-45

1483

combined_interference_and_noise_pdf = conv_fct(NS.isi_and_xtalk_pdf, NS.noise_pdf);

1496

combined_interference_and_noise_pdf = conv_fct(NS.isi_and_xtalk_pdf, NS.noise_pdf);

1484

1497

1485

%%

1498

%%

1486

% Equation 93A-37

1499

% Equation 93A-37

1487

if param.N_qb ~=0

1500

if param.ENOB ~=0

1488

[chdata,NS,combined_interference_and_noise_pdf] = adjust_Rx_noise_for_quantization(combined_interference_and_noise_pdf,NS, chdata,fom_result,param,OP);

1501

[chdata,NS,combined_interference_and_noise_pdf] = adjust_Rx_noise_for_quantization(combined_interference_and_noise_pdf,NS, chdata,fom_result,param,OP);

1489

end

1502

end

1490

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1503

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1491

CDF=combined_interference_and_noise_cdf;

1504

CDF=combined_interference_and_noise_cdf;

1492

PDF=combined_interference_and_noise_pdf;

1505

PDF=combined_interference_and_noise_pdf;

1493

1506

1494

function [hctf] = FD_CTLE(freq, fb, f_z, f_p1, f_p2, kacdc_dB)

1507

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)) ;

1508

hctf = ( 10.^(kacdc_dB/20) + 1i*freq/f_z ) ./ ( (1+1i*freq/f_p1) .* (1+1i*freq/f_p2)) ;

1496

1509

1497

function [chdata,output_args]=FD_Processing(chdata,output_args,param,OP,SDDp2p,DO_ONCE)

1510

function [chdata,output_args]=FD_Processing(chdata,output_args,param,OP,SDDp2p,DO_ONCE)

1498

%This function calculates various frequency domain metrics

1511

%This function calculates various frequency domain metrics

1499

%Mainly IL_fit, FOM_ILD, ICN, ICN_Fext, and ICN_Next

1512

%Mainly IL_fit, FOM_ILD, ICN, ICN_Fext, and ICN_Next

1500

db = @(x) 20*log10(abs(x));

1513

db = @(x) 20*log10(abs(x));

1501

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1514

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1502

if OP.WC_PORTZ

1515

if OP.WC_PORTZ

1503

A_thru = param.a_thru(param.Tx_rd_sel);

1516

A_thru = param.a_thru(param.Tx_rd_sel);

1504

A_fext = param.a_fext(param.Tx_rd_sel);

1517

A_fext = param.a_fext(param.Tx_rd_sel);

1505

A_next = param.a_next(param.Tx_rd_sel);

1518

A_next = param.a_next(param.Tx_rd_sel);

1506

else

1519

else

1507

A_thru = param.a_thru(package_testcase);

1520

A_thru = param.a_thru(package_testcase);

1508

A_fext = param.a_fext(package_testcase);

1521

A_fext = param.a_fext(package_testcase);

1509

A_next = param.a_next(package_testcase);

1522

A_next = param.a_next(package_testcase);

1510

end

1523

end

1511

for i=1:param.number_of_s4p_files

1524

for i=1:param.number_of_s4p_files

1512

if isequal(chdata(i).type, 'THRU')

1525

if isequal(chdata(i).type, 'THRU')

1513

chdata(i).A=A_thru;

1526

chdata(i).A=A_thru;

1514

chdata(i).Aicn=A_thru;

1527

chdata(i).Aicn=A_thru;

1515

elseif isequal(chdata(i).type, 'FEXT')

1528

elseif isequal(chdata(i).type, 'FEXT')

1516

chdata(i).A=A_fext;

1529

chdata(i).A=A_fext;

1517

chdata(i).Aicn=param.a_icn_fext;

1530

chdata(i).Aicn=param.a_icn_fext;

1518

elseif isequal(chdata(i).type, 'NEXT')

1531

elseif isequal(chdata(i).type, 'NEXT')

1519

chdata(i).A=A_next;

1532

chdata(i).A=A_next;

1520

chdata(i).Aicn=param.a_icn_next;

1533

chdata(i).Aicn=param.a_icn_next;

1521

end

1534

end

1522

end

1535

end

1523

if OP.TDMODE

1536

if OP.TDMODE

1524

for i=1:param.number_of_s4p_files % freq delta for integration

1537

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);

1538

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1526

end

1539

end

1527

end

1540

end

1528

if ~DO_ONCE

1541

if ~DO_ONCE

1529

return;

1542

return;

1530

end

1543

end

1531

%Any new output_args fields set in this function should be initialized here as empty

1544

%Any new output_args fields set in this function should be initialized here as empty

1532

output_args.fitted_IL_dB_at_Fnq = [];

1545

output_args.fitted_IL_dB_at_Fnq = [];

1533

output_args.cable__assembley_loss=[];

1546

output_args.cable__assembley_loss=[];

1534

output_args.loss_with_PCB=[];

1547

output_args.loss_with_PCB=[];

1535

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1548

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1536

output_args.IL_dB_channel_only_at_Fnq=[];

1549

output_args.IL_dB_channel_only_at_Fnq=[];

1537

output_args.VTF_loss_dB_at_Fnq=[];

1550

output_args.VTF_loss_dB_at_Fnq=[];

1538

output_args.IL_db_die_to_die_at_Fnq=[];

1551

output_args.IL_db_die_to_die_at_Fnq=[];

1539

output_args.FOM_TDILN=[];

1552

output_args.FOM_TDILN=[];

1540

output_args.TD_ILN=[];

1553

output_args.TD_ILN=[];

1541

output_args.FOM_RILN=[];

1554

output_args.FOM_RILN=[];

1542

output_args.FOM_ILD=[];

1555

output_args.FOM_ILD=[];

1543

%TD_Mode is just a pass through to set the empty values and return

1556

%TD_Mode is just a pass through to set the empty values and return

1544

if ~OP.GET_FD

1557

if ~OP.GET_FD

1545

return;

1558

return;

1546

end

1559

end

1547

case_number=param.package_testcase_i;

1560

case_number=param.package_testcase_i;

1548

f2=param.f2;

1561

f2=param.f2;

1549

f1=param.f1;

1562

f1=param.f1;

1550

MDFEXT_ICN=0; MDNEXT_ICN=0;

1563

MDFEXT_ICN=0; MDNEXT_ICN=0;

1551

for i=1:param.number_of_s4p_files

1564

for i=1:param.number_of_s4p_files

1552

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1565

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1553

% Equation 93A-20 %%

1566

% 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));

1567

% 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;

1568

f=chdata(i).faxis;

1556

%

1569

%

1557

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

1570

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

1558

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

1571

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

1572

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

1573

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

1574

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;

1575

chdata(i).sdd21=chdata(i).sdd21.*H_r;

1563

if OP.DISPLAY_WINDOW

1576

if OP.DISPLAY_WINDOW

1564

if i==1

1577

if i==1

1565

figure(300+param.package_testcase_i);

1578

figure(300+param.package_testcase_i);

1566

subplot(3,1,1)

1579

subplot(3,1,1)

1567

hold on

1580

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)')')

1581

plot(chdata(i).faxis/1e9, 20*log10(abs(squeeze(chdata(i).sdd21))), 'k-','linewidth',2, 'Disp',sprintf('VTF (no Tx/Rx eq)')')

1569

try

1582

try

1570

legend('NumColumns',2)

1583

legend('NumColumns',2)

1571

legend('location','south')

1584

legend('location','south')

1572

catch

1585

catch

1573

end

1586

end

1574

end

1587

end

1575

end

1588

end

1576

end

1589

end

1577

end

1590

end

1578

for i=1:param.number_of_s4p_files

1591

for i=1:param.number_of_s4p_files

1579

if i == 2

1592

if i == 2

1580

PSXT(1:length(chdata(i).sdd21f))=0;

1593

PSXT(1:length(chdata(i).sdd21f))=0;

1581

MDFEXT(1:length(chdata(i).sdd21f))=0;

1594

MDFEXT(1:length(chdata(i).sdd21f))=0;

1582

MDNEXT(1:length(chdata(i).sdd21f))=0;

1595

MDNEXT(1:length(chdata(i).sdd21f))=0;

1583

end

1596

end

1584

a=find(chdata(i).faxis(:)>=f2,1,'first');% RIM 01-12-21

1597

a=find(chdata(i).faxis(:)>=f2,1,'first');% RIM 01-12-21

1585

if isempty(a)

1598

if isempty(a)

1586

f2=chdata(i).faxis(end);

1599

f2=chdata(i).faxis(end);

1587

index_f2=length(chdata(i).faxis);

1600

index_f2=length(chdata(i).faxis);

1588

else

1601

else

1589

index_f2=a(1);

1602

index_f2=a(1);

1590

end

1603

end

1591

b=find(chdata(i).faxis(:)<=f1,1,'last');% RIM 01-12-21

1604

b=find(chdata(i).faxis(:)<=f1,1,'last');% RIM 01-12-21

1592

if isempty(b)

1605

if isempty(b)

1593

f1=chdata(i).faxis(1);

1606

f1=chdata(i).faxis(1);

1594

index_f1=1;

1607

index_f1=1;

1595

else

1608

else

1596

index_f1=b(1);

1609

index_f1=b(1);

1597

end

1610

end

1598

% R is the frequency dependent parameter for the sinc function use in the

1611

% R is the frequency dependent parameter for the sinc function use in the

1599

% PWF for ICN

1612

% PWF for ICN

1600

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(i).faxis;

1613

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(i).faxis;

1601

if(chdata(i).faxis(1)==0)

1614

if(chdata(i).faxis(1)==0)

1602

temp_angle(1)=1e-20;% we don't want to divide by zero

1615

temp_angle(1)=1e-20;% we don't want to divide by zero

1603

end

1616

end

1604

SINC = sin(temp_angle)./temp_angle;

1617

SINC = sin(temp_angle)./temp_angle;

1605

PWF_data=SINC.^2;

1618

PWF_data=SINC.^2;

1606

PWF_trf=(1+(chdata(i).faxis/chdata(i).ftr).^4).^-1;

1619

PWF_trf=(1+(chdata(i).faxis/chdata(i).ftr).^4).^-1;

1607

%// bw1=2.613126; bw2=3.4142136; bw3=2.613126;

1620

%// bw1=2.613126; bw2=3.4142136; bw3=2.613126;

1608

fr=param.f_r*param.fb;

1621

fr=param.f_r*param.fb;

1609

PWF_rx=(1+(chdata(i).faxis/fr).^8).^-1;

1622

PWF_rx=(1+(chdata(i).faxis/fr).^8).^-1;

1610

PWF_highpass=1;

1623

PWF_highpass=1;

1611

% Equation 93A-57 %

1624

% Equation 93A-57 %

1612

PWF=PWF_data.*PWF_trf.*PWF_rx.*PWF_highpass; % power weight function

1625

PWF=PWF_data.*PWF_trf.*PWF_rx.*PWF_highpass; % power weight function

1613

% freq delta for integration

1626

% freq delta for integration

1614

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1627

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1615

% from ba spec, this is basically ICN

1628

% from ba spec, this is basically ICN

1616

faxis_GHz = chdata(i).faxis/1e9;

1629

faxis_GHz = chdata(i).faxis/1e9;

1617

if isequal(chdata(i).type, 'THRU')

1630

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));

1631

[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

1632

% 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);

1633

[~, 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);

1634

fit_loss = interp1(chdata(i).faxis, -chdata(i).fit_orig, 1/param.ui/2);

1622

chdata(i).fit_ILatNq = fit_loss;

1635

chdata(i).fit_ILatNq = fit_loss;

1623

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1636

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);

1637

IL_interp = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21f)), 1/param.ui/2);

1625

chdata(i).ILatNq = IL_interp;

1638

chdata(i).ILatNq = IL_interp;

1626

if OP.include_pcb

1639

if OP.include_pcb

1627

cable_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_orig)), 1/param.ui/2);

1640

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);

1641

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;

1642

output_args.cable__assembley_loss=cable_loss;

1630

output_args.loss_with_PCB=loss_with_PCB;

1643

output_args.loss_with_PCB=loss_with_PCB;

1631

end

1644

end

1632

Nq_loss=chdata(i).ILatNq;

1645

Nq_loss=chdata(i).ILatNq;

1633

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1646

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1634

% time domain ref RR = complex fit pulse

1647

% time domain ref RR = complex fit pulse

1635

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1648

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);

1649

[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;

1650

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1638

FOM_ILN_complex= TD_ILN.FOM;

1651

FOM_ILN_complex= TD_ILN.FOM;

1639

end

1652

end

1640

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1653

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);

1654

[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;

1655

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1643

FOM_ILN_complex= TD_ILN.FOM;

1656

FOM_ILN_complex= TD_ILN.FOM;

1644

end

1657

end

1645

if OP.COMPUTE_TDILN

1658

if OP.COMPUTE_TDILN

1646

output_args.FOM_TDILN=FOM_TDILN;

1659

output_args.FOM_TDILN=FOM_TDILN;

1647

output_args.TD_ILN=TD_ILN; % struct

1660

output_args.TD_ILN=TD_ILN; % struct

1648

end

1661

end

1649

if OP.COMPUTE_RILN

1662

if OP.COMPUTE_RILN

1650

% Get RIL, RILN, and TD_RILN

1663

% Get RIL, RILN, and TD_RILN

1651

[RIL_struct]= capture_RIL_RILN(chdata);

1664

[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));

1665

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;

1666

output_args.FOM_RILN=FOM_RILN;

1654

%---start. plotting ILN based on ILD and RILN % Hansel 10/18/2021

1667

%---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

1668

plot_tdomain_debug= 0; % must have OP.COMPUTE_TDILN = 1 to use

1656

if plot_tdomain_debug== 1

1669

if plot_tdomain_debug== 1

1657

figure(988); set(gcf,'Tag','COM')

1670

figure(988); set(gcf,'Tag','COM')

1658

ax_1= subplot(3,1,1);

1671

ax_1= subplot(3,1,1);

1659

plot(TD_ILN.REF.t*1e9, TD_ILN.REF.PR*1e3,'disp','ref');

1672

plot(TD_ILN.REF.t*1e9, TD_ILN.REF.PR*1e3,'disp','ref');

1660

hold on;

1673

hold on;

1661

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1674

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1662

hold on;

1675

hold on;

1663

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k','disp','ref - fit (IL noise)');

1676

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);

1677

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1665

grid on;

1678

grid on;

1666

box on;

1679

box on;

1667

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1680

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1668

xlabel('Time [nsec]');

1681

xlabel('Time [nsec]');

1669

ylabel('Pulse Response [mV]');

1682

ylabel('Pulse Response [mV]');

1670

1683

1671

ax_2= subplot(3,1,2);

1684

ax_2= subplot(3,1,2);

1672

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1685

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1673

hold on;

1686

hold on;

1674

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1687

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1675

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1688

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1676

grid on;

1689

grid on;

1677

box on;

1690

box on;

1678

legend('REF', 'TD\_RILN');

1691

legend('REF', 'TD\_RILN');

1679

xlabel('Time [nsec]');

1692

xlabel('Time [nsec]');

1680

ylabel('Pulse Response [mV]');

1693

ylabel('Pulse Response [mV]');

1681

ax_3= subplot(3,1,3);

1694

ax_3= subplot(3,1,3);

1682

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1695

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1683

hold on;

1696

hold on;

1684

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1697

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1685

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1698

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1686

grid on;

1699

grid on;

1687

box on;

1700

box on;

1688

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1701

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1689

xlabel('Time [nsec]');

1702

xlabel('Time [nsec]');

1690

ylabel('Pulse Response [mV]');

1703

ylabel('Pulse Response [mV]');

1691

1704

1692

linkaxes([ax_1, ax_2, ax_3], 'x');

1705

linkaxes([ax_1, ax_2, ax_3], 'x');

1693

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1706

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1694

end

1707

end

1695

%---end. plotting ILN based on ILD and RILN

1708

%---end. plotting ILN based on ILD and RILN

1696

end

1709

end

1697

% Equation 93A-56 %

1710

% Equation 93A-56 %

1698

FOM_ILD=sqrt(chdata(i).delta_f/(param.fb)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1711

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;

1712

output_args.FOM_ILD=FOM_ILD;

1700

if OP.DEBUG

1713

if OP.DEBUG

1701

if OP.DISPLAY_WINDOW

1714

if OP.DISPLAY_WINDOW

1702

figure(300+case_number);

1715

figure(300+case_number);

1703

set(gcf,'Tag','COM')

1716

set(gcf,'Tag','COM')

1704

screen_size=get(0,'ScreenSize');

1717

screen_size=get(0,'ScreenSize');

1705

pos = get(gcf, 'OuterPosition');

1718

pos = get(gcf, 'OuterPosition');

1706

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1719

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

1720

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]);

1721

- (case_number-1)*[0 20 0 0]);

1709

subplot(3,1,1)

1722

subplot(3,1,1)

1710

title('Losses')

1723

title('Losses')

1711

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1724

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1712

hold on

1725

hold on

1713

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1726

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')

1727

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1715

ylim(get(gca, 'ylim'));

1728

ylim(get(gca, 'ylim'));

1716

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1729

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')

1730

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1718

subplot(3,1,3)

1731

subplot(3,1,3)

1719

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1732

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1720

if OP.PLOT_CM

1733

if OP.PLOT_CM

1721

if case_number ==1

1734

if case_number ==1

1722

h350=figure(350);set(gcf,'Tag','COM')

1735

h350=figure(350);set(gcf,'Tag','COM')

1723

screen_size=get(0,'ScreenSize');

1736

screen_size=get(0,'ScreenSize');

1724

pos = get(gcf, 'OuterPosition');

1737

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])

1738

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');

1739

movegui(gcf,'center');

1727

htabgroup350 = uitabgroup(h350);

1740

htabgroup350 = uitabgroup(h350);

1728

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1741

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1729

hax1 = axes('Parent', htab1);

1742

hax1 = axes('Parent', htab1);

1730

set(h350,'CurrentAxes',hax1)

1743

set(h350,'CurrentAxes',hax1)

1731

hold on

1744

hold on

1732

set(gcf,'Tag','COM')

1745

set(gcf,'Tag','COM')

1733

screen_size=get(0,'ScreenSize');

1746

screen_size=get(0,'ScreenSize');

1734

pos = get(gcf, 'OuterPosition');

1747

pos = get(gcf, 'OuterPosition');

1735

title('IL & CM Losses')

1748

title('IL & CM Losses')

1736

base=strrep(chdata(i).base,'_',' ');

1749

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])

1750

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])

1751

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1739

ylabel('dB')

1752

ylabel('dB')

1740

xlabel('GHz')

1753

xlabel('GHz')

1741

legend show

1754

legend show

1742

legend('Location','eastoutside')

1755

legend('Location','eastoutside')

1743

hold on

1756

hold on

1744

grid on

1757

grid on

1745

if param.number_of_s4p_files > 1

1758

if param.number_of_s4p_files > 1

1746

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1759

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1747

hax2 = axes('Parent', htab2);

1760

hax2 = axes('Parent', htab2);

1748

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1761

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1749

hax3 = axes('Parent', htab3);

1762

hax3 = axes('Parent', htab3);

1750

end

1763

end

1751

1764

1752

end

1765

end

1753

end

1766

end

1754

else

1767

else

1755

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1768

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1756

end

1769

end

1757

end

1770

end

1758

else % NEXT or FEXT

1771

else % NEXT or FEXT

1759

if isequal(chdata(i).type, 'FEXT')

1772

if isequal(chdata(i).type, 'FEXT')

1760

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1773

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1761

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.fb*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46 corrected for fb

1774

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.fb*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46 corrected for fb

1762

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1775

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1763

elseif isequal(chdata(i).type, 'NEXT')

1776

elseif isequal(chdata(i).type, 'NEXT')

1764

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1777

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1765

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.fb*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47 corrected for fb

1778

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.fb*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47 corrected for fb

1766

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1779

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1767

end

1780

end

1768

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1781

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1769

ICN=sqrt(2*chdata(i).delta_f/param.fb*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));% corrected for fb

1782

ICN=sqrt(2*chdata(i).delta_f/param.fb*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));% corrected for fb

1770

output_args.ICN_mV=ICN*1000;

1783

output_args.ICN_mV=ICN*1000;

1771

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1784

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1772

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1785

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1773

if case_number ==1

1786

if case_number ==1

1774

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1787

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1775

% hax2 = axes('Parent', htab2);

1788

% hax2 = axes('Parent', htab2);

1776

set(h350,'CurrentAxes',hax2)

1789

set(h350,'CurrentAxes',hax2)

1777

hold on

1790

hold on

1778

title('CM Losses')

1791

title('CM Losses')

1779

base=strrep(chdata(i).base,'_',' ');

1792

base=strrep(chdata(i).base,'_',' ');

1780

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1793

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1781

legend('Location','eastoutside')

1794

legend('Location','eastoutside')

1782

hold on

1795

hold on

1783

grid on

1796

grid on

1784

set(h350,'CurrentAxes',hax3)

1797

set(h350,'CurrentAxes',hax3)

1785

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1798

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1786

legend('Location','eastoutside')

1799

legend('Location','eastoutside')

1787

hold on

1800

hold on

1788

grid on

1801

grid on

1789

end

1802

end

1790

end

1803

end

1791

end

1804

end

1792

end % for loop

1805

end % for loop

1793

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1806

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1794

if OP.DEBUG && OP.DISPLAY_WINDOW

1807

if OP.DEBUG && OP.DISPLAY_WINDOW

1795

figure(300+case_number);set(gcf,'Tag','COM');

1808

figure(300+case_number);set(gcf,'Tag','COM');

1796

if param.number_of_s4p_files > 1

1809

if param.number_of_s4p_files > 1

1797

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1810

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1798

subplot(3,1,1)

1811

subplot(3,1,1)

1799

hold on

1812

hold on

1800

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1813

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1801

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1814

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1802

subplot(3,1,2)

1815

subplot(3,1,2)

1803

grid on

1816

grid on

1804

ILtemp=20*log10(abs(chdata(1).sdd21f));

1817

ILtemp=20*log10(abs(chdata(1).sdd21f));

1805

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1818

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1806

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1819

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1807

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1820

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1808

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1821

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1809

hold on

1822

hold on

1810

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1823

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1811

end

1824

end

1812

subplot(3,1,1)

1825

subplot(3,1,1)

1813

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1826

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1814

grid on; legend show

1827

grid on; legend show

1815

subplot(3,1,2)

1828

subplot(3,1,2)

1816

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1829

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1817

ylim([0 80])

1830

ylim([0 80])

1818

xlim([.1 100])

1831

xlim([.1 100])

1819

grid on; %legend show

1832

grid on; %legend show

1820

subplot(3,1,3)

1833

subplot(3,1,3)

1821

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1834

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1822

ylim([-3 3])

1835

ylim([-3 3])

1823

grid on; legend show

1836

grid on; legend show

1824

end

1837

end

1825

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1838

% 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);

1839

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);

1840

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);

1841

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;

1842

output_args.VTF_loss_dB_at_Fnq=total_loss;

1830

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1843

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1831

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1844

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1832

function [ V0 ] = FFE( C , cmx,spui, V )

1845

function [ V0 ] = FFE( C , cmx,spui, V )

1833

% C FFE taps

1846

% C FFE taps

1834

% cmx number of precursors taps

1847

% cmx number of precursors taps

1835

% spui samples per ui

1848

% spui samples per ui

1836

% V input signal

1849

% V input signal

1837

%speed ups implemented:

1850

%speed ups implemented:

1838

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1851

%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

1852

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1840

1853

1841

V0=0;

1854

V0=0;

1842

if iscolumn(V); V=V.';end

1855

if iscolumn(V); V=V.';end

1843

for i=1:length(C)

1856

for i=1:length(C)

1844

if C(i)~=0

1857

if C(i)~=0

1845

ishift=(i-1-cmx)*spui;

1858

ishift=(i-1-cmx)*spui;

1846

V0=circshift(V',[ishift,0])*C(i)+V0;

1859

V0=circshift(V',[ishift,0])*C(i)+V0;

1847

end

1860

end

1848

end

1861

end

1849

%V0=circshift(V0,[(-cmx)*spui,0]);

1862

%V0=circshift(V0,[(-cmx)*spui,0]);

1850

% disp(max(V0));

1863

% disp(max(V0));

1851

1864

1852

1865

1853

% begin yasuo patch 12/11/2018

1866

% begin yasuo patch 12/11/2018

1854

% calculate sigma (standard deviation) value of PDF

1867

% calculate sigma (standard deviation) value of PDF

1855

function [ V0 ] = FFE_Fast( C,V_shift )

1868

function [ V0 ] = FFE_Fast( C,V_shift )

1856

% C FFE taps

1869

% C FFE taps

1857

% V input signal separated into length(C) columns with circshift already performed

1870

% 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

1871

% 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

1872

% 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

1873

% saved by pre-shifting it and remembering it across loops

1861

% Another speed up: only multiply by indices of C that are not 0

1874

% Another speed up: only multiply by indices of C that are not 0

1862

1875

1863

V0=0;

1876

V0=0;

1864

for i=1:length(C)

1877

for i=1:length(C)

1865

if C(i)~=0

1878

if C(i)~=0

1866

V0=V_shift(:,i)*C(i)+V0;

1879

V0=V_shift(:,i)*C(i)+V0;

1867

end

1880

end

1868

end

1881

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)

1882

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1870

1883

1871

hisi=h(isi_start:isi_end);

1884

hisi=h(isi_start:isi_end);

1872

hisi=hisi(param.RxFFE_cpx+1:param.N_bmax);

1885

hisi=hisi(param.RxFFE_cpx+1:param.N_bmax);

1873

bank_size = param.N_bf;

1886

bank_size = param.N_bf;

1874

num_groups = param.N_bg;

1887

num_groups = param.N_bg;

1875

1888

1876

1889

1877

%start with one by one Floating Tap

1890

%start with one by one Floating Tap

1878

num_isi=length(hisi);

1891

num_isi=length(hisi);

1879

max_isi=num_isi-bank_size+1;

1892

max_isi=num_isi-bank_size+1;

1880

valid_tap_locations=1:max_isi;

1893

valid_tap_locations=1:max_isi;

1881

all_idx=[];

1894

all_idx=[];

1882

for j=1:num_groups

1895

for j=1:num_groups

1883

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1896

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1884

for k=1:length(valid_tap_locations)

1897

for k=1:length(valid_tap_locations)

1885

this_location=valid_tap_locations(k);

1898

this_location=valid_tap_locations(k);

1886

new_idx = [all_idx this_location:this_location+bank_size-1];

1899

new_idx = [all_idx this_location:this_location+bank_size-1];

1887

new_idx=sort(new_idx);

1900

new_idx=sort(new_idx);

1888

new_idx = new_idx+param.RxFFE_cpx;

1901

new_idx = new_idx+param.RxFFE_cpx;

1889

%calculate FOM for each one

1902

%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);

1903

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1891

end

1904

end

1892

%choose the location with best FOM

1905

%choose the location with best FOM

1893

%add it to the "all_idx" list and remove it from valid locations

1906

%add it to the "all_idx" list and remove it from valid locations

1894

[~,best_FOM_idx]=max(best_FOM);

1907

[~,best_FOM_idx]=max(best_FOM);

1895

start_tap = valid_tap_locations(best_FOM_idx);

1908

start_tap = valid_tap_locations(best_FOM_idx);

1896

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1909

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1897

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1910

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1898

remove_range(remove_range>length(valid_tap_locations))=[];

1911

remove_range(remove_range>length(valid_tap_locations))=[];

1899

valid_tap_locations(remove_range)=[];

1912

valid_tap_locations(remove_range)=[];

1900

1913

1901

%Also remove illegal taps from valid locations

1914

%Also remove illegal taps from valid locations

1902

%illegal taps are ones that would overlap with the chosen bank

1915

%illegal taps are ones that would overlap with the chosen bank

1903

bad_tap=start_tap-bank_size+1:start_tap-1;

1916

bad_tap=start_tap-bank_size+1:start_tap-1;

1904

bad_tap(bad_tap<1)=[];

1917

bad_tap(bad_tap<1)=[];

1905

for n=1:length(bad_tap)

1918

for n=1:length(bad_tap)

1906

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1919

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1907

if ~isempty(bad_tap_idx)

1920

if ~isempty(bad_tap_idx)

1908

valid_tap_locations(bad_tap_idx)=[];

1921

valid_tap_locations(bad_tap_idx)=[];

1909

end

1922

end

1910

end

1923

end

1911

end

1924

end

1912

1925

1913

%put idx back in the right location (adding RxFFE_cpx)

1926

%put idx back in the right location (adding RxFFE_cpx)

1914

idx = all_idx+param.RxFFE_cpx;

1927

idx = all_idx+param.RxFFE_cpx;

1915

idx = sort(idx);

1928

idx = sort(idx);

1916

function [ V0 ] = Fract_T_FFE( V , skew_step)

1929

function [ V0 ] = Fract_T_FFE( V , skew_step)

1917

% skew_step sub UI skew assuming param.samples_per_ui

1930

% skew_step sub UI skew assuming param.samples_per_ui

1918

% V input signal

1931

% V input signal

1919

% V0 output signal

1932

% V0 output signal

1920

% Richard Mellitz 8/17/2021

1933

% Richard Mellitz 8/17/2021

1921

V0=0;

1934

V0=0;

1922

if iscolumn(V); V=V.';end

1935

if iscolumn(V); V=V.';end

1923

ishift=skew_step;

1936

ishift=skew_step;

1924

V0=circshift(V',[ishift,0])'+V;

1937

V0=circshift(V',[ishift,0])'+V;

1925

V0=V0/2;

1938

V0=V0/2;

1926

function out=Full_Grid_Matrix(in)

1939

function out=Full_Grid_Matrix(in)

1927

1940

1928

%create a full grid matrix of input variables

1941

%create a full grid matrix of input variables

1929

%used to create the full grid of all txffe cases

1942

%used to create the full grid of all txffe cases

1930

%example:

1943

%example:

1931

%Full_Grid_Matrix({ [1 2] [100 200] })

1944

%Full_Grid_Matrix({ [1 2] [100 200] })

1932

%out =

1945

%out =

1933

% 1 100

1946

% 1 100

1934

% 1 200

1947

% 1 200

1935

% 2 100

1948

% 2 100

1936

% 2 200

1949

% 2 200

1937

%

1950

%

1938

%input can also be mixed between numeric and cell of char

1951

%input can also be mixed between numeric and cell of char

1939

%example:

1952

%example:

1940

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1953

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1941

%out =

1954

%out =

1942

% {[1]} {'A'}

1955

% {[1]} {'A'}

1943

% {[1]} {'B'}

1956

% {[1]} {'B'}

1944

% {[2]} {'A'}

1957

% {[2]} {'A'}

1945

% {[2]} {'B'}

1958

% {[2]} {'B'}

1946

1959

1947

if ~iscell(in)

1960

if ~iscell(in)

1948

error('input must be cell array of individual sweep variables');

1961

error('input must be cell array of individual sweep variables');

1949

end

1962

end

1950

1963

1951

num_columns=length(in);

1964

num_columns=length(in);

1952

num_cases=prod(cellfun('length',in));

1965

num_cases=prod(cellfun('length',in));

1953

1966

1954

cell_output=0;

1967

cell_output=0;

1955

cell_indices=cellfun(@(x) iscell(x),in);

1968

cell_indices=cellfun(@(x) iscell(x),in);

1956

if any(cell_indices)

1969

if any(cell_indices)

1957

cell_output=1;

1970

cell_output=1;

1958

end

1971

end

1959

if cell_output

1972

if cell_output

1960

for k=find(~cell_indices)

1973

for k=find(~cell_indices)

1961

in{k}=num2cell(in{k});

1974

in{k}=num2cell(in{k});

1962

end

1975

end

1963

end

1976

end

1964

1977

1965

if cell_output

1978

if cell_output

1966

out=cell(num_cases,num_columns);

1979

out=cell(num_cases,num_columns);

1967

else

1980

else

1968

out=zeros(num_cases,num_columns);

1981

out=zeros(num_cases,num_columns);

1969

end

1982

end

1970

1983

1971

%num_repetitions controls how many times each element of the column

1984

%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

1985

%repeats. The first column is always just a copy of itself since every

1973

%case will vary.

1986

%case will vary.

1974

num_repetitions=1;

1987

num_repetitions=1;

1975

for k=num_columns:-1:1

1988

for k=num_columns:-1:1

1976

this_column=in{k}(:);

1989

this_column=in{k}(:);

1977

%copy the column into a matrix to create the repetitions needed

1990

%copy the column into a matrix to create the repetitions needed

1978

B=repmat(this_column,[1 num_repetitions]);

1991

B=repmat(this_column,[1 num_repetitions]);

1979

%reshape into single column (actual repetitions)

1992

%reshape into single column (actual repetitions)

1980

C=reshape(B',[numel(B) 1]);

1993

C=reshape(B',[numel(B) 1]);

1981

%repeat the single column to build the entire length required

1994

%repeat the single column to build the entire length required

1982

num_repeats=num_cases/length(C);

1995

num_repeats=num_cases/length(C);

1983

D=repmat(C,[num_repeats 1]);

1996

D=repmat(C,[num_repeats 1]);

1984

out(:,k)=D;

1997

out(:,k)=D;

1985

%determine how many repetitions the next column needs

1998

%determine how many repetitions the next column needs

1986

num_repetitions=num_repetitions*length(this_column);

1999

num_repetitions=num_repetitions*length(this_column);

1987

end

2000

end

1988

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

2001

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1989

% p=cpdf(type, ...)

2002

% p=cpdf(type, ...)

1990

%

2003

%

1991

% CPDF is a probability mass function for discrete distributions or an

2004

% CPDF is a probability mass function for discrete distributions or an

1992

% approxmation of a PDF for continuous distributions.

2005

% approxmation of a PDF for continuous distributions.

1993

%

2006

%

1994

% cpdf is internally normalized so that the sum of probabilities is 1

2007

% cpdf is internally normalized so that the sum of probabilities is 1

1995

% (regardless of bin size).

2008

% (regardless of bin size).

1996

2009

1997

% Internal fields:

2010

% Internal fields:

1998

% Min: *bin number* of minimum value.

2011

% Min: *bin number* of minimum value.

1999

% BinSize: size of PDF bins. Bin center is the representative value.

2012

% BinSize: size of PDF bins. Bin center is the representative value.

2000

% Vec: vector of probabilities per bin.

2013

% Vec: vector of probabilities per bin.

2001

2014

2002

pdf=EmptyPDF;

2015

pdf=EmptyPDF;

2003

2016

2004

rounded_values_div_binsize=round(values/pdf.BinSize);

2017

rounded_values_div_binsize=round(values/pdf.BinSize);

2005

%values=pdf.BinSize*rounded_values_div_binsize;

2018

%values=pdf.BinSize*rounded_values_div_binsize;

2006

2019

2007

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2020

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2008

% if all(values==0)

2021

% if all(values==0)

2009

% return;

2022

% return;

2010

% end

2023

% end

2011

%

2024

%

2012

% %speed up for all values rounded to the same bin

2025

% %speed up for all values rounded to the same bin

2013

% %The output pdf is the same as the

2026

% %The output pdf is the same as the

2014

% %empty pdf, but the x value is non-zero (but still scalar)

2027

% %empty pdf, but the x value is non-zero (but still scalar)

2015

% if all(values==values(1))

2028

% if all(values==values(1))

2016

% pdf.Min=rounded_values_div_binsize(1);

2029

% pdf.Min=rounded_values_div_binsize(1);

2017

% pdf.x=values(1);

2030

% pdf.x=values(1);

2018

% return;

2031

% return;

2019

% end

2032

% end

2020

%

2033

%

2021

% %The code below requires that values is

2034

% %The code below requires that values is

2022

% %sorted. Generally this should be true, but check to be sure

2035

% %sorted. Generally this should be true, but check to be sure

2023

% if ~issorted(values)

2036

% if ~issorted(values)

2024

% [values,si]=sort(values);

2037

% [values,si]=sort(values);

2025

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2038

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2026

% probs=probs(si);

2039

% probs=probs(si);

2027

% end

2040

% end

2028

2041

2029

2042

2030

%pdf.x=values(1):pdf.BinSize:values(end);

2043

%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);

2044

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);

2045

pdf.Min=rounded_values_div_binsize(1);

2033

2046

2034

pdf.y=zeros(size(pdf.x));

2047

pdf.y=zeros(size(pdf.x));

2035

%The rounded values divided by binsize will reveal the bin number if

2048

%The rounded values divided by binsize will reveal the bin number if

2036

%pdf.Min is subtracted from it

2049

%pdf.Min is subtracted from it

2037

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2050

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2038

%Can avoid one addition by inserting the first probability

2051

%Can avoid one addition by inserting the first probability

2039

%actually helps when calling this 2 million times

2052

%actually helps when calling this 2 million times

2040

pdf.y(bin_placement(1))=probs(1);

2053

pdf.y(bin_placement(1))=probs(1);

2041

for k=2:length(values)

2054

for k=2:length(values)

2042

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2055

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2043

end

2056

end

2044

2057

2045

2058

2046

%Have already ensured that sum(pdf.y)=1

2059

%Have already ensured that sum(pdf.y)=1

2047

%pdf.y=pdf.y/sum(pdf.y);

2060

%pdf.y=pdf.y/sum(pdf.y);

2048

2061

2049

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2062

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2050

% error('PDF must be real and nonnegative');

2063

% error('PDF must be real and nonnegative');

2051

% end

2064

% end

2052

2065

2053

% pMax=pdf.Min+length(pdf.y)-1;

2066

% pMax=pdf.Min+length(pdf.y)-1;

2054

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2067

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2055

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2068

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

2069

% 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

2070

% 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

2071

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2059

2072

2060

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2073

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2061

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2074

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2062

2075

2063

%% step 0

2076

%% step 0

2064

COM_from_matlab=20*log10(A_s/A_ni);

2077

COM_from_matlab=20*log10(A_s/A_ni);

2065

L=param.levels;

2078

L=param.levels;

2066

DER0=param.specBER;

2079

DER0=param.specBER;

2067

%% step 1 from slide 6/5

2080

%% step 1 from slide 6/5

2068

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2081

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2069

main=A_peak;

2082

main=A_peak;

2070

k_DER=qfuncinv(param.specBER);

2083

k_DER=qfuncinv(param.specBER);

2071

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2084

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) ;

2085

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);

2086

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)

2087

% 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

2088

if A_s >= A_ni

2076

%% step 2 slide 10/8

2089

%% step 2 slide 10/8

2077

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2090

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2078

%% step 2 slide 10/8

2091

%% 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));

2092

% 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);

2093

% 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

2094

%% step 3 side 11/9

2082

j=1:200;

2095

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 ) ));

2096

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;

2097

DER_MLSE_CDF=0; jj=1;

2085

DER_delta = inf;

2098

DER_delta = inf;

2086

while DER_delta > .001

2099

while DER_delta > .001

2087

last_DER_MLSE_CDF=DER_MLSE_CDF;

2100

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;

2101

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;

2102

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2090

jj=jj+1;

2103

jj=jj+1;

2091

end

2104

end

2092

%% step 4 slide 12/10

2105

%% step 4 slide 12/10

2093

SNR_DFE_eqivalent=SNR_DFE*(...

2106

SNR_DFE_eqivalent=SNR_DFE*(...

2094

(L-1)*sigma_noise/main * qfuncinv(...

2107

(L-1)*sigma_noise/main * qfuncinv(...

2095

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2108

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2096

) ...

2109

) ...

2097

)^2;

2110

)^2;

2098

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2111

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2099

(L-1)/main * CDF_inv_ev(...

2112

(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 )) ...

2113

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2101

,PDF, CDF ) ...

2114

,PDF, CDF ) ...

2102

)^2;

2115

)^2;

2103

2116

2104

%% step 5 slide 13/11

2117

%% step 5 slide 13/11

2105

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2118

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2106

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2119

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2107

new_com_CDF=COM_from_matlab+delta_com_CDF;

2120

new_com_CDF=COM_from_matlab+delta_com_CDF;

2108

else

2121

else

2109

warning('MLSE not applied because there is more noise than signal')

2122

warning('MLSE not applied because there is more noise than signal')

2110

DER_MLSE=[];

2123

DER_MLSE=[];

2111

DER_MLSE_CDF=[];

2124

DER_MLSE_CDF=[];

2112

SNR_DFE_eqivalent=[];

2125

SNR_DFE_eqivalent=[];

2113

SNR_DFE_eqivalent_CDF=[];

2126

SNR_DFE_eqivalent_CDF=[];

2114

new_com_CDF=COM_from_matlab;

2127

new_com_CDF=COM_from_matlab;

2115

delta_com_CDF=0;

2128

delta_com_CDF=0;

2116

delta_com=0;

2129

delta_com=0;

2117

SNR_DFE=[];

2130

SNR_DFE=[];

2118

end

2131

end

2119

2132

2120

%%

2133

%%

2121

MLSE_results.COM_from_matlab=COM_from_matlab;

2134

MLSE_results.COM_from_matlab=COM_from_matlab;

2122

MLSE_results.SNR_DFE=SNR_DFE;

2135

MLSE_results.SNR_DFE=SNR_DFE;

2123

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2136

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2124

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2137

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2125

MLSE_results.sigma_noise=sigma_noise;

2138

MLSE_results.sigma_noise=sigma_noise;

2126

MLSE_results.SNR_dB=SNR_dB ;

2139

MLSE_results.SNR_dB=SNR_dB ;

2127

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2140

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2128

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2141

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2129

MLSE_results.COM_Gaussian=new_com_CDF;

2142

MLSE_results.COM_Gaussian=new_com_CDF;

2130

MLSE_results.COM_CDF=new_com_CDF;

2143

MLSE_results.COM_CDF=new_com_CDF;

2131

MLSE_results.k_DER=k_DER;

2144

MLSE_results.k_DER=k_DER;

2132

MLSE_results.delta_com_CDF=delta_com_CDF;

2145

MLSE_results.delta_com_CDF=delta_com_CDF;

2133

MLSE_results.delta_com_Gaussian=delta_com;

2146

MLSE_results.delta_com_Gaussian=delta_com;

2134

2147

2135

2148

2136

2149

2137

function [MLSE_results] = MLSE_U1_c_178A(param,b,A_s,A_ni,PDF,CDF,PSD_results)

2150

function [MLSE_results] = MLSE_U1_c_178A(param,b,A_s,A_ni,PDF,CDF,PSD_results)

2138

if 1

2151

if 1

2139

num_ui=param.num_ui_RXFF_noise;

2152

num_ui=param.num_ui_RXFF_noise;

2140

M=param.samples_per_ui;

2153

M=param.samples_per_ui;

2141

L=param.levels;

2154

L=param.levels;

2142

sigma_X2=(L^2-1)/(3*(L-1)^2);

2155

sigma_X2=(L^2-1)/(3*(L-1)^2);

2143

f_b=param.fb;

2156

f_b=param.fb;

2144

DER0=param.specBER; % align terminology

2157

DER0=param.specBER; % align terminology

2145

delta_COM_an=param.pass_threshold; % align terminology

2158

delta_COM_an=param.pass_threshold; % align terminology

2146

end

2159

end

2147

% new function to scale CDF at specified DER; healey_3dj_01_2409 slide 8, 12, and 13

2160

% 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);

2161

% directly compute p_an (PDF) and P_an (CDF);

2149

[p_an, P_an, ~] = scaleCDF( PDF,delta_COM_an,DER0, A_s );

2162

[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);

2163

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;

2164

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;

2165

g_an=(sigma_an_2_pdf-PSD_results.S_G_rms^2)/PSD_results.S_rn_rms^2;

2153

2166

2154

% g_an be squared since votltage was scalted: healey_3dj_01_2409 slide 12 (178A –X) units are power

2167

% 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;

2168

% g_an=g_an^2;

2156

COM_from_matlab=20*log10(A_s/A_ni);

2169

COM_from_matlab=20*log10(A_s/A_ni);

2157

DER_DFE= CDF_ev(A_s,PDF, CDF);% remove 2*(L-1)/L COM Commit Request Numbers 4p7_5

2170

DER_DFE= 2*(L-1)/L*CDF_ev(A_s,PDF, CDF);

2158

if 0 % comparing to healey_3dj_01_2409 slide 8

2171

if 1 % comparing to healey_3dj_01_2409 slide 8

2159

figure(1200);set(gcf,'Tag','COM');

2172

figure(1200);set(gcf,'Tag','COM');

2160

semilogy(PDF.x/A_s,CDF,'disp',sprintf('P(y) case %g',param.package_testcase_i))

2173

semilogy(PDF.x/A_s,CDF,'disp',sprintf('P(y) case %g',param.package_testcase_i))

2161

ylim([1e-7 1e-1])

2174

ylim([1e-7 1e-1])

2162

grid on

2175

grid on

2163

movegui(gcf,[randn randn]*100)

2176

movegui(gcf,[randn randn]*100)

2164

xlabel('-A_ni/A_s')

2177

xlabel('-A_ni/A_s')

2165

ylabel('DER')

2178

ylabel('DER')

2166

hold on

2179

hold on

2167

semilogy(p_an.x/A_s,P_an,'disp',sprintf('P_a_n(y) case %g',param.package_testcase_i'))

2180

semilogy(p_an.x/A_s,P_an,'disp',sprintf('P_a_n(y) case %g',param.package_testcase_i'))

2168

legend show

2181

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 ) ))

2182

% 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

2183

end

2171

% PDF=p_an;

2184

% PDF=p_an;

2172

% CDF=P_an;

2185

% CDF=P_an;

2173

S_an=g_an*PSD_results.S_rn.*PSD_results.H_rxffe_2; % healey_3dj_01_2409 slide 12

2186

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

2187

S_ni=PSD_results.S_isi +PSD_results.S_n +S_an; % 178A-40, healey_3dj_01_2409 slide 15

2175

R_ni=ifft(S_ni)*f_b;

2188

R_ni=ifft(S_ni)*f_b;

2176

p_scaled_by_b=scalePDF(p_an,b(1));

2189

p_scaled_by_b=scalePDF(p_an,b(1));

2177

p_j=conv_fct(p_an,p_scaled_by_b);

2190

p_j=conv_fct(p_an,p_scaled_by_b);

2178

p_scaled_by_1mb=scalePDF(p_an,1-b(1));

2191

p_scaled_by_1mb=scalePDF(p_an,1-b(1));

2179

%% %% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2192

%% %% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2180

p_trunc = p_an;

2193

p_trunc = p_an;

2181

%

2194

%

2182

j=1; DER_MLSE=0; DER_MLSE_j= inf;

2195

j=1; DER_MLSE=0; DER_MLSE_j= inf;

2183

P_j.y=cumsum(p_j.y);

2196

P_j.y=cumsum(p_j.y);

2184

smallest_relative_change=.0001;

2197

smallest_relative_change=.0001;

2185

%% 178A–37

2198

%% 178A–37

2186

rou=R_ni'/R_ni(1);

2199

rou=R_ni'/R_ni(1);

2187

if DER_DFE <= param.DER_CDR

2200

if DER_DFE <= param.DER_CDR

2188

while j <= floor(num_ui/2) && DER_MLSE_j> DER_MLSE*smallest_relative_change

2201

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)

2202

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);

2203

u_j(2:2:end-1)=-u_j(2:2:end-1);

2191

% V_j=toeplitz(R_ni(1:j+1).'/R_ni(1));

2204

% V_j=toeplitz(R_ni(1:j+1).'/R_ni(1));

2192

V_j=toeplitz(rou(1:j+1));

2205

V_j=toeplitz(rou(1:j+1));

2193

P_j=cumsum(p_j.y);

2206

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)

2207

DER_MLSE_j= ((L-1)/L)^(j-1) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(1/2), p_j, P_j ) ) ; % CDF_ev is (1-P_an)

2195

% DER_MLSE_j= 2*(3/4)^(j) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(0.5), p_j, P_j ) ) ; % CDF_ev is (1-CDF)

2208

% 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;

2209

DER_MLSE=DER_MLSE+DER_MLSE_j;

2197

p_j=conv_fct(p_j,p_scaled_by_1mb);

2210

p_j=conv_fct(p_j,p_scaled_by_1mb);

2198

%% %% shakiba_3dj_01_2407(to add MLSE sequence truncation penalty)

2211

%% %% shakiba_3dj_01_2407(to add MLSE sequence truncation penalty)

2199

if j == param.trunc

2212

if j == param.trunc

2200

u_trunc = u_j(1:j);

2213

u_trunc = u_j(1:j);

2201

V_trunc = V_j(1:j, 1:j);

2214

V_trunc = V_j(1:j, 1:j);

2202

P_trunc = cumsum(p_trunc.y);

2215

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);

2216

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

2217

elseif j < param.trunc

2205

DER_MLSE_trunc = DER_MLSE;

2218

DER_MLSE_trunc = DER_MLSE;

2206

p_trunc = conv_fct(p_trunc, p_scaled_by_1mb); % Convolves trunc-1 times

2219

p_trunc = conv_fct(p_trunc, p_scaled_by_1mb); % Convolves trunc-1 times

2207

P_trunc = cumsum(p_trunc.y);

2220

P_trunc = cumsum(p_trunc.y);

2208

end

2221

end

2209

j=j+1;

2222

j=j+1;

2210

end

2223

end

2211

%% healey_3dj_01a_2407

2224

%% healey_3dj_01a_2407

2212

if param.Q_budget_adj == 0

2225

if param.Q_budget_adj == 0

2213

Q_budget_adj=0;

2226

Q_budget_adj=0;

2214

else

2227

else

2215

Q_budget_adj=param.Q_budget_adj(1) -param.Q_budget_adj(2)*COM_from_matlab;

2228

Q_budget_adj=param.Q_budget_adj(1) -param.Q_budget_adj(2)*COM_from_matlab;

2216

end

2229

end

2217

%% shakiba_3dj_01_2407

2230

%% 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

2231

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE ,p_an,P_an ) )- param.Q ;% shakiba_3dj_01_2405

2219

delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE_trunc,p_an,P_an ) )- Q_budget_adj ;% shakiba_3dj_01_2405

2232

delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE_trunc,p_an,P_an ) )- Q_budget_adj ;% shakiba_3dj_01_2405

2220

DER_MLSE_trunc= CDF_ev(A_s*10^(delta_com/20),PDF,CDF);% 4p7 re-evaluates with truncation (delta_com includes truncation)

2221

delta_com_notrunc= 20*log10(1/A_s *-CDF_inv_ev(DER_MLSE,p_an,P_an) ) - Q_budget_adj; % 4p7 calculates COM without truncation

2222

DER_MLSE=CDF_ev(A_s*10^(delta_com_notrunc/20),PDF,CDF);% 4p7 re-evaluated DER without truncation

2223

%% shakiba_3dj_01_2407

2233

%% shakiba_3dj_01_2407

2224

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( 2/3*DER_MLSE,p_an,CDF ) )- Q ;% (178A–36)

2234

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( 2/3*DER_MLSE,p_an,CDF ) )- Q ;% (178A–36)

2225

new_com=COM_from_matlab+delta_com;

2235

new_com=COM_from_matlab+delta_com;

2226

if(delta_com<0)

2236

if(delta_com<0)

2227

delta_com=0;

2237

delta_com=0;

2228

warning('MLSE truncation failed. Try increasing trunc')

2238

warning('MLSE truncation failed. Try increasing trunc')

2229

try

2239

try

2230

hx=msgbox('MLSE truncation failed. Try increasing N_tc','warning','warn');

2240

hx=msgbox('MLSE truncation failed. Try increasing N_tc','warning','warn');

2231

set(hx,'Color',[1 0 1]);

2241

set(hx,'Color',[1 0 1]);

2232

movegui(hx,[randn randn]*100)

2242

movegui(hx,[randn randn]*100)

2233

set(hx,'Tag','COM') %

2243

set(hx,'Tag','COM') %

2234

catch

2244

catch

2235

end

2245

end

2236

end

2246

end

2237

else

2247

else

2238

warning('MLSE not applied because the DER is less than that required for the CDR to lock')

2248

warning('MLSE not applied because the DER is less than that required for the CDR to lock')

2239

DER_MLSE=NaN;

2249

DER_MLSE=NaN;

2240

new_com=COM_from_matlab;

2250

new_com=COM_from_matlab;

2241

delta_com=0;

2251

delta_com=0;

2242

Q=0;

2252

Q=0;

2243

Q_budget_adj=0;

2253

Q_budget_adj=0;

2244

DER_MLSE_trunc=NaN;

2254

DER_MLSE_trunc=NaN;

2245

%% shakiba_3dj_01_2407

2255

%% shakiba_3dj_01_2407

2246

end

2256

end

2247

2257

2248

%%

2258

%%

2249

[PDF1, CDF1, ~] = scaleCDF( PDF,-delta_com,DER0, A_s ); % create new pdf/cdf estimate for display only

2259

[PDF1, CDF1, ~] = scaleCDF( PDF,-delta_com,DER0, A_s ); % create new pdf/cdf estimate for display only

2250

MLSE_results.CDF=CDF1;

2260

MLSE_results.CDF=CDF1;

2251

MLSE_results.PDF=PDF1;

2261

MLSE_results.PDF=PDF1;

2252

MLSE_results.DER_MLSE_trunc = DER_MLSE_trunc;% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2262

MLSE_results.DER_MLSE_trunc = DER_MLSE_trunc;% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2253

MLSE_results.Q_budget_adj=Q_budget_adj; % healey_3dj_01a_2407

2263

MLSE_results.Q_budget_adj=Q_budget_adj; % healey_3dj_01a_2407

2254

MLSE_results.COM_from_matlab=COM_from_matlab;

2264

MLSE_results.COM_from_matlab=COM_from_matlab;

2255

MLSE_results.DER_MLSE=DER_MLSE;

2265

MLSE_results.DER_MLSE=DER_MLSE;

2256

MLSE_results.DER_DFE=DER_DFE;

2266

MLSE_results.DER_DFE=DER_DFE;

2257

MLSE_results.COM=new_com;

2267

MLSE_results.COM=new_com;

2258

MLSE_results.delta_com=delta_com;

2268

MLSE_results.delta_com=delta_com;

2259

MLSE_results.g_an=g_an;

2269

MLSE_results.g_an=g_an;

2260

2270

2261

2271

2262

2272

2263

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2273

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2264

if 1

2274

if 1

2265

num_ui=param.num_ui_RXFF_noise;

2275

num_ui=param.num_ui_RXFF_noise;

2266

M=param.samples_per_ui;

2276

M=param.samples_per_ui;

2267

L=param.levels;

2277

L=param.levels;

2268

sigma_X2=(L^2-1)/(3*(L-1)^2);

2278

sigma_X2=(L^2-1)/(3*(L-1)^2);

2269

fb=param.fb;

2279

fb=param.fb;

2270

R_LM=param.R_LM;

2280

R_LM=param.R_LM;

2271

end

2281

end

2272

% h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2282

% h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2273

% h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2283

% h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2274

% h=reshape(h,1,[]); % make row vectors

2284

% h=reshape(h,1,[]); % make row vectors

2275

% h=[ h(1:floor(length(h)/M)*M) ];

2285

% h=[ h(1:floor(length(h)/M)*M) ];

2276

% h= [h zeros(1,num_ui*M-length(h)) ];

2286

% h= [h zeros(1,num_ui*M-length(h)) ];

2277

% h=h(1:M:end);% resample

2287

% h=h(1:M:end);% resample

2278

% N=length(h);

2288

% N=length(h);

2279

% dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2289

% dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2280

% dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2290

% dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2281

2291

2282

samp_idx = (mod(cursor_i-1,M )+1):M:length(sbr);

2292

samp_idx = (mod(cursor_i-1,M )+1):M:length(sbr);

2283

dh= find(samp_idx == cursor_i)-1;

2293

dh= find(samp_idx == cursor_i)-1;

2284

dw=param.RxFFE_cmx;

2294

dw=param.RxFFE_cmx;

2285

h = reshape(sbr(samp_idx),1,[]); % make row vector

2295

h = reshape(sbr(samp_idx),1,[]); % make row vector

2286

h(end+1:num_ui)=0;

2296

h(end+1:num_ui)=0;

2287

h = h(1:num_ui); % h needs to have num_ui points

2297

h = h(1:num_ui); % h needs to have num_ui points

2288

N=length(h); % used in subsequent expressions

2298

N=length(h); % used in subsequent expressions

2289

2299

2290

if param.N_bg == 0

2300

if param.N_bg == 0

2291

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2301

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2292

bmax=param.bmax;

2302

bmax=param.bmax;

2293

bmin=param.bmin ;

2303

bmin=param.bmin ;

2294

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2304

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2295

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2305

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2296

idx=[];

2306

idx=[];

2297

else

2307

else

2298

Nfloating_taps=param.N_bf*param.N_bg;

2308

Nfloating_taps=param.N_bf*param.N_bg;

2299

Nmax=param.N_bmax;

2309

Nmax=param.N_bmax;

2300

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2310

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2301

Ng=param.N_bg;

2311

Ng=param.N_bg;

2302

Nf=param.N_bf;

2312

Nf=param.N_bf;

2303

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2313

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2304

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2314

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2305

% hisi=h(dh+2:((dh-dw)+Nw));

2315

% hisi=h(dh+2:((dh-dw)+Nw));

2306

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2316

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2307

% idx=sort(idx);

2317

% idx=sort(idx);

2308

bmax=param.bmax;

2318

bmax=param.bmax;

2309

bmin=param.bmin ;

2319

bmin=param.bmin ;

2310

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ones(1,Nfloating_taps)*param.bmaxg ];

2320

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ones(1,Nfloating_taps)*param.bmaxg ];

2311

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max -ones(1,Nfloating_taps)*param.bmaxg ];

2321

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max -ones(1,Nfloating_taps)*param.bmaxg ];

2312

end

2322

end

2313

Nb=param.ndfe; % DFE taps

2323

Nb=param.ndfe; % DFE taps

2314

d=dw+dh; % used for index in algorithms

2324

d=dw+dh; % used for index in algorithms

2315

indx(1:N)=(1:N)-dh-1;

2325

indx(1:N)=(1:N)-dh-1;

2316

S_n=PSD_results.S_n; % total agregate noise PSD

2326

S_n=PSD_results.S_n; % total agregate noise PSD

2317

Rn=ifft(S_n)*fb;

2327

Rn=ifft(S_n)*fb;

2318

%% HH and R

2328

%% HH and R

2319

2329

2320

%Test routine finding rxffe floating taps using best FOM for each bank

2330

%Test routine finding rxffe floating taps using best FOM for each bank

2321

isi_start = dh+2;

2331

isi_start = dh+2;

2322

isi_end = (dh-dw)+Nw;

2332

isi_end = (dh-dw)+Nw;

2323

2333

2324

%check for num_ui too small

2334

%check for num_ui too small

2325

if isi_end > length(h)

2335

if isi_end > length(h)

2326

error('num_ui_RXFF_noise (%d) is too small',num_ui);

2336

error('num_ui_RXFF_noise (%d) is too small',num_ui);

2327

end

2337

end

2328

2338

2329

hc1=[ h zeros(1,Nw-1) ];

2339

hc1=[ h zeros(1,Nw-1) ];

2330

hr1=[ h(1) zeros(1,Nw-1)];

2340

hr1=[ h(1) zeros(1,Nw-1)];

2331

H=toeplitz(hc1,hr1);

2341

H=toeplitz(hc1,hr1);

2332

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2342

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2333

if param.N_bg ~= 0

2343

if param.N_bg ~= 0

2334

switch lower(OP.RXFFE_FLOAT_CTL)

2344

switch lower(OP.RXFFE_FLOAT_CTL)

2335

case 'isi'

2345

case 'isi'

2336

hisi=h(dh+2:((dh-dw)+Nw));

2346

hisi=h(dh+2:((dh-dw)+Nw));

2337

[idx]=findbankloc( hisi ,param.RxFFE_cpx+1,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2347

[idx]=findbankloc( hisi ,param.RxFFE_cpx+1,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2338

idx=sort(idx);

2348

idx=sort(idx);

2339

otherwise

2349

otherwise

2340

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2350

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2341

idx=sort(idx);

2351

idx=sort(idx);

2342

end

2352

end

2343

end

2353

end

2344

[sigma_e,FOM,w,idx,Nw,blim] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx); % bring out blim for

2354

[sigma_e,FOM,w,idx,Nw,blim] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx); % bring out blim for

2345

MMSE_results.sigma_e=sigma_e; %

2355

MMSE_results.sigma_e=sigma_e; %

2346

MMSE_results.FOM=FOM;

2356

MMSE_results.FOM=FOM;

2347

Craw=w/w(dw+1); % returned Rx FFE taps

2357

Craw=w/w(dw+1); % returned Rx FFE taps

2348

% re-align Cmod to floating tap locations

2358

% re-align Cmod to floating tap locations

2349

if param.N_bg ~= 0

2359

if param.N_bg ~= 0

2350

C=Craw;

2360

C=Craw;

2351

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2361

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2352

C(idx+param.RxFFE_cmx+1 )=Craw(Nfix+(1:Nfloating_taps));

2362

C(idx+param.RxFFE_cmx+1 )=Craw(Nfix+(1:Nfloating_taps));

2353

else

2363

else

2354

C=Craw;

2364

C=Craw;

2355

end

2365

end

2356

MMSE_results.floating_tap_locations=idx + param.RxFFE_cmx+1;

2366

MMSE_results.floating_tap_locations=idx + param.RxFFE_cmx+1;

2357

MMSE_results.C=C;

2367

MMSE_results.C=C;

2358

MMSE_results.blim=blim; % added blim passed out for MLSD for 178A-39

2368

MMSE_results.blim=blim; % added blim passed out for MLSD for 178A-39

2359

MMSE_results.Nw=Nw;

2369

MMSE_results.Nw=Nw;

2360

2370

2361

2371

2362

2372

2363

2373

2364

2374

2365

function [sigma_e,FOM,w,idx,Nw,blim] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2375

function [sigma_e,FOM,w,idx,Nw,blim] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2366

% added blim passed out for MLSD

2376

% added blim passed out for MLSD

2367

if isempty(idx)

2377

if isempty(idx)

2368

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2378

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2369

bmax=param.bmax;

2379

bmax=param.bmax;

2370

bmin=param.bmin ;

2380

bmin=param.bmin ;

2371

else

2381

else

2372

Nfloating_taps=param.N_bf*param.N_bg;

2382

Nfloating_taps=param.N_bf*param.N_bg;

2373

%If using the routine that finds RXFFE floating taps bank-by-bank, the number of total floating taps can be less than the final amount

2383

%If using the routine that finds RXFFE floating taps bank-by-bank, the number of total floating taps can be less than the final amount

2374

Nfloating_taps = length(idx);

2384

Nfloating_taps = length(idx);

2375

Nmax=param.N_bmax;

2385

Nmax=param.N_bmax;

2376

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2386

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2377

Ng=param.N_bg;

2387

Ng=param.N_bg;

2378

Nf=param.N_bf;

2388

Nf=param.N_bf;

2379

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2389

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2380

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2390

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2381

end

2391

end

2382

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2392

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2383

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2393

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2384

% hc1=[ h zeros(1,Nw-1) ];

2394

% hc1=[ h zeros(1,Nw-1) ];

2385

% hr1=[ h(1) zeros(1,Nw-1)];

2395

% hr1=[ h(1) zeros(1,Nw-1)];

2386

% H=toeplitz(hc1,hr1);

2396

% H=toeplitz(hc1,hr1);

2387

2397

2388

if param.N_bg ~= 0

2398

if param.N_bg ~= 0

2389

H=H( :,[1:Nfix idx+param.RxFFE_cmx+1 ]);

2399

H=H( :,[1:Nfix idx+param.RxFFE_cmx+1 ]);

2390

end

2400

end

2391

%% HH and R

2401

%% HH and R

2392

HH= H'*H;

2402

HH= H'*H;

2393

if param.N_bg ~= 0

2403

if param.N_bg ~= 0

2394

Rnn=Rnn( [1:Nfix idx+param.RxFFE_cmx+1],[1:Nfix idx+param.RxFFE_cmx+1]);

2404

Rnn=Rnn( [1:Nfix idx+param.RxFFE_cmx+1],[1:Nfix idx+param.RxFFE_cmx+1]);

2395

end

2405

end

2396

R=HH+Rnn/sigma_X2;

2406

R=HH+Rnn/sigma_X2;

2397

%% hb and h0

2407

%% hb and h0

2398

Hb= H(d+2:d+Nb+1,:);

2408

Hb= H(d+2:d+Nb+1,:);

2399

h0=H(d+1,:);

2409

h0=H(d+1,:);

2400

% display(floor(h0));

2410

% display(floor(h0));

2401

2411

2402

%% Ib and zb (slide 10)

2412

%% Ib and zb (slide 10)

2403

ib=eye(Nb);

2413

ib=eye(Nb);

2404

zb=zeros(1,Nb);

2414

zb=zeros(1,Nb);

2405

wbl= [ R -Hb' -h0';...

2415

wbl= [ R -Hb' -h0';...

2406

-Hb ib zb'; ...

2416

-Hb ib zb'; ...

2407

h0 zb 0]\[h0'; zb' ;1];

2417

h0 zb 0]\[h0'; zb' ;1];

2408

2418

2409

%% re-adjust Nw to number of used taps

2419

%% re-adjust Nw to number of used taps

2410

if param.N_bg ~= 0

2420

if param.N_bg ~= 0

2411

Nw=Nwft;

2421

Nw=Nwft;

2412

end

2422

end

2413

%% check equalized pulse

2423

%% check equalized pulse

2414

w=wbl(1:Nw);

2424

w=wbl(1:Nw);

2415

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2425

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2416

2426

2417

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2427

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2418

blim = min(bmax(:), max(bmin(:), b));

2428

blim = min(bmax(:), max(bmin(:), b));

2419

if (Nb > 0) && ~isequal(b, blim)

2429

if (Nb > 0) && ~isequal(b, blim)

2420

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2430

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2421

w = wl(1:Nw);

2431

w = wl(1:Nw);

2422

end

2432

end

2423

2433

2424

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2434

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2425

%so need to chop off the extra indices on wmax and wmin

2435

%so need to chop off the extra indices on wmax and wmin

2426

if length(w)<length(wmax)

2436

if length(w)<length(wmax)

2427

wmax=wmax(1:length(w));

2437

wmax=wmax(1:length(w));

2428

wmin=wmin(1:length(w));

2438

wmin=wmin(1:length(w));

2429

end

2439

end

2430

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2440

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2431

if ~isequal(w, wlim)

2441

if ~isequal(w, wlim)

2432

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2442

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2433

if Nb > 0

2443

if Nb > 0

2434

b = Hb*wlim; % Update the feedback coefficients.

2444

b = Hb*wlim; % Update the feedback coefficients.

2435

blim = min(bmax(:), max(bmin(:), b));

2445

blim = min(bmax(:), max(bmin(:), b));

2436

end

2446

end

2437

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2447

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2438

% wl = wl(1:Nw);

2448

% wl = wl(1:Nw);

2439

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2449

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2440

end

2450

end

2441

% w=w(1:Nw) ;

2451

% w=w(1:Nw) ;

2442

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2452

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2443

w=wlim;

2453

w=wlim;

2444

b=blim;

2454

b=blim;

2445

sigma_e=sqrt(sigma_X2*(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b)); % Commit request 4p4_5 from healey_3dj_COM_01_240416

2455

sigma_e=sqrt(sigma_X2*(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b)); % Commit request 4p4_5 from healey_3dj_COM_01_240416

2446

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2456

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2447

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2457

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2448

2458

2449

%not all output_args are filled here but most are

2459

%not all output_args are filled here but most are

2450

2460

2451

switch lower(OP.TDECQ)

2461

switch lower(OP.TDECQ)

2452

case { false 'none' } % should be the default

2462

case { false 'none' } % should be the default

2453

output_args.VMA=[];

2463

output_args.VMA=[];

2454

case 'vma'

2464

case 'vma'

2455

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2465

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2456

output_args.VMA=est_vma.VMA;

2466

output_args.VMA=est_vma.VMA;

2457

otherwise

2467

otherwise

2458

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2468

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2459

end

2469

end

2460

2470

2461

fileset_str=str2csv({chdata.base});

2471

fileset_str=str2csv({chdata.base});

2462

output_args.file_names=sprintf('"%s"', fileset_str);

2472

output_args.file_names=sprintf('"%s"', fileset_str);

2463

% [ahealey] Echo the termination parameters in the output arguments..

2473

% [ahealey] Echo the termination parameters in the output arguments..

2464

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2474

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2465

output_args.(odt_param{:}) = param.(odt_param{:});

2475

output_args.(odt_param{:}) = param.(odt_param{:});

2466

end

2476

end

2467

% [ahealey] End of modifications.

2477

% [ahealey] End of modifications.

2468

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2478

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2469

output_args.(pkg_params{:})= param.(pkg_params{:});

2479

output_args.(pkg_params{:})= param.(pkg_params{:});

2470

end

2480

end

2471

output_args.baud_rate_GHz=param.fb/1e9;

2481

output_args.baud_rate_GHz=param.fb/1e9;

2472

output_args.f_Nyquist_GHz = param.fb/2e9;

2482

output_args.f_Nyquist_GHz = param.fb/2e9;

2473

output_args.BER=param.specBER;

2483

output_args.BER=param.specBER;

2474

output_args.FOM = fom_result.FOM;

2484

output_args.FOM = fom_result.FOM;

2475

output_args.sigma_N=Noise_Struct.sigma_N;

2485

output_args.sigma_N=Noise_Struct.sigma_N;

2476

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2486

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2477

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2487

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2478

output_args.tail_RSS=fom_result.tail_RSS;

2488

output_args.tail_RSS=fom_result.tail_RSS;

2479

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2489

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2480

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2490

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2481

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2491

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2482

try

2492

try

2483

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2493

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2484

catch

2494

catch

2485

output_args.uneq_FIR_peak_time=[];

2495

output_args.uneq_FIR_peak_time=[];

2486

end

2496

end

2487

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2497

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2488

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2498

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2489

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2499

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2490

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2500

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2491

2501

2492

if OP.RX_CALIBRATION== 1

2502

if OP.RX_CALIBRATION== 1

2493

output_args.sigma_bn=sigma_bn;

2503

output_args.sigma_bn=sigma_bn;

2494

else

2504

else

2495

output_args.sigma_bn=[];

2505

output_args.sigma_bn=[];

2496

end

2506

end

2497

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2507

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2498

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2508

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2499

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2509

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2500

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2510

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2501

2511

2502

if OP.RX_CALIBRATION == 0

2512

if OP.RX_CALIBRATION == 0

2503

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2513

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2504

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2514

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2505

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2515

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2506

else

2516

else

2507

output_args.peak_MDXTK_interference_at_BER_mV=[];

2517

output_args.peak_MDXTK_interference_at_BER_mV=[];

2508

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2518

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2509

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2519

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2510

end

2520

end

2511

%output_args.ICN_mV=ICN*1000;

2521

%output_args.ICN_mV=ICN*1000;

2512

% output_args.ICN_test_mV=ICN_test*1000;

2522

% output_args.ICN_test_mV=ICN_test*1000;

2513

xtk=param.num_next+param.num_fext;

2523

xtk=param.num_next+param.num_fext;

2514

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2524

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2515

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2525

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2516

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2526

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2517

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2527

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2518

else

2528

else

2519

output_args.MDNEXT_ICN_92_46_mV=0;

2529

output_args.MDNEXT_ICN_92_46_mV=0;

2520

output_args.MDFEXT_ICN_92_47_mV=0;

2530

output_args.MDFEXT_ICN_92_47_mV=0;

2521

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2531

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2522

end

2532

end

2523

%output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(A_s/(peak_interference_at_BER/qfuncinv(param.specBER))); modified by Yasuo Hidaka, 8/7/17

2533

%output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(A_s/(peak_interference_at_BER/qfuncinv(param.specBER))); modified by Yasuo Hidaka, 8/7/17

2524

if 1

2534

if 1

2525

output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(COM_SNR_Struct.A_s/(Noise_Struct.peak_interference_at_BER/sqrt(2)/erfcinv(2*param.specBER)));

2535

output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(COM_SNR_Struct.A_s/(Noise_Struct.peak_interference_at_BER/sqrt(2)/erfcinv(2*param.specBER)));

2526

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2536

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2527

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2537

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2528

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2538

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2529

end

2539

end

2530

2540

2531

2541

2532

switch param.CTLE_type

2542

switch param.CTLE_type

2533

case 'CL93'

2543

case 'CL93'

2534

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2544

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2535

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2545

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2536

output_args.g_DC_HP=[];

2546

output_args.g_DC_HP=[];

2537

output_args.HP_poles_zero=[];

2547

output_args.HP_poles_zero=[];

2538

case 'CL120d'

2548

case 'CL120d'

2539

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2549

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2540

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2550

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2541

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2551

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2542

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2552

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2543

case 'CL120e'

2553

case 'CL120e'

2544

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.f_HP_Z(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle) param.f_HP_P(fom_result.ctle)];

2554

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.f_HP_Z(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle) param.f_HP_P(fom_result.ctle)];

2545

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2555

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2546

output_args.g_DC_HP=[];

2556

output_args.g_DC_HP=[];

2547

output_args.HP_poles_zero=[];

2557

output_args.HP_poles_zero=[];

2548

end

2558

end

2549

output_args.TXLE_taps=fom_result.txffe;

2559

output_args.TXLE_taps=fom_result.txffe;

2550

if length(output_args.TXLE_taps) >= 3

2560

if length(output_args.TXLE_taps) >= 3

2551

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2561

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2552

else

2562

else

2553

output_args.Pre2Pmax=[];

2563

output_args.Pre2Pmax=[];

2554

end

2564

end

2555

output_args.DFE_taps=fom_result.DFE_taps;

2565

output_args.DFE_taps=fom_result.DFE_taps;

2556

if param.Floating_DFE || param.Floating_RXFFE

2566

if param.Floating_DFE || param.Floating_RXFFE

2557

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2567

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2558

else

2568

else

2559

output_args.floating_tap_locations=[];

2569

output_args.floating_tap_locations=[];

2560

end

2570

end

2561

2571

2562

if OP.RxFFE

2572

if OP.RxFFE

2563

output_args.RxFFE=fom_result.RxFFE;

2573

output_args.RxFFE=fom_result.RxFFE;

2564

output_args.RxFFEgain=param.current_ffegain;

2574

output_args.RxFFEgain=param.current_ffegain;

2565

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2575

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2566

output_args.RxFFE=[];

2576

output_args.RxFFE=[];

2567

output_args.RxFFEgain=[];

2577

output_args.RxFFEgain=[];

2568

end

2578

end

2569

2579

2570

output_args.itick=fom_result.itick;

2580

output_args.itick=fom_result.itick;

2571

2581

2572

% Calculation of error propagation and burst probability

2582

% Calculation of error propagation and burst probability

2573

if OP.nburst>0

2583

if OP.nburst>0

2574

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2584

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2575

output_args.error_propagation_probability = p_error_propagation;

2585

output_args.error_propagation_probability = p_error_propagation;

2576

output_args.burst_probabilities = p_burst;

2586

output_args.burst_probabilities = p_burst;

2577

else

2587

else

2578

output_args.error_propagation_probability = [];

2588

output_args.error_propagation_probability = [];

2579

output_args.burst_probabilities = [];

2589

output_args.burst_probabilities = [];

2580

end

2590

end

2581

2591

2582

2592

2583

%begin yasuo patch 12/11/2018

2593

%begin yasuo patch 12/11/2018

2584

% collect sigma values to report

2594

% collect sigma values to report

2585

% pdf2sgm() is a function to calculate sigma value from PDF

2595

% pdf2sgm() is a function to calculate sigma value from PDF

2586

% It is added at the end of this file code.

2596

% It is added at the end of this file code.

2587

% I am not sure if an equivalent function already exists.

2597

% I am not sure if an equivalent function already exists.

2588

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2598

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2589

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2599

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2590

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2600

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2591

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2601

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2592

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2602

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2593

output_args.sgm_G = Noise_Struct.sigma_G;

2603

output_args.sgm_G = Noise_Struct.sigma_G;

2594

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2604

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2595

output_args.sgm_N = Noise_Struct.sigma_N;

2605

output_args.sgm_N = Noise_Struct.sigma_N;

2596

output_args.sgm_TX = Noise_Struct.sigma_TX;

2606

output_args.sgm_TX = Noise_Struct.sigma_TX;

2597

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2607

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2598

if OP.RX_CALIBRATION == 0

2608

if OP.RX_CALIBRATION == 0

2599

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2609

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2600

else

2610

else

2601

output_args.sgm_xt=[];

2611

output_args.sgm_xt=[];

2602

end

2612

end

2603

% end yasuo patch

2613

% end yasuo patch

2604

2614

2605

% r259 putting COM, VEO and loss last in report

2615

% r259 putting COM, VEO and loss last in report

2606

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2616

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2607

if param.N_qb ~= 0

2617

if param.ENOB ~= 0

2608

output_args.sgm_Q =Noise_Struct.sigma_Q;

2618

output_args.sgm_Q =Noise_Struct.sigma_Q;

2609

output_args.sigma_before_clip = Noise_Struct.sigma_before_clip;

2619

output_args.sigma_before_clip = Noise_Struct.sigma_before_clip;

2610

output_args.peak_clip = Noise_Struct.peak_clip;

2620

output_args.peak_clip = Noise_Struct.peak_clip;

2611

output_args.P2ptopsigma_clip = Noise_Struct.p2ptosigma_clip;

2621

output_args.P2ptopsigma_clip = Noise_Struct.p2ptosigma_clip;

2612

end

2622

end

2613

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2623

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2614

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2624

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2615

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2625

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2616

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2626

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2617

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2627

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2618

output_args.VEO_window_mUI= param.T_O;

2628

output_args.VEO_window_mUI= param.T_O;

2619

else

2629

else

2620

output_args.EW_UI_est=[];

2630

output_args.EW_UI_est=[];

2621

output_args.eye_contour=[];

2631

output_args.eye_contour=[];

2622

output_args.VEO_window_mUI= [];

2632

output_args.VEO_window_mUI= [];

2623

end

2633

end

2624

2634

2625

if sum(param.AC_CM_RMS) ~= 0

2635

if sum(param.AC_CM_RMS) ~= 0

2626

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2636

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2627

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2637

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2628

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2638

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2629

else

2639

else

2630

output_args.sigma_ACCM_at_tp0_mV=[];

2640

output_args.sigma_ACCM_at_tp0_mV=[];

2631

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2641

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2632

end

2642

end

2633

if OP.MLSE

2643

if OP.MLSE

2634

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2644

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2635

output_args.delta_COM = COM_SNR_Struct.delta_COM;

2645

output_args.delta_COM = COM_SNR_Struct.delta_COM;

2636

output_args.DER_DFE= COM_SNR_Struct.DER_DFE;

2646

output_args.DER_DFE= COM_SNR_Struct.DER_DFE;

2637

output_args.DER_MLSE= COM_SNR_Struct.DER_MLSE;

2647

output_args.DER_MLSE= COM_SNR_Struct.DER_MLSE;

2638

if strcmpi(upper(OP.PHY),'C2M')

2648

if strcmpi(upper(OP.PHY),'C2M')

2639

output_args.VEC_dB_orig= COM_SNR_Struct.VEC_dB_orig;

2649

output_args.VEC_dB_orig= COM_SNR_Struct.VEC_dB_orig;

2640

output_args.delta_VEC = COM_SNR_Struct.delta_VEC;

2650

output_args.delta_VEC = COM_SNR_Struct.delta_VEC;

2641

output_args.VEC_dB_orig = COM_SNR_Struct.VEC_dB_orig;

2651

output_args.VEC_dB_orig = COM_SNR_Struct.VEC_dB_orig;

2642

output_args.VEC_dB= COM_SNR_Struct.VEC_dB;

2652

output_args.VEC_dB= COM_SNR_Struct.VEC_dB;

2643

end

2653

end

2644

end

2654

end

2645

%

2655

%

2646

output_args.COM_dB=COM_SNR_Struct.COM;

2656

output_args.COM_dB=COM_SNR_Struct.COM;

2647

% end yasuo patch

2657

% end yasuo patch

2648

% begin yasuo patch 3/18/2019

2658

% begin yasuo patch 3/18/2019

2649

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2659

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2650

% end yasuo patch

2660

% end yasuo patch

2651

function [ seq syms syms_nrz ] = PRBS13Q( )

2661

function [ seq syms syms_nrz ] = PRBS13Q( )

2652

%UNTITLED Summary of this function goes here

2662

%UNTITLED Summary of this function goes here

2653

% Detailed explanation goes here

2663

% Detailed explanation goes here

2654

2664

2655

2665

2656

taps = ([13 12 2 1]);

2666

taps = ([13 12 2 1]);

2657

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2667

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2658

[seq_nrz c] =LFSR(seed,taps);

2668

[seq_nrz c] =LFSR(seed,taps);

2659

seq_nrz=2*(seq_nrz-0.5);

2669

seq_nrz=2*(seq_nrz-0.5);

2660

seq=pam(seq_nrz);

2670

seq=pam(seq_nrz);

2661

% syms=round(2*(seq+1));

2671

% syms=round(2*(seq+1));

2662

syms((round(2*(seq+1))/2==2))=3;

2672

syms((round(2*(seq+1))/2==2))=3;

2663

syms((round(2*(seq+1))/2==1.5))=2;

2673

syms((round(2*(seq+1))/2==1.5))=2;

2664

syms((round(2*(seq+1))/2==.5))=1;

2674

syms((round(2*(seq+1))/2==.5))=1;

2665

syms((round(2*(seq+1))/2==0))=0;

2675

syms((round(2*(seq+1))/2==0))=0;

2666

2676

2667

% syms_nrz=((seq_nrz+1)/2);

2677

% syms_nrz=((seq_nrz+1)/2);

2668

2678

2669

syms_nrz=seq_nrz;

2679

syms_nrz=seq_nrz;

2670

2680

2671

2681

2672

function[seq c]=LFSR(s,t)

2682

function[seq c]=LFSR(s,t)

2673

%s=initial state of LFSR, you can choose any lenght of LFSR

2683

%s=initial state of LFSR, you can choose any lenght of LFSR

2674

%Instruction:==========

2684

%Instruction:==========

2675

%Save LFSR.m in your current directory and type following

2685

%Save LFSR.m in your current directory and type following

2676

%on Command window for simulating 5 bit LFSR with tap [5 2]

2686

%on Command window for simulating 5 bit LFSR with tap [5 2]

2677

%---------------------

2687

%---------------------

2678

%>>s=[1 1 0 0 1]

2688

%>>s=[1 1 0 0 1]

2679

%>>t=[5 2]

2689

%>>t=[5 2]

2680

%>>[seq c] =LFSR(s,t)

2690

%>>[seq c] =LFSR(s,t)

2681

%---------------------------

2691

%---------------------------

2682

%seq = generated sequence

2692

%seq = generated sequence

2683

%c will be matrix containing the states of LFSR raw wise

2693

%c will be matrix containing the states of LFSR raw wise

2684

%

2694

%

2685

%-----------------------------------------------------------

2695

%-----------------------------------------------------------

2686

%If any doubt, confusion or feedback please contact me

2696

%If any doubt, confusion or feedback please contact me

2687

% NIKESH BAJAJ

2697

% NIKESH BAJAJ

2688

% bajaj.nikkey@gmail.com (+91-9915522564)

2698

% bajaj.nikkey@gmail.com (+91-9915522564)

2689

% Asst. Professor at Lovely Profesional University

2699

% Asst. Professor at Lovely Profesional University

2690

% Masters from Aligarh Muslim University,INDIA

2700

% Masters from Aligarh Muslim University,INDIA

2691

%--------------------------------------------------

2701

%--------------------------------------------------

2692

n=length(s);

2702

n=length(s);

2693

c(1,:)=s;

2703

c(1,:)=s;

2694

m=length(t);

2704

m=length(t);

2695

for k=1:2^n-2;

2705

for k=1:2^n-2;

2696

b(1)=xor(s(t(1)), s(t(2)));

2706

b(1)=xor(s(t(1)), s(t(2)));

2697

if m>2;

2707

if m>2;

2698

for i=1:m-2;

2708

for i=1:m-2;

2699

b(i+1)=xor(s(t(i+2)), b(i));

2709

b(i+1)=xor(s(t(i+2)), b(i));

2700

end

2710

end

2701

end

2711

end

2702

j=1:n-1;

2712

j=1:n-1;

2703

s(n+1-j)=s(n-j);

2713

s(n+1-j)=s(n-j);

2704

s(1)=b(m-1);

2714

s(1)=b(m-1);

2705

c(k+1,:)=s;

2715

c(k+1,:)=s;

2706

end

2716

end

2707

seq=c(:,n)';

2717

seq=c(:,n)';

2708

2718

2709

function [ dataout ] = pam( data )

2719

function [ dataout ] = pam( data )

2710

% mapping data usng Grey Coding

2720

% mapping data usng Grey Coding

2711

for i=1:2:floor(length(data)/2)*2

2721

for i=1:2:floor(length(data)/2)*2

2712

if data(i:i+1)==[ -1 -1 ]

2722

if data(i:i+1)==[ -1 -1 ]

2713

dataout(ceil(i/2)) = -1;

2723

dataout(ceil(i/2)) = -1;

2714

elseif data(i:i+1)==[ -1 1 ]

2724

elseif data(i:i+1)==[ -1 1 ]

2715

dataout(ceil(i/2)) = -1/3;

2725

dataout(ceil(i/2)) = -1/3;

2716

elseif data(i:i+1)==[ 1 1 ]

2726

elseif data(i:i+1)==[ 1 1 ]

2717

dataout(ceil(i/2)) = 1/3;

2727

dataout(ceil(i/2)) = 1/3;

2718

elseif data(i:i+1)==[ 1 -1 ]

2728

elseif data(i:i+1)==[ 1 -1 ]

2719

dataout(ceil(i/2)) = 1;

2729

dataout(ceil(i/2)) = 1;

2720

end

2730

end

2721

end

2731

end

2722

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2732

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2723

db = @(x) 20*log10(abs(x));

2733

db = @(x) 20*log10(abs(x));

2724

disp('computing TD_RILN...')

2734

disp('computing TD_RILN...')

2725

sdd21=squeeze(sdd21);

2735

sdd21=squeeze(sdd21);

2726

if iscolumn(sdd21)

2736

if iscolumn(sdd21)

2727

sdd21=sdd21.';

2737

sdd21=sdd21.';

2728

end

2738

end

2729

RIL=squeeze(RIL);

2739

RIL=squeeze(RIL);

2730

if iscolumn(RIL)

2740

if iscolumn(RIL)

2731

RIL=RIL.';

2741

RIL=RIL.';

2732

end

2742

end

2733

print_for_codereview=1;

2743

print_for_codereview=1;

2734

if exist('OP','var')

2744

if exist('OP','var')

2735

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2745

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2736

2746

2737

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2747

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2738

H_bw=Butterworth_Filter(param,faxis_f2,1);

2748

H_bw=Butterworth_Filter(param,faxis_f2,1);

2739

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2749

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2740

H_tw=Tukey_Window(faxis_f2,param);

2750

H_tw=Tukey_Window(faxis_f2,param);

2741

H_tw=ones(1,length(faxis_f2) );

2751

H_tw=ones(1,length(faxis_f2) );

2742

[RILN_TD_struct.REF.FIR, ...

2752

[RILN_TD_struct.REF.FIR, ...

2743

RILN_TD_struct.REF.t, ...

2753

RILN_TD_struct.REF.t, ...

2744

RILN_TD_struct.REF.causality_correction_dB, ...

2754

RILN_TD_struct.REF.causality_correction_dB, ...

2745

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2755

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2746

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2756

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2747

[RILN_TD_struct.FIT.FIR, ...

2757

[RILN_TD_struct.FIT.FIR, ...

2748

RILN_TD_struct.FIT.t, ...

2758

RILN_TD_struct.FIT.t, ...

2749

RILN_TD_struct.FIT.causality_correction_dB, ...

2759

RILN_TD_struct.FIT.causality_correction_dB, ...

2750

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2760

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2751

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2761

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2752

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2762

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2753

NrangeUI=1000;

2763

NrangeUI=1000;

2754

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2764

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2755

range=ipeak:range_end;

2765

range=ipeak:range_end;

2756

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2766

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2757

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2767

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2758

RILN_TD_struct.FOM=-inf;

2768

RILN_TD_struct.FOM=-inf;

2759

RILN_TD_struct.FOM_PDF=-inf;

2769

RILN_TD_struct.FOM_PDF=-inf;

2760

rms_fom=-inf;

2770

rms_fom=-inf;

2761

for im=1:param.samples_per_ui

2771

for im=1:param.samples_per_ui

2762

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2772

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2763

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2773

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2764

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2774

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2765

cdf=pdf; cdf.y=cumsum(pdf.y);

2775

cdf=pdf; cdf.y=cumsum(pdf.y);

2766

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2776

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2767

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2777

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2768

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2778

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2769

if print_for_codereview % remove once all checked out

2779

if print_for_codereview % remove once all checked out

2770

h=figure(191);set(gcf,'Tag','COM');

2780

h=figure(191);set(gcf,'Tag','COM');

2771

semilogy(-cdf.x,cdf.y);

2781

semilogy(-cdf.x,cdf.y);

2772

% xlim ([0,-cdf.x(1)])

2782

% xlim ([0,-cdf.x(1)])

2773

ylim([param.specBER 1]);title ('CDF of RILN')

2783

ylim([param.specBER 1]);title ('CDF of RILN')

2774

hold on

2784

hold on

2775

end

2785

end

2776

if rms>rms_fom

2786

if rms>rms_fom

2777

rms_fom=rms;

2787

rms_fom=rms;

2778

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2788

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2779

RILN_TD_struct.PDF=pdf;

2789

RILN_TD_struct.PDF=pdf;

2780

end

2790

end

2781

end

2791

end

2782

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2792

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2783

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2793

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2784

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2794

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2785

if print_for_codereview % remove once all checked out

2795

if print_for_codereview % remove once all checked out

2786

figure(9003);set(gcf,'Tag','COM');

2796

figure(9003);set(gcf,'Tag','COM');

2787

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2797

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2788

hold on

2798

hold on

2789

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2799

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2790

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2800

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2791

hold off

2801

hold off

2792

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

2802

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

2793

figure(9004);set(gcf,'Tag','COM');

2803

figure(9004);set(gcf,'Tag','COM');

2794

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2804

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2795

hold on

2805

hold on

2796

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2806

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2797

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2807

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2798

grid on

2808

grid on

2799

legend('show')

2809

legend('show')

2800

end

2810

end

2801

end

2811

end

2802

function is_illegal=RXFFE_Illegal(C,param,last_index)

2812

function is_illegal=RXFFE_Illegal(C,param,last_index)

2803

2813

2804

%check if RXFFE taps are illegal

2814

%check if RXFFE taps are illegal

2805

%C = RXFFE taps

2815

%C = RXFFE taps

2806

%param = COM param struct

2816

%param = COM param struct

2807

%last_index is used when computing illegality prior to Backoff. It will be set so taps

2817

%last_index is used when computing illegality prior to Backoff. It will be set so taps

2808

% in the Backoff region are not considered in the legality check.

2818

% in the Backoff region are not considered in the legality check.

2809

2819

2810

%If last index is omitted, set it to length(C)

2820

%If last index is omitted, set it to length(C)

2811

if nargin<3

2821

if nargin<3

2812

last_index=length(C);

2822

last_index=length(C);

2813

end

2823

end

2814

2824

2815

is_illegal=0;

2825

is_illegal=0;

2816

2826

2817

%Check cursor tap

2827

%Check cursor tap

2818

Ccur_i=param.RxFFE_cmx+1;

2828

Ccur_i=param.RxFFE_cmx+1;

2819

if C(Ccur_i) < param.ffe_main_cursor_min

2829

if C(Ccur_i) < param.ffe_main_cursor_min

2820

is_illegal=1;

2830

is_illegal=1;

2821

return;

2831

return;

2822

end

2832

end

2823

2833

2824

%Check postcursors

2834

%Check postcursors

2825

if param.ffe_post_tap_len ~=0

2835

if param.ffe_post_tap_len ~=0

2826

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

2836

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

2827

is_illegal=1;

2837

is_illegal=1;

2828

return;

2838

return;

2829

end

2839

end

2830

if (param.ffe_post_tap_len > 1)

2840

if (param.ffe_post_tap_len > 1)

2831

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

2841

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

2832

is_illegal=1;

2842

is_illegal=1;

2833

return;

2843

return;

2834

end

2844

end

2835

end

2845

end

2836

end

2846

end

2837

2847

2838

%Check precursors

2848

%Check precursors

2839

if param.ffe_pre_tap_len ~=0

2849

if param.ffe_pre_tap_len ~=0

2840

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

2850

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

2841

is_illegal=1;

2851

is_illegal=1;

2842

return;

2852

return;

2843

end

2853

end

2844

if (param.ffe_pre_tap_len > 1)

2854

if (param.ffe_pre_tap_len > 1)

2845

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

2855

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

2846

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

2856

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

2847

is_illegal=1;

2857

is_illegal=1;

2848

return;

2858

return;

2849

end % 11.22.2018 Yasou Hadaka

2859

end % 11.22.2018 Yasou Hadaka

2850

end

2860

end

2851

end

2861

end

2852

function S =R_series2(zref,f,R)

2862

function S =R_series2(zref,f,R)

2853

r=ones(1,length(f))*R;

2863

r=ones(1,length(f))*R;

2854

S.Parameters(1,1,:) = r./(r + 2*zref);

2864

S.Parameters(1,1,:) = r./(r + 2*zref);

2855

S.Parameters(2,2,:) = r./(r + 2*zref);

2865

S.Parameters(2,2,:) = r./(r + 2*zref);

2856

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

2866

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

2857

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

2867

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

2858

% Sm=sparameters(S.Parameters,f,zref);

2868

% Sm=sparameters(S.Parameters,f,zref);

2859

2869

2860

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

2870

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

2861

2871

2862

if use_RC

2872

if use_RC

2863

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

2873

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

2864

else

2874

else

2865

H_tw=ones(1,length(f));

2875

H_tw=ones(1,length(f));

2866

end

2876

end

2867

function SLD=SL(S,f,R)

2877

function SLD=SL(S,f,R)

2868

% source load impact return loss add to S21

2878

% source load impact return loss add to S21

2869

% S and SLD are the same structure

2879

% S and SLD are the same structure

2870

% S.Parameters

2880

% S.Parameters

2871

% S.Impedance

2881

% S.Impedance

2872

% S.NumPorts

2882

% S.NumPorts

2873

% S.Frequencies

2883

% S.Frequencies

2874

SLD=S; % assign the fields

2884

SLD=S; % assign the fields

2875

zref=100;

2885

zref=100;

2876

if R==0

2886

if R==0

2877

warndlg('Termination should not be set to zero');

2887

warndlg('Termination should not be set to zero');

2878

SLD=S;

2888

SLD=S;

2879

return

2889

return

2880

end

2890

end

2881

2891

2882

if R > zref

2892

if R > zref

2883

spr =R_series2(zref,f,(R-zref)); % make series sparameter

2893

spr =R_series2(zref,f,(R-zref)); % make series sparameter

2884

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

2894

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

2885

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2895

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2886

combines4p( ...

2896

combines4p( ...

2887

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2897

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2888

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2898

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2889

);

2899

);

2890

elseif R < zref

2900

elseif R < zref

2891

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

2901

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

2892

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

2902

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

2893

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2903

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2894

combines4p( ...

2904

combines4p( ...

2895

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2905

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2896

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2906

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2897

);

2907

);

2898

else

2908

else

2899

SLD=S;

2909

SLD=S;

2900

end

2910

end

2901

2911

2902

%%

2912

%%

2903

2913

2904

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

2914

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

2905

p1=param.CTLE_fp1(1);

2915

p1=param.CTLE_fp1(1);

2906

z1=param.CTLE_fz(1);

2916

z1=param.CTLE_fz(1);

2907

p2=param.CTLE_fp2(1);

2917

p2=param.CTLE_fp2(1);

2908

zlf=param.f_HP(1);

2918

zlf=param.f_HP(1);

2909

plf=param.f_HP(1);

2919

plf=param.f_HP(1);

2910

f_b=param.fb;

2920

f_b=param.fb;

2911

f_r=param.f_r;

2921

f_r=param.f_r;

2912

eta_0=param.eta_0;

2922

eta_0=param.eta_0;

2913

H_CTF = ( 10^(G_DC/20)+ 1i*f/z1 ) .*( 10^(G_DC2/20) + 1i*f/zlf )./ ( ( 1+1i*f/p1) .* ( 1+1i*f/p2) .* ( 1+1i*f/plf));

2923

H_CTF = ( 10^(G_DC/20)+ 1i*f/z1 ) .*( 10^(G_DC2/20) + 1i*f/zlf )./ ( ( 1+1i*f/p1) .* ( 1+1i*f/p2) .* ( 1+1i*f/plf));

2914

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

2924

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

2915

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

2925

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

2916

if 0

2926

if 0

2917

figure

2927

figure

2918

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

2928

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

2919

% see if it looks correct

2929

% see if it looks correct

2920

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

2930

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

2921

ylabel('dB');

2931

ylabel('dB');

2922

xlabel('GHz');

2932

xlabel('GHz');

2923

title( 'H_ctf with H_r')

2933

title( 'H_ctf with H_r')

2924

grid on

2934

grid on

2925

ylim([-30 0])

2935

ylim([-30 0])

2926

end

2936

end

2927

2937

2928

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

2938

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

2929

2939

2930

%Fill TDR data

2940

%Fill TDR data

2931

if package_testcase_i == 1

2941

if package_testcase_i == 1

2932

if OP.TDR

2942

if OP.TDR

2933

output_args.Z11est=chdata(1).TDR11.avgZport;

2943

output_args.Z11est=chdata(1).TDR11.avgZport;

2934

if ~param.FLAG.S2P

2944

if ~param.FLAG.S2P

2935

output_args.Z22est=chdata(1).TDR22.avgZport;

2945

output_args.Z22est=chdata(1).TDR22.avgZport;

2936

else

2946

else

2937

output_args.Z22est=[];

2947

output_args.Z22est=[];

2938

end

2948

end

2939

if OP.AUTO_TFX

2949

if OP.AUTO_TFX

2940

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

2950

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

2941

else

2951

else

2942

output_args.tfx_estimate=[];

2952

output_args.tfx_estimate=[];

2943

end

2953

end

2944

else

2954

else

2945

output_args.Z11est=[];

2955

output_args.Z11est=[];

2946

output_args.Z22est=[];

2956

output_args.Z22est=[];

2947

output_args.tfx_estimate=[];

2957

output_args.tfx_estimate=[];

2948

end

2958

end

2949

end

2959

end

2950

2960

2951

% Process ERL

2961

% Process ERL

2952

if package_testcase_i == 1

2962

if package_testcase_i == 1

2953

if OP.ERL

2963

if OP.ERL

2954

output_args.ERL11=chdata(1).TDR11.ERL;

2964

output_args.ERL11=chdata(1).TDR11.ERL;

2955

if ~param.FLAG.S2P

2965

if ~param.FLAG.S2P

2956

output_args.ERL22=chdata(1).TDR22.ERL;

2966

output_args.ERL22=chdata(1).TDR22.ERL;

2957

else

2967

else

2958

output_args.ERL22=[];

2968

output_args.ERL22=[];

2959

end

2969

end

2960

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

2970

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

2961

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

2971

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

2962

else

2972

else

2963

output_args.ERL11=[];

2973

output_args.ERL11=[];

2964

output_args.ERL22=[];

2974

output_args.ERL22=[];

2965

end

2975

end

2966

end

2976

end

2967

if OP.ERL

2977

if OP.ERL

2968

if OP.TDR_W_TXPKG

2978

if OP.TDR_W_TXPKG

2969

min_ERL=output_args.ERL22;

2979

min_ERL=output_args.ERL22;

2970

ERL= [ nan output_args.ERL22 ];

2980

ERL= [ nan output_args.ERL22 ];

2971

else

2981

else

2972

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

2982

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

2973

min_ERL=output_args.ERL11;

2983

min_ERL=output_args.ERL11;

2974

ERL= [ output_args.ERL11 nan ];

2984

ERL= [ output_args.ERL11 nan ];

2975

else

2985

else

2976

min_ERL=min(output_args.ERL11,output_args.ERL22);

2986

min_ERL=min(output_args.ERL11,output_args.ERL22);

2977

ERL= [ output_args.ERL11 output_args.ERL22 ];

2987

ERL= [ output_args.ERL11 output_args.ERL22 ];

2978

end

2988

end

2979

end

2989

end

2980

output_args.ERL=min_ERL;

2990

output_args.ERL=min_ERL;

2981

else

2991

else

2982

min_ERL=[];

2992

min_ERL=[];

2983

ERL= [];

2993

ERL= [];

2984

output_args.ERL=[];

2994

output_args.ERL=[];

2985

end

2995

end

2986

if OP.ERL_ONLY

2996

if OP.ERL_ONLY

2987

if OP.BREAD_CRUMBS

2997

if OP.BREAD_CRUMBS

2988

output_args.OP=OP;

2998

output_args.OP=OP;

2989

output_args.param=param;

2999

output_args.param=param;

2990

output_args.chdata=chdata;

3000

output_args.chdata=chdata;

2991

%This seems to be the intent of setting fom_result.ran=0. Add it

3001

%This seems to be the intent of setting fom_result.ran=0. Add it

2992

%to output_args so there is a fom_result field.

3002

%to output_args so there is a fom_result field.

2993

fom_result.ran=0;

3003

fom_result.ran=0;

2994

output_args.fom_result=fom_result;

3004

output_args.fom_result=fom_result;

2995

end

3005

end

2996

output_args.Z_t=param.Z_t;

3006

output_args.Z_t=param.Z_t;

2997

fileset_str=str2csv({chdata(1).base});

3007

fileset_str=str2csv({chdata(1).base});

2998

output_args.file_names=sprintf('"%s"', fileset_str);

3008

output_args.file_names=sprintf('"%s"', fileset_str);

2999

if OP.DISPLAY_WINDOW

3009

if OP.DISPLAY_WINDOW

3000

savefigs(param, OP);

3010

savefigs(param, OP);

3001

end

3011

end

3002

end

3012

end

3003

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3013

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3004

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3014

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3005

p1_ctle = -2*pi*f_p1;

3015

p1_ctle = -2*pi*f_p1;

3006

p2_ctle = -2*pi*f_p2;

3016

p2_ctle = -2*pi*f_p2;

3007

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3017

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3008

k_ctle = -p2_ctle;

3018

k_ctle = -p2_ctle;

3009

bilinear_fs = 2*fb*oversampling;

3019

bilinear_fs = 2*fb*oversampling;

3010

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3020

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3011

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3021

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3012

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3022

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3013

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3023

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3014

% allow for different pole zeros RIM 9-29-2015

3024

% allow for different pole zeros RIM 9-29-2015

3015

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3025

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3016

B_filt =k_ctle*kd*poly([zd, -1]);

3026

B_filt =k_ctle*kd*poly([zd, -1]);

3017

A_filt=poly([p1d, p2d]);

3027

A_filt=poly([p1d, p2d]);

3018

impulse_response=filter(B_filt,A_filt,ir_in);

3028

impulse_response=filter(B_filt,A_filt,ir_in);

3019

3029

3020

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3030

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3021

Over_sample=2;

3031

Over_sample=2;

3022

num_files=length(chdata);

3032

num_files=length(chdata);

3023

for i=1:num_files

3033

for i=1:num_files

3024

V=chdata(i).uneq_pulse_response;

3034

V=chdata(i).uneq_pulse_response;

3025

T=chdata(i).t;

3035

T=chdata(i).t;

3026

dt=T(2)-T(1);

3036

dt=T(2)-T(1);

3027

f=0:1/max(T):1/dt;

3037

f=0:1/max(T):1/dt;

3028

chdata(i).faxis=f;

3038

chdata(i).faxis=f;

3029

f75=find(f >= param.fb*.75,1,'first');

3039

f75=find(f >= param.fb*.75,1,'first');

3030

fnq=find(f >= param.fb*.5,1,'first');

3040

fnq=find(f >= param.fb*.5,1,'first');

3031

chdata(i).fmaxi = length(f);

3041

chdata(i).fmaxi = length(f);

3032

chdata(i).faxis = f;

3042

chdata(i).faxis = f;

3033

UI=param.ui; % unit interval

3043

UI=param.ui; % unit interval

3034

M=param.samples_per_ui; % sample per UI

3044

M=param.samples_per_ui; % sample per UI

3035

N_v=param.N_v; % number of UI for Vf determination

3045

N_v=param.N_v; % number of UI for Vf determination

3036

3046

3037

% filters

3047

% filters

3038

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3048

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3039

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3049

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3040

H_ftr=H_bw.*H_bt;

3050

H_ftr=H_bw.*H_bt;

3041

H_ftr=H_ftr(:);

3051

H_ftr=H_ftr(:);

3042

% fd of PR

3052

% fd of PR

3043

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3053

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3044

prr = prr(:);

3054

prr = prr(:);

3045

if f(1)==0, prr(1)=1; end %remove NaN

3055

if f(1)==0, prr(1)=1; end %remove NaN

3046

fd=fft(V);

3056

fd=fft(V);

3047

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3057

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3048

3058

3049

%% get Vf

3059

%% get Vf

3050

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3060

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3051

step_response=filter(V,1, shifting_vector);

3061

step_response=filter(V,1, shifting_vector);

3052

Vf=step_response(end);

3062

Vf=step_response(end);

3053

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3063

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3054

%%

3064

%%

3055

% ILest=20.*log10(abs(fd(1:f75)/Vf/M/Over_sample)) - 20.*log10(abs(prr(1:f75))) - 20*log10(abs(squeeze(H_ftr(1:f75)))) ; %removing db function to avoid using sig proc toolbox

3065

% ILest=20.*log10(abs(fd(1:f75)/Vf/M/Over_sample)) - 20.*log10(abs(prr(1:f75))) - 20*log10(abs(squeeze(H_ftr(1:f75)))) ; %removing db function to avoid using sig proc toolbox

3056

% figure

3066

% figure

3057

% plot(f(1:f75),ILest)

3067

% plot(f(1:f75),ILest)

3058

3068

3059

IL_conv=fd(1:f75)/Vf/M/Over_sample ./ prr(1:f75) ./ H_ftr(1:f75) ; %removing db function to avoid using sig proc toolbox

3069

IL_conv=fd(1:f75)/Vf/M/Over_sample ./ prr(1:f75) ./ H_ftr(1:f75) ; %removing db function to avoid using sig proc toolbox

3060

% set same variables as get_s4p_files

3070

% set same variables as get_s4p_files

3061

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3071

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3062

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3072

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3063

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3073

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3064

zero_vector=zeros(length(IL_conv),1);

3074

zero_vector=zeros(length(IL_conv),1);

3065

for j=1:length(IL_fields)

3075

for j=1:length(IL_fields)

3066

chdata(i).(IL_fields{j})=IL_conv;

3076

chdata(i).(IL_fields{j})=IL_conv;

3067

end

3077

end

3068

for j=1:length(Zero_fields)

3078

for j=1:length(Zero_fields)

3069

chdata(i).(Zero_fields{j})=zero_vector;

3079

chdata(i).(Zero_fields{j})=zero_vector;

3070

end

3080

end

3071

3081

3072

if i==1

3082

if i==1

3073

SDDch(:,1,2)=chdata.sdd12_raw;

3083

SDDch(:,1,2)=chdata.sdd12_raw;

3074

SDDch(:,2,1)=chdata.sdd21_raw;

3084

SDDch(:,2,1)=chdata.sdd21_raw;

3075

SDDch(:,1,1)=chdata.sdd11_raw;

3085

SDDch(:,1,1)=chdata.sdd11_raw;

3076

SDDch(:,2,2)=chdata.sdd22_raw;

3086

SDDch(:,2,2)=chdata.sdd22_raw;

3077

SDDp2p= zeros(length(IL_conv),1);

3087

SDDp2p= zeros(length(IL_conv),1);

3078

end

3088

end

3079

chdata(i).TX_RL=[];

3089

chdata(i).TX_RL=[];

3080

chdata(i).TDR11=[];

3090

chdata(i).TDR11=[];

3081

chdata(i).PDTR11=[];

3091

chdata(i).PDTR11=[];

3082

chdata(i).TDR22=[];

3092

chdata(i).TDR22=[];

3083

chdata(i).PDTR22=[];

3093

chdata(i).PDTR22=[];

3084

end

3094

end

3085

3095

3086

3096

3087

function H_tw=Tukey_Window(f,param,fr,fb)

3097

function H_tw=Tukey_Window(f,param,fr,fb)

3088

% RIM 05/26/2022 added optional fr and fb

3098

% RIM 05/26/2022 added optional fr and fb

3089

% fr is the start of the raised cosine window

3099

% fr is the start of the raised cosine window

3090

% fb is the end of the raised cosine window

3100

% fb is the end of the raised cosine window

3091

if ~exist('fr','var') && ~exist('fb','var')

3101

if ~exist('fr','var') && ~exist('fb','var')

3092

fb=param.fb;

3102

fb=param.fb;

3093

fr=param.f_r*param.fb;

3103

fr=param.f_r*param.fb;

3094

end

3104

end

3095

fperiod=2*(fb-fr);

3105

fperiod=2*(fb-fr);

3096

H_tw = [ ones(1,length(f(f<fr))) ...

3106

H_tw = [ ones(1,length(f(f<fr))) ...

3097

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3107

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3098

zeros(1,length(f(f>fb)) )];

3108

zeros(1,length(f(f>fb)) )];

3099

H_tw=H_tw(1:length(f));

3109

H_tw=H_tw(1:length(f));

3100

if 0

3110

if 0

3101

plot(f/1e9,H_tw)

3111

plot(f/1e9,H_tw)

3102

end

3112

end

3103

3113

3104

3114

3105

3115

3106

%% moved output control to functions

3116

%% moved output control to functions

3107

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3117

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3108

% Author: Richard Mellitz

3118

% Author: Richard Mellitz

3109

% Date: 7/29/2022

3119

% Date: 7/29/2022

3110

% generate FD tx ffe system function

3120

% generate FD tx ffe system function

3111

% varagins...

3121

% varagins...

3112

% param - stucture

3122

% param - stucture

3113

% param.fb baud rate

3123

% param.fb baud rate

3114

% param.Tx_FFE Tx FFE coef

3124

% param.Tx_FFE Tx FFE coef

3115

% f - freq array

3125

% f - freq array

3116

% Use_Tx_FFE = flag to use or not

3126

% Use_Tx_FFE = flag to use or not

3117

% H_TxFFE is system function for Tx_FFE

3127

% H_TxFFE is system function for Tx_FFE

3118

db = @(x) 20*log10(abs(x));

3128

db = @(x) 20*log10(abs(x));

3119

[param,varargin]=varargin_extractor(varargin{:});

3129

[param,varargin]=varargin_extractor(varargin{:});

3120

[f,varargin]=varargin_extractor(varargin{:});

3130

[f,varargin]=varargin_extractor(varargin{:});

3121

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3131

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3122

if isempty(Use_Tx_FFE)

3132

if isempty(Use_Tx_FFE)

3123

Use_Tx_FFE=0;

3133

Use_Tx_FFE=0;

3124

end

3134

end

3125

if isempty(param)

3135

if isempty(param)

3126

param.fb=106.25e9;

3136

param.fb=106.25e9;

3127

Tx_FFE=[1 ];

3137

Tx_FFE=[1 ];

3128

else

3138

else

3129

if ~isfield(param, 'Pkg_TXFFE_preset')

3139

if ~isfield(param, 'Pkg_TXFFE_preset')

3130

Tx_FFE=[ 1 ];

3140

Tx_FFE=[ 1 ];

3131

else

3141

else

3132

Tx_FFE=param.Pkg_TXFFE_preset;

3142

Tx_FFE=param.Pkg_TXFFE_preset;

3133

end

3143

end

3134

end

3144

end

3135

if isempty(f)

3145

if isempty(f)

3136

f=0:10e6:param.fb;

3146

f=0:10e6:param.fb;

3137

end

3147

end

3138

3148

3139

3149

3140

if Use_Tx_FFE ~=0

3150

if Use_Tx_FFE ~=0

3141

[mcur,icur] = max(Tx_FFE);

3151

[mcur,icur] = max(Tx_FFE);

3142

H_TxFFE=zeros(1,length(f));

3152

H_TxFFE=zeros(1,length(f));

3143

for ii=1:length(Tx_FFE)

3153

for ii=1:length(Tx_FFE)

3144

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3154

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3145

end

3155

end

3146

else

3156

else

3147

H_TxFFE=ones(1,length(f));

3157

H_TxFFE=ones(1,length(f));

3148

end

3158

end

3149

% figure (1102320)

3159

% figure (1102320)

3150

% plot(f/1e9,db(H_TxFFE))

3160

% plot(f/1e9,db(H_TxFFE))

3151

% hold on

3161

% hold on

3152

function Write_CSV(output_args,csv_file)

3162

function Write_CSV(output_args,csv_file)

3153

3163

3154

items = fieldnames(output_args);

3164

items = fieldnames(output_args);

3155

item_value_strings = cell(size(items));

3165

item_value_strings = cell(size(items));

3156

for field_id=1:length(items)

3166

for field_id=1:length(items)

3157

field_name=items{field_id};

3167

field_name=items{field_id};

3158

field_value=output_args.(field_name);

3168

field_value=output_args.(field_name);

3159

if isstruct(output_args.(field_name))

3169

if isstruct(output_args.(field_name))

3160

field_value='struct';

3170

field_value='struct';

3161

end

3171

end

3162

if ischar(field_value)

3172

if ischar(field_value)

3163

item_value_strings{field_id}=field_value;

3173

item_value_strings{field_id}=field_value;

3164

elseif isempty(field_value)

3174

elseif isempty(field_value)

3165

item_value_strings{field_id}='';

3175

item_value_strings{field_id}='';

3166

elseif numel(field_value)==1

3176

elseif numel(field_value)==1

3167

item_value_strings{field_id}=num2str(field_value);

3177

item_value_strings{field_id}=num2str(field_value);

3168

else

3178

else

3169

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3179

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3170

end

3180

end

3171

end

3181

end

3172

3182

3173

header_string = str2csv(items);

3183

header_string = str2csv(items);

3174

data_string = str2csv(item_value_strings);

3184

data_string = str2csv(item_value_strings);

3175

fid = fopen(csv_file,'w');

3185

fid = fopen(csv_file,'w');

3176

fprintf(fid,'%s\n', header_string);

3186

fprintf(fid,'%s\n', header_string);

3177

fprintf(fid,'%s\n', data_string);

3187

fprintf(fid,'%s\n', data_string);

3178

fclose(fid);

3188

fclose(fid);

3179

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3189

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3180

%% Used in Clause 92 for adding board trace between TP0 and TP2

3190

%% Used in Clause 92 for adding board trace between TP0 and TP2

3181

3191

3182

switch chdata.type

3192

switch chdata.type

3183

case 'THRU'

3193

case 'THRU'

3184

z_bp_tx = param.z_bp_tx;

3194

z_bp_tx = param.z_bp_tx;

3185

z_bp_rx = param.z_bp_rx;

3195

z_bp_rx = param.z_bp_rx;

3186

case 'NEXT'

3196

case 'NEXT'

3187

z_bp_tx = param.z_bp_rx;

3197

z_bp_tx = param.z_bp_rx;

3188

z_bp_rx = param.z_bp_next;

3198

z_bp_rx = param.z_bp_next;

3189

case 'FEXT'

3199

case 'FEXT'

3190

z_bp_tx = param.z_bp_fext;

3200

z_bp_tx = param.z_bp_fext;

3191

z_bp_rx = param.z_bp_rx;

3201

z_bp_rx = param.z_bp_rx;

3192

end

3202

end

3193

% Same cap on each tx and rx three is a data stratue for bifrucation but

3203

% Same cap on each tx and rx three is a data stratue for bifrucation but

3194

% logic no implemented here RIM 06/28/2019

3204

% logic no implemented here RIM 06/28/2019

3195

zref=param.Z0;

3205

zref=param.Z0;

3196

c1=param.C_0;

3206

c1=param.C_0;

3197

c2=param.C_1;

3207

c2=param.C_1;

3198

f=chdata.faxis;

3208

f=chdata.faxis;

3199

f(f<eps)=eps;

3209

f(f<eps)=eps;

3200

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3210

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3201

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3211

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3202

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3212

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3203

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3213

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3204

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3214

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3205

% add Tx caps

3215

% add Tx caps

3206

[s11tx, s12tx, s21tx, s22tx ]= ...

3216

[s11tx, s12tx, s21tx, s22tx ]= ...

3207

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3217

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3208

[s11tx, s12tx, s21tx, s22tx ]= ...

3218

[s11tx, s12tx, s21tx, s22tx ]= ...

3209

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3219

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3210

3220

3211

3221

3212

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3222

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3213

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3223

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3214

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3224

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3215

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3225

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3216

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_rx);

3226

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_rx);

3217

% add Rx caps

3227

% add Rx caps

3218

[s11rx, s12rx, s21rx, s22rx ]= ...

3228

[s11rx, s12rx, s21rx, s22rx ]= ...

3219

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3229

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3220

[s11rx, s12rx, s21rx, s22rx ]= ...

3230

[s11rx, s12rx, s21rx, s22rx ]= ...

3221

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3231

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3222

3232

3223

3233

3224

switch OP.include_pcb

3234

switch OP.include_pcb

3225

case 1

3235

case 1

3226

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3236

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3227

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3237

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3228

case 2

3238

case 2

3229

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3239

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3230

end

3240

end

3231

3241

3232

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3242

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3233

% Used in Clause 92 for adding board trace between TP0 and TP2

3243

% Used in Clause 92 for adding board trace between TP0 and TP2

3234

switch chdata.type

3244

switch chdata.type

3235

case 'THRU'

3245

case 'THRU'

3236

z_bp_tx = param.z_bp_tx;

3246

z_bp_tx = param.z_bp_tx;

3237

case 'NEXT'

3247

case 'NEXT'

3238

z_bp_tx = param.z_bp_next;

3248

z_bp_tx = param.z_bp_next;

3239

case 'FEXT'

3249

case 'FEXT'

3240

z_bp_tx = param.z_bp_fext;

3250

z_bp_tx = param.z_bp_fext;

3241

end

3251

end

3242

3252

3243

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3253

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3244

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, param.z_bp_rx);

3254

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, param.z_bp_rx);

3245

3255

3246

switch OP.include_pcb

3256

switch OP.include_pcb

3247

case 1

3257

case 1

3248

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3258

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3249

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3259

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3250

case 2

3260

case 2

3251

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3261

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3252

end

3262

end

3253

3263

3254

function [chdata,NS,combined_interference_and_noise_pdf] = adjust_Rx_noise_for_quantization(combined_interference_and_noise_pdf,NS, chdata,fom_result,param,OP)

3264

function [chdata,NS,combined_interference_and_noise_pdf] = adjust_Rx_noise_for_quantization(combined_interference_and_noise_pdf,NS, chdata,fom_result,param,OP)

3255

% expected input

3265

% expected input

3256

% chdata(1).eq_pulse_response --- includes packages, Hf, and Hr, Ht, and Hffe(from tx)

3266

% chdata(1).eq_pulse_response --- includes packages, Hf, and Hr, Ht, and Hffe(from tx)

3257

% align the first sample point to to ts in chdata(1).eq_pulse_response

3267

% align the first sample point to to ts in chdata(1).eq_pulse_response

3258

% align to termiolgy used in MMSE and optimize_FOM

3268

% align to termiolgy used in MMSE and optimize_FOM

3259

3269

3260

%

3270

%

3261

sig_after_ctle_pdf = get_pdf_from_sampled_signal(chdata(1).pulse_sampled_w_tx_ffe_ctle, param.levels, param.delta_y);

3271

sig_after_ctle_pdf = get_pdf_from_sampled_signal(chdata(1).pulse_sampled_w_tx_ffe_ctle, param.levels, param.delta_y);

3262

sig_after_ctle_pdf = conv_fct(sig_after_ctle_pdf, combined_interference_and_noise_pdf);

3272

sig_after_ctle_pdf = conv_fct(sig_after_ctle_pdf, combined_interference_and_noise_pdf);

3263

sig_after_ctle_cdf = cumsum(sig_after_ctle_pdf.y);

3273

sig_after_ctle_cdf = cumsum(sig_after_ctle_pdf.y);

3264

adc_clip = -CDF_inv_ev(param.P_qc, sig_after_ctle_pdf, sig_after_ctle_cdf);

3274

adc_clip = -CDF_inv_ev(2*param.specBER, sig_after_ctle_pdf, sig_after_ctle_cdf);

3265

ctle_signal_sigma = sqrt(sum((sig_after_ctle_pdf.x.^2).*sig_after_ctle_pdf.y));

3275

ctle_pulse_sigma = sqrt(sum((sig_after_ctle_pdf.x.^2).*sig_after_ctle_pdf.y));

3266

adc_lsb = 2*adc_clip/(2^param.N_qb-1);

3276

adc_lsb = 2*adc_clip/(2^param.ENOB-1);

3267

NS.sigma_Q = adc_lsb/sqrt(12);

3277

NS.sigma_Q = adc_lsb/sqrt(12);

3268

NS.sigma_before_clip = ctle_signal_sigma;

3278

NS.sigma_before_clip = ctle_pulse_sigma;

3269

NS.peak_clip = adc_clip;

3279

NS.peak_clip = adc_clip;

3270

NS.p2ptosigma_clip = 2*adc_clip/ctle_signal_sigma;

3280

NS.p2ptosigma_clip = 2*adc_clip/ctle_pulse_sigma;

3271

quantization_noise_in_pdf = combined_interference_and_noise_pdf; % This is to copy the fields of the structure

3281

quantizaiton_noise_pdf = combined_interference_and_noise_pdf; % This is to copy the fields of the structure

3272

[~,adc_ind_right] = min(abs(quantization_noise_in_pdf.x-adc_lsb/2));

3282

[~,adc_ind_right] = min(abs(quantizaiton_noise_pdf.x-adc_lsb/2));

3273

[~,adc_ind_left] = min(abs(quantization_noise_in_pdf.x+adc_lsb/2));

3283

[~,adc_ind_left] = min(abs(quantizaiton_noise_pdf.x+adc_lsb/2));

3274

% adc_ind_right= find ( min(abs(quantization_noise_pdf.x-adc_lsb/2)) == abs(quantization_noise_pdf.x-adc_lsb/2) );

3284

% adc_ind_right= find ( min(abs(quantizaiton_noise_pdf.x-adc_lsb/2)) == abs(quantizaiton_noise_pdf.x-adc_lsb/2) );

3275

% adc_ind_left= find ( min(abs(quantization_noise_pdf.x+adc_lsb/2)) == abs(quantization_noise_pdf.x+adc_lsb/2) );

3285

% adc_ind_left= find ( min(abs(quantizaiton_noise_pdf.x+adc_lsb/2)) == abs(quantizaiton_noise_pdf.x+adc_lsb/2) );

3276

quantization_noise_in_pdf.y = zeros(size(quantization_noise_in_pdf.x));

3286

quantizaiton_noise_pdf.y = zeros(size(quantizaiton_noise_pdf.x));

3277

quantization_noise_in_pdf.y(adc_ind_left:adc_ind_right) = 1/(adc_ind_right-adc_ind_left+1);

3287

quantizaiton_noise_pdf.y(adc_ind_left:adc_ind_right) = 1/(adc_ind_right-adc_ind_left+1);

3278

% initialize quantization noise PDF afeter RxFFE to a Dirac delta PDF

3279

quantization_noise_pdf = combined_interference_and_noise_pdf;

3280

[~,ind_center]= min(abs(quantization_noise_pdf.x));

3281

quantization_noise_pdf.y = zeros(size(quantization_noise_pdf.x));

3282

quantization_noise_pdf.y(ind_center) = 1;

3283

% Calculate quantization noise PDF after RxFFE

3288

% Calculate quantization noise PDF after RxFFE

3284

h_rxffe = fom_result.RxFFE(find(fom_result.RxFFE ~= 0));

3289

h_rxffe = fom_result.RxFFE(find(fom_result.RxFFE ~= 0));

3285

for irxffe = 1:length(h_rxffe)

3290

for irxffe = 1:length(h_rxffe)

3286

if irxffe ~= param.ffe_pre_tap_len

3291

if irxffe ~= param.ffe_pre_tap_len

3287

quantization_noise_in_pdf_scale = scalePDF(quantization_noise_in_pdf, abs(h_rxffe(irxffe)));

3292

quantizaiton_noise_pdf_scale = scalePDF(quantizaiton_noise_pdf, abs(h_rxffe(irxffe)));

3288

quantization_noise_pdf = conv_fct(quantization_noise_pdf, quantization_noise_in_pdf_scale);

3293

quantizaiton_noise_pdf = conv_fct(quantizaiton_noise_pdf, quantizaiton_noise_pdf_scale);

3289

end

3294

end

3290

end

3295

end

3291

combined_interference_and_noise_pdf = conv_fct(combined_interference_and_noise_pdf, quantization_noise_pdf);

3296

combined_interference_and_noise_pdf = conv_fct(combined_interference_and_noise_pdf, quantizaiton_noise_pdf);

3292

NS.quantization_noise_pdf = quantization_noise_pdf ;

3297

NS.quantizaiton_noise_pdf = quantizaiton_noise_pdf ;

3293

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3298

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3294

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3299

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3295

% applying a bank of DFE at desired location

3300

% applying a bank of DFE at desired location

3296

% hisi: waveform with cursor values;

3301

% hisi: waveform with cursor values;

3297

% idx: starting index of the bank;

3302

% idx: starting index of the bank;

3298

% tap_bk: number of taps in bank;

3303

% tap_bk: number of taps in bank;

3299

% bmaxg: maxmum coefficient in bank;

3304

% bmaxg: maxmum coefficient in bank;

3300

3305

3301

if nargin<6

3306

if nargin<6

3302

dfe_delta=0;

3307

dfe_delta=0;

3303

end

3308

end

3304

3309

3305

rng=idx:idx+tap_bk-1;

3310

rng=idx:idx+tap_bk-1;

3306

flt_curval=hisi(rng);

3311

flt_curval=hisi(rng);

3307

3312

3308

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3313

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3309

3314

3310

if dfe_delta~=0

3315

if dfe_delta~=0

3311

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3316

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3312

dfe_delta.*sign(flt_curval)*curval;

3317

dfe_delta.*sign(flt_curval)*curval;

3313

else

3318

else

3314

flt_curval_q=hisi(rng);

3319

flt_curval_q=hisi(rng);

3315

end

3320

end

3316

3321

3317

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3322

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3318

hisi(rng)= hisi(rng) - curval*tap_coef;

3323

hisi(rng)= hisi(rng) - curval*tap_coef;

3319

hisi_ref(rng)=0;

3324

hisi_ref(rng)=0;

3320

3325

3321

%AJG021820

3326

%AJG021820

3322

function [ a] = bessel( n )

3327

function [ a] = bessel( n )

3323

% bessel polynomial

3328

% bessel polynomial

3324

for ii= 0:n

3329

for ii= 0:n

3325

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3330

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3326

end

3331

end

3327

3332

3328

3333

3329

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3334

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3330

% History:

3335

% History:

3331

% 1. 14th October, 2021 (Intial release)

3336

% 1. 14th October, 2021 (Intial release)

3332

3337

3333

% Definition:

3338

% Definition:

3334

% This function captures the channel delay through the time domain using causality enforcement.

3339

% This function captures the channel delay through the time domain using causality enforcement.

3335

% Following are the steps being followed.

3340

% Following are the steps being followed.

3336

% Step 1. Cascade negative frequencies

3341

% Step 1. Cascade negative frequencies

3337

% Step 2. Extract magnitude

3342

% Step 2. Extract magnitude

3338

% Step 3. IFFT of the magnitude

3343

% Step 3. IFFT of the magnitude

3339

% Step 4. Multiply by the sign(t)

3344

% Step 4. Multiply by the sign(t)

3340

% Step 5. Calculate the phase of the 1j*causal_phase

3345

% Step 5. Calculate the phase of the 1j*causal_phase

3341

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3346

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3342

% Step 7. f-domain to t-domain pulse response

3347

% Step 7. f-domain to t-domain pulse response

3343

% Step 8. Calculate the delay

3348

% Step 8. Calculate the delay

3344

3349

3345

% Author:

3350

% Author:

3346

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3351

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3347

3352

3348

% Reference:

3353

% Reference:

3349

% 1] "IEEE Standard for Electrical Characterization of Printed Circuit Board and Related Interconnects at Frequencies up to 50 GHz," in IEEE Std 370-2020 , vol., no., pp.1-147, 8 Jan. 2021, doi: 10.1109/IEEESTD.2021.9316329.

3354

% 1] "IEEE Standard for Electrical Characterization of Printed Circuit Board and Related Interconnects at Frequencies up to 50 GHz," in IEEE Std 370-2020 , vol., no., pp.1-147, 8 Jan. 2021, doi: 10.1109/IEEESTD.2021.9316329.

3350

3355

3351

% Input:

3356

% Input:

3352

% freq %frequency in hertz (odd number points)

3357

% freq %frequency in hertz (odd number points)

3353

% sdd21 %insertion loss in complex (odd number points)

3358

% sdd21 %insertion loss in complex (odd number points)

3354

% param %COM native structure passed

3359

% param %COM native structure passed

3355

% OP %COM native structure passed

3360

% OP %COM native structure passed

3356

3361

3357

% Output:

3362

% Output:

3358

% delay_sec %channel delay in seconds

3363

% delay_sec %channel delay in seconds

3359

% delay_idx %channel delay index

3364

% delay_idx %channel delay index

3360

3365

3361

if iscolumn(sdd21)

3366

if iscolumn(sdd21)

3362

sdd21= sdd21.';

3367

sdd21= sdd21.';

3363

end

3368

end

3364

if iscolumn(freq)

3369

if iscolumn(freq)

3365

freq= freq.';

3370

freq= freq.';

3366

end

3371

end

3367

3372

3368

%---start. Step 1. Cascade negative frequencies

3373

%---start. Step 1. Cascade negative frequencies

3369

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3374

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3370

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3375

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3371

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3376

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3372

%---end. Step 1. Cascade negative frequencies

3377

%---end. Step 1. Cascade negative frequencies

3373

3378

3374

%---start. Step 2. Extract magnitude

3379

%---start. Step 2. Extract magnitude

3375

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3380

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3376

%---end. Step 2. Extract magnitude

3381

%---end. Step 2. Extract magnitude

3377

3382

3378

%---start. Step 3. IFFT of the magnitude

3383

%---start. Step 3. IFFT of the magnitude

3379

sdd21_mag_time = ifft(sdd21_mag_conj);

3384

sdd21_mag_time = ifft(sdd21_mag_conj);

3380

%---end. Step 3. IFFT of the magnitude

3385

%---end. Step 3. IFFT of the magnitude

3381

3386

3382

%---start. Step 4. Multiply by the sign(t)

3387

%---start. Step 4. Multiply by the sign(t)

3383

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3388

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3384

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3389

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3385

%---end. Step 4. Multiply by the sign(t)

3390

%---end. Step 4. Multiply by the sign(t)

3386

3391

3387

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3392

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3388

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3393

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3389

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3394

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3390

3395

3391

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3396

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3392

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3397

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3393

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3398

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3394

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3399

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3395

3400

3396

%---start. Step 7. f-domain to t-domain pulse response

3401

%---start. Step 7. f-domain to t-domain pulse response

3397

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3402

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3398

%--------- Extrapolation has been already done by the COM tool

3403

%--------- Extrapolation has been already done by the COM tool

3399

freq_array= freq;

3404

freq_array= freq;

3400

time_step= param.sample_dt;

3405

time_step= param.sample_dt;

3401

fmax=1/time_step/2;

3406

fmax=1/time_step/2;

3402

freq_step=(freq_array(3)-freq_array(2))/1;

3407

freq_step=(freq_array(3)-freq_array(2))/1;

3403

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3408

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3404

3409

3405

ILin=sdd21;

3410

ILin=sdd21;

3406

IL=interp_Sparam(ILin,freq_array,fout, ...

3411

IL=interp_Sparam(ILin,freq_array,fout, ...

3407

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3412

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3408

IL_nan = find(isnan(IL));

3413

IL_nan = find(isnan(IL));

3409

for in=IL_nan

3414

for in=IL_nan

3410

IL(in)=IL(in-1);

3415

IL(in)=IL(in-1);

3411

end

3416

end

3412

IL = IL(:);

3417

IL = IL(:);

3413

% add padding for time steps

3418

% add padding for time steps

3414

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3419

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3415

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3420

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3416

clear IL IL_nan IL_symmetric

3421

clear IL IL_nan IL_symmetric

3417

3422

3418

ILin=sdd21_causality_enforced;

3423

ILin=sdd21_causality_enforced;

3419

IL=interp_Sparam(ILin,freq_array,fout, ...

3424

IL=interp_Sparam(ILin,freq_array,fout, ...

3420

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3425

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3421

IL_nan = find(isnan(IL));

3426

IL_nan = find(isnan(IL));

3422

for in=IL_nan

3427

for in=IL_nan

3423

IL(in)=IL(in-1);

3428

IL(in)=IL(in-1);

3424

end

3429

end

3425

IL = IL(:);

3430

IL = IL(:);

3426

% add padding for time steps

3431

% add padding for time steps

3427

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3432

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3428

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3433

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3429

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3434

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3430

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3435

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3431

clear IL IL_nan IL_symmetric

3436

clear IL IL_nan IL_symmetric

3432

3437

3433

clear time_step fmax freq_step freq_array

3438

clear time_step fmax freq_step freq_array

3434

3439

3435

freq_step=(fout(3)-fout(2))/1;

3440

freq_step=(fout(3)-fout(2))/1;

3436

L= length(sdd21_PR);

3441

L= length(sdd21_PR);

3437

t_base = (0:L-1)/(freq_step*L);

3442

t_base = (0:L-1)/(freq_step*L);

3438

clear fout freq_step L

3443

clear fout freq_step L

3439

%---end. Step 7. f-domain to t-domain pulse response

3444

%---end. Step 7. f-domain to t-domain pulse response

3440

3445

3441

%---start. Step 8. Calculate the delay

3446

%---start. Step 8. Calculate the delay

3442

%------start. Remove the last 5% of the waveform for noise due to IFFT

3447

%------start. Remove the last 5% of the waveform for noise due to IFFT

3443

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3448

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3444

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3449

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3445

%------end. Remove the last 5% of the waveform for noise due to IFFT

3450

%------end. Remove the last 5% of the waveform for noise due to IFFT

3446

3451

3447

%---start. calculate the difference in index between the peaks

3452

%---start. calculate the difference in index between the peaks

3448

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3453

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3449

[~, peak_y_idx] = max(sdd21_PR_reduced);

3454

[~, peak_y_idx] = max(sdd21_PR_reduced);

3450

peak_idx_difference = peak_x_idx - peak_y_idx;

3455

peak_idx_difference = peak_x_idx - peak_y_idx;

3451

%---end. calculate the difference in index between the peaks

3456

%---end. calculate the difference in index between the peaks

3452

3457

3453

if peak_idx_difference~=0

3458

if peak_idx_difference~=0

3454

search_bounds = min(peak_x_idx, peak_y_idx);%<----one may fix it to 1e3; using minimum of the peaks in assuming the other signal has zero delay

3459

search_bounds = min(peak_x_idx, peak_y_idx);%<----one may fix it to 1e3; using minimum of the peaks in assuming the other signal has zero delay

3455

error_value = length(sdd21_causality_enforced_PR_reduced);

3460

error_value = length(sdd21_causality_enforced_PR_reduced);

3456

error_idx = 0;

3461

error_idx = 0;

3457

% i= 1;

3462

% i= 1;

3458

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3463

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3459

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3464

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3460

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3465

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3461

if (error_value > current_error)

3466

if (error_value > current_error)

3462

error_idx = shift_value;

3467

error_idx = shift_value;

3463

error_value = current_error;

3468

error_value = current_error;

3464

end

3469

end

3465

% error_idx_H(i)= error_idx;

3470

% error_idx_H(i)= error_idx;

3466

% i= i+ 1;

3471

% i= i+ 1;

3467

end

3472

end

3468

%plot(error_idx_H);

3473

%plot(error_idx_H);

3469

3474

3470

if error_idx==0

3475

if error_idx==0

3471

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3476

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3472

end

3477

end

3473

3478

3474

delay_idx = error_idx;

3479

delay_idx = error_idx;

3475

else

3480

else

3476

delay_idx= 1;

3481

delay_idx= 1;

3477

end

3482

end

3478

3483

3479

delay_sec= t_base(abs(delay_idx));

3484

delay_sec= t_base(abs(delay_idx));

3480

3485

3481

3486

3482

function [return_struct]= capture_RIL_RILN(chdata)

3487

function [return_struct]= capture_RIL_RILN(chdata)

3483

% History:

3488

% History:

3484

% 1. 12th April, 2019 (Intial release)

3489

% 1. 12th April, 2019 (Intial release)

3485

%

3490

%

3486

% 2. 11th October, 2021

3491

% 2. 11th October, 2021

3487

% - Details:

3492

% - Details:

3488

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3493

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3489

% 2] Revised the selection criteria for the solution of the quadratic

3494

% 2] Revised the selection criteria for the solution of the quadratic

3490

% equation in finding the reflection coefficient (rho).

3495

% equation in finding the reflection coefficient (rho).

3491

% - Impact:

3496

% - Impact:

3492

% => Zero impact in |RIL|, while impact on angle(RIL).

3497

% => Zero impact in |RIL|, while impact on angle(RIL).

3493

% - Previous:

3498

% - Previous:

3494

% %---start. For passive networks the reflection coefficient should be less than one

3499

% %---start. For passive networks the reflection coefficient should be less than one

3495

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3500

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3496

% rho_port2= solution_1;

3501

% rho_port2= solution_1;

3497

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3502

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3498

% rho_port2= solution_2;

3503

% rho_port2= solution_2;

3499

% else

3504

% else

3500

% rho_port2= solution_1;

3505

% rho_port2= solution_1;

3501

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3506

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3502

% end

3507

% end

3503

% %---end. For passive networks the reflection coefficient should be less than one

3508

% %---end. For passive networks the reflection coefficient should be less than one

3504

%

3509

%

3505

% RIL= conj((1- rho_port1).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- rho_port2).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3510

% RIL= conj((1- rho_port1).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- rho_port2).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3506

% - Change:

3511

% - Change:

3507

% %---start. Given the real part of the impedance is to be positive

3512

% %---start. Given the real part of the impedance is to be positive

3508

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3513

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3509

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3514

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3510

%

3515

%

3511

% rho_port2= zeros(length(solution_1), 1);

3516

% rho_port2= zeros(length(solution_1), 1);

3512

% for solution_idx= 1:length(solution_1)

3517

% for solution_idx= 1:length(solution_1)

3513

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3518

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3514

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3519

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3515

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3520

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3516

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3521

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3517

% else

3522

% else

3518

% error('An odd case has occured. Please contact the tool developer.');

3523

% error('An odd case has occured. Please contact the tool developer.');

3519

% end

3524

% end

3520

% end

3525

% end

3521

% %---end. Given the real part of the impedance is to be positive

3526

% %---end. Given the real part of the impedance is to be positive

3522

% RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3527

% RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3523

3528

3524

% Definition:

3529

% Definition:

3525

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3530

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3526

3531

3527

% Author:

3532

% Author:

3528

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3533

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3529

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3534

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3530

3535

3531

% This function has been shared by Hansel for others to evaluate for reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter.

3536

% This function has been shared by Hansel for others to evaluate for reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter.

3532

3537

3533

% Reference:

3538

% Reference:

3534

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3539

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3535

% 2] H. Dsilva, A. Jain, J. Sasikala and A. Kumar, "Novel Signal Integrity Application of Power Wave Scattering Matrix theory," 2019 IEEE MTT-S International Microwave and RF Conference (IMARC), 2019, pp. 1-7, doi: 10.1109/IMaRC45935.2019.9118701.

3540

% 2] H. Dsilva, A. Jain, J. Sasikala and A. Kumar, "Novel Signal Integrity Application of Power Wave Scattering Matrix theory," 2019 IEEE MTT-S International Microwave and RF Conference (IMARC), 2019, pp. 1-7, doi: 10.1109/IMaRC45935.2019.9118701.

3536

3541

3537

% Input:

3542

% Input:

3538

% 1] SCH: S-matrix structure

3543

% 1] SCH: S-matrix structure

3539

% SCH.Frequencies= faxis;

3544

% SCH.Frequencies= faxis;

3540

% SCH.Parameters(1,1,:)= sdd11;

3545

% SCH.Parameters(1,1,:)= sdd11;

3541

% SCH.Parameters(2,2,:)= sdd22;

3546

% SCH.Parameters(2,2,:)= sdd22;

3542

% SCH.Parameters(1,2,:)= sdd12;

3547

% SCH.Parameters(1,2,:)= sdd12;

3543

% SCH.Parameters(2,1,:)= sdd21;

3548

% SCH.Parameters(2,1,:)= sdd21;

3544

% SCH.NumPorts= 2;

3549

% SCH.NumPorts= 2;

3545

% SCH.Impedance= 100;

3550

% SCH.Impedance= 100;

3546

3551

3547

% Output: Struct returned has the following,

3552

% Output: Struct returned has the following,

3548

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3553

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3549

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3554

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3550

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3555

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3551

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3556

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3552

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3557

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3553

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3558

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3554

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3559

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3555

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3560

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3556

% return_struct.freq %Frequency axis

3561

% return_struct.freq %Frequency axis

3557

3562

3558

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3563

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3559

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3564

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3560

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3565

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3561

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3566

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3562

SCH.Frequencies=chdata(1).faxis;

3567

SCH.Frequencies=chdata(1).faxis;

3563

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3568

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3564

SCH.NumPorts= 2;

3569

SCH.NumPorts= 2;

3565

3570

3566

%---start. allowed is only a 2-port network having a transmitter and receiver

3571

%---start. allowed is only a 2-port network having a transmitter and receiver

3567

if size(SCH.Parameters, 1)~=2

3572

if size(SCH.Parameters, 1)~=2

3568

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3573

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3569

error('Allowed is only a 2-port network having a transmitter and receiver.');

3574

error('Allowed is only a 2-port network having a transmitter and receiver.');

3570

end

3575

end

3571

%---end. allowed is only a 2-port network having a transmitter and receiver

3576

%---end. allowed is only a 2-port network having a transmitter and receiver

3572

3577

3573

%---start. do not include the DC point given sinusoidals at DC are not

3578

%---start. do not include the DC point given sinusoidals at DC are not

3574

%defined

3579

%defined

3575

if SCH.Frequencies(1)==0

3580

if SCH.Frequencies(1)==0

3576

idx_start= 2;

3581

idx_start= 2;

3577

else

3582

else

3578

idx_start= 1;

3583

idx_start= 1;

3579

end

3584

end

3580

%---end. do not include the DC point given sinusoidals at DC are not

3585

%---end. do not include the DC point given sinusoidals at DC are not

3581

%defined

3586

%defined

3582

3587

3583

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3588

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3584

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3589

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3585

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3590

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3586

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3591

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3587

3592

3588

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3593

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3589

b= 1+ Sdd22.*conj(Sdd22)+...

3594

b= 1+ Sdd22.*conj(Sdd22)+...

3590

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3595

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3591

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3596

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3592

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3597

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3593

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3598

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3594

Sdd11.*conj(Sdd11);

3599

Sdd11.*conj(Sdd11);

3595

c= -conj(Sdd22)-...

3600

c= -conj(Sdd22)-...

3596

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3601

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3597

Sdd11.*conj(Sdd11).*conj(Sdd22);

3602

Sdd11.*conj(Sdd11).*conj(Sdd22);

3598

3603

3599

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3604

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3600

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3605

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3601

3606

3602

clear a b c

3607

clear a b c

3603

3608

3604

%---start. Given the real part of the impedance is to be positive

3609

%---start. Given the real part of the impedance is to be positive

3605

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3610

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3606

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3611

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3607

3612

3608

rho_port2= zeros(length(solution_1), 1);

3613

rho_port2= zeros(length(solution_1), 1);

3609

for solution_idx= 1:length(solution_1)

3614

for solution_idx= 1:length(solution_1)

3610

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3615

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3611

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3616

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3612

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3617

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3613

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3618

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3614

else

3619

else

3615

error('An odd case has occured. Please contact the tool developer.');

3620

error('An odd case has occured. Please contact the tool developer.');

3616

end

3621

end

3617

end

3622

end

3618

%---end. Given the real part of the impedance is to be positive

3623

%---end. Given the real part of the impedance is to be positive

3619

3624

3620

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3625

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3621

3626

3622

%---start. calculate the equivalent port impedance

3627

%---start. calculate the equivalent port impedance

3623

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3628

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3624

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3629

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3625

%---end. calculate the equivalent port impedance

3630

%---end. calculate the equivalent port impedance

3626

3631

3627

3632

3628

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3633

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3629

% %to zero reflections.

3634

% %to zero reflections.

3630

RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3635

RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3631

%---end. The reflectionless insertion loss is the insertion loss corresponding

3636

%---end. The reflectionless insertion loss is the insertion loss corresponding

3632

%to zero reflections.

3637

%to zero reflections.

3633

3638

3634

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3639

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3635

RILN= RIL- Sdd21;

3640

RILN= RIL- Sdd21;

3636

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3641

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3637

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3642

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3638

3643

3639

%---start. preparing returns struct

3644

%---start. preparing returns struct

3640

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3645

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3641

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3646

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3642

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3647

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3643

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3648

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3644

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3649

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3645

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3650

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3646

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3651

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3647

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3652

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3648

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3653

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3649

%---end. preparing returns struct

3654

%---end. preparing returns struct

3650

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3655

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3651

3656

3652

3657

3653

%For the given BER, find the top & bottom voltage level in the CDF

3658

%For the given BER, find the top & bottom voltage level in the CDF

3654

3659

3655

%for the top, just find the first index at the spec BER

3660

%for the top, just find the first index at the spec BER

3656

nidx=find(cdf.y>specBER, 1, 'first');

3661

nidx=find(cdf.y>specBER, 1, 'first');

3657

noise_bottom = cdf.x(nidx);

3662

noise_bottom = cdf.x(nidx);

3658

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3663

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3659

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3664

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3660

%the true index without flipping

3665

%the true index without flipping

3661

nidx=length(cdf.y)-nidx+1;

3666

nidx=length(cdf.y)-nidx+1;

3662

noise_top = cdf.x(nidx);

3667

noise_top = cdf.x(nidx);

3663

function p=comb_fct(p1, p2)

3668

function p=comb_fct(p1, p2)

3664

if p1.BinSize ~= p2.BinSize

3669

if p1.BinSize ~= p2.BinSize

3665

error('bin size must be equal')

3670

error('bin size must be equal')

3666

end

3671

end

3667

3672

3668

p=p1;

3673

p=p1;

3669

p.BinSize=p1.BinSize;

3674

p.BinSize=p1.BinSize;

3670

%p.Min=p1.Min+p2.Min;

3675

%p.Min=p1.Min+p2.Min;

3671

p.Min=min(p1.Min,p2.Min);

3676

p.Min=min(p1.Min,p2.Min);

3672

difsz=abs(p1.Min-p2.Min);

3677

difsz=abs(p1.Min-p2.Min);

3673

lp1=length(p1.y);

3678

lp1=length(p1.y);

3674

lp2=length(p2.y);

3679

lp2=length(p2.y);

3675

if p1.Min == p.Min

3680

if p1.Min == p.Min

3676

p2.y(difsz+1:lp2+difsz)=p2.y;

3681

p2.y(difsz+1:lp2+difsz)=p2.y;

3677

p2.y(1:difsz)=0;

3682

p2.y(1:difsz)=0;

3678

p2.y(lp2+difsz+1:lp1)=0;

3683

p2.y(lp2+difsz+1:lp1)=0;

3679

elseif p2.Min == p.Min

3684

elseif p2.Min == p.Min

3680

p1.y(difsz+1:lp1+difsz)=p1.y;

3685

p1.y(difsz+1:lp1+difsz)=p1.y;

3681

p1.y(1:difsz)=0;

3686

p1.y(1:difsz)=0;

3682

p1.y(lp1+difsz+1:lp2)=0;

3687

p1.y(lp1+difsz+1:lp2)=0;

3683

end

3688

end

3684

% p.y=conv(p1.y, p2.y);

3689

% p.y=conv(p1.y, p2.y);

3685

p.y=(p1.y+p2.y);

3690

p.y=(p1.y+p2.y);

3686

% p.y=p.y/sum(p.y);

3691

% p.y=p.y/sum(p.y);

3687

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3692

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3688

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3693

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3689

3694

3690

3695

3691

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

3696

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

3692

3697

3693

if pdf1.BinSize ~= pdf2.BinSize

3698

if pdf1.BinSize ~= pdf2.BinSize

3694

error('bin size must be equal')

3699

error('bin size must be equal')

3695

end

3700

end

3696

3701

3697

x1=pdf1.x;

3702

x1=pdf1.x;

3698

y1=pdf1.y;

3703

y1=pdf1.y;

3699

x2=pdf2.x;

3704

x2=pdf2.x;

3700

y2=pdf2.y;

3705

y2=pdf2.y;

3701

%find the pdf with a larger min, force it to have the same min, and insert

3706

%find the pdf with a larger min, force it to have the same min, and insert

3702

%probability = 0

3707

%probability = 0

3703

min1=pdf1.x(1);

3708

min1=pdf1.x(1);

3704

min2=pdf2.x(1);

3709

min2=pdf2.x(1);

3705

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

3710

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

3706

if min1<min2

3711

if min1<min2

3707

x2=[pdf1.x(1:shift_amount) pdf2.x];

3712

x2=[pdf1.x(1:shift_amount) pdf2.x];

3708

y2=[zeros(1,shift_amount) pdf2.y];

3713

y2=[zeros(1,shift_amount) pdf2.y];

3709

else

3714

else

3710

x1=[pdf2.x(1:shift_amount) pdf1.x];

3715

x1=[pdf2.x(1:shift_amount) pdf1.x];

3711

y1=[zeros(1,shift_amount) pdf1.y];

3716

y1=[zeros(1,shift_amount) pdf1.y];

3712

end

3717

end

3713

%find the pdf with smaller max, force it to have the same max, and insert

3718

%find the pdf with smaller max, force it to have the same max, and insert

3714

%probability=0

3719

%probability=0

3715

L1=length(x1);

3720

L1=length(x1);

3716

L2=length(x2);

3721

L2=length(x2);

3717

Ldiff=abs(L1-L2);

3722

Ldiff=abs(L1-L2);

3718

if L1>L2

3723

if L1>L2

3719

out_x=x1;

3724

out_x=x1;

3720

y2=[y2 zeros(1,Ldiff)];

3725

y2=[y2 zeros(1,Ldiff)];

3721

else

3726

else

3722

out_x=x2;

3727

out_x=x2;

3723

y1=[y1 zeros(1,Ldiff)];

3728

y1=[y1 zeros(1,Ldiff)];

3724

end

3729

end

3725

%now the 2 pdfs have the same voltage axis, add probabilities together

3730

%now the 2 pdfs have the same voltage axis, add probabilities together

3726

%renormalization is not handled here, so the output pdf will not have sum=1

3731

%renormalization is not handled here, so the output pdf will not have sum=1

3727

%It is the responsibility of the calling function to handle renormalization

3732

%It is the responsibility of the calling function to handle renormalization

3728

%if needed

3733

%if needed

3729

out_y=y1+y2;

3734

out_y=y1+y2;

3730

out_pdf.x=out_x;

3735

out_pdf.x=out_x;

3731

out_pdf.y=out_y;

3736

out_pdf.y=out_y;

3732

out_pdf.BinSize=pdf1.BinSize;

3737

out_pdf.BinSize=pdf1.BinSize;

3733

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

3738

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

3734

3739

3735

%original method:

3740

%original method:

3736

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

3741

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

3737

% for i=1:length(s11in1)

3742

% for i=1:length(s11in1)

3738

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

3743

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

3739

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

3744

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

3740

% end

3745

% end

3741

% t1=stot(s1);

3746

% t1=stot(s1);

3742

% t2=stot(s2);

3747

% t2=stot(s2);

3743

% for i=1:length(s11in1)

3748

% for i=1:length(s11in1)

3744

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

3749

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

3745

% end

3750

% end

3746

% s3=ttos(t3);

3751

% s3=ttos(t3);

3747

% s11out=s3(1,1,:);

3752

% s11out=s3(1,1,:);

3748

% s11out=transpose(s11out(:));

3753

% s11out=transpose(s11out(:));

3749

% s12out=s3(1,2,:);

3754

% s12out=s3(1,2,:);

3750

% s12out=transpose(s12out(:));

3755

% s12out=transpose(s12out(:));

3751

% s21out=s3(2,1,:);

3756

% s21out=s3(2,1,:);

3752

% s21out=transpose(s21out(:));

3757

% s21out=transpose(s21out(:));

3753

% s22out=s3(2,2,:);

3758

% s22out=s3(2,2,:);

3754

% s22out=transpose(s22out(:));

3759

% s22out=transpose(s22out(:));

3755

3760

3756

3761

3757

%vectorized method:

3762

%vectorized method:

3758

s1(1,1,:)=s11in1;

3763

s1(1,1,:)=s11in1;

3759

s1(1,2,:)=s12in1;

3764

s1(1,2,:)=s12in1;

3760

s1(2,1,:)=s21in1;

3765

s1(2,1,:)=s21in1;

3761

s1(2,2,:)=s22in1;

3766

s1(2,2,:)=s22in1;

3762

s2(1,1,:)=s11in2;

3767

s2(1,1,:)=s11in2;

3763

s2(1,2,:)=s12in2;

3768

s2(1,2,:)=s12in2;

3764

s2(2,1,:)=s21in2;

3769

s2(2,1,:)=s21in2;

3765

s2(2,2,:)=s22in2;

3770

s2(2,2,:)=s22in2;

3766

3771

3767

3772

3768

N = (1-s1(2,2,:).*s2(1,1,:)) ;

3773

N = (1-s1(2,2,:).*s2(1,1,:)) ;

3769

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

3774

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

3770

s12out = s1(1,2,:).*s2(1,2,:)./N ;

3775

s12out = s1(1,2,:).*s2(1,2,:)./N ;

3771

s21out = s2(2,1,:).*s1(2,1,:)./N;

3776

s21out = s2(2,1,:).*s1(2,1,:)./N;

3772

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

3777

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

3773

3778

3774

s11out=transpose(squeeze(s11out));

3779

s11out=transpose(squeeze(s11out));

3775

s12out=transpose(squeeze(s12out));

3780

s12out=transpose(squeeze(s12out));

3776

s21out=transpose(squeeze(s21out));

3781

s21out=transpose(squeeze(s21out));

3777

s22out=transpose(squeeze(s22out));

3782

s22out=transpose(squeeze(s22out));

3778

function p=conv_fct(p1, p2)

3783

function p=conv_fct(p1, p2)

3779

if p1.BinSize ~= p2.BinSize

3784

if p1.BinSize ~= p2.BinSize

3780

error('bin size must be equal')

3785

error('bin size must be equal')

3781

end

3786

end

3782

3787

3783

p=p1;

3788

p=p1;

3784

%p.BinSize=p1.BinSize;

3789

%p.BinSize=p1.BinSize;

3785

%p.Min=p1.Min+p2.Min;

3790

%p.Min=p1.Min+p2.Min;

3786

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3791

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3787

p.y=conv2(p1.y, p2.y);

3792

p.y=conv2(p1.y, p2.y);

3788

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3793

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3789

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3794

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3790

pMax=p.Min+length(p.y)-1;

3795

pMax=p.Min+length(p.y)-1;

3791

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3796

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3792

3797

3793

3798

3794

3799

3795

3800

3796

function p=conv_fct_MeanNotZero(p1, p2)

3801

function p=conv_fct_MeanNotZero(p1, p2)

3797

3802

3798

if p1.BinSize ~= p2.BinSize

3803

if p1.BinSize ~= p2.BinSize

3799

error('bin size must be equal')

3804

error('bin size must be equal')

3800

end

3805

end

3801

3806

3802

p=p1;

3807

p=p1;

3803

%p.BinSize=p1.BinSize;

3808

%p.BinSize=p1.BinSize;

3804

%p.Min=p1.Min+p2.Min;

3809

%p.Min=p1.Min+p2.Min;

3805

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3810

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3806

p.y=conv2(p1.y, p2.y);

3811

p.y=conv2(p1.y, p2.y);

3807

3812

3808

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

3813

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

3809

%But it is faster to pre-multiply BinSize instead of multiplying the entire

3814

%But it is faster to pre-multiply BinSize instead of multiplying the entire

3810

%vector by BinSize

3815

%vector by BinSize

3811

pMax=p.Min+length(p.y)-1;

3816

pMax=p.Min+length(p.y)-1;

3812

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3817

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3813

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

3818

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

3814

3819

3815

%IN:

3820

%IN:

3816

%sbr = pulse response

3821

%sbr = pulse response

3817

%param = COM "param" struct

3822

%param = COM "param" struct

3818

%OP = COM "OP" struct

3823

%OP = COM "OP" struct

3819

%peak_search_range= a limited range to search for the peak (for speed up)

3824

%peak_search_range= a limited range to search for the peak (for speed up)

3820

% it is usually +/- 20 UI

3825

% it is usually +/- 20 UI

3821

%

3826

%

3822

%OUT:

3827

%OUT:

3823

%cursor_i = sampling location

3828

%cursor_i = sampling location

3824

%no_zero_crossing = flag that reveals if sampling is not possible.

3829

%no_zero_crossing = flag that reveals if sampling is not possible.

3825

% When this function is called in optimize_fom, it signals to quit the current case

3830

% When this function is called in optimize_fom, it signals to quit the current case

3826

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

3831

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

3827

% time consuming, so saving the peak in one spot is advantageous

3832

% time consuming, so saving the peak in one spot is advantageous

3828

%zxi = zero crossing index (returned because RXFFE uses it)

3833

%zxi = zero crossing index (returned because RXFFE uses it)

3829

3834

3830

no_zero_crossing=0;

3835

no_zero_crossing=0;

3831

%need to set cursor_i to empty in case no_zero_crossing flag is set

3836

%need to set cursor_i to empty in case no_zero_crossing flag is set

3832

cursor_i=[];

3837

cursor_i=[];

3833

3838

3834

%get peak of pulse and peak index

3839

%get peak of pulse and peak index

3835

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

3840

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

3836

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

3841

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

3837

3842

3838

3843

3839

% initial guess at cursor location (t_s) - based on approximate zero crossing

3844

% initial guess at cursor location (t_s) - based on approximate zero crossing

3840

%limit search space for speed up

3845

%limit search space for speed up

3841

search_start=sbr_peak_i-4*param.samples_per_ui;

3846

search_start=sbr_peak_i-4*param.samples_per_ui;

3842

if search_start<1

3847

if search_start<1

3843

search_start=1;

3848

search_start=1;

3844

end

3849

end

3845

%Find zero crossings

3850

%Find zero crossings

3846

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

3851

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

3847

3852

3848

%Note: the original implementation of zxi:

3853

%Note: the original implementation of zxi:

3849

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

3854

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

3850

% zxi = zxi(zxi<sbr_peak_i);

3855

% zxi = zxi(zxi<sbr_peak_i);

3851

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

3856

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

3852

% The changes to limit search space and remember max(sbr) give 10x speed up

3857

% The changes to limit search space and remember max(sbr) give 10x speed up

3853

% A test case of 25k runs, reduced from 1.2s to 0.1s

3858

% A test case of 25k runs, reduced from 1.2s to 0.1s

3854

3859

3855

3860

3856

if isempty(zxi)

3861

if isempty(zxi)

3857

%if no zero crossing, the calling program must respond (since sample point will be empty)

3862

%if no zero crossing, the calling program must respond (since sample point will be empty)

3858

no_zero_crossing=1;

3863

no_zero_crossing=1;

3859

return;

3864

return;

3860

elseif length(zxi)>1

3865

elseif length(zxi)>1

3861

%only need the last zero crossing

3866

%only need the last zero crossing

3862

zxi=zxi(end);

3867

zxi=zxi(end);

3863

end

3868

end

3864

if param.ndfe==0

3869

if param.ndfe==0

3865

max_dfe1=0;

3870

max_dfe1=0;

3866

else

3871

else

3867

max_dfe1=param.bmax(1);

3872

max_dfe1=param.bmax(1);

3868

end

3873

end

3869

% adjust cursor_i to Solve equation 93A-25 %%

3874

% adjust cursor_i to Solve equation 93A-25 %%

3870

% Muller-Mueller criterion with DFE

3875

% Muller-Mueller criterion with DFE

3871

mm_range = zxi+(0:2*param.samples_per_ui);

3876

mm_range = zxi+(0:2*param.samples_per_ui);

3872

switch OP.CDR

3877

switch OP.CDR

3873

case 'Mod-MM'

3878

case 'Mod-MM'

3874

mm_metric = ...

3879

mm_metric = ...

3875

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

3880

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

3876

otherwise % MM

3881

otherwise % MM

3877

%MM is generally: first precursor = 0

3882

%MM is generally: first precursor = 0

3878

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

3883

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

3879

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

3884

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

3880

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

3885

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

3881

%first precursor = first postcursor - max_dfe

3886

%first precursor = first postcursor - max_dfe

3882

mm_metric = ...

3887

mm_metric = ...

3883

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

3888

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

3884

end

3889

end

3885

[~, mm_cursor_offset] = min(mm_metric);

3890

[~, mm_cursor_offset] = min(mm_metric);

3886

3891

3887

%cursor_i = the sample location

3892

%cursor_i = the sample location

3888

cursor_i = zxi+mm_cursor_offset-1;

3893

cursor_i = zxi+mm_cursor_offset-1;

3889

function pdf=d_cpdf( binsize, values, probs)

3894

function pdf=d_cpdf( binsize, values, probs)

3890

% p=cpdf(type, ...)

3895

% p=cpdf(type, ...)

3891

%

3896

%

3892

% CPDF is a probability mass function for discrete distributions or an

3897

% CPDF is a probability mass function for discrete distributions or an

3893

% approxmation of a PDF for continuous distributions.

3898

% approxmation of a PDF for continuous distributions.

3894

%

3899

%

3895

% cpdf is internally normalized so that the sum of probabilities is 1

3900

% cpdf is internally normalized so that the sum of probabilities is 1

3896

% (regardless of bin size).

3901

% (regardless of bin size).

3897

3902

3898

% Internal fields:

3903

% Internal fields:

3899

% Min: *bin number* of minimum value.

3904

% Min: *bin number* of minimum value.

3900

% BinSize: size of PDF bins. Bin center is the representative value.

3905

% BinSize: size of PDF bins. Bin center is the representative value.

3901

% Vec: vector of probabilities per bin.

3906

% Vec: vector of probabilities per bin.

3902

3907

3903

%speed up for initializing empty pdf

3908

%speed up for initializing empty pdf

3904

if all(values==0)

3909

if all(values==0)

3905

pdf.BinSize=binsize;

3910

pdf.BinSize=binsize;

3906

pdf.Min=0;

3911

pdf.Min=0;

3907

pdf.y=1;

3912

pdf.y=1;

3908

pdf.x=0;

3913

pdf.x=0;

3909

return;

3914

return;

3910

end

3915

end

3911

3916

3912

if ~issorted(values)

3917

if ~issorted(values)

3913

[values,si]=sort(values);

3918

[values,si]=sort(values);

3914

probs=probs(si);

3919

probs=probs(si);

3915

end

3920

end

3916

values=binsize*round(values/binsize);

3921

values=binsize*round(values/binsize);

3917

t=(values(1):binsize:values(end));

3922

t=(values(1):binsize:values(end));

3918

pdf.Min=values(1)/binsize;

3923

pdf.Min=values(1)/binsize;

3919

pdf.y=zeros(size(t));

3924

pdf.y=zeros(size(t));

3920

for k=1:length(values)

3925

for k=1:length(values)

3921

if k==1

3926

if k==1

3922

bin=1;

3927

bin=1;

3923

elseif k==length(values)

3928

elseif k==length(values)

3924

bin=length(t);

3929

bin=length(t);

3925

else

3930

else

3926

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

3931

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

3927

end

3932

end

3928

pdf.y(bin) = pdf.y(bin)+probs(k);

3933

pdf.y(bin) = pdf.y(bin)+probs(k);

3929

end

3934

end

3930

3935

3931

pdf.BinSize=binsize;

3936

pdf.BinSize=binsize;

3932

pdf.y=pdf.y/sum(pdf.y);

3937

pdf.y=pdf.y/sum(pdf.y);

3933

if any(~isreal(pdf.y)) || any(pdf.y<0)

3938

if any(~isreal(pdf.y)) || any(pdf.y<0)

3934

error('PDF must be real and nonnegative');

3939

error('PDF must be real and nonnegative');

3935

end

3940

end

3936

support=find(pdf.y);

3941

support=find(pdf.y);

3937

pdf.y=pdf.y(support(1):support(end));

3942

pdf.y=pdf.y(support(1):support(end));

3938

pdf.Min=pdf.Min+(support(1)-1);

3943

pdf.Min=pdf.Min+(support(1)-1);

3939

pdf.x=(pdf.Min:-pdf.Min)*binsize;

3944

pdf.x=(pdf.Min:-pdf.Min)*binsize;

3940

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

3945

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

3941

3946

3942

if isrow(input)

3947

if isrow(input)

3943

max_threshold=max_threshold(:).';

3948

max_threshold=max_threshold(:).';

3944

min_threshold=min_threshold(:).';

3949

min_threshold=min_threshold(:).';

3945

else

3950

else

3946

max_threshold=max_threshold(:);

3951

max_threshold=max_threshold(:);

3947

min_threshold=min_threshold(:);

3952

min_threshold=min_threshold(:);

3948

end

3953

end

3949

3954

3950

clip_output=input;

3955

clip_output=input;

3951

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

3956

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

3952

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

3957

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

3953

3958

3954

3959

3955

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

3960

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

3956

[ncases, mele]=size(param.z_p_tx_cases);

3961

[ncases, mele]=size(param.z_p_tx_cases);

3957

if mele ==2

3962

if mele ==2

3958

param.flex=2;

3963

param.flex=2;

3959

elseif mele==4

3964

elseif mele==4

3960

param.flex=4;

3965

param.flex=4;

3961

elseif mele==1

3966

elseif mele==1

3962

param.flex=1;

3967

param.flex=1;

3963

else

3968

else

3964

error(springf('config file syntax error'))

3969

error(springf('config file syntax error'))

3965

end

3970

end

3966

3971

3967

3972

3968

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

3973

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

3969

% display bathtub curves in one axis per test case.

3974

% display bathtub curves in one axis per test case.

3970

% h=findall(0, 'Name', 'COM results');

3975

% h=findall(0, 'Name', 'COM results');

3971

if ~exist('h','var')

3976

if ~exist('h','var')

3972

msgtext = cell(1, length(OP.pkg_len_select));

3977

msgtext = cell(1, length(OP.pkg_len_select));

3973

msgcolor = 'g';

3978

msgcolor = 'g';

3974

else

3979

else

3975

msgtext=get(findobj(h, 'type', 'text'), 'string');

3980

msgtext=get(findobj(h, 'type', 'text'), 'string');

3976

msgcolor = get(h, 'color');

3981

msgcolor = get(h, 'color');

3977

close(h); % will be recreated

3982

close(h); % will be recreated

3978

end

3983

end

3979

msgctr=size(msgtext,1)+1;

3984

msgctr=size(msgtext,1)+1;

3980

if ~OP.ERL_ONLY

3985

if ~OP.ERL_ONLY

3981

switch OP.PHY

3986

switch OP.PHY

3982

case 'C2M'

3987

case 'C2M'

3983

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

3988

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

3984

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

3989

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

3985

msg, VEO_mV);

3990

msg, VEO_mV);

3986

else

3991

else

3987

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

3992

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

3988

msg, VEO_mV);

3993

msg, VEO_mV);

3989

msgcolor = 'r';

3994

msgcolor = 'r';

3990

end

3995

end

3991

3996

3992

if VEC_dB <= param.VEC_pass_threshold

3997

if VEC_dB <= param.VEC_pass_threshold

3993

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

3998

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

3994

(msg), VEC_dB);

3999

(msg), VEC_dB);

3995

else

4000

else

3996

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4001

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

3997

(msg), VEC_dB);

4002

(msg), VEC_dB);

3998

msgcolor = 'r';

4003

msgcolor = 'r';

3999

end

4004

end

4000

case 'C2C'

4005

case 'C2C'

4001

if COM >= param.pass_threshold

4006

if COM >= param.pass_threshold

4002

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4007

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4003

% msg, COM);

4008

% msg, COM);

4004

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4009

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4005

msg, COM);

4010

msg, COM);

4006

else

4011

else

4007

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4012

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4008

% msg, COM);

4013

% msg, COM);

4009

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4014

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4010

msg, COM);

4015

msg, COM);

4011

msgcolor = 'r';

4016

msgcolor = 'r';

4012

end

4017

end

4013

% begin yasuo patch 3/18/2019

4018

% begin yasuo patch 3/18/2019

4014

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4019

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4015

% end yasuo patch

4020

% end yasuo patch

4016

case 'C2Mcom'

4021

case 'C2Mcom'

4017

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4022

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4018

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4023

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4019

msg, VEO_mV);

4024

msg, VEO_mV);

4020

else

4025

else

4021

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4026

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4022

msg, VEO_mV);

4027

msg, VEO_mV);

4023

msgcolor = 'r';

4028

msgcolor = 'r';

4024

end

4029

end

4025

4030

4026

if VEC_dB <= param.VEC_pass_threshold

4031

if VEC_dB <= param.VEC_pass_threshold

4027

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4032

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4028

(msg), VEC_dB);

4033

(msg), VEC_dB);

4029

else

4034

else

4030

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4035

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4031

(msg), VEC_dB);

4036

(msg), VEC_dB);

4032

msgcolor = 'r';

4037

msgcolor = 'r';

4033

end

4038

end

4034

if COM >= param.pass_threshold

4039

if COM >= param.pass_threshold

4035

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4040

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4036

% msg, COM);

4041

% msg, COM);

4037

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4042

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4038

msg, COM);

4043

msg, COM);

4039

else

4044

else

4040

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4045

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4041

% msg, COM);

4046

% msg, COM);

4042

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4047

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4043

msg, COM);

4048

msg, COM);

4044

msgcolor = 'r';

4049

msgcolor = 'r';

4045

end

4050

end

4046

% begin yasuo patch 3/18/2019

4051

% begin yasuo patch 3/18/2019

4047

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4052

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4048

% end yasuo patch

4053

% end yasuo patch

4049

end

4054

end

4050

end

4055

end

4051

if OP.ERL

4056

if OP.ERL

4052

if ~isempty(ERL)

4057

if ~isempty(ERL)

4053

if min_ERL >= param.ERL_pass_threshold

4058

if min_ERL >= param.ERL_pass_threshold

4054

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4059

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4055

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4060

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4056

else

4061

else

4057

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4062

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4058

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4063

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4059

msgcolor = 'r';

4064

msgcolor = 'r';

4060

end

4065

end

4061

end

4066

end

4062

end

4067

end

4063

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4068

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4064

set(h, 'color', msgcolor, 'tag', 'COM');

4069

set(h, 'color', msgcolor, 'tag', 'COM');

4065

movegui(h, 'center');

4070

movegui(h, 'center');

4066

else % no windows

4071

else % no windows

4067

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4072

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4068

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4073

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4069

if ~OP.ERL_ONLY

4074

if ~OP.ERL_ONLY

4070

switch OP.PHY

4075

switch OP.PHY

4071

case 'C2C'

4076

case 'C2C'

4072

if COM >= param.pass_threshold

4077

if COM >= param.pass_threshold

4073

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4078

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4074

else

4079

else

4075

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4080

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4076

end

4081

end

4077

% begin yasuo patch 3/18/2019

4082

% begin yasuo patch 3/18/2019

4078

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4083

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4079

% end yasuo patch

4084

% end yasuo patch

4080

case 'C2Mcom'

4085

case 'C2Mcom'

4081

if VEC_dB <= param.VEC_pass_threshold

4086

if VEC_dB <= param.VEC_pass_threshold

4082

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4087

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4083

else

4088

else

4084

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4089

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4085

end

4090

end

4086

4091

4087

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4092

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4088

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4093

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4089

else

4094

else

4090

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4095

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4091

end

4096

end

4092

if COM >= param.pass_threshold

4097

if COM >= param.pass_threshold

4093

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4098

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4094

else

4099

else

4095

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4100

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4096

end

4101

end

4097

% begin yasuo patch 3/18/2019

4102

% begin yasuo patch 3/18/2019

4098

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4103

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4099

% end yasuo patch

4104

% end yasuo patch

4100

case 'C2M'

4105

case 'C2M'

4101

if VEC_dB <= param.VEC_pass_threshold

4106

if VEC_dB <= param.VEC_pass_threshold

4102

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4107

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4103

else

4108

else

4104

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4109

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4105

end

4110

end

4106

4111

4107

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4112

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4108

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4113

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4109

else

4114

else

4110

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4115

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4111

end

4116

end

4112

end

4117

end

4113

end

4118

end

4114

if OP.ERL

4119

if OP.ERL

4115

if ~isempty(ERL)

4120

if ~isempty(ERL)

4116

if min_ERL >= param.ERL_pass_threshold

4121

if min_ERL >= param.ERL_pass_threshold

4117

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4122

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4118

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4123

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4119

else

4124

else

4120

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4125

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4121

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4126

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4122

end

4127

end

4123

end

4128

end

4124

end

4129

end

4125

end

4130

end

4126

4131

4127

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4132

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4128

4133

4129

%Left eye Width (Top Eye)

4134

%Left eye Width (Top Eye)

4130

left_top=eye_contour(half_UI:-1:1,1);

4135

left_top=eye_contour(half_UI:-1:1,1);

4131

%vref_crossing is the first point less than vref (usually first point < 0)

4136

%vref_crossing is the first point less than vref (usually first point < 0)

4132

vref_crossing=find(left_top<vref,1,'first');

4137

vref_crossing=find(left_top<vref,1,'first');

4133

if isempty(vref_crossing)

4138

if isempty(vref_crossing)

4134

%this case handles completely open eye

4139

%this case handles completely open eye

4135

L1=half_UI;

4140

L1=half_UI;

4136

elseif vref_crossing==1

4141

elseif vref_crossing==1

4137

%this case handles completely closed eye

4142

%this case handles completely closed eye

4138

L1=0;

4143

L1=0;

4139

else

4144

else

4140

%this case handles the normal eye

4145

%this case handles the normal eye

4141

%INT is a linear interpolation between the 2 points on either side of

4146

%INT is a linear interpolation between the 2 points on either side of

4142

%vref to determine where the vref crossing occurred. In systems with

4147

%vref to determine where the vref crossing occurred. In systems with

4143

%a small number of samples_per_UI, interpolation improves accuracy over

4148

%a small number of samples_per_UI, interpolation improves accuracy over

4144

%just using the integer sample point

4149

%just using the integer sample point

4145

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4150

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4146

L1=half_UI-INT;

4151

L1=half_UI-INT;

4147

end

4152

end

4148

%Left eye Width (Bottom Eye)

4153

%Left eye Width (Bottom Eye)

4149

left_bot=eye_contour(half_UI:-1:1,2);

4154

left_bot=eye_contour(half_UI:-1:1,2);

4150

vref_crossing=find(left_bot>vref,1,'first');

4155

vref_crossing=find(left_bot>vref,1,'first');

4151

if isempty(vref_crossing)

4156

if isempty(vref_crossing)

4152

L0=half_UI;

4157

L0=half_UI;

4153

elseif vref_crossing==1

4158

elseif vref_crossing==1

4154

L0=0;

4159

L0=0;

4155

else

4160

else

4156

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4161

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4157

L0=half_UI-INT;

4162

L0=half_UI-INT;

4158

end

4163

end

4159

%Right eye Width (Top Eye)

4164

%Right eye Width (Top Eye)

4160

right_top=eye_contour(half_UI:end,1);

4165

right_top=eye_contour(half_UI:end,1);

4161

vref_crossing=find(right_top<vref,1,'first');

4166

vref_crossing=find(right_top<vref,1,'first');

4162

if isempty(vref_crossing)

4167

if isempty(vref_crossing)

4163

R1=samples_per_UI-half_UI;

4168

R1=samples_per_UI-half_UI;

4164

elseif vref_crossing==1

4169

elseif vref_crossing==1

4165

R1=0;

4170

R1=0;

4166

else

4171

else

4167

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4172

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4168

R1=INT-half_UI;

4173

R1=INT-half_UI;

4169

end

4174

end

4170

%Right eye Width (Bottom Eye)

4175

%Right eye Width (Bottom Eye)

4171

right_bot=eye_contour(half_UI:end,2);

4176

right_bot=eye_contour(half_UI:end,2);

4172

vref_crossing=find(right_bot>vref,1,'first');

4177

vref_crossing=find(right_bot>vref,1,'first');

4173

if isempty(vref_crossing)

4178

if isempty(vref_crossing)

4174

R0=samples_per_UI-half_UI;

4179

R0=samples_per_UI-half_UI;

4175

elseif vref_crossing==1

4180

elseif vref_crossing==1

4176

R0=0;

4181

R0=0;

4177

else

4182

else

4178

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4183

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4179

R0=INT-half_UI;

4184

R0=INT-half_UI;

4180

end

4185

end

4181

4186

4182

%L1 = top left eye width

4187

%L1 = top left eye width

4183

%L0 = bottom left eye width

4188

%L0 = bottom left eye width

4184

%Left eye width is the minimum

4189

%Left eye width is the minimum

4185

%R1 = top right eye width

4190

%R1 = top right eye width

4186

%R0 = bottom right eye width

4191

%R0 = bottom right eye width

4187

%Right eye width is the minimum

4192

%Right eye width is the minimum

4188

Left_EW=min([L1 L0]);

4193

Left_EW=min([L1 L0]);

4189

Right_EW=min([R1 R0]);

4194

Right_EW=min([R1 R0]);

4190

4195

4191

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4196

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4192

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4197

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4193

% find the location of the DFE bank

4198

% find the location of the DFE bank

4194

% hisi: waveform with cursor values;

4199

% hisi: waveform with cursor values;

4195

% idx_st: starting index;

4200

% idx_st: starting index;

4196

% idx_en: ending index ;

4201

% idx_en: ending index ;

4197

% tap_bk: number of taps per bank;

4202

% tap_bk: number of taps per bank;

4198

% bmaxg: maximum coefficient;

4203

% bmaxg: maximum coefficient;

4199

4204

4200

hisi=hisi(:);

4205

hisi=hisi(:);

4201

len=idx_en-idx_st+1;

4206

len=idx_en-idx_st+1;

4202

h0=abs(hisi(idx_st:idx_en));

4207

h0=abs(hisi(idx_st:idx_en));

4203

h1=max(0,h0-bmaxg*curval);

4208

h1=max(0,h0-bmaxg*curval);

4204

4209

4205

%if cursor value is negative, force h1 to all zeros

4210

%if cursor value is negative, force h1 to all zeros

4206

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4211

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4207

%this makes the weakest isi the most desirable to choose so everything breaks

4212

%this makes the weakest isi the most desirable to choose so everything breaks

4208

if curval<0

4213

if curval<0

4209

h1=zeros(size(h0));

4214

h1=zeros(size(h0));

4210

end

4215

end

4211

4216

4212

h0n=zeros(len-tap_bk+1,1);

4217

h0n=zeros(len-tap_bk+1,1);

4213

h1n=h0n;

4218

h1n=h0n;

4214

4219

4215

for ii=1:tap_bk

4220

for ii=1:tap_bk

4216

h0tmp=h0(ii:ii+len-tap_bk);

4221

h0tmp=h0(ii:ii+len-tap_bk);

4217

h0n=h0n+h0tmp.^2;

4222

h0n=h0n+h0tmp.^2;

4218

h1tmp=h1(ii:ii+len-tap_bk);

4223

h1tmp=h1(ii:ii+len-tap_bk);

4219

h1n=h1n+h1tmp.^2;

4224

h1n=h1n+h1tmp.^2;

4220

end

4225

end

4221

4226

4222

ndiff=h0n-h1n;

4227

ndiff=h0n-h1n;

4223

4228

4224

min_energy = -Inf;

4229

min_energy = -Inf;

4225

4230

4226

idx=zeros(1,tap_bk*N_bg);

4231

idx=zeros(1,tap_bk*N_bg);

4227

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4232

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4228

set_next_bank=0;

4233

set_next_bank=0;

4229

%Loop through each group

4234

%Loop through each group

4230

for k=1:N_bg

4235

for k=1:N_bg

4231

%Sort to choose the strongest

4236

%Sort to choose the strongest

4232

[~,val_sort]=sort(ndiff,'descend');

4237

[~,val_sort]=sort(ndiff,'descend');

4233

if k==1

4238

if k==1

4234

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4239

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4235

if isequal(sort(val_sort(ordered_set)),ordered_set)

4240

if isequal(sort(val_sort(ordered_set)),ordered_set)

4236

idx=1:N_bg*tap_bk;

4241

idx=1:N_bg*tap_bk;

4237

break;

4242

break;

4238

end

4243

end

4239

end

4244

end

4240

if set_next_bank>0

4245

if set_next_bank>0

4241

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4246

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4242

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4247

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4243

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4248

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4244

set_next_bank=0;

4249

set_next_bank=0;

4245

ndiff(new_bank)=min_energy;

4250

ndiff(new_bank)=min_energy;

4246

bad_start=new_bank(1)-tap_bk+1;

4251

bad_start=new_bank(1)-tap_bk+1;

4247

bad_end=new_bank(1)-1;

4252

bad_end=new_bank(1)-1;

4248

if bad_end<=0

4253

if bad_end<=0

4249

badV=[];

4254

badV=[];

4250

elseif bad_start>0

4255

elseif bad_start>0

4251

badV=bad_start:bad_end;

4256

badV=bad_start:bad_end;

4252

else

4257

else

4253

badV=1:bad_end;

4258

badV=1:bad_end;

4254

end

4259

end

4255

if ~isempty(badV)

4260

if ~isempty(badV)

4256

ndiff(badV)=min_energy;

4261

ndiff(badV)=min_energy;

4257

end

4262

end

4258

continue;

4263

continue;

4259

end

4264

end

4260

%potential bank = the strongest tap group

4265

%potential bank = the strongest tap group

4261

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4266

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4262

if k==N_bg

4267

if k==N_bg

4263

%Last group: just choose the strongest

4268

%Last group: just choose the strongest

4264

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4269

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4265

break;

4270

break;

4266

end

4271

end

4267

4272

4268

do_it_again=1;

4273

do_it_again=1;

4269

first_time=1;

4274

first_time=1;

4270

num_loops=0;

4275

num_loops=0;

4271

while do_it_again

4276

while do_it_again

4272

do_it_again=0;

4277

do_it_again=0;

4273

if num_loops>length(ndiff)

4278

if num_loops>length(ndiff)

4274

break;

4279

break;

4275

end

4280

end

4276

%note badV: taps smaller and less than 1 group away

4281

%note badV: taps smaller and less than 1 group away

4277

bad_start=new_bank(1)-tap_bk+1;

4282

bad_start=new_bank(1)-tap_bk+1;

4278

bad_end=new_bank(1)-1;

4283

bad_end=new_bank(1)-1;

4279

if bad_end<=0

4284

if bad_end<=0

4280

badV=[];

4285

badV=[];

4281

elseif bad_start>0

4286

elseif bad_start>0

4282

badV=bad_start:bad_end;

4287

badV=bad_start:bad_end;

4283

else

4288

else

4284

badV=1:bad_end;

4289

badV=1:bad_end;

4285

end

4290

end

4286

for j=length(badV):-1:1

4291

for j=length(badV):-1:1

4287

if any(badV(j)-idx==0)

4292

if any(badV(j)-idx==0)

4288

badV(j)=[];

4293

badV(j)=[];

4289

end

4294

end

4290

end

4295

end

4291

%note goodV: the tap exactly 1 tap_bk smaller

4296

%note goodV: the tap exactly 1 tap_bk smaller

4292

goodV=new_bank(1)-tap_bk;

4297

goodV=new_bank(1)-tap_bk;

4293

if ~isempty(badV)

4298

if ~isempty(badV)

4294

if ~first_time

4299

if ~first_time

4295

[~,val_sort]=sort(ndiff,'descend');

4300

[~,val_sort]=sort(ndiff,'descend');

4296

end

4301

end

4297

first_time=0;

4302

first_time=0;

4298

checkV=[badV new_bank];

4303

checkV=[badV new_bank];

4299

4304

4300

badV_pos=zeros(1,length(badV));

4305

badV_pos=zeros(1,length(badV));

4301

for j=1:length(badV)

4306

for j=1:length(badV)

4302

badV_pos(j)=find(badV(j)==val_sort);

4307

badV_pos(j)=find(badV(j)==val_sort);

4303

end

4308

end

4304

4309

4305

%loop through the sorted list to find the first tap outside the group and not a member of badV

4310

%loop through the sorted list to find the first tap outside the group and not a member of badV

4306

found_goodV=0;

4311

found_goodV=0;

4307

for ii=1:length(val_sort)

4312

for ii=1:length(val_sort)

4308

if val_sort(ii)==goodV

4313

if val_sort(ii)==goodV

4309

found_goodV=1;

4314

found_goodV=1;

4310

break;

4315

break;

4311

end

4316

end

4312

if all(val_sort(ii)-checkV~=0)

4317

if all(val_sort(ii)-checkV~=0)

4313

break;

4318

break;

4314

end

4319

end

4315

end

4320

end

4316

4321

4317

if ~found_goodV && min(badV_pos)<ii

4322

if ~found_goodV && min(badV_pos)<ii

4318

%if goodV wasn't found and bad taps occur before non group members are found

4323

%if goodV wasn't found and bad taps occur before non group members are found

4319

%throw out the strongest tap and take the next strongest

4324

%throw out the strongest tap and take the next strongest

4320

do_it_again=1;

4325

do_it_again=1;

4321

ndiff(new_bank(1))=min_energy;

4326

ndiff(new_bank(1))=min_energy;

4322

%speed up: new max_val is always val_sort(2)

4327

%speed up: new max_val is always val_sort(2)

4323

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4328

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4324

end

4329

end

4325

if found_goodV

4330

if found_goodV

4326

%if goodV was found, set the next bank to goodV

4331

%if goodV was found, set the next bank to goodV

4327

set_next_bank=goodV;

4332

set_next_bank=goodV;

4328

end

4333

end

4329

end

4334

end

4330

num_loops=num_loops+1;

4335

num_loops=num_loops+1;

4331

end

4336

end

4332

%at the end, the floating taps are set to idx

4337

%at the end, the floating taps are set to idx

4333

%and ndiff has illegal values set to zero

4338

%and ndiff has illegal values set to zero

4334

ndiff(new_bank)=min_energy;

4339

ndiff(new_bank)=min_energy;

4335

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4340

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4336

if ~isempty(badV)

4341

if ~isempty(badV)

4337

ndiff(badV)=min_energy;

4342

ndiff(badV)=min_energy;

4338

end

4343

end

4339

end

4344

end

4340

4345

4341

4346

4342

idx=idx+idx_st-1;

4347

idx=idx+idx_st-1;

4343

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4348

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4344

4349

4345

% hisi = postcursor isi

4350

% hisi = postcursor isi

4346

% N_b = number of fixed dfe taps (before floating taps begin)

4351

% N_b = number of fixed dfe taps (before floating taps begin)

4347

% N_bf = number of floating taps per group

4352

% N_bf = number of floating taps per group

4348

% N_bg = nubmber of groups

4353

% N_bg = nubmber of groups

4349

% N_bmax = max tap number that can be used for floating tap

4354

% N_bmax = max tap number that can be used for floating tap

4350

% bmaxg = max tap strength for floating taps

4355

% bmaxg = max tap strength for floating taps

4351

% curval = value of the cursor

4356

% curval = value of the cursor

4352

4357

4353

4358

4354

if nargin<8, dfe_delta=0;end

4359

if nargin<8, dfe_delta=0;end

4355

4360

4356

4361

4357

tap_coef=zeros(1,length(hisi));

4362

tap_coef=zeros(1,length(hisi));

4358

b=zeros(1,length(hisi));

4363

b=zeros(1,length(hisi));

4359

4364

4360

4365

4361

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4366

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4362

4367

4363

%Apply DFE to all taps

4368

%Apply DFE to all taps

4364

flt_curval=hisi(tap_loc);

4369

flt_curval=hisi(tap_loc);

4365

if dfe_delta~=0

4370

if dfe_delta~=0

4366

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4371

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4367

dfe_delta.*sign(flt_curval)*curval;

4372

dfe_delta.*sign(flt_curval)*curval;

4368

else

4373

else

4369

flt_curval_q=hisi(tap_loc);

4374

flt_curval_q=hisi(tap_loc);

4370

end

4375

end

4371

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4376

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4372

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4377

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4373

tap_coef(tap_loc)=applied_coef;

4378

tap_coef(tap_loc)=applied_coef;

4374

4379

4375

4380

4376

4381

4377

tap_loc=sort(tap_loc,'ascend');

4382

tap_loc=sort(tap_loc,'ascend');

4378

b(tap_loc)=bmaxg;

4383

b(tap_loc)=bmaxg;

4379

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4384

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4380

% Richard Mellitz: 04/23/2019

4385

% Richard Mellitz: 04/23/2019

4381

% hisi is the isi 1 ui/sample

4386

% hisi is the isi 1 ui/sample

4382

% N_b number of fixed dfe taps

4387

% N_b number of fixed dfe taps

4383

% N_bf number of floating taps per group

4388

% N_bf number of floating taps per group

4384

% N_bg number of floating tap groups. 1 2 or 3 right now

4389

% N_bg number of floating tap groups. 1 2 or 3 right now

4385

% N_bmax number of ui for the max reach of the floating taps

4390

% N_bmax number of ui for the max reach of the floating taps

4386

% bmaxg limit for the floating taps

4391

% bmaxg limit for the floating taps

4387

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4392

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4388

%

4393

%

4389

%

4394

%

4390

% function to remove isi or add noise above bmaxg

4395

% function to remove isi or add noise above bmaxg

4391

if ~exist('COOP','var'), COOP=0;end

4396

if ~exist('COOP','var'), COOP=0;end

4392

if iscolumn(hisi); hisi=hisi.';end

4397

if iscolumn(hisi); hisi=hisi.';end

4393

hsis_in=hisi;

4398

hsis_in=hisi;

4394

% find all the reduction group taken N_bf at a time

4399

% find all the reduction group taken N_bf at a time

4395

% we are looking for the group when when remove yield the miminim isi, h, power

4400

% we are looking for the group when when remove yield the miminim isi, h, power

4396

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4401

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4397

% add on switch and loop for each potential group

4402

% add on switch and loop for each potential group

4398

switch N_bg

4403

switch N_bg

4399

case 0

4404

case 0

4400

bmax=0;

4405

bmax=0;

4401

return

4406

return

4402

case 1

4407

case 1

4403

end1=N_bmax-N_bf;

4408

end1=N_bmax-N_bf;

4404

end2=N_b+1;

4409

end2=N_b+1;

4405

end3=N_b+1;

4410

end3=N_b+1;

4406

case 2

4411

case 2

4407

end1=N_bmax-N_bf;

4412

end1=N_bmax-N_bf;

4408

end2=N_bmax-N_bf;

4413

end2=N_bmax-N_bf;

4409

end3=N_b+1;

4414

end3=N_b+1;

4410

case 3

4415

case 3

4411

end1=N_bmax-N_bf;

4416

end1=N_bmax-N_bf;

4412

end2=N_bmax-N_bf;

4417

end2=N_bmax-N_bf;

4413

end3=N_bmax-N_bf;

4418

end3=N_bmax-N_bf;

4414

end

4419

end

4415

if COOP

4420

if COOP

4416

for ig1= N_b+1:end1 % now remove the 2nd group

4421

for ig1= N_b+1:end1 % now remove the 2nd group

4417

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4422

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4418

% loop for 2rd group

4423

% loop for 2rd group

4419

for ig2= N_b+1: end2

4424

for ig2= N_b+1: end2

4420

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4425

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4421

if N_bg < 2; hcap2 =hcap; end

4426

if N_bg < 2; hcap2 =hcap; end

4422

for ig3= N_b+1: end3

4427

for ig3= N_b+1: end3

4423

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4428

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4424

if N_bg < 3 ; hcap3=hcap2 ; end

4429

if N_bg < 3 ; hcap3=hcap2 ; end

4425

sigma=norm( hcap3 );

4430

sigma=norm( hcap3 );

4426

if sigma < best_sigma

4431

if sigma < best_sigma

4427

best_sigma=sigma;

4432

best_sigma=sigma;

4428

best_ig1=ig1;

4433

best_ig1=ig1;

4429

best_ig2=ig2;

4434

best_ig2=ig2;

4430

best_ig3=ig3;

4435

best_ig3=ig3;

4431

best_hcap=hcap3;

4436

best_hcap=hcap3;

4432

end

4437

end

4433

end

4438

end

4434

end

4439

end

4435

end

4440

end

4436

else % sequentail

4441

else % sequentail

4437

for ig1= N_b+1:end1 % now remove the 1st group

4442

for ig1= N_b+1:end1 % now remove the 1st group

4438

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4443

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4439

sigma=norm( hcap );

4444

sigma=norm( hcap );

4440

if sigma < best_sigma

4445

if sigma < best_sigma

4441

best_sigma=sigma;

4446

best_sigma=sigma;

4442

best_ig1=ig1;

4447

best_ig1=ig1;

4443

best_hcap=hcap;

4448

best_hcap=hcap;

4444

end

4449

end

4445

end

4450

end

4446

% loop for 2rd group

4451

% loop for 2rd group

4447

hisi=best_hcap;

4452

hisi=best_hcap;

4448

for ig2= N_b+1: end2

4453

for ig2= N_b+1: end2

4449

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4454

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4450

sigma=norm( hcap );

4455

sigma=norm( hcap );

4451

if sigma < best_sigma

4456

if sigma < best_sigma

4452

best_sigma=sigma;

4457

best_sigma=sigma;

4453

best_ig2=ig2;

4458

best_ig2=ig2;

4454

best_hcap=hcap;

4459

best_hcap=hcap;

4455

end

4460

end

4456

end

4461

end

4457

hisi=best_hcap;

4462

hisi=best_hcap;

4458

% loop for 3rd group

4463

% loop for 3rd group

4459

for ig3= N_b+1: end3

4464

for ig3= N_b+1: end3

4460

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4465

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4461

sigma=norm( hcap );

4466

sigma=norm( hcap );

4462

if sigma < best_sigma

4467

if sigma < best_sigma

4463

best_sigma=sigma;

4468

best_sigma=sigma;

4464

best_ig3=ig3;

4469

best_ig3=ig3;

4465

best_hcap=hcap;

4470

best_hcap=hcap;

4466

end

4471

end

4467

end

4472

end

4468

4473

4469

end

4474

end

4470

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4475

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4471

switch N_bg

4476

switch N_bg

4472

case 1

4477

case 1

4473

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4478

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4474

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4479

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4475

case 2

4480

case 2

4476

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4481

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4477

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4482

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4478

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4483

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4479

case 3

4484

case 3

4480

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4485

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4481

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4486

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4482

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4487

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4483

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4488

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4484

end

4489

end

4485

floating_tap_locations=sort(floating_tap_locations);

4490

floating_tap_locations=sort(floating_tap_locations);

4486

if 0 % for code debug

4491

if 0 % for code debug

4487

close force all

4492

close force all

4488

stem(best_hcap,'disp','hcap')

4493

stem(best_hcap,'disp','hcap')

4489

hold on

4494

hold on

4490

stem(bmax,'-k','disp','bmax')

4495

stem(bmax,'-k','disp','bmax')

4491

stem(hisi,'disp','hisi')

4496

stem(hisi,'disp','hisi')

4492

hold off

4497

hold off

4493

end

4498

end

4494

4499

4495

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4500

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4496

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4501

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4497

% Vfilter is vector forced filtered sbr

4502

% Vfilter is vector forced filtered sbr

4498

% Cmod is the ffe tap co-efficient vector

4503

% Cmod is the ffe tap co-efficient vector

4499

% if C is passed, just process V with C else compute C

4504

% if C is passed, just process V with C else compute C

4500

% cmx=param.rx_cmx; number of pre cursor taps

4505

% cmx=param.rx_cmx; number of pre cursor taps

4501

% cpx=param.rx_cps; number of post cursor taps

4506

% cpx=param.rx_cps; number of post cursor taps

4502

% V=sbr; pass pulse response

4507

% V=sbr; pass pulse response

4503

% ix the sample point in the passed pulse response

4508

% ix the sample point in the passed pulse response

4504

% the sample point is recomputed by optimize_fom

4509

% the sample point is recomputed by optimize_fom

4505

% idx - return floating tap location (RIM 9-19-2023)

4510

% idx - return floating tap location (RIM 9-19-2023)

4506

% OP not used for now

4511

% OP not used for now

4507

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4512

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4508

% this allows significant speed up in optimize_fom since FFE is time consuming

4513

% this allows significant speed up in optimize_fom since FFE is time consuming

4509

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4514

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4510

% Vfiltered to be calculated

4515

% Vfiltered to be calculated

4511

% test with load('SBR_FIR_resp.mydata','-mat')

4516

% test with load('SBR_FIR_resp.mydata','-mat')

4512

idx=[];

4517

idx=[];

4513

if nargin<4

4518

if nargin<4

4514

ix=find(V==max(V),1,'first');

4519

ix=find(V==max(V),1,'first');

4515

end

4520

end

4516

if nargin<5

4521

if nargin<5

4517

C=[];

4522

C=[];

4518

end

4523

end

4519

if nargin<6

4524

if nargin<6

4520

return_V=1;

4525

return_V=1;

4521

end

4526

end

4522

cmx=param.RxFFE_cmx;

4527

cmx=param.RxFFE_cmx;

4523

cpx=param.RxFFE_cpx;

4528

cpx=param.RxFFE_cpx;

4524

% do this early on so we can reuse the old code

4529

% do this early on so we can reuse the old code

4525

if param.N_bg ~=0 % must be floating taps

4530

if param.N_bg ~=0 % must be floating taps

4526

cpx=param.N_bmax; % N_f in spreadsheet

4531

cpx=param.N_bmax; % N_f in spreadsheet

4527

end

4532

end

4528

num_taps=cmx+cpx+1;

4533

num_taps=cmx+cpx+1;

4529

cstep=param.RxFFE_stepz;

4534

cstep=param.RxFFE_stepz;

4530

ndfe=param.ndfe;

4535

ndfe=param.ndfe;

4531

spui=param.samples_per_ui;

4536

spui=param.samples_per_ui;

4532

param.current_ffegain=0;

4537

param.current_ffegain=0;

4533

if return_V && ~isempty(C)

4538

if return_V && ~isempty(C)

4534

% RIM 2-3-23 when we just want to EQ not find EQ

4539

% RIM 2-3-23 when we just want to EQ not find EQ

4535

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4540

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4536

Cmod=C;

4541

Cmod=C;

4537

return

4542

return

4538

end

4543

end

4539

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4544

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4540

if ix < length(V)

4545

if ix < length(V)

4541

if isrow(V)

4546

if isrow(V)

4542

if mod(ix,spui) == 0

4547

if mod(ix,spui) == 0

4543

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4548

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4544

else

4549

else

4545

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4550

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4546

end

4551

end

4547

4552

4548

else

4553

else

4549

if mod(ix,spui) == 0

4554

if mod(ix,spui) == 0

4550

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4555

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4551

else

4556

else

4552

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4557

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4553

end

4558

end

4554

end

4559

end

4555

else

4560

else

4556

if isrow(V)

4561

if isrow(V)

4557

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4562

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4558

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4563

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4559

else

4564

else

4560

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4565

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4561

end

4566

end

4562

else

4567

else

4563

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4568

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4564

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4569

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4565

else

4570

else

4566

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4571

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4567

end

4572

end

4568

end

4573

end

4569

end

4574

end

4570

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4575

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4571

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4576

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4572

4577

4573

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4578

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4574

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4579

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4575

% Upen Kareti suggested fix for indexing 11/04/18

4580

% Upen Kareti suggested fix for indexing 11/04/18

4576

if ix < length(V)

4581

if ix < length(V)

4577

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4582

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4578

else

4583

else

4579

ivs=find(vsampled == max(vsampled),1,'first');

4584

ivs=find(vsampled == max(vsampled),1,'first');

4580

end

4585

end

4581

4586

4582

4587

4583

%% create VV matrix of shifted UI spaced sample of the pulse response

4588

%% create VV matrix of shifted UI spaced sample of the pulse response

4584

% only consider the VV matrix that correstonds to the FFE taps

4589

% only consider the VV matrix that correstonds to the FFE taps

4585

VV=zeros(num_taps,num_taps);

4590

VV=zeros(num_taps,num_taps);

4586

for i=1:num_taps

4591

for i=1:num_taps

4587

start_idx=ivs+i-1;

4592

start_idx=ivs+i-1;

4588

end_idx=start_idx-num_taps+1;

4593

end_idx=start_idx-num_taps+1;

4589

VV(:,i)=vsampled(start_idx:-1:end_idx);

4594

VV(:,i)=vsampled(start_idx:-1:end_idx);

4590

end

4595

end

4591

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4596

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4592

%% Apply RXFFE

4597

%% Apply RXFFE

4593

if isempty(C)

4598

if isempty(C)

4594

switch upper(OP.FFE_OPT_METHOD)

4599

switch upper(OP.FFE_OPT_METHOD)

4595

case 'WIENER-HOPF'

4600

case 'WIENER-HOPF'

4596

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4601

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4597

Cmod=C(1:num_taps);

4602

Cmod=C(1:num_taps);

4598

otherwise

4603

otherwise

4599

% cmx+1 is the cursor or sample point

4604

% cmx+1 is the cursor or sample point

4600

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4605

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4601

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4606

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4602

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4607

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4603

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4608

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4604

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4609

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4605

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4610

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4606

end

4611

end

4607

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4612

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4608

if diff(size(VV))==0

4613

if diff(size(VV))==0

4609

%For square matrix, can solve C using simple inv(VV')*FV'

4614

%For square matrix, can solve C using simple inv(VV')*FV'

4610

C=VV'\FV';

4615

C=VV'\FV';

4611

else

4616

else

4612

%otherwise use the general solution with psuedo inverse

4617

%otherwise use the general solution with psuedo inverse

4613

%note: this is the same as doing pinv(VV') but pinv is far slower

4618

%note: this is the same as doing pinv(VV') but pinv is far slower

4614

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4619

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4615

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4620

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4616

end

4621

end

4617

4622

4618

Cmod=C(1:num_taps);

4623

Cmod=C(1:num_taps);

4619

end

4624

end

4620

4625

4621

4626

4622

% added for 4.2 find floating taps with either ISI or taps

4627

% added for 4.2 find floating taps with either ISI or taps

4623

switch lower(OP.RXFFE_FLOAT_CTL)

4628

switch lower(OP.RXFFE_FLOAT_CTL)

4624

case 'taps'

4629

case 'taps'

4625

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4630

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4626

otherwise

4631

otherwise

4627

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4632

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4628

end

4633

end

4629

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4634

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4630

case 'unity cursor'

4635

case 'unity cursor'

4631

Cmod=Cmod/Cmod(cmx+1);

4636

Cmod=Cmod/Cmod(cmx+1);

4632

otherwise

4637

otherwise

4633

Cmod=C;

4638

Cmod=C;

4634

end

4639

end

4635

if cstep ~= 0

4640

if cstep ~= 0

4636

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4641

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4637

end

4642

end

4638

4643

4639

if ~isempty(idx)

4644

if ~isempty(idx)

4640

idx=sort(idx);

4645

idx=sort(idx);

4641

C1=Cmod;

4646

C1=Cmod;

4642

% C1(param.N_tail_start:end)=0;

4647

% C1(param.N_tail_start:end)=0;

4643

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4648

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4644

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4649

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4645

Cmod=C1;

4650

Cmod=C1;

4646

else

4651

else

4647

% Cmod=C;

4652

% Cmod=C;

4648

end

4653

end

4649

4654

4650

% now when ussing RxFFE floating taps need to tag stems correctly and

4655

% now when ussing RxFFE floating taps need to tag stems correctly and

4651

% make sure DFEfloating tap code does not get exectuted

4656

% make sure DFEfloating tap code does not get exectuted

4652

4657

4653

%

4658

%

4654

else

4659

else

4655

Cmod=C;%just us the FFE taps, C, passed for filtering

4660

Cmod=C;%just us the FFE taps, C, passed for filtering

4656

end

4661

end

4657

%%

4662

%%

4658

%% filter the pulse response with the solved FFE

4663

%% filter the pulse response with the solved FFE

4659

% (now option to avoid this and just return Cmod for speed up)

4664

% (now option to avoid this and just return Cmod for speed up)

4660

if return_V

4665

if return_V

4661

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4666

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4662

else

4667

else

4663

Vfiltered=[];

4668

Vfiltered=[];

4664

end

4669

end

4665

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4670

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4666

% used for FD IL fitting

4671

% used for FD IL fitting

4667

% sdd21 us a complex insertion loss

4672

% sdd21 us a complex insertion loss

4668

db = @(x) 20*log10(abs(x));

4673

db = @(x) 20*log10(abs(x));

4669

sdd21=squeeze(sdd21);

4674

sdd21=squeeze(sdd21);

4670

if iscolumn(sdd21)

4675

if iscolumn(sdd21)

4671

sdd21=sdd21.';

4676

sdd21=sdd21.';

4672

end

4677

end

4673

fmbg=[ones(length(faxis_f2),1).*transpose(abs(sdd21)) transpose(sqrt(faxis_f2)).*transpose(abs(sdd21)) transpose(faxis_f2).*transpose(abs(sdd21)) transpose(faxis_f2.^2).*transpose(abs(sdd21)) ];

4678

fmbg=[ones(length(faxis_f2),1).*transpose(abs(sdd21)) transpose(sqrt(faxis_f2)).*transpose(abs(sdd21)) transpose(faxis_f2).*transpose(abs(sdd21)) transpose(faxis_f2.^2).*transpose(abs(sdd21)) ];

4674

warning('off','MATLAB:nearlySingularMatrix');

4679

warning('off','MATLAB:nearlySingularMatrix');

4675

LGw=transpose(abs(sdd21).*db(sdd21));

4680

LGw=transpose(abs(sdd21).*db(sdd21));

4676

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4681

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4677

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4682

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4678

ILN = db(sdd21)-efit;

4683

ILN = db(sdd21)-efit;

4679

4684

4680

4685

4681

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4686

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4682

% Complex IL fitting

4687

% Complex IL fitting

4683

% sdd21 us a complex insertion loss

4688

% sdd21 us a complex insertion loss

4684

% efit and ILN are in db

4689

% efit and ILN are in db

4685

% faxix_f2 needs to be at least to fb

4690

% faxix_f2 needs to be at least to fb

4686

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

4691

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

4687

% still need to settle on voltage scaling.

4692

% still need to settle on voltage scaling.

4688

% maybe db(peak/Rss

4693

% maybe db(peak/Rss

4689

4694

4690

OP.interp_sparam_mag= 'trend_to_DC';

4695

OP.interp_sparam_mag= 'trend_to_DC';

4691

OP.interp_sparam_phase= 'interp_to_DC';

4696

OP.interp_sparam_phase= 'interp_to_DC';

4692

% OP.interp_sparam_mag= 'linear_trend_to_DC';

4697

% OP.interp_sparam_mag= 'linear_trend_to_DC';

4693

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

4698

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

4694

4699

4695

print_for_codereview=0;

4700

print_for_codereview=0;

4696

if ~exist('A_T','var')

4701

if ~exist('A_T','var')

4697

A_T=1;

4702

A_T=1;

4698

end

4703

end

4699

4704

4700

db = @(x) 20*log10(abs(x));

4705

db = @(x) 20*log10(abs(x));

4701

sdd21=squeeze(sdd21);

4706

sdd21=squeeze(sdd21);

4702

if iscolumn(sdd21)

4707

if iscolumn(sdd21)

4703

sdd21=sdd21.';

4708

sdd21=sdd21.';

4704

end

4709

end

4705

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

4710

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

4706

warning('off','MATLAB:nearlySingularMatrix');

4711

warning('off','MATLAB:nearlySingularMatrix');

4707

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

4712

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

4708

LGw=transpose(sdd21.*unwraplog);

4713

LGw=transpose(sdd21.*unwraplog);

4709

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4714

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4710

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4715

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4711

FIT=transpose(exp(transpose(efit_C)));

4716

FIT=transpose(exp(transpose(efit_C)));

4712

efit=db(abs(FIT));

4717

efit=db(abs(FIT));

4713

ILN = db(sdd21)-efit;

4718

ILN = db(sdd21)-efit;

4714

% time domain

4719

% time domain

4715

fprintf('computing TD_ILN (dB) ...')

4720

fprintf('computing TD_ILN (dB) ...')

4716

if exist('OP','var')

4721

if exist('OP','var')

4717

% OP.fraction_of_F_range_start_extrap_from=.95;

4722

% OP.fraction_of_F_range_start_extrap_from=.95;

4718

OP.impulse_response_truncation_threshold =1e-7;

4723

OP.impulse_response_truncation_threshold =1e-7;

4719

4724

4720

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

4725

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

4721

H_bw=Butterworth_Filter(param,faxis_f2,1);

4726

H_bw=Butterworth_Filter(param,faxis_f2,1);

4722

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

4727

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

4723

H_tw=Tukey_Window(faxis_f2,param);

4728

H_tw=Tukey_Window(faxis_f2,param);

4724

H_tw=ones(1,length(faxis_f2) );

4729

H_tw=ones(1,length(faxis_f2) );

4725

4730

4726

[TD_ILN.REF.FIR, ...

4731

[TD_ILN.REF.FIR, ...

4727

TD_ILN.REF.t, ...

4732

TD_ILN.REF.t, ...

4728

TD_ILN.REF.causality_correction_dB, ...

4733

TD_ILN.REF.causality_correction_dB, ...

4729

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4734

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4730

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

4735

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

4731

4736

4732

[TD_ILN.FIT.FIR, ...

4737

[TD_ILN.FIT.FIR, ...

4733

TD_ILN.FIT.t, ...

4738

TD_ILN.FIT.t, ...

4734

TD_ILN.FIT.causality_correction_dB, ...

4739

TD_ILN.FIT.causality_correction_dB, ...

4735

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4740

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4736

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

4741

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

4737

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

4742

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

4738

% NrangeUI=1000;

4743

% NrangeUI=1000;

4739

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(TD_ILN.FIT.PR)-param.samples_per_ui ),length(TD_ILN.REF.PR)-param.samples_per_ui);

4744

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(TD_ILN.FIT.PR)-param.samples_per_ui ),length(TD_ILN.REF.PR)-param.samples_per_ui);

4740

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

4745

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

4741

range=ipeak:range_end;

4746

range=ipeak:range_end;

4742

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

4747

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

4743

TD_ILN.t=TD_ILN.FIT.t(range);

4748

TD_ILN.t=TD_ILN.FIT.t(range);

4744

TD_ILN.FOM=-inf;

4749

TD_ILN.FOM=-inf;

4745

TD_ILN.FOM_PDF=-inf;

4750

TD_ILN.FOM_PDF=-inf;

4746

rms_fom=-inf;

4751

rms_fom=-inf;

4747

for im=1:param.samples_per_ui

4752

for im=1:param.samples_per_ui

4748

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

4753

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

4749

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

4754

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

4750

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

4755

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

4751

cdf=pdf; cdf.y=cumsum(pdf.y);

4756

cdf=pdf; cdf.y=cumsum(pdf.y);

4752

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

4757

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

4753

% signal_and_isi_pdf = conv_fct(cursors, pdf);

4758

% signal_and_isi_pdf = conv_fct(cursors, pdf);

4754

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

4759

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

4755

if print_for_codereview % remove once all checked out

4760

if print_for_codereview % remove once all checked out

4756

h=figure(190);set(gcf,'Tag','COM');

4761

h=figure(190);set(gcf,'Tag','COM');

4757

semilogy(-cdf.x,cdf.y);

4762

semilogy(-cdf.x,cdf.y);

4758

% xlim ([0,-cdf.x(1)])

4763

% xlim ([0,-cdf.x(1)])

4759

ylim([param.specBER 1]);title ('CDF of ILN')

4764

ylim([param.specBER 1]);title ('CDF of ILN')

4760

hold on

4765

hold on

4761

end

4766

end

4762

if rms>rms_fom

4767

if rms>rms_fom

4763

rms_fom=rms;

4768

rms_fom=rms;

4764

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

4769

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

4765

TD_ILN.PDF=pdf;

4770

TD_ILN.PDF=pdf;

4766

end

4771

end

4767

end

4772

end

4768

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

4773

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

4769

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

4774

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

4770

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

4775

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

4771

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

4776

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

4772

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

4777

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

4773

if print_for_codereview % remove once all checked out

4778

if print_for_codereview % remove once all checked out

4774

figure(9000);set(gcf,'Tag','COM');

4779

figure(9000);set(gcf,'Tag','COM');

4775

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

4780

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

4776

hold on

4781

hold on

4777

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

4782

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

4778

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

4783

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

4779

hold off

4784

hold off

4780

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',TD_ILN.SNR_ISI_FOM,TD_ILN.SNR_ISI_FOM_PDF)

4785

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',TD_ILN.SNR_ISI_FOM,TD_ILN.SNR_ISI_FOM_PDF)

4781

figure(9002);set(gcf,'Tag','COM');

4786

figure(9002);set(gcf,'Tag','COM');

4782

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

4787

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

4783

hold on

4788

hold on

4784

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

4789

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

4785

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

4790

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

4786

grid on

4791

grid on

4787

legend('show')

4792

legend('show')

4788

end

4793

end

4789

end

4794

end

4790

% display('got to end of get_ILN_cmp_td')

4795

% display('got to end of get_ILN_cmp_td')

4791

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

4796

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

4792

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

4797

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

4793

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

4798

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

4794

if 1 % force indent for doc

4799

if 1 % force indent for doc

4795

num_ui=param.num_ui_RXFF_noise;

4800

num_ui=param.num_ui_RXFF_noise;

4796

M=param.samples_per_ui;

4801

M=param.samples_per_ui;

4797

L=param.levels;

4802

L=param.levels;

4798

f_b=param.fb;

4803

f_b=param.fb;

4799

SNR_TX=param.SNR_TX;

4804

SNR_TX=param.SNR_TX;

4800

dw=param.RxFFE_cmx;

4805

dw=param.RxFFE_cmx;

4801

bmax=param.bmax;

4806

bmax=param.bmax;

4802

bmin=param.bmin ;

4807

bmin=param.bmin ;

4803

Nb=param.ndfe;

4808

Nb=param.ndfe;

4804

sigma_X2=(L^2-1)/(3*(L-1)^2);

4809

sigma_X2=(L^2-1)/(3*(L-1)^2);

4805

eta_0=param.eta_0; %V^2/GHz

4810

eta_0=param.eta_0; %V^2/GHz

4806

T_b=1/f_b;

4811

T_b=1/f_b;

4807

delta_f = f_b/num_ui; % Units are Hz.

4812

delta_f = f_b/num_ui; % Units are Hz.

4808

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

4813

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

4809

result.fvec=fvec;

4814

result.fvec=fvec;

4810

end

4815

end

4811

if OP.COMPUTE_COM

4816

if OP.COMPUTE_COM

4812

%% H_rxffe eq 178A-28 d1.0

4817

%% H_rxffe eq 178A-28 d1.0

4813

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

4818

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

4814

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

4819

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

4815

H_rxffe=0;

4820

H_rxffe=0;

4816

for nn=1:length(result.w)

4821

for nn=1:length(result.w)

4817

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

4822

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

4818

end

4823

end

4819

H_rxffe_2_of_f=abs(H_rxffe).^2;

4824

H_rxffe_2_of_f=abs(H_rxffe).^2;

4820

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

4825

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

4821

H_rxffe_2= [real( H_rxffe_2(1)), H_rxffe_2(2:end-1), real( H_rxffe_2(end)), conj( H_rxffe_2(end-1:-1:2))];

4826

H_rxffe_2= [real( H_rxffe_2(1)), H_rxffe_2(2:end-1), real( H_rxffe_2(end)), conj( H_rxffe_2(end-1:-1:2))];

4822

else

4827

else

4823

H_rxffe_2=1;

4828

H_rxffe_2=1;

4824

end

4829

end

4825

result.H_rxffe_2=H_rxffe_2;% pass as output for compuation in healey_3dj_01_2409 slide 12

4830

result.H_rxffe_2=H_rxffe_2;% pass as output for compuation in healey_3dj_01_2409 slide 12

4826

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

4831

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

4827

% --->this is the point in the code may fork where we add extra rx noise

4832

% --->this is the point in the code may fork where we add extra rx noise

4828

%% compute S_rn ( eq 178A-15 d0.2 )

4833

%% compute S_rn ( eq 178A-15 d0.2 )

4829

if ~OP.COMPUTE_COM

4834

if ~OP.COMPUTE_COM

4830

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

4835

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

4831

rxn_psd=[real(S_RN_of_f(1)), S_RN_of_f(2:end-1), real(S_RN_of_f(end)), conj(S_RN_of_f(end-1:-1:2))]; % Convert single-sided frequency response to conjugate-symmetric

4836

rxn_psd=[real(S_RN_of_f(1)), S_RN_of_f(2:end-1), real(S_RN_of_f(end)), conj(S_RN_of_f(end-1:-1:2))]; % Convert single-sided frequency response to conjugate-symmetric

4832

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

4837

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

4833

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

4838

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

4834

S_rn = sum(reshape(rxn_psd, num_ui, M).');

4839

S_rn = sum(reshape(rxn_psd, num_ui, M).');

4835

S_rn=S_rn(1:num_ui/2+1);

4840

S_rn=S_rn(1:num_ui/2+1);

4836

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

4841

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

4837

result.S_rn=S_rn;

4842

result.S_rn=S_rn;

4838

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4843

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4839

else

4844

else

4840

result.S_rn=result.S_rn.*H_rxffe_2;

4845

result.S_rn=result.S_rn.*H_rxffe_2;

4841

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4846

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4842

end

4847

end

4843

4848

4844

else % find noise for item that set have tx ffe for each loop

4849

else % find noise for item that set have tx ffe for each loop

4845

%% S_xn from eq 178A-16

4850

%% S_xn from eq 178A-16

4846

%% Crosstalk power spectral density

4851

%% Crosstalk power spectral density

4847

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

4852

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

4848

result.S_xn=0;

4853

result.S_xn=0;

4849

if length(chdata)~=1

4854

if length(chdata)~=1

4850

for xchan=2:length(chdata)

4855

for xchan=2:length(chdata)

4851

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

4856

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

4852

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

4857

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

4853

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

4858

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

4854

% enable less UI for computation speed improvement

4859

% enable less UI for computation speed improvement

4855

%%

4860

%%

4856

if num_ui*M > length(pulse_ctle)

4861

if num_ui*M > length(pulse_ctle)

4857

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

4862

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

4858

else

4863

else

4859

hk(xchan).k=hk(xchan).k(1:num_ui*M);

4864

hk(xchan).k=hk(xchan).k(1:num_ui*M);

4860

end

4865

end

4861

for i1=1:M

4866

for i1=1:M

4862

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

4867

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

4863

end

4868

end

4864

iphase(xchan)=find(hxn==max(hxn));

4869

iphase(xchan)=find(hxn==max(hxn));

4865

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

4870

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

4866

result.hk(xchan).hrn= hk(xchan).hrn;

4871

result.hk(xchan).hrn= hk(xchan).hrn;

4867

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

4872

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

4868

result.S_xn=hk(xchan).S_xn+result.S_xn;

4873

result.S_xn=hk(xchan).S_xn+result.S_xn;

4869

end

4874

end

4870

result.S_xn=result.S_xn;

4875

result.S_xn=result.S_xn;

4871

result.hk=hk;

4876

result.hk=hk;

4872

result.iphase=iphase;

4877

result.iphase=iphase;

4873

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4878

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4874

else % if no crosstalk, perserve structure and return 0 for S_xn

4879

else % if no crosstalk, perserve structure and return 0 for S_xn

4875

result.S_xn=0;

4880

result.S_xn=0;

4876

result.hk=[];

4881

result.hk=[];

4877

result.iphase=1;

4882

result.iphase=1;

4878

result.S_xn_rms = 0;

4883

result.S_xn_rms = 0;

4879

end

4884

end

4880

else % adjust for H_rxffe when computing COM

4885

else % adjust for H_rxffe when computing COM

4881

result.S_xn=result.S_xn.*H_rxffe_2;

4886

result.S_xn=result.S_xn.*H_rxffe_2;

4882

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4887

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4883

end

4888

end

4884

%% S_tn from eq 178A-17

4889

%% S_tn from eq 178A-17

4885

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

4890

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

4886

%% Transmitter noise power spectral density

4891

%% Transmitter noise power spectral density

+4892

if ~OP.COMPUTE_COM

4887

if ~OP.TDMODE

4893

if ~OP.TDMODE

4888

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

4894

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

4889

else % only use when the input was a pulse response not s-parameters

4895

else % only use when the input was a pulse response not s-parameters

4890

if isfield(chdata(1),'ctle_pulse_response')

4896

if isfield(chdata(1),'ctle_pulse_response')

4891

htn=chdata(1).ctle_pulse_response;

4897

htn=chdata(1).ctle_pulse_response;

4892

else

4898

else

4893

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

4899

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

4894

end

4900

end

4895

end

4901

end

4896

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

4902

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

4897

htn=reshape(htn,1,[]); % make row vectors

4903

htn=reshape(htn,1,[]); % make row vectors

4898

htn=[ htn(1:floor(length(htn)/M)*M) ];

4904

htn=[ htn(1:floor(length(htn)/M)*M) ];

4899

htn= [htn zeros(1,num_ui*M-length(htn)) ];

4905

htn= [htn zeros(1,num_ui*M-length(htn)) ];

4900

htn=htn(1:M:end);% resample

4906

htn=htn(1:M:end);% resample

4901

if num_ui>length(htn)

4907

if num_ui>length(htn)

4902

hext=[htn zeros(1,num_ui-length(htn))];

4908

hext=[htn zeros(1,num_ui-length(htn))];

4903

else

4909

else

4904

hext=htn(1:num_ui);

4910

hext=htn(1:num_ui);

4905

end

4911

end

4906

if ~OP.COMPUTE_COM

4907

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

4912

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

4908

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4913

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4909

else

4914

else

4910

result.S_tn=result.S_tn.*H_rxffe_2;

4915

result.S_tn=result.S_tn.*H_rxffe_2;

4911

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4916

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4912

end

4917

end

4913

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

4918

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

4914

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

4919

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

4915

%% Power spectral density of noise due to jitter

4920

%% Power spectral density of noise due to jitter

4916

%% Eq. 93A-28 %%

4921

%% Eq. 93A-28 %%

4917

if ~OP.COMPUTE_COM

4922

if ~OP.COMPUTE_COM

4918

sampling_offset = mod(cursor_i, M);

4923

sampling_offset = mod(cursor_i, M);

4919

%ensure we can take early sample

4924

%ensure we can take early sample

4920

if sampling_offset<=1

4925

if sampling_offset<=1

4921

sampling_offset=sampling_offset+M;

4926

sampling_offset=sampling_offset+M;

4922

end

4927

end

4923

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

4928

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

4924

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

4929

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

4925

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

4930

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

4926

else

4931

else

4927

cursors_early_sample = h(sampling_offset-1:M:end);

4932

cursors_early_sample = h(sampling_offset-1:M:end);

4928

cursors_late_sample = h(sampling_offset+1:M:end);

4933

cursors_late_sample = h(sampling_offset+1:M:end);

4929

end

4934

end

4930

% ensure lengths are equal

4935

% ensure lengths are equal

4931

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

4936

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

4932

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

4937

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

4933

h_J=reshape(h_J,1,[]); % make row vectors

4938

h_J=reshape(h_J,1,[]); % make row vectors

4934

if num_ui>length(h_J)

4939

if num_ui>length(h_J)

4935

h_J=[h_J zeros(1,num_ui-length(h_J))];

4940

h_J=[h_J zeros(1,num_ui-length(h_J))];

4936

else

4941

else

4937

h_J=h_J(1:num_ui);

4942

h_J=h_J(1:num_ui);

4938

end

4943

end

4939

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4944

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4940

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4945

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4941

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4946

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4942

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4947

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4943

else

4948

else

4944

result.S_jn=result.S_jn.*H_rxffe_2;

4949

result.S_jn=result.S_jn.*H_rxffe_2;

4945

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4950

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4946

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

4951

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

4947

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4952

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4948

end

4953

end

4949

% result.S_qn

4954

% result.S_qn

4950

if(param.N_qb ~=0)

4955

if(param.ENOB ~=0)

4951

hext_txffe=filter(txffe,1,hext);

4952

sig_aftert_ctle_pdf = get_pdf_from_sampled_signal(hext_txffe,param.levels,OP.BinSize);

4953

noise_after_ctle_pdf = sig_aftert_ctle_pdf;

4954

sigma_noise = sqrt(result.S_rn_rms^2+result.S_xn_rms^2++result.S_tn_rms^2++result.S_rj_rms^2);

4955

noise_after_ctle_pdf.y = 1/(sqrt(2*pi)*sigma_noise)*exp(-noise_after_ctle_pdf.x.^2/(2*sigma_noise^2))*OP.BinSize;

4956

sig_noise_after_ctle_pdf= conv_fct(sig_aftert_ctle_pdf,noise_after_ctle_pdf);

4957

sig_noise_after_ctle_cdf = cumsum(sig_noise_after_ctle_pdf.y);

4958

ctle_signal_sigma = sqrt(sum((sig_noise_after_ctle_pdf.x.^2).*sig_noise_after_ctle_pdf.y));

4959

adc_clip=-CDF_inv_ev(param.P_qc, sig_noise_after_ctle_pdf,sig_noise_after_ctle_cdf);

4960

adc_lsb=2*adc_clip/(2^param.N_qb-1);

4961

sigma_Q=adc_lsb/sqrt(12);

4962

S_qn=sigma_Q^2/f_b*ones(size(hext));

4963

result.adc_clip=adc_clip;

4964

result.ctle_signal_sigma=ctle_signal_sigma;

4965

result.S_qn=S_qn;

4966

result.s_qn_rms=sqrt(sum(result.S_qn)*delta_f);

4967

if OP.INCLUDE_CTLE == 1

4956

if OP.INCLUDE_CTLE == 1

4968

eq_ir = TD_CTLE(chdata(1).uneq_imp_response, param.fb, param.CTLE_fz(1), param.CTLE_fp1(1), param.CTLE_fp2(1), G_DC, param.samples_per_ui);

4957

eq_ir = TD_CTLE(chdata(1).uneq_imp_response, param.fb, param.CTLE_fz(1), param.CTLE_fp1(1), param.CTLE_fp2(1), G_DC, param.samples_per_ui);

4969

eq_ir = TD_CTLE(eq_ir, param.fb, param.f_HP(1), param.f_HP(1), 100e100 , G_DC2, param.samples_per_ui);

4958

eq_ir = TD_CTLE(eq_ir, param.fb, param.f_HP(1), param.f_HP(1), 100e100 , G_DC2, param.samples_per_ui);

4970

else

4959

else

4971

eq_ir = chdata(1).uneq_imp_response;

4960

eq_ir = chdata(1).uneq_imp_response;

4972

end

4961

end

4973

ctle_pulse = filter(ones(1, param.samples_per_ui), 1, eq_ir);

4962

ctle_pulse = filter(ones(1, param.samples_per_ui), 1, eq_ir);

4974

ind_max = find(ctle_pulse == max(ctle_pulse));

4963

ind_max = find(ctle_pulse == max(ctle_pulse));

4975

adc_clip = sum(abs([ctle_pulse(ind_max-param.samples_per_ui:-param.samples_per_ui:1); ctle_pulse(ind_max:param.samples_per_ui:end)]));

4964

adc_clip = sum(abs([ctle_pulse(ind_max-param.samples_per_ui:-param.samples_per_ui:1); ctle_pulse(ind_max:param.samples_per_ui:end)]));

4976

adc_lsb = 2*adc_clip/(2^param.N_qb-1);

4965

adc_lsb = 2*adc_clip/(2^param.ENOB-1);

4977

sigma_Q = adc_lsb/sqrt(12);

4966

sigma_Q = adc_lsb/sqrt(12);

4978

S_qn = sigma_Q^2/(length(result.S_rn)*delta_f)*ones(size(result.S_rn));

4967

S_qn = sigma_Q^2/(length(result.S_rn)*delta_f)*ones(size(result.S_rn));

4979

result.S_qn = S_qn;

4968

result.S_qn = S_qn;

4980

result.qn_rms = sqrt(sum(result.S_qn)* delta_f);

4969

result.qn_rms = sqrt(sum(result.S_qn)* delta_f);

4981

else

4970

else

4982

result.S_qn=0;

4971

result.S_qn=0;

4983

result.S_qn_rms = 0;

4972

result.S_qn_rms = 0;

4984

% result.S_n

4973

% result.S_n

4985

end

4974

end

4986

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn+ result.S_qn;

4975

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn+ result.S_qn;

4987

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

4976

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

4988

4977

4989

%%

4978

%%

4990

%% Hisi to be included in MLSE rho eq 178a-28

4979

%% Hisi to be included in MLSE rho eq 178a-28

4991

if OP.COMPUTE_COM

4980

if OP.COMPUTE_COM

4992

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

4981

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

4993

% sampling_offset = mod(cursor_i-1, M)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

4982

% sampling_offset = mod(cursor_i-1, M)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

4994

% hisi=h(sampling_offset:M:end);

4983

% hisi=h(sampling_offset:M:end);

4995

% hisi=hisi(:).';

4984

% hisi=hisi(:).';

4996

% if num_ui>length(hisi)

4985

% if num_ui>length(hisi)

4997

% hisi=[hisi zeros(1,num_ui-length(hisi))];

4986

% hisi=[hisi zeros(1,num_ui-length(hisi))];

4998

% else

4987

% else

4999

% hisi=hisi(1:num_ui);% sometime cable channels need a bigger num_ui. prehap compare to the tripple transit time and compute num_ui

4988

% hisi=hisi(1:num_ui);% sometime cable channels need a bigger num_ui. prehap compare to the tripple transit time and compute num_ui

5000

% end

4989

% end

5001

% cursor_n=find(hisi==max(hisi),1','first');

4990

% cursor_n=find(hisi==max(hisi),1','first');

5002

samp_idx = (mod(cursor_i-1,M)+1):M:length(h);% Commit request 4p5_2, healey_3dj_COM_01_240521.pdf

4991

samp_idx = (mod(cursor_i-1,M)+1):M:length(h);% Commit request 4p5_2, healey_3dj_COM_01_240521.pdf

5003

cursor_n=find(samp_idx == cursor_i);

4992

cursor_n=find(samp_idx == cursor_i);

5004

hisi=h(samp_idx);

4993

hisi=h(samp_idx);

5005

hisi(end+1:num_ui)=0;

4994

hisi(end+1:num_ui)=0;

5006

hisi=reshape(hisi(1:num_ui),1,[]);

4995

hisi=reshape(hisi(1:num_ui),1,[]);

5007

%% Eq 178a-29

4996

%% Eq 178a-29

5008

for ii=1:length(hisi)

4997

for ii=1:length(hisi)

5009

if ii==cursor_n % cursor

4998

if ii==cursor_n % cursor

5010

cursor=hisi(ii);

4999

cursor=hisi(ii);

5011

hisi(ii)= 0;

5000

hisi(ii)= 0;

5012

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

5001

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

5013

ib_indx=ii-cursor_n;

5002

ib_indx=ii-cursor_n;

5014

if hisi(ii) >= bmax(ib_indx)*cursor

5003

if hisi(ii) >= bmax(ib_indx)*cursor

5015

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

5004

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

5016

elseif hisi(ii) <= bmin(ib_indx)*cursor

5005

elseif hisi(ii) <= bmin(ib_indx)*cursor

5017

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

5006

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

5018

else

5007

else

5019

hisi(ii)=0;

5008

hisi(ii)=0;

5020

end

5009

end

5021

end

5010

end

5022

end

5011

end

5023

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

5012

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

5024

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

5013

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

5025

%%

5014

%%

5026

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

5015

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

5027

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

5016

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

5028

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

5017

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

5029

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

5018

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

5030

end

5019

end

5031

end

5020

end

5032

function result=get_PulseR(ir,param,cb_step,ZT)

5021

function result=get_PulseR(ir,param,cb_step,ZT)

5033

%ir = impulse response

5022

%ir = impulse response

5034

%t_base=time array with equal time steps

5023

%t_base=time array with equal time steps

5035

%samp_UI = number of samples per UI for ir

5024

%samp_UI = number of samples per UI for ir

5036

5025

5037

% t for debug

5026

% t for debug

5038

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5027

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5039

5028

5040

if cb_step

5029

if cb_step

5041

Ag=1;

5030

Ag=1;

5042

dt=1/param.fb/param.samples_per_ui;

5031

dt=1/param.fb/param.samples_per_ui;

5043

edge_time=param.TR_TDR*1e-9;

5032

edge_time=param.TR_TDR*1e-9;

5044

fedge=1/edge_time;

5033

fedge=1/edge_time;

5045

tedge=0:dt:edge_time*2;

5034

tedge=0:dt:edge_time*2;

5046

%

5035

%

5047

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5036

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5048

drive_pulse=[edge ones(1,param.samples_per_ui)];

5037

drive_pulse=[edge ones(1,param.samples_per_ui)];

5049

%pulse=filter(UI_ones,1,ir);

5038

%pulse=filter(UI_ones,1,ir);

5050

% t for debug

5039

% t for debug

5051

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5040

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5052

5041

5053

pulse=filter(drive_pulse,1,ir);

5042

pulse=filter(drive_pulse,1,ir);

5054

else

5043

else

5055

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5044

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5056

end

5045

end

5057

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5046

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5058

result.PDR=PDR_response;

5047

result.PDR=PDR_response;

5059

result.pulse=pulse;

5048

result.pulse=pulse;

5060

5049

5061

5050

5062

5051

5063

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5052

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5064

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

5053

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

5065

if ~iscolumn(H), H=H.';end

5054

if ~iscolumn(H), H=H.';end

5066

if ~iscolumn(H_r), H_r=H_r.';end

5055

if ~iscolumn(H_r), H_r=H_r.';end

5067

H=H(:).*H_r;

5056

H=H(:).*H_r;

5068

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5057

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5069

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5058

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5070

5059

5071

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5060

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5072

% Complex reflection and re-reflection noise using the concept of zero'ing

5061

% Complex reflection and re-reflection noise using the concept of zero'ing

5073

% out of reflections

5062

% out of reflections

5074

% sdd21 us a complex insertion loss

5063

% sdd21 us a complex insertion loss

5075

% RIL_struct is the output of capture_RIL_RILN()

5064

% RIL_struct is the output of capture_RIL_RILN()

5076

% faxix_f2 needs to be at least to fb

5065

% faxix_f2 needs to be at least to fb

5077

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5066

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5078

% still need to settle on voltage scaling.

5067

% still need to settle on voltage scaling.

5079

% maybe db(peak/Rss

5068

% maybe db(peak/Rss

5080

db = @(x) 20*log10(abs(x));

5069

db = @(x) 20*log10(abs(x));

5081

fprintf('computing TD_RILN (dB) ...');

5070

fprintf('computing TD_RILN (dB) ...');

5082

5071

5083

OP.interp_sparam_mag= 'trend_to_DC';

5072

OP.interp_sparam_mag= 'trend_to_DC';

5084

OP.interp_sparam_phase= 'interp_to_DC';

5073

OP.interp_sparam_phase= 'interp_to_DC';

5085

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5074

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5086

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5075

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5087

5076

5088

sdd21=squeeze(sdd21);

5077

sdd21=squeeze(sdd21);

5089

if iscolumn(sdd21)

5078

if iscolumn(sdd21)

5090

sdd21=sdd21.';

5079

sdd21=sdd21.';

5091

end

5080

end

5092

RIL=squeeze(RIL_struct.RIL);

5081

RIL=squeeze(RIL_struct.RIL);

5093

if iscolumn(RIL)

5082

if iscolumn(RIL)

5094

RIL=RIL.';

5083

RIL=RIL.';

5095

end

5084

end

5096

rho_port1=squeeze(RIL_struct.rho_port1);

5085

rho_port1=squeeze(RIL_struct.rho_port1);

5097

if iscolumn(rho_port1)

5086

if iscolumn(rho_port1)

5098

rho_port1=rho_port1.';

5087

rho_port1=rho_port1.';

5099

end

5088

end

5100

rho_port2=squeeze(RIL_struct.rho_port2);

5089

rho_port2=squeeze(RIL_struct.rho_port2);

5101

if iscolumn(rho_port2)

5090

if iscolumn(rho_port2)

5102

rho_port2=rho_port2.';

5091

rho_port2=rho_port2.';

5103

end

5092

end

5104

RIL_f=squeeze(RIL_struct.freq);

5093

RIL_f=squeeze(RIL_struct.freq);

5105

if iscolumn(RIL_f)

5094

if iscolumn(RIL_f)

5106

RIL_f=RIL_f.';

5095

RIL_f=RIL_f.';

5107

end

5096

end

5108

5097

5109

%---start. Calculate the reflection and re-reflection noise

5098

%---start. Calculate the reflection and re-reflection noise

5110

number_of_echos= 1e3;

5099

number_of_echos= 1e3;

5111

fmin= 1e9;%<-------------

5100

fmin= 1e9;%<-------------

5112

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5101

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5113

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5102

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5114

for m= 1:number_of_echos

5103

for m= 1:number_of_echos

5115

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m)).*(rho_port1.^m).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port2);

5104

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m)).*(rho_port1.^m).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port2);

5116

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m-1)).*(rho_port1.^(m-1)).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port1);

5105

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m-1)).*(rho_port1.^(m-1)).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port1);

5117

end

5106

end

5118

5107

5119

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5108

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5120

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5109

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5121

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5110

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5122

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5111

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5123

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5112

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5124

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5113

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5125

5114

5126

% clear RIL RIL_f rho_port1 rho_port2

5115

% clear RIL RIL_f rho_port1 rho_port2

5127

% clear fmin m

5116

% clear fmin m

5128

%---end. Calculate the reflection and re-reflection noise

5117

%---end. Calculate the reflection and re-reflection noise

5129

5118

5130

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5119

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5131

warning('off','MATLAB:nearlySingularMatrix');

5120

warning('off','MATLAB:nearlySingularMatrix');

5132

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5121

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5133

LGw=transpose(sdd21.*unwraplog);

5122

LGw=transpose(sdd21.*unwraplog);

5134

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5123

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5135

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5124

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5136

FIT=transpose(exp(transpose(efit_C)));

5125

FIT=transpose(exp(transpose(efit_C)));

5137

efit=db(abs(FIT));

5126

efit=db(abs(FIT));

5138

ILN = db(sdd21)-efit;

5127

ILN = db(sdd21)-efit;

5139

5128

5140

5129

5141

OP.impulse_response_truncation_threshold =1e-7;

5130

OP.impulse_response_truncation_threshold =1e-7;

5142

5131

5143

print_for_codereview=0;

5132

print_for_codereview=0;

5144

if exist('OP','var')

5133

if exist('OP','var')

5145

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5134

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5146

H_bw=Butterworth_Filter(param,faxis_f2,1);

5135

H_bw=Butterworth_Filter(param,faxis_f2,1);

5147

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5136

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5148

H_tw=Tukey_Window(faxis_f2,param);

5137

H_tw=Tukey_Window(faxis_f2,param);

5149

H_tw=ones(1,length(faxis_f2) );

5138

H_tw=ones(1,length(faxis_f2) );

5150

[RILN_TD_struct.REF.FIR, ...

5139

[RILN_TD_struct.REF.FIR, ...

5151

RILN_TD_struct.REF.t, ...

5140

RILN_TD_struct.REF.t, ...

5152

RILN_TD_struct.REF.causality_correction_dB, ...

5141

RILN_TD_struct.REF.causality_correction_dB, ...

5153

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5142

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5154

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5143

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5155

5144

5156

5145

5157

[RILN_TD_struct.FIT.FIR, ...

5146

[RILN_TD_struct.FIT.FIR, ...

5158

RILN_TD_struct.FIT.t, ...

5147

RILN_TD_struct.FIT.t, ...

5159

RILN_TD_struct.FIT.causality_correction_dB, ...

5148

RILN_TD_struct.FIT.causality_correction_dB, ...

5160

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5149

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5161

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5150

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5162

5151

5163

5152

5164

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5153

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5165

H_bw=Butterworth_Filter(param,RIL_f,1);

5154

H_bw=Butterworth_Filter(param,RIL_f,1);

5166

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5155

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5167

H_tw=Tukey_Window(RIL_f,param);

5156

H_tw=Tukey_Window(RIL_f,param);

5168

H_tw=ones(1,length(RIL_f) );

5157

H_tw=ones(1,length(RIL_f) );

5169

[RILN_TD_struct.RIL.FIR, ...

5158

[RILN_TD_struct.RIL.FIR, ...

5170

RILN_TD_struct.RIL.t, ...

5159

RILN_TD_struct.RIL.t, ...

5171

RILN_TD_struct.RIL.causality_correction_dB, ...

5160

RILN_TD_struct.RIL.causality_correction_dB, ...

5172

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5161

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5173

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5162

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5174

5163

5175

5164

5176

%---start. Calculate the channel delay

5165

%---start. Calculate the channel delay

5177

try

5166

try

5178

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5167

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5179

catch

5168

catch

5180

end

5169

end

5181

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5170

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5182

clear delay_sec delay_idx

5171

clear delay_sec delay_idx

5183

%---end. Calculate the channel delay

5172

%---end. Calculate the channel delay

5184

5173

5185

5174

5186

5175

5187

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5176

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5188

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5177

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5189

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5178

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5190

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5179

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5191

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5180

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5192

[RILN_TD_struct.REF_noise.FIR, ...

5181

[RILN_TD_struct.REF_noise.FIR, ...

5193

RILN_TD_struct.REF_noise.t, ...

5182

RILN_TD_struct.REF_noise.t, ...

5194

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5183

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5195

RILN_TD_struct.REF_noise.truncation_dB] = s21_to_impulse_DC(port2_reflection_rereflection_noise.*H_bw.*H_t.*H_tw ,f_reflection_rereflection_noise, param.sample_dt, OP) ;

5184

RILN_TD_struct.REF_noise.truncation_dB] = s21_to_impulse_DC(port2_reflection_rereflection_noise.*H_bw.*H_t.*H_tw ,f_reflection_rereflection_noise, param.sample_dt, OP) ;

5196

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5185

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5197

5186

5198

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5187

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5199

% NrangeUI=1000;

5188

% NrangeUI=1000;

5200

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(RILN_TD_struct.FIT.PR)-param.samples_per_ui ),length(RILN_TD_struct.REF.PR)-param.samples_per_ui);

5189

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(RILN_TD_struct.FIT.PR)-param.samples_per_ui ),length(RILN_TD_struct.REF.PR)-param.samples_per_ui);

5201

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5190

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5202

range=ipeak:range_end;

5191

range=ipeak:range_end;

5203

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5192

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5204

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5193

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5205

RILN_TD_struct.FOM=-inf;

5194

RILN_TD_struct.FOM=-inf;

5206

RILN_TD_struct.FOM_PDF=-inf;

5195

RILN_TD_struct.FOM_PDF=-inf;

5207

rms_fom=-inf;

5196

rms_fom=-inf;

5208

for im=1:param.samples_per_ui

5197

for im=1:param.samples_per_ui

5209

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5198

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5210

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5199

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5211

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5200

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5212

cdf=pdf; cdf.y=cumsum(pdf.y);

5201

cdf=pdf; cdf.y=cumsum(pdf.y);

5213

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5202

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5214

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5203

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5215

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5204

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5216

if print_for_codereview % remove once all checked out

5205

if print_for_codereview % remove once all checked out

5217

h=figure(190);set(gcf,'Tag','COM');

5206

h=figure(190);set(gcf,'Tag','COM');

5218

semilogy(-cdf.x,cdf.y);

5207

semilogy(-cdf.x,cdf.y);

5219

% xlim ([0,-cdf.x(1)])

5208

% xlim ([0,-cdf.x(1)])

5220

ylim([param.specBER 1]);title ('CDF of ILN')

5209

ylim([param.specBER 1]);title ('CDF of ILN')

5221

hold on

5210

hold on

5222

end

5211

end

5223

if rms>rms_fom

5212

if rms>rms_fom

5224

rms_fom=rms;

5213

rms_fom=rms;

5225

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5214

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5226

RILN_TD_struct.PDF=pdf;

5215

RILN_TD_struct.PDF=pdf;

5227

end

5216

end

5228

end

5217

end

5229

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5218

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5230

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5219

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5231

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5220

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5232

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5221

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5233

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5222

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5234

if print_for_codereview % remove once all checked out

5223

if print_for_codereview % remove once all checked out

5235

figure(9000);set(gcf,'Tag','COM');

5224

figure(9000);set(gcf,'Tag','COM');

5236

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5225

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5237

hold on

5226

hold on

5238

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5227

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5239

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5228

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5240

yyaxis right

5229

yyaxis right

5241

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5230

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5242

hold off

5231

hold off

5243

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

5232

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

5244

figure(9002);set(gcf,'Tag','COM');

5233

figure(9002);set(gcf,'Tag','COM');

5245

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5234

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5246

hold on

5235

hold on

5247

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5236

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5248

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5237

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5249

grid on

5238

grid on

5250

legend('show')

5239

legend('show')

5251

end

5240

end

5252

end

5241

end

5253

function result=get_StepR(ir,param,cb_step,ZT)

5242

function result=get_StepR(ir,param,cb_step,ZT)

5254

%ir = impulse response

5243

%ir = impulse response

5255

%t_base=time array with equal time steps

5244

%t_base=time array with equal time steps

5256

%samp_UI = number of samples per UI for ir

5245

%samp_UI = number of samples per UI for ir

5257

% result.SBR

5246

% result.SBR

5258

% t for debug

5247

% t for debug

5259

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5248

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5260

5249

5261

if cb_step

5250

if cb_step

5262

Ag=1;

5251

Ag=1;

5263

dt=1/param.fb/param.samples_per_ui;

5252

dt=1/param.fb/param.samples_per_ui;

5264

edge_time=param.TR_TDR*1e-9;

5253

edge_time=param.TR_TDR*1e-9;

5265

fedge=1/edge_time;

5254

fedge=1/edge_time;

5266

tedge=0:dt:edge_time*2;

5255

tedge=0:dt:edge_time*2;

5267

%

5256

%

5268

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5257

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5269

drive_pulse=[edge ones(1,param.samples_per_ui)];

5258

drive_pulse=[edge ones(1,param.samples_per_ui)];

5270

%pulse=filter(UI_ones,1,ir);

5259

%pulse=filter(UI_ones,1,ir);

5271

5260

5272

pulse=filter(drive_pulse,1,ir);

5261

pulse=filter(drive_pulse,1,ir);

5273

else

5262

else

5274

pulse=cumsum(ir);

5263

pulse=cumsum(ir);

5275

end

5264

end

5276

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5265

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5277

result.ZSR=TDR_response;

5266

result.ZSR=TDR_response;

5278

result.pulse=pulse;

5267

result.pulse=pulse;

5279

5268

5280

5269

5281

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5270

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5282

% sdd is differential s-parameters structure (2 port assumed)

5271

% sdd is differential s-parameters structure (2 port assumed)

5283

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5272

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5284

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5273

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5285

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5274

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5286

% TDR_results.t starting at t=0

5275

% TDR_results.t starting at t=0

5287

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5276

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5288

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5277

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5289

% TDR_results.f frequency for filter and s parameters

5278

% TDR_results.f frequency for filter and s parameters

5290

% TDR_results.ptdr_RL reflection waveform from the pulse

5279

% TDR_results.ptdr_RL reflection waveform from the pulse

5291

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5280

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5292

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5281

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5293

% TDR_results.ERL reported effective return loss

5282

% TDR_results.ERL reported effective return loss

5294

%

5283

%

5295

db = @(x) 20*log10(abs(x));

5284

db = @(x) 20*log10(abs(x));

5296

rms =@(x) norm(x)/sqrt(length(x));

5285

rms =@(x) norm(x)/sqrt(length(x));

5297

if isfield(OP,'TDR_duration')

5286

if isfield(OP,'TDR_duration')

5298

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5287

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5299

else

5288

else

5300

TDR_duration=5;

5289

TDR_duration=5;

5301

end

5290

end

5302

if ~isfield(OP,'DISPLAY_WINDOW')

5291

if ~isfield(OP,'DISPLAY_WINDOW')

5303

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5292

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5304

end

5293

end

5305

f=sdd.Frequencies;

5294

f=sdd.Frequencies;

5306

TDR_results.f=f;

5295

TDR_results.f=f;

5307

% OP.Zt_adj=2;

5296

% OP.Zt_adj=2;

5308

if param.FLAG.S2P == 0

5297

if param.FLAG.S2P == 0

5309

5298

5310

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5299

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5311

TDR_RL =@(Zin,Zout,s11,s12,s21,s22)(Zin.^2.*s11+Zin.^2.*s22+Zout.^2.*s11+Zout.^2.*s22+Zin.^2-Zout.^2+Zin.*Zout.*s11.*2.0-Zin.*Zout.*s22.*2.0+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21-Zout.^2.*s11.*s22+Zout.^2.*s12.*s21)./(Zin.*Zout.*2.0+Zin.^2.*s11+Zin.^2.*s22-Zout.^2.*s11-Zout.^2.*s22+Zin.^2+Zout.^2+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21+Zout.^2.*s11.*s22-Zout.^2.*s12.*s21-Zin.*Zout.*s11.*s22.*2.0+Zin.*Zout.*s12.*s21.*2.0);

5300

TDR_RL =@(Zin,Zout,s11,s12,s21,s22)(Zin.^2.*s11+Zin.^2.*s22+Zout.^2.*s11+Zout.^2.*s22+Zin.^2-Zout.^2+Zin.*Zout.*s11.*2.0-Zin.*Zout.*s22.*2.0+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21-Zout.^2.*s11.*s22+Zout.^2.*s12.*s21)./(Zin.*Zout.*2.0+Zin.^2.*s11+Zin.^2.*s22-Zout.^2.*s11-Zout.^2.*s22+Zin.^2+Zout.^2+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21+Zout.^2.*s11.*s22-Zout.^2.*s12.*s21-Zin.*Zout.*s11.*s22.*2.0+Zin.*Zout.*s12.*s21.*2.0);

5312

5301

5313

if param.RL_sel==1, other_port=2;end

5302

if param.RL_sel==1, other_port=2;end

5314

if param.RL_sel==2, other_port=1;end

5303

if param.RL_sel==2, other_port=1;end

5315

for i = 1:length(sdd.Frequencies)

5304

for i = 1:length(sdd.Frequencies)

5316

if size(sdd.Parameters,2) ==1 % for s2p files

5305

if size(sdd.Parameters,2) ==1 % for s2p files

5317

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,1, 1 ,sdd.Parameters(param.RL_sel,param.RL_sel,i) );

5306

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,1, 1 ,sdd.Parameters(param.RL_sel,param.RL_sel,i) );

5318

else

5307

else

5319

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,sdd.Parameters( 1,2 ,i), sdd.Parameters( 2,1 ,i),sdd.Parameters( other_port,other_port ,i) );

5308

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,sdd.Parameters( 1,2 ,i), sdd.Parameters( 2,1 ,i),sdd.Parameters( other_port,other_port ,i) );

5320

end

5309

end

5321

end

5310

end

5322

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5311

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5323

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5312

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5324

% Z_t=ZT;

5313

% Z_t=ZT;

5325

% zref=sdd.Impedance/2;

5314

% zref=sdd.Impedance/2;

5326

% if Z_t > zref

5315

% if Z_t > zref

5327

% radjust= (zref-Z_t);

5316

% radjust= (zref-Z_t);

5328

% S11adjust= radjust./(radjust + 2*zref);

5317

% S11adjust= radjust./(radjust + 2*zref);

5329

% RL=RL +S11adjust;

5318

% RL=RL +S11adjust;

5330

% elseif Z_t < zref

5319

% elseif Z_t < zref

5331

% rpad=-Z_t*zref/(Z_t-zref);

5320

% rpad=-Z_t*zref/(Z_t-zref);

5332

% S11adjust=zref/(rpad*(zref/rpad + 2));

5321

% S11adjust=zref/(rpad*(zref/rpad + 2));

5333

% RL=RL + S11adjust;

5322

% RL=RL + S11adjust;

5334

% else

5323

% else

5335

% RL=RL;

5324

% RL=RL;

5336

% end

5325

% end

5337

else

5326

else

5338

for i = 1:length(sdd.Frequencies)

5327

for i = 1:length(sdd.Frequencies)

5339

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5328

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5340

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5329

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5341

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5330

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5342

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5331

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5343

end

5332

end

5344

end

5333

end

5345

5334

5346

% end

5335

% end

5347

RL=squeeze(RL);

5336

RL=squeeze(RL);

5348

f9=f/1e9;

5337

f9=f/1e9;

5349

tr=param.TR_TDR;

5338

tr=param.TR_TDR;

5350

TDR_results.delay=500e-12 ;

5339

TDR_results.delay=500e-12 ;

5351

% determine max time from thue

5340

% determine max time from thue

5352

% if sdd.NumPorts==1

5341

% if sdd.NumPorts==1

5353

% try

5342

% try

5354

% maxtime=OP.N*param.ui;

5343

% maxtime=OP.N*param.ui;

5355

% catch

5344

% catch

5356

% maxtime=2e-9;

5345

% maxtime=2e-9;

5357

% end

5346

% end

5358

% pix=1;

5347

% pix=1;

5359

% else

5348

% else

5360

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5349

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5361

% pix=find(fir4del==max(fir4del),1);

5350

% pix=find(fir4del==max(fir4del),1);

5362

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5351

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5363

% if maxtime > tu(end); maxtime=tu(end);end

5352

% if maxtime > tu(end); maxtime=tu(end);end

5364

% endS

5353

% endS

5365

5354

5366

try

5355

try

5367

maxtime=OP.N*param.ui;

5356

maxtime=OP.N*param.ui;

5368

catch

5357

catch

5369

maxtime=2e-9;

5358

maxtime=2e-9;

5370

end

5359

end

5371

if OP.N==0

5360

if OP.N==0

5372

if sdd.NumPorts==1

5361

if sdd.NumPorts==1

5373

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5362

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5374

else

5363

else

5375

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5364

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5376

pix=find(fir4del==max(fir4del),1);

5365

pix=find(fir4del==max(fir4del),1);

5377

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5366

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5378

if maxtime > tu(end); maxtime=tu(end);end

5367

if maxtime > tu(end); maxtime=tu(end);end

5379

end

5368

end

5380

end

5369

end

5381

5370

5382

5371

5383

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5372

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5384

% (makes gausian edge somewhat causal)

5373

% (makes gausian edge somewhat causal)

5385

H_t = exp( -2*(pi*f9*(tr)/1.6832).^2 ).*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9).*exp(-1j*2*pi*f9*tr*3);

5374

H_t = exp( -2*(pi*f9*(tr)/1.6832).^2 ).*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9).*exp(-1j*2*pi*f9*tr*3);

5386

if ~isfield(OP,'cb_Guassian')

5375

if ~isfield(OP,'cb_Guassian')

5387

Use_gaussian=1;

5376

Use_gaussian=1;

5388

else

5377

else

5389

Use_gaussian=OP.cb_Guassian;

5378

Use_gaussian=OP.cb_Guassian;

5390

end

5379

end

5391

if Use_gaussian

5380

if Use_gaussian

5392

if iscolumn(H_t), H_t=H_t.'; end

5381

if iscolumn(H_t), H_t=H_t.'; end

5393

RLf=RL(:).'.*H_t;

5382

RLf=RL(:).'.*H_t;

5394

else % add extra 3x tr delay for causality

5383

else % add extra 3x tr delay for causality

5395

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5384

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5396

end

5385

end

5397

5386

5398

%Bessesl-Thomson turned off here (3rd input=0)

5387

%Bessesl-Thomson turned off here (3rd input=0)

5399

OP.TDR_Bessel_Thomson=0;

5388

OP.TDR_Bessel_Thomson=0;

5400

H_bt=Bessel_Thomson_Filter(param,f,OP.TDR_Bessel_Thomson);

5389

H_bt=Bessel_Thomson_Filter(param,f,OP.TDR_Bessel_Thomson);

5401

5390

5402

if isfield(OP,'TDR_Butterworth')

5391

if isfield(OP,'TDR_Butterworth')

5403

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5392

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5404

else

5393

else

5405

H_bw=ones(1,length(f));

5394

H_bw=ones(1,length(f));

5406

end

5395

end

5407

5396

5408

5397

5409

if param.Tukey_Window ~= 0

5398

if param.Tukey_Window ~= 0

5410

H_tw= Tukey_Window(f,param);

5399

H_tw= Tukey_Window(f,param);

5411

else

5400

else

5412

H_tw=ones(1,length(f));

5401

H_tw=ones(1,length(f));

5413

end

5402

end

5414

5403

5415

5404

5416

if iscolumn(H_tw), H_tw=H_tw.';end

5405

if iscolumn(H_tw), H_tw=H_tw.';end

5417

if iscolumn(H_bt), H_bt=H_bt.';end

5406

if iscolumn(H_bt), H_bt=H_bt.';end

5418

if iscolumn(H_bw), H_bw=H_bw.';end

5407

if iscolumn(H_bw), H_bw=H_bw.';end

5419

if iscolumn(RLf), RLf=RLf.';end

5408

if iscolumn(RLf), RLf=RLf.';end

5420

5409

5421

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5410

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5422

RLf=RLf.*TDR_results.Rx_filter;

5411

RLf=RLf.*TDR_results.Rx_filter;

5423

TDR_results.tx_filter=H_t;

5412

TDR_results.tx_filter=H_t;

5424

5413

5425

5414

5426

[IR, t, causality_correction_dB, truncation_dB] = ...

5415

[IR, t, causality_correction_dB, truncation_dB] = ...

5427

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5416

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5428

5417

5429

5418

5430

%

5419

%

5431

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5420

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5432

tfx=param.tfx(np); % use fixture delay for port (np)

5421

tfx=param.tfx(np); % use fixture delay for port (np)

5433

5422

5434

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5423

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5435

5424

5436

t = t-TDR_results.delay;

5425

t = t-TDR_results.delay;

5437

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5426

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5438

if isempty(tend), tend=length(t); end

5427

if isempty(tend), tend=length(t); end

5439

IR=IR(1:tend);

5428

IR=IR(1:tend);

5440

t=t(1:tend);

5429

t=t(1:tend);

5441

if isempty(tend), tend=length(t); end

5430

if isempty(tend), tend=length(t); end

5442

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5431

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5443

if isempty(tstart), tstart=1;end

5432

if isempty(tstart), tstart=1;end

5444

if isempty(tend) || tstart >= tend

5433

if isempty(tend) || tstart >= tend

5445

if isempty(tend) || tstart >= tend

5434

if isempty(tend) || tstart >= tend

5446

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5435

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5447

end

5436

end

5448

tend=length(t);

5437

tend=length(t);

5449

tstart=1;

5438

tstart=1;

5450

end

5439

end

5451

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5440

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5452

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5441

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5453

TDR_results.tdr= ch.ZSR;

5442

TDR_results.tdr= ch.ZSR;

5454

TDR_results.t = t(tstart:tend);

5443

TDR_results.t = t(tstart:tend);

5455

5444

5456

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5445

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5457

if OP.TDR || OP.PTDR % determin average impededance with

5446

if OP.TDR || OP.PTDR % determin average impededance with

5458

try

5447

try

5459

tfstart=find(t>=3*tr*1e-9,1);

5448

tfstart=find(t>=3*tr*1e-9,1);

5460

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5449

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5461

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5450

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5462

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5451

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5463

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5452

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5464

catch

5453

catch

5465

TDR_results.avgZport=0;

5454

TDR_results.avgZport=0;

5466

fit=zeros(1,1);

5455

fit=zeros(1,1);

5467

p=[0 0 0 0 ];

5456

p=[0 0 0 0 ];

5468

end

5457

end

5469

TDR_results.RL=RL;

5458

TDR_results.RL=RL;

5470

end

5459

end

5471

if OP.PTDR

5460

if OP.PTDR

5472

% param.N_bx=param.ndfe;

5461

% param.N_bx=param.ndfe;

5473

RL_equiv=-inf;

5462

RL_equiv=-inf;

5474

L=param.levels;

5463

L=param.levels;

5475

BinSize=OP.BinSize;

5464

BinSize=OP.BinSize;

5476

% param.specBER=1e-5;

5465

% param.specBER=1e-5;

5477

if OP.DISPLAY_WINDOW

5466

if OP.DISPLAY_WINDOW

5478

hwaitbar=waitbar(0);

5467

hwaitbar=waitbar(0);

5479

else

5468

else

5480

fprintf('Worst ERL searching');

5469

fprintf('Worst ERL searching');

5481

end

5470

end

5482

% adjust PTDR for NDFE

5471

% adjust PTDR for NDFE

5483

% ---------------------- 2.7 code

5472

% ---------------------- 2.7 code

5484

% ntx=find(TDR_results.t >= tfx,1,'first');

5473

% ntx=find(TDR_results.t >= tfx,1,'first');

5485

% % gatestartt=TDR_results.t(ntx);

5474

% % gatestartt=TDR_results.t(ntx);

5486

% % gatestartV=PTDR.pulse(ntx);

5475

% % gatestartV=PTDR.pulse(ntx);

5487

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5476

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5488

% tk=param.ui*1*(param.N_bx+1)+tfx;

5477

% tk=param.ui*1*(param.N_bx+1)+tfx;

5489

% -------------------

5478

% -------------------

5490

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5479

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5491

% time filter.

5480

% time filter.

5492

% ntx=find(TDR_results.t >= tfx,1,'first');

5481

% ntx=find(TDR_results.t >= tfx,1,'first');

5493

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5482

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5494

% gatestartt=TDR_results.t(ntx);

5483

% gatestartt=TDR_results.t(ntx);

5495

% gatestartV=PTDR.pulse(ntx);

5484

% gatestartV=PTDR.pulse(ntx);

5496

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5485

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5497

% tk=param.ui*1*(param.N_bx+1)+tfx;

5486

% tk=param.ui*1*(param.N_bx+1)+tfx;

5498

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5487

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5499

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5488

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5500

% [ahealey] End of modifications.

5489

% [ahealey] End of modifications.

5501

if isempty(ndfex), ndfex=length(TDR_results.t); end

5490

if isempty(ndfex), ndfex=length(TDR_results.t); end

5502

PTDR.pulse_orig=PTDR.pulse;

5491

PTDR.pulse_orig=PTDR.pulse;

5503

5492

5504

switch param.Grr

5493

switch param.Grr

5505

case 0 % pre .3cd release

5494

case 0 % pre .3cd release

5506

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5495

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5507

case 1 % .3cd release

5496

case 1 % .3cd release

5508

fctrx(1:length(PTDR.pulse_orig))=1;

5497

fctrx(1:length(PTDR.pulse_orig))=1;

5509

case 2 % .3ck working

5498

case 2 % .3ck working

5510

fctrx(1:length(PTDR.pulse_orig))=1;

5499

fctrx(1:length(PTDR.pulse_orig))=1;

5511

end

5500

end

5512

Gloss(1:length(TDR_results.t))=1;

5501

Gloss(1:length(TDR_results.t))=1;

5513

Grr(1:length(TDR_results.t))=1;

5502

Grr(1:length(TDR_results.t))=1;

5514

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5503

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5515

5504

5516

for ii=ntx:ndfex

5505

for ii=ntx:ndfex

5517

% adjust for near end loss

5506

% adjust for near end loss

5518

if param.N_bx>0 && param.beta_x~=0;

5507

if param.N_bx>0 && param.beta_x~=0;

5519

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5508

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5520

else

5509

else

5521

Gloss(ii)=1;

5510

Gloss(ii)=1;

5522

end

5511

end

5523

% ---------------------- 2.7 code

5512

% ---------------------- 2.7 code

5524

% x=(TDR_results.t(ii)-tfx)/param.ui;

5513

% x=(TDR_results.t(ii)-tfx)/param.ui;

5525

% ----------------------

5514

% ----------------------

5526

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5515

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5527

% rise time filter.

5516

% rise time filter.

5528

% x=(TDR_results.t(ii)-tfx)/param.ui;

5517

% x=(TDR_results.t(ii)-tfx)/param.ui;

5529

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5518

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5530

% determine how much of the return loss to use base on expected

5519

% determine how much of the return loss to use base on expected

5531

% missing reflections

5520

% missing reflections

5532

switch param.Grr

5521

switch param.Grr

5533

case 0 % pre .3cd release

5522

case 0 % pre .3cd release

5534

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5523

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5535

case 1 % .3cd release

5524

case 1 % .3cd release

5536

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5525

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5537

case 2 % .3ck working

5526

case 2 % .3ck working

5538

Grr(ii)= param.rho_x ;

5527

Grr(ii)= param.rho_x ;

5539

end

5528

end

5540

fctrx(ii)=Gloss(ii).*Grr(ii);

5529

fctrx(ii)=Gloss(ii).*Grr(ii);

5541

end

5530

end

5542

5531

5543

if isrow(fctrx), fctrx=fctrx(:);end

5532

if isrow(fctrx), fctrx=fctrx(:);end

5544

PTDR.pulse=PTDR.pulse.*fctrx;

5533

PTDR.pulse=PTDR.pulse.*fctrx;

5545

if 0

5534

if 0

5546

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5535

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5547

s1=subplot(2,1,1);

5536

s1=subplot(2,1,1);

5548

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5537

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5549

hold on

5538

hold on

5550

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5539

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5551

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5540

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5552

grid on

5541

grid on

5553

ylim([ 0 1.2])

5542

ylim([ 0 1.2])

5554

s2=subplot(2,1,2);

5543

s2=subplot(2,1,2);

5555

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5544

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5556

grid on

5545

grid on

5557

linkaxes([s1,s2],'x')

5546

linkaxes([s1,s2],'x')

5558

xlabel 'UI'

5547

xlabel 'UI'

5559

xlim ([ 1 200])

5548

xlim ([ 1 200])

5560

end

5549

end

5561

5550

5562

FAST_NOISE_CONV=0;

5551

FAST_NOISE_CONV=0;

5563

ERLRMS=rms(PTDR.pulse);

5552

ERLRMS=rms(PTDR.pulse);

5564

for ki=1:param.samples_per_ui

5553

for ki=1:param.samples_per_ui

5565

progress = ki/param.samples_per_ui;

5554

progress = ki/param.samples_per_ui;

5566

if OP.DISPLAY_WINDOW

5555

if OP.DISPLAY_WINDOW

5567

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5556

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5568

else

5557

else

5569

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5558

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5570

end

5559

end

5571

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5560

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5572

if OP.RL_norm_test

5561

if OP.RL_norm_test

5573

rl_fom=(norm(tps));

5562

rl_fom=(norm(tps));

5574

else

5563

else

5575

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5564

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5576

cdf_test=cumsum(testpdf.y);

5565

cdf_test=cumsum(testpdf.y);

5577

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5566

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5578

rl_fom=rl_test;

5567

rl_fom=rl_test;

5579

end

5568

end

5580

if rl_fom > RL_equiv

5569

if rl_fom > RL_equiv

5581

RL_equiv=rl_fom;

5570

RL_equiv=rl_fom;

5582

best_ki=ki;

5571

best_ki=ki;

5583

end

5572

end

5584

if ~OP.RL_norm_test

5573

if ~OP.RL_norm_test

5585

best_erl=rl_test;

5574

best_erl=rl_test;

5586

best_pdf=testpdf;

5575

best_pdf=testpdf;

5587

best_cdf=cdf_test;

5576

best_cdf=cdf_test;

5588

end

5577

end

5589

5578

5590

end

5579

end

5591

if OP.RL_norm_test

5580

if OP.RL_norm_test

5592

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5581

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5593

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5582

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5594

cdf_test=cumsum(testpdf.y);

5583

cdf_test=cumsum(testpdf.y);

5595

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5584

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5596

end

5585

end

5597

5586

5598

fprintf('\n');

5587

fprintf('\n');

5599

try

5588

try

5600

close(hwaitbar)

5589

close(hwaitbar)

5601

catch

5590

catch

5602

end

5591

end

5603

if ~exist('best_ki','var'),best_ki=1;end

5592

if ~exist('best_ki','var'),best_ki=1;end

5604

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5593

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5605

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5594

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5606

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5595

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5607

TDR_results.ERL=-db(best_erl);

5596

TDR_results.ERL=-db(best_erl);

5608

TDR_results.ERLRMS=-db(ERLRMS);

5597

TDR_results.ERLRMS=-db(ERLRMS);

5609

5598

5610

end

5599

end

5611

5600

5612

5601

5613

% end get TDR

5602

% end get TDR

5614

%%

5603

%%

5615

5604

5616

5605

5617

5606

5618

5607

5619

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5608

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5620

% filename parsing and acquisition

5609

% filename parsing and acquisition

5621

%------------------------------------------------------------------

5610

%------------------------------------------------------------------

5622

%----------put files names into chdata structure ---------

5611

%----------put files names into chdata structure ---------

5623

% The thru file has the index of 1

5612

% The thru file has the index of 1

5624

% crosstalk file are indexed from 2

5613

% crosstalk file are indexed from 2

5625

% nxi is incremented each time a file is read in so that nxi will end

5614

% nxi is incremented each time a file is read in so that nxi will end

5626

filepath=[]; % path name for file

5615

filepath=[]; % path name for file

5627

nxi=0; % file index

5616

nxi=0; % file index

5628

% get the THRU file

5617

% get the THRU file

5629

if size(file_list,2) ~= 0

5618

if size(file_list,2) ~= 0

5630

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5619

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5631

[filepath, basename, fileext]=fileparts(file_list{1});

5620

[filepath, basename, fileext]=fileparts(file_list{1});

5632

5621

5633

else

5622

else

5634

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5623

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5635

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5624

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5636

movegui(h,'northeast')

5625

movegui(h,'northeast')

5637

end

5626

end

5638

dir=fullfile(filepath, '*.csv');

5627

dir=fullfile(filepath, '*.csv');

5639

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5628

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5640

if filepath == 0

5629

if filepath == 0

5641

error('No Thru file')

5630

error('No Thru file')

5642

end

5631

end

5643

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5632

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5644

end

5633

end

5645

nxi=nxi+1;

5634

nxi=nxi+1;

5646

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5635

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5647

chdata(nxi).ext = fileext;

5636

chdata(nxi).ext = fileext;

5648

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5637

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5649

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5638

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5650

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5639

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5651

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5640

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5652

chdata(nxi).type='THRU';

5641

chdata(nxi).type='THRU';

5653

chdata(nxi).ftr=param.fb*param.f_v;

5642

chdata(nxi).ftr=param.fb*param.f_v;

5654

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5643

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5655

5644

5656

% now get FEXT file names into chdata structure

5645

% now get FEXT file names into chdata structure

5657

kxi=nxi;

5646

kxi=nxi;

5658

for nxi=kxi+1:num_fext+kxi

5647

for nxi=kxi+1:num_fext+kxi

5659

lastfilepath=filepath;

5648

lastfilepath=filepath;

5660

if size(file_list,2) ~= 0

5649

if size(file_list,2) ~= 0

5661

[filepath, basename, fileext]=fileparts(file_list{nxi});

5650

[filepath, basename, fileext]=fileparts(file_list{nxi});

5662

else

5651

else

5663

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5652

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5664

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5653

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5665

movegui(h,'northeast')

5654

movegui(h,'northeast')

5666

end

5655

end

5667

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5656

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5668

dir=fullfile(filepath, '*.csv');

5657

dir=fullfile(filepath, '*.csv');

5669

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5658

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5670

if filepath==0

5659

if filepath==0

5671

error('Not enough NEXT files')

5660

error('Not enough NEXT files')

5672

end

5661

end

5673

else

5662

else

5674

dir=fullfile(filepath, '*.csv');

5663

dir=fullfile(filepath, '*.csv');

5675

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5664

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5676

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5665

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5677

else

5666

else

5678

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5667

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5679

end

5668

end

5680

if filepath==0

5669

if filepath==0

5681

error('Not enough NEXT files')

5670

error('Not enough NEXT files')

5682

end

5671

end

5683

end

5672

end

5684

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5673

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5685

end

5674

end

5686

if isempty( filepath), filepath=lastfilepath; end

5675

if isempty( filepath), filepath=lastfilepath; end

5687

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5676

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5688

chdata(nxi).ext = fileext;

5677

chdata(nxi).ext = fileext;

5689

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5678

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5690

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5679

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5691

% chdata(nxi).A=param.a_fext;

5680

% chdata(nxi).A=param.a_fext;

5692

chdata(nxi).ftr=param.fb*param.f_f;

5681

chdata(nxi).ftr=param.fb*param.f_f;

5693

chdata(nxi).type='FEXT';

5682

chdata(nxi).type='FEXT';

5694

end

5683

end

5695

% now get NEXT file names into chdata structure

5684

% now get NEXT file names into chdata structure

5696

kxi=num_fext+kxi;

5685

kxi=num_fext+kxi;

5697

for nxi=kxi+1:num_next+kxi

5686

for nxi=kxi+1:num_next+kxi

5698

lastfilepath=filepath;

5687

lastfilepath=filepath;

5699

if size(file_list,2) ~= 0

5688

if size(file_list,2) ~= 0

5700

[filepath, basename, fileext]=fileparts(file_list{nxi});

5689

[filepath, basename, fileext]=fileparts(file_list{nxi});

5701

else

5690

else

5702

dir=fullfile(filepath, '*.csv');

5691

dir=fullfile(filepath, '*.csv');

5703

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5692

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5704

if filepath==0

5693

if filepath==0

5705

error('Not enough NEXT files')

5694

error('Not enough NEXT files')

5706

end

5695

end

5707

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5696

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5708

end

5697

end

5709

if isempty( filepath), filepath=lastfilepath; end

5698

if isempty( filepath), filepath=lastfilepath; end

5710

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5699

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5711

chdata(nxi).ext = fileext;

5700

chdata(nxi).ext = fileext;

5712

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5701

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5713

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5702

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5714

% chdata(nxi).A=param.A_next;

5703

% chdata(nxi).A=param.A_next;

5715

chdata(nxi).ftr=param.fb*param.f_n;

5704

chdata(nxi).ftr=param.fb*param.f_n;

5716

chdata(nxi).type='NEXT';

5705

chdata(nxi).type='NEXT';

5717

end

5706

end

5718

function half_UI=get_center_of_UI(samples_per_UI)

5707

function half_UI=get_center_of_UI(samples_per_UI)

5719

5708

5720

%half_UI reveals which value to use for the center of the UI. For eye

5709

%half_UI reveals which value to use for the center of the UI. For eye

5721

%width calculations, it is necessary to place the cursor in the center of the

5710

%width calculations, it is necessary to place the cursor in the center of the

5722

%UI window to ensure a 0 crossing on both left/right inside the window.

5711

%UI window to ensure a 0 crossing on both left/right inside the window.

5723

%This function was written in order to support even and odd samples_per_UI

5712

%This function was written in order to support even and odd samples_per_UI

5724

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

5713

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

5725

5714

5726

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

5715

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

5727

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

5716

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

5728

%the center of the UI is sample closest to 0.5

5717

%the center of the UI is sample closest to 0.5

5729

[temp_diff,half_UI]=min(abs(UI_window-0.5));

5718

[temp_diff,half_UI]=min(abs(UI_window-0.5));

5730

function results= get_cm_noise(M,PR,L,BER,OP)

5719

function results= get_cm_noise(M,PR,L,BER,OP)

5731

5720

5732

if ~exist('OP')

5721

if ~exist('OP')

5733

OP.DC_norm_test=0;

5722

OP.DC_norm_test=0;

5734

OP.DISPLAY_WINDOW=1;

5723

OP.DISPLAY_WINDOW=1;

5735

end

5724

end

5736

param.BinSize=1e-5;

5725

param.BinSize=1e-5;

5737

PR_test=-inf;

5726

PR_test=-inf;

5738

PR_fom_best=-inf;

5727

PR_fom_best=-inf;

5739

% hwaitbar=waitbar(0);

5728

% hwaitbar=waitbar(0);

5740

for ki=1:M

5729

for ki=1:M

5741

progress = ki/M;

5730

progress = ki/M;

5742

% if OP.DISPLAY_WINDOW

5731

% if OP.DISPLAY_WINDOW

5743

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

5732

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

5744

% else

5733

% else

5745

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5734

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5746

% end

5735

% end

5747

tps=PR(ki:M:end);

5736

tps=PR(ki:M:end);

5748

if OP.DC_norm_test

5737

if OP.DC_norm_test

5749

PR_fom=(norm(tps));

5738

PR_fom=(norm(tps));

5750

else

5739

else

5751

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

5740

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

5752

cdf_test=cumsum(testpdf.y);

5741

cdf_test=cumsum(testpdf.y);

5753

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

5742

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

5754

PR_fom=PRn_test;

5743

PR_fom=PRn_test;

5755

end

5744

end

5756

if PR_fom > PR_fom_best

5745

if PR_fom > PR_fom_best

5757

PR_fom_best=PR_fom;

5746

PR_fom_best=PR_fom;

5758

best_ki=ki;

5747

best_ki=ki;

5759

end

5748

end

5760

if ~OP.DC_norm_test

5749

if ~OP.DC_norm_test

5761

results.DCn=PR_fom_best;

5750

results.DCn=PR_fom_best;

5762

results.DCn_pdf=testpdf;

5751

results.DCn_pdf=testpdf;

5763

results.DCn_cdf=cdf_test;

5752

results.DCn_cdf=cdf_test;

5764

else

5753

else

5765

results.DCn=PR_fom_best;

5754

results.DCn=PR_fom_best;

5766

end

5755

end

5767

results.DCn_p2p=max(PR)-min(PR);

5756

results.DCn_p2p=max(PR)-min(PR);

5768

end

5757

end

5769

5758

5770

5759

5771

5760

5772

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

5761

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

5773

SBR=chdata.eq_pulse_response(:)'; % row vector

5762

SBR=chdata.eq_pulse_response(:)'; % row vector

5774

type=chdata.type;

5763

type=chdata.type;

5775

samp_UI=param.samples_per_ui;

5764

samp_UI=param.samples_per_ui;

5776

residual_response = SBR;

5765

residual_response = SBR;

5777

5766

5778

if isequal(type, 'THRU')

5767

if isequal(type, 'THRU')

5779

% for thru pulse response:

5768

% for thru pulse response:

5780

% remove the cursor and the DFE postcursors (up to their limit), since

5769

% remove the cursor and the DFE postcursors (up to their limit), since

5781

% we only care about the residuals.

5770

% we only care about the residuals.

5782

5771

5783

if ~param.Floating_DFE

5772

if ~param.Floating_DFE

5784

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

5773

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

5785

else

5774

else

5786

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

5775

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

5787

end

5776

end

5788

if param.dfe_delta ~= 0

5777

if param.dfe_delta ~= 0

5789

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

5778

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

5790

else

5779

else

5791

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5780

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5792

end

5781

end

5793

5782

5794

%AJG021820

5783

%AJG021820

5795

if ~param.Floating_DFE

5784

if ~param.Floating_DFE

5796

bmax_vec=residual_response(t_s)*[1,param.bmax];

5785

bmax_vec=residual_response(t_s)*[1,param.bmax];

5797

bmin_vec=residual_response(t_s)*[1,param.bmin];

5786

bmin_vec=residual_response(t_s)*[1,param.bmin];

5798

else

5787

else

5799

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

5788

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

5800

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

5789

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

5801

end

5790

end

5802

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5791

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5803

5792

5804

5793

5805

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

5794

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

5806

dfetaps=effective_cancelled_cursors/SBR(t_s);

5795

dfetaps=effective_cancelled_cursors/SBR(t_s);

5807

5796

5808

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5797

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5809

% really needed for COM, but helps debugging. May be factored out in future revisions.

5798

% really needed for COM, but helps debugging. May be factored out in future revisions.

5810

start_cancel = t_s-param.samples_per_ui/2;

5799

start_cancel = t_s-param.samples_per_ui/2;

5811

if ~param.Floating_DFE

5800

if ~param.Floating_DFE

5812

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

5801

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

5813

else

5802

else

5814

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

5803

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

5815

end

5804

end

5816

residual_response(start_cancel:end_cancel) = ...

5805

residual_response(start_cancel:end_cancel) = ...

5817

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5806

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5818

%else

5807

%else

5819

% for crosstalk pulse responses, nothing is cancelled, and all phases

5808

% for crosstalk pulse responses, nothing is cancelled, and all phases

5820

% are equally important.

5809

% are equally important.

5821

end

5810

end

5822

5811

5823

nui=round(length(residual_response)/param.samples_per_ui);

5812

nui=round(length(residual_response)/param.samples_per_ui);

5824

5813

5825

vs=zeros(nui-2, param.samples_per_ui);

5814

vs=zeros(nui-2, param.samples_per_ui);

5826

for i=1:param.samples_per_ui

5815

for i=1:param.samples_per_ui

5827

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

5816

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

5828

end

5817

end

5829

5818

5830

if OP.DISPLAY_WINDOW,

5819

if OP.DISPLAY_WINDOW,

5831

hwaitbar=waitbar(0);

5820

hwaitbar=waitbar(0);

5832

end

5821

end

5833

5822

5834

% determine which pdf to use

5823

% determine which pdf to use

5835

if isequal(type, 'THRU')

5824

if isequal(type, 'THRU')

5836

% one phase is interesting for thru

5825

% one phase is interesting for thru

5837

phases = mod(t_s,param.samples_per_ui);

5826

phases = mod(t_s,param.samples_per_ui);

5838

if phases==0, phases = param.samples_per_ui; end

5827

if phases==0, phases = param.samples_per_ui; end

5839

else

5828

else

5840

phases=1:samp_UI;

5829

phases=1:samp_UI;

5841

end

5830

end

5842

5831

5843

mxV = zeros(size(phases));

5832

mxV = zeros(size(phases));

5844

% we already found the phase in the PSD process for MMSE

5833

% we already found the phase in the PSD process for MMSE

5845

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

5834

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

5846

if isequal(type, 'THRU')

5835

if isequal(type, 'THRU')

5847

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

5836

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

5848

else

5837

else

5849

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

5838

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

5850

end

5839

end

5851

else

5840

else

5852

for k=phases

5841

for k=phases

5853

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

5842

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

5854

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

5843

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

5855

progress = k/length(phases);

5844

progress = k/length(phases);

5856

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

5845

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

5857

end

5846

end

5858

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

5847

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

5859

pdf=pdf_samples(pxi);

5848

pdf=pdf_samples(pxi);

5860

end

5849

end

5861

5850

5862

5851

5863

5852

5864

if OP.DISPLAY_WINDOW

5853

if OP.DISPLAY_WINDOW

5865

close(hwaitbar);

5854

close(hwaitbar);

5866

end

5855

end

5867

5856

5868

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

5857

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

5869

% Create PDF from interference vector using successive delta-set convolutions.

5858

% Create PDF from interference vector using successive delta-set convolutions.

5870

% input_vector = list of values of samples

5859

% input_vector = list of values of samples

5871

% return

5860

% return

5872

% pdf.x

5861

% pdf.x

5873

% pdf.y

5862

% pdf.y

5874

% pdf.vec

5863

% pdf.vec

5875

% pdf.bin

5864

% pdf.bin

5876

if ~exist('FAST_NOISE_CONV','var')

5865

if ~exist('FAST_NOISE_CONV','var')

5877

FAST_NOISE_CONV=0;

5866

FAST_NOISE_CONV=0;

5878

end

5867

end

5879

if max(input_vector) > BinSize

5868

if max(input_vector) > BinSize

5880

input_vector=input_vector(abs(input_vector)>BinSize);

5869

input_vector=input_vector(abs(input_vector)>BinSize);

5881

end

5870

end

5882

% for i = 1:length(input_vector)

5871

% for i = 1:length(input_vector)

5883

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

5872

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

5884

%end

5873

%end

5885

5874

5886

input_vector(abs(input_vector)<BinSize) = 0;

5875

input_vector(abs(input_vector)<BinSize) = 0;

5887

b=sign(input_vector);

5876

b=sign(input_vector);

5888

[input_vector,index]=sort(abs(input_vector),'descend');

5877

[input_vector,index]=sort(abs(input_vector),'descend');

5889

input_vector=input_vector.*b(index);

5878

input_vector=input_vector.*b(index);

5890

if FAST_NOISE_CONV

5879

if FAST_NOISE_CONV

5891

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

5880

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

5892

res_pdf= normal_dist(sig_res,5,BinSize);

5881

res_pdf= normal_dist(sig_res,5,BinSize);

5893

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

5882

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

5894

end

5883

end

5895

%% Equation 93A-39 %%

5884

%% Equation 93A-39 %%

5896

values = 2*(0:L-1)/(L-1)-1;

5885

values = 2*(0:L-1)/(L-1)-1;

5897

prob = ones(1,L)/L;

5886

prob = ones(1,L)/L;

5898

5887

5899

%% Initialize pdf to delta at 0

5888

%% Initialize pdf to delta at 0

5900

pdf=d_cpdf(BinSize, 0, 1);

5889

pdf=d_cpdf(BinSize, 0, 1);

5901

empty_pdf=pdf;

5890

empty_pdf=pdf;

5902

for k = 1:length(input_vector)

5891

for k = 1:length(input_vector)

5903

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

5892

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

5904

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

5893

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

5905

pdf=conv_fct(pdf, pdfn);

5894

pdf=conv_fct(pdf, pdfn);

5906

end

5895

end

5907

if FAST_NOISE_CONV

5896

if FAST_NOISE_CONV

5908

% pdf=conv_fct(pdf,res_pdf);

5897

% pdf=conv_fct(pdf,res_pdf);

5909

pdf=conv_fct_TEST(pdf,res_pdf);

5898

pdf=conv_fct_TEST(pdf,res_pdf);

5910

end

5899

end

5911

5900

5912

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

5901

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

5913

t_s_orig=t_s;

5902

t_s_orig=t_s;

5914

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

5903

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

5915

type=chdata.type;

5904

type=chdata.type;

5916

5905

5917

pulse_orig=chdata.eq_pulse_response(:)';

5906

pulse_orig=chdata.eq_pulse_response(:)';

5918

%build arbitrary time axis with step size = 1/samples per ui

5907

%build arbitrary time axis with step size = 1/samples per ui

5919

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

5908

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

5920

%force t_s at time =0 (makes the other things below easy)

5909

%force t_s at time =0 (makes the other things below easy)

5921

original_sample_time=old_time(t_s_orig);

5910

original_sample_time=old_time(t_s_orig);

5922

old_time=old_time-original_sample_time;

5911

old_time=old_time-original_sample_time;

5923

%build new time axis that forces time=0 to be in the axis

5912

%build new time axis that forces time=0 to be in the axis

5924

%unless the new/old samples per UI are integer ratios, time 0 will not be

5913

%unless the new/old samples per UI are integer ratios, time 0 will not be

5925

%there by default

5914

%there by default

5926

samp_UI=param.samples_for_C2M;

5915

samp_UI=param.samples_for_C2M;

5927

new_timea=[0:-1/samp_UI:min(old_time)];

5916

new_timea=[0:-1/samp_UI:min(old_time)];

5928

new_timeb=[0:1/samp_UI:max(old_time)];

5917

new_timeb=[0:1/samp_UI:max(old_time)];

5929

new_time=[fliplr(new_timea) new_timeb(2:end)];

5918

new_time=[fliplr(new_timea) new_timeb(2:end)];

5930

SBR=interp1(old_time,pulse_orig,new_time);

5919

SBR=interp1(old_time,pulse_orig,new_time);

5931

%new sample time is simply the point where new_time = 0

5920

%new sample time is simply the point where new_time = 0

5932

[tmp,t_s]=min(abs(new_time));

5921

[tmp,t_s]=min(abs(new_time));

5933

5922

5934

residual_response = SBR;

5923

residual_response = SBR;

5935

5924

5936

half_UI=get_center_of_UI(samp_UI);

5925

half_UI=get_center_of_UI(samp_UI);

5937

5926

5938

if isequal(type, 'THRU')

5927

if isequal(type, 'THRU')

5939

% for thru pulse response:

5928

% for thru pulse response:

5940

% remove the cursor and the DFE postcursors (up to their limit), since

5929

% remove the cursor and the DFE postcursors (up to their limit), since

5941

% we only care about the residuals.

5930

% we only care about the residuals.

5942

5931

5943

%AJG021820

5932

%AJG021820

5944

if ~param.Floating_DFE

5933

if ~param.Floating_DFE

5945

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

5934

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

5946

else

5935

else

5947

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

5936

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

5948

end

5937

end

5949

if param.dfe_delta ~= 0

5938

if param.dfe_delta ~= 0

5950

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

5939

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

5951

else

5940

else

5952

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5941

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5953

end

5942

end

5954

5943

5955

if ~param.Floating_DFE

5944

if ~param.Floating_DFE

5956

bmax_vec=residual_response(t_s)*[param.bmax];

5945

bmax_vec=residual_response(t_s)*[param.bmax];

5957

bmin_vec=residual_response(t_s)*[param.bmin];

5946

bmin_vec=residual_response(t_s)*[param.bmin];

5958

else

5947

else

5959

bmax_vec=residual_response(t_s)*[param.use_bmax];

5948

bmax_vec=residual_response(t_s)*[param.use_bmax];

5960

bmin_vec=residual_response(t_s)*[param.use_bmin];

5949

bmin_vec=residual_response(t_s)*[param.use_bmin];

5961

end

5950

end

5962

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5951

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5963

5952

5964

5953

5965

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

5954

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

5966

dfetaps=effective_cancelled_cursors/SBR(t_s);

5955

dfetaps=effective_cancelled_cursors/SBR(t_s);

5967

5956

5968

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5957

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5969

% really needed for COM, but helps debugging. May be factored out in future revisions.

5958

% really needed for COM, but helps debugging. May be factored out in future revisions.

5970

5959

5971

%avoid dividing samp_UI by 2 in case it is not even

5960

%avoid dividing samp_UI by 2 in case it is not even

5972

start_cancel=t_s-half_UI+1+samp_UI;

5961

start_cancel=t_s-half_UI+1+samp_UI;

5973

%AJG021820

5962

%AJG021820

5974

if ~param.Floating_DFE

5963

if ~param.Floating_DFE

5975

end_cancel=start_cancel+param.ndfe*samp_UI-1;

5964

end_cancel=start_cancel+param.ndfe*samp_UI-1;

5976

else

5965

else

5977

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

5966

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

5978

end

5967

end

5979

residual_response(start_cancel:end_cancel) = ...

5968

residual_response(start_cancel:end_cancel) = ...

5980

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5969

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5981

%else

5970

%else

5982

% for crosstalk pulse responses, nothing is cancelled, and all phases

5971

% for crosstalk pulse responses, nothing is cancelled, and all phases

5983

% are equally important.

5972

% are equally important.

5984

5973

5985

%remove entire cursor UI

5974

%remove entire cursor UI

5986

uiv_start=start_cancel-samp_UI;

5975

uiv_start=start_cancel-samp_UI;

5987

uiv_end=uiv_start+samp_UI-1;

5976

uiv_end=uiv_start+samp_UI-1;

5988

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

5977

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

5989

residual_response(uiv_start:uiv_end)=0;

5978

residual_response(uiv_start:uiv_end)=0;

5990

end

5979

end

5991

5980

5992

nui=round(length(residual_response)/samp_UI);

5981

nui=round(length(residual_response)/samp_UI);

5993

5982

5994

5983

5995

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5984

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5996

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

5985

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

5997

%response without DFE included. (Can't include DFE for jitter calc)

5986

%response without DFE included. (Can't include DFE for jitter calc)

5998

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5987

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5999

5988

6000

% if OP.DISPLAY_WINDOW,

5989

% if OP.DISPLAY_WINDOW,

6001

% hwaitbar=waitbar(0);

5990

% hwaitbar=waitbar(0);

6002

% end

5991

% end

6003

5992

6004

% determine which pdf to use

5993

% determine which pdf to use

6005

if isequal(type, 'THRU')

5994

if isequal(type, 'THRU')

6006

% one phase is interesting for thru

5995

% one phase is interesting for thru

6007

phases = mod(t_s,samp_UI);

5996

phases = mod(t_s,samp_UI);

6008

if phases==0, phases = samp_UI; end

5997

if phases==0, phases = samp_UI; end

6009

else

5998

else

6010

phases=1:samp_UI;

5999

phases=1:samp_UI;

6011

end

6000

end

6012

6001

6013

mxV = zeros(size(phases));

6002

mxV = zeros(size(phases));

6014

6003

6015

%phases reveals the raw position in the UI window of the cursor.

6004

%phases reveals the raw position in the UI window of the cursor.

6016

%shift_amount is the amount to shift so that it aligns with half_UI

6005

%shift_amount is the amount to shift so that it aligns with half_UI

6017

shift_amount=half_UI-phases;

6006

shift_amount=half_UI-phases;

6018

%vs_shift puts the cursor at the center

6007

%vs_shift puts the cursor at the center

6019

vs_shift=circshift(vs,[0 shift_amount]);

6008

vs_shift=circshift(vs,[0 shift_amount]);

6020

L=size(vs_raw,1);

6009

L=size(vs_raw,1);

6021

%allow partial UI computation through pdf_range

6010

%allow partial UI computation through pdf_range

6022

%if pdf_range is empty, do full UI

6011

%if pdf_range is empty, do full UI

6023

if isempty(pdf_range)

6012

if isempty(pdf_range)

6024

pdf_range=1:samp_UI;

6013

pdf_range=1:samp_UI;

6025

else

6014

else

6026

pdf_range=min(pdf_range):max(pdf_range);

6015

pdf_range=min(pdf_range):max(pdf_range);

6027

end

6016

end

6028

h_j_full=zeros(L,samp_UI);

6017

h_j_full=zeros(L,samp_UI);

6029

for k=pdf_range

6018

for k=pdf_range

6030

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6019

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6031

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6020

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6032

%progress = k/length(phases);

6021

%progress = k/length(phases);

6033

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6022

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6034

6023

6035

%build the circshift of h_j_full into the loop to support a reduced

6024

%build the circshift of h_j_full into the loop to support a reduced

6036

%range of sampling points. circshift at the end only works if doing the

6025

%range of sampling points. circshift at the end only works if doing the

6037

%full range of sampling points. And shifting before the loop will

6026

%full range of sampling points. And shifting before the loop will

6038

%yield the wrong answer at the edges of the UI

6027

%yield the wrong answer at the edges of the UI

6039

hk=k-shift_amount;

6028

hk=k-shift_amount;

6040

if hk<1

6029

if hk<1

6041

hk=hk+samp_UI;

6030

hk=hk+samp_UI;

6042

elseif hk>samp_UI

6031

elseif hk>samp_UI

6043

hk=hk-samp_UI;

6032

hk=hk-samp_UI;

6044

end

6033

end

6045

if hk==1

6034

if hk==1

6046

%when hk=1, the early UI is the last column

6035

%when hk=1, the early UI is the last column

6047

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6036

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6048

elseif hk==samp_UI

6037

elseif hk==samp_UI

6049

%when hk=samp_UI, the late UI is the first column

6038

%when hk=samp_UI, the late UI is the first column

6050

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6039

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6051

else

6040

else

6052

%for all other cases, do the normal late=+1, early = -1

6041

%for all other cases, do the normal late=+1, early = -1

6053

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6042

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6054

end

6043

end

6055

end

6044

end

6056

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6045

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6057

% filename parsing and acquisition

6046

% filename parsing and acquisition

6058

%------------------------------------------------------------------

6047

%------------------------------------------------------------------

6059

%----------put files names into chdata structure ---------

6048

%----------put files names into chdata structure ---------

6060

% The thru file has the index of 1

6049

% The thru file has the index of 1

6061

% crosstalk file are indexed from 2

6050

% crosstalk file are indexed from 2

6062

% nxi is incremented each time a file is read in so that nxi will end

6051

% nxi is incremented each time a file is read in so that nxi will end

6063

filepath=[]; % path name for file

6052

filepath=[]; % path name for file

6064

nxi=0; % file index

6053

nxi=0; % file index

6065

% get the THRU file

6054

% get the THRU file

6066

if size(file_list,2) ~= 0

6055

if size(file_list,2) ~= 0

6067

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6056

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6068

[filepath, basename, fileext]=fileparts(file_list{1});

6057

[filepath, basename, fileext]=fileparts(file_list{1});

6069

6058

6070

else

6059

else

6071

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6060

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6072

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6061

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6073

movegui(h,'northeast')

6062

movegui(h,'northeast')

6074

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6063

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6075

end

6064

end

6076

if OP.ERL == 2

6065

if OP.ERL == 2

6077

dir=fullfile(filepath, '*.s2p');

6066

dir=fullfile(filepath, '*.s2p');

6078

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6067

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6079

if filepath == 0

6068

if filepath == 0

6080

error('No RL measurement file')

6069

error('No RL measurement file')

6081

end

6070

end

6082

else

6071

else

6083

dir=fullfile(filepath, '*.s4p');

6072

dir=fullfile(filepath, '*.s4p');

6084

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6073

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6085

if filepath == 0

6074

if filepath == 0

6086

error('No Thru file')

6075

error('No Thru file')

6087

end

6076

end

6088

end

6077

end

6089

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6078

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6090

end

6079

end

6091

nxi=nxi+1;

6080

nxi=nxi+1;

6092

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6081

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6093

chdata(nxi).ext = fileext;

6082

chdata(nxi).ext = fileext;

6094

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6083

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6095

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6084

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6096

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6085

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6097

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6086

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6098

chdata(nxi).type='THRU';

6087

chdata(nxi).type='THRU';

6099

chdata(nxi).ftr=param.fb*param.f_v;

6088

chdata(nxi).ftr=param.fb*param.f_v;

6100

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6089

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6101

6090

6102

% now get FEXT file names into chdata structure

6091

% now get FEXT file names into chdata structure

6103

kxi=nxi;

6092

kxi=nxi;

6104

for nxi=kxi+1:num_fext+kxi

6093

for nxi=kxi+1:num_fext+kxi

6105

lastfilepath=filepath;

6094

lastfilepath=filepath;

6106

if size(file_list,2) ~= 0

6095

if size(file_list,2) ~= 0

6107

[filepath, basename, fileext]=fileparts(file_list{nxi});

6096

[filepath, basename, fileext]=fileparts(file_list{nxi});

6108

else

6097

else

6109

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6098

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6110

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6099

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6111

movegui(h,'northeast')

6100

movegui(h,'northeast')

6112

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6101

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6113

end

6102

end

6114

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6103

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6115

dir=fullfile(filepath, '*.s4p');

6104

dir=fullfile(filepath, '*.s4p');

6116

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6105

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6117

if filepath==0

6106

if filepath==0

6118

error('Not enough NEXT files')

6107

error('Not enough NEXT files')

6119

end

6108

end

6120

else

6109

else

6121

dir=fullfile(filepath, '*.s4p');

6110

dir=fullfile(filepath, '*.s4p');

6122

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6111

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6123

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6112

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6124

else

6113

else

6125

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6114

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6126

end

6115

end

6127

if filepath==0

6116

if filepath==0

6128

error('Not enough NEXT files')

6117

error('Not enough NEXT files')

6129

end

6118

end

6130

end

6119

end

6131

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6120

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6132

end

6121

end

6133

if isempty( filepath), filepath=lastfilepath; end

6122

if isempty( filepath), filepath=lastfilepath; end

6134

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6123

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6135

chdata(nxi).ext = fileext;

6124

chdata(nxi).ext = fileext;

6136

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6125

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6137

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6126

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6138

% chdata(nxi).A=param.a_fext;

6127

% chdata(nxi).A=param.a_fext;

6139

chdata(nxi).ftr=param.fb*param.f_v;

6128

chdata(nxi).ftr=param.fb*param.f_f;

6140

chdata(nxi).type='FEXT';

6129

chdata(nxi).type='FEXT';

6141

end

6130

end

6142

% now get NEXT file names into chdata structure

6131

% now get NEXT file names into chdata structure

6143

kxi=num_fext+kxi;

6132

kxi=num_fext+kxi;

6144

for nxi=kxi+1:num_next+kxi

6133

for nxi=kxi+1:num_next+kxi

6145

lastfilepath=filepath;

6134

lastfilepath=filepath;

6146

if size(file_list,2) ~= 0

6135

if size(file_list,2) ~= 0

6147

[filepath, basename, fileext]=fileparts(file_list{nxi});

6136

[filepath, basename, fileext]=fileparts(file_list{nxi});

6148

else

6137

else

6149

dir=fullfile(filepath, '*.s4p');

6138

dir=fullfile(filepath, '*.s4p');

6150

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6139

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6151

if filepath==0

6140

if filepath==0

6152

error('Not enough NEXT files')

6141

error('Not enough NEXT files')

6153

end

6142

end

6154

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6143

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6155

end

6144

end

6156

if isempty( filepath), filepath=lastfilepath; end

6145

if isempty( filepath), filepath=lastfilepath; end

6157

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6146

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6158

chdata(nxi).ext = fileext;

6147

chdata(nxi).ext = fileext;

6159

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6148

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6160

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6149

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6161

% chdata(nxi).A=param.A_next;

6150

% chdata(nxi).A=param.A_next;

6162

chdata(nxi).ftr=param.fb*param.f_v;

6151

chdata(nxi).ftr=param.fb*param.f_n;

6163

chdata(nxi).type='NEXT';

6152

chdata(nxi).type='NEXT';

6164

end

6153

end

6165

6154

6166

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6155

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6167

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6156

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6168

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6157

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6169

% H_r - receiver filter, Butterworth

6158

% H_r - receiver filter, Butterworth

6170

% H_ctf - total gain of CTLE and low freq filtering

6159

% H_ctf - total gain of CTLE and low freq filtering

6171

% H_dc - the common mode channel gain

6160

% H_dc - the common mode channel gain

6172

% param.eta_0 -input referred Rx noise

6161

% param.eta_0 -input referred Rx noise

6173

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6162

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6174

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6163

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6175

%% Equation 93A-35 - independent of FFE setting %%

6164

%% Equation 93A-35 - independent of FFE setting %%

6176

sigma_N1 = sqrt(param.eta_0*sum( abs(H_sy(2:end) .* H_r(2:end) .* H_ctf(2:end) ).^2 .* diff(chdata(1).faxis)/1e9));% eta_0 is V^2/Ghz i.e. /1

6165

sigma_N1 = sqrt(param.eta_0*sum( abs(H_sy(2:end) .* H_r(2:end) .* H_ctf(2:end) ).^2 .* diff(chdata(1).faxis)/1e9));% eta_0 is V^2/Ghz i.e. /1

6177

if sum(param.AC_CM_RMS) ~= 0

6166

if sum(param.AC_CM_RMS) ~= 0

6178

sigma_ACCM=0;

6167

sigma_ACCM=0;

6179

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6168

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6180

for i=1:length(chdata)

6169

for i=1:length(chdata)

6181

H_dc=abs(squeeze(chdata(i).sdc21));

6170

H_dc=abs(squeeze(chdata(i).sdc21));

6182

sigma_ACCM_acc= sqrt( 2*param.AC_CM_RMS_TX^2.*sum( abs(H_sy(2:length(f_int)) .* H_r(2:length(f_int)) .* H_ctf(2:length(f_int)).*H_dc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end) );

6171

sigma_ACCM_acc= sqrt( 2*param.AC_CM_RMS_TX^2.*sum( abs(H_sy(2:length(f_int)) .* H_r(2:length(f_int)) .* H_ctf(2:length(f_int)).*H_dc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end) );

6183

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6172

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6184

end

6173

end

6185

sigma_N=norm([sigma_N1,sigma_ACCM]);

6174

sigma_N=norm([sigma_N1,sigma_ACCM]);

6186

else

6175

else

6187

sigma_N=sigma_N1;

6176

sigma_N=sigma_N1;

6188

end

6177

end

6189

%%

6178

%%

6190

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6179

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6191

% for Rx calibratrion only

6180

% for Rx calibratrion only

6192

% the FEXT channel for calibration basically a DC connection unlike normal

6181

% the FEXT channel for calibration basically a DC connection unlike normal

6193

% FEXT channels which are nearly open at DC channels

6182

% FEXT channels which are nearly open at DC channels

6194

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6183

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6195

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6184

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6196

if size(chdata,2) >= 2

6185

if size(chdata,2) >= 2

6197

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6186

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6198

else

6187

else

6199

Hnoise_channel=1;

6188

Hnoise_channel=1;

6200

end

6189

end

6201

f=chdata(2).faxis;

6190

f=chdata(2).faxis;

6202

f_hp=param.f_hp;

6191

f_hp=param.f_hp;

6203

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6192

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6204

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6193

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6205

else

6194

else

6206

H_hp=ones(1,length(f));

6195

H_hp=ones(1,length(f));

6207

end

6196

end

6208

%% Equation 93A-47 or 162-12

6197

%% Equation 93A-47 or 162-12

6209

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6198

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6210

6199

6211

%% Equation 93A-48 or 162-14%%

6200

%% Equation 93A-48 or 162-14%%

6212

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6201

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6213

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6202

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6214

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6203

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6215

% Modified not to double count crosstalk: John Ewen 13/12/2018

6204

% Modified not to double count crosstalk: John Ewen 13/12/2018

6216

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6205

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6217

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6206

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6218

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6207

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6219

f=chdata(1).faxis;

6208

f=chdata(1).faxis;

6220

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6209

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6221

if(f(1)==0)

6210

if(f(1)==0)

6222

temp_angle(1)=1e-20;% we don't want to divide by zero

6211

temp_angle(1)=1e-20;% we don't want to divide by zero

6223

end

6212

end

6224

PWF_tx=ones(1,length(f));

6213

PWF_tx=ones(1,length(f));

6225

if max(upsampled_txffe) > 0

6214

if max(upsampled_txffe) > 0

6226

PWF_tx=zeros(1,length(f));

6215

PWF_tx=zeros(1,length(f));

6227

[mcur,icur] = max(upsampled_txffe);

6216

[mcur,icur] = max(upsampled_txffe);

6228

if exist('phase_memory','var') && ~isempty(phase_memory)

6217

if exist('phase_memory','var') && ~isempty(phase_memory)

6229

pre_calc=1;

6218

pre_calc=1;

6230

else

6219

else

6231

pre_calc=0;

6220

pre_calc=0;

6232

end

6221

end

6233

for ii=1:length(upsampled_txffe)

6222

for ii=1:length(upsampled_txffe)

6234

if upsampled_txffe(ii)==0

6223

if upsampled_txffe(ii)==0

6235

%speed up: skip cases when txffe=0

6224

%speed up: skip cases when txffe=0

6236

continue;

6225

continue;

6237

end

6226

end

6238

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6227

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6239

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6228

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6240

% that is needed

6229

% that is needed

6241

if ii==icur

6230

if ii==icur

6242

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6231

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6243

PWF_tx = PWF_tx + upsampled_txffe(ii);

6232

PWF_tx = PWF_tx + upsampled_txffe(ii);

6244

else

6233

else

6245

if pre_calc

6234

if pre_calc

6246

%speed up: avoid vector exp calculation by externally pre-calculating it

6235

%speed up: avoid vector exp calculation by externally pre-calculating it

6247

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6236

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6248

else

6237

else

6249

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6238

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6250

end

6239

end

6251

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6240

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6252

PWF_tx = PWF_tx + transpose(term_ii(:));

6241

PWF_tx = PWF_tx + transpose(term_ii(:));

6253

end

6242

end

6254

% /Adee

6243

% /Adee

6255

end

6244

end

6256

end

6245

end

6257

PWF_rx=ones(1,length(f));

6246

PWF_rx=ones(1,length(f));

6258

if exist('C','var')

6247

if exist('C','var')

6259

PWF_rx=zeros(1,length(f));

6248

PWF_rx=zeros(1,length(f));

6260

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6249

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6261

if C(ii+param.RxFFE_cmx+1)==0

6250

if C(ii+param.RxFFE_cmx+1)==0

6262

%speed up: skip cases when rxffe=0

6251

%speed up: skip cases when rxffe=0

6263

continue;

6252

continue;

6264

end

6253

end

6265

if ii+1==0

6254

if ii+1==0

6266

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6255

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6267

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6256

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6268

else

6257

else

6269

if pre_calc

6258

if pre_calc

6270

%speed up: avoid vector exp calculation by externally pre-calculating it

6259

%speed up: avoid vector exp calculation by externally pre-calculating it

6271

%The latter columns of phase_memory hold RXFFE shift vectors

6260

%The latter columns of phase_memory hold RXFFE shift vectors

6272

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6261

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6273

term_ii=transpose(term_ii);

6262

term_ii=transpose(term_ii);

6274

else

6263

else

6275

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6264

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6276

end

6265

end

6277

PWF_rx=PWF_rx+term_ii;

6266

PWF_rx=PWF_rx+term_ii;

6278

end

6267

end

6279

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6268

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6280

end

6269

end

6281

end

6270

end

6282

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6271

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6283

for ii=2:size(chdata,2)

6272

for ii=2:size(chdata,2)

6284

SINC = sin(temp_angle)./temp_angle;

6273

SINC = sin(temp_angle)./temp_angle;

6285

PWF_data=SINC.^2;

6274

PWF_data=SINC.^2;

6286

PWF=PWF_data.*PWF_rx; % power weight function

6275

PWF=PWF_data.*PWF_rx; % power weight function

6287

PWFnext=abs(PWF);

6276

PWFnext=abs(PWF);

6288

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6277

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6289

PWFfext=abs(PWF);

6278

PWFfext=abs(PWF);

6290

if isequal(chdata(ii).type, 'FEXT')

6279

if isequal(chdata(ii).type, 'FEXT')

6291

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6280

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6292

MDFEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFfext(1:index_f2).*abs(MDFEXT(1:index_f2)).^2)); %eq 46

6281

MDFEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFfext(1:index_f2).*abs(MDFEXT(1:index_f2)).^2)); %eq 46

6293

elseif isequal(chdata(ii).type, 'NEXT')

6282

elseif isequal(chdata(ii).type, 'NEXT')

6294

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6283

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6295

MDNEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFnext(1:index_f2).*abs(MDNEXT(1:index_f2)).^2)); %eq 47

6284

MDNEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFnext(1:index_f2).*abs(MDNEXT(1:index_f2)).^2)); %eq 47

6296

end

6285

end

6297

end

6286

end

6298

if nargout == 1 && isequal(type,'NEXT')

6287

if nargout == 1 && isequal(type,'NEXT')

6299

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6288

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6300

elseif nargout == 1 && isequal(type,'FEXT')

6289

elseif nargout == 1 && isequal(type,'FEXT')

6301

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6290

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6302

elseif nargout == 3

6291

elseif nargout == 3

6303

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6292

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6304

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6293

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6305

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6294

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6306

end

6295

end

6307

6296

6308

function out=hrem(h,index,N_bf,bmaxg)

6297

function out=hrem(h,index,N_bf,bmaxg)

6309

6298

6310

out=[ h(1:index-1) h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) h(index+N_bf:end) ];

6299

out=[ h(1:index-1) h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) h(index+N_bf:end) ];

6311

% faster than single line function

6300

% faster than single line function

6312

% hrem =@(h,index,N_bf,bmaxg) ...

6301

% hrem =@(h,index,N_bf,bmaxg) ...

6313

% [ h(1:index-1) ...

6302

% [ h(1:index-1) ...

6314

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6303

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6315

% h(index+N_bf:end) ]...

6304

% h(index+N_bf:end) ]...

6316

% ;

6305

% ;

6317

6306

6318

%% floating DFE taps

6307

%% floating DFE taps

6319

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6308

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6320

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6309

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6321

% Sout = interp_Sparam(Sin,fin,fout)

6310

% Sout = interp_Sparam(Sin,fin,fout)

6322

%

6311

%

6323

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6312

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6324

% fout.

6313

% fout.

6325

6314

6326

if ( fin(end)<fout(end) )

6315

if ( fin(end)<fout(end) )

6327

% warning('Channel high frequencies extrapolation might be inaccurate!');

6316

% warning('Channel high frequencies extrapolation might be inaccurate!');

6328

end

6317

end

6329

6318

6330

H_mag = abs(Sin);

6319

H_mag = abs(Sin);

6331

H_mag(H_mag<eps)=eps; % handle ill cases...

6320

H_mag(H_mag<eps)=eps; % handle ill cases...

6332

H_ph = unwrap(angle(Sin));

6321

H_ph = unwrap(angle(Sin));

6333

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6322

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6334

% user ignore that.

6323

% user ignore that.

6335

if mean(diff(H_ph))>0

6324

if mean(diff(H_ph))>0

6336

if OP.DEBUG

6325

if OP.DEBUG

6337

warning('Anti-causal response found. Finer frequency step is required for this channel');

6326

warning('Anti-causal response found. Finer frequency step is required for this channel');

6338

else

6327

else

6339

error('Anti-causal response found. Finer frequency step is required for this channel');

6328

error('Anti-causal response found. Finer frequency step is required for this channel');

6340

end

6329

end

6341

end

6330

end

6342

6331

6343

%opt_interp_Sparam_mag='linear_trend_to_DC';

6332

%opt_interp_Sparam_mag='linear_trend_to_DC';

6344

switch opt_interp_Sparam_mag

6333

switch opt_interp_Sparam_mag

6345

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6334

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6346

if -iscolumn(H_mag), H_mag=H_mag.';end

6335

if -iscolumn(H_mag), H_mag=H_mag.';end

6347

if -iscolumn(fin), fin=fin.';end

6336

if -iscolumn(fin), fin=fin.';end

6348

fin_x=fin;

6337

fin_x=fin;

6349

H_mag_x=H_mag(:);

6338

H_mag_x=H_mag(:);

6350

if fin(1)>0

6339

if fin(1)>0

6351

p=polyfit(fin(1:10), H_mag(1:10), 1);

6340

p=polyfit(fin(1:10), H_mag(1:10), 1);

6352

dc_trend_val=polyval(p, 0);

6341

dc_trend_val=polyval(p, 0);

6353

fin_x=[0, fin_x];

6342

fin_x=[0, fin_x];

6354

H_mag_x = [dc_trend_val; H_mag_x];

6343

H_mag_x = [dc_trend_val; H_mag_x];

6355

end

6344

end

6356

if fin(end)<fout(end)

6345

if fin(end)<fout(end)

6357

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6346

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6358

mid_freq_ind=round(length(fin)/2);

6347

mid_freq_ind=round(length(fin)/2);

6359

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6348

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6360

warning(warn_state);

6349

warning(warn_state);

6361

hf_trend_val=polyval(p, fout(end));

6350

hf_trend_val=polyval(p, fout(end));

6362

if hf_trend_val>H_mag(end)

6351

if hf_trend_val>H_mag(end)

6363

hf_trend_val=H_mag(end);

6352

hf_trend_val=H_mag(end);

6364

hf_logtrend_val = H_mag(end);

6353

hf_logtrend_val = H_mag(end);

6365

elseif hf_trend_val<eps

6354

elseif hf_trend_val<eps

6366

hf_trend_val=eps;

6355

hf_trend_val=eps;

6367

hf_logtrend_val = realmin;

6356

hf_logtrend_val = realmin;

6368

end

6357

end

6369

fin_x=[fin_x, fout(end)];

6358

fin_x=[fin_x, fout(end)];

6370

H_mag_x = [H_mag_x; hf_trend_val];

6359

H_mag_x = [H_mag_x; hf_trend_val];

6371

end

6360

end

6372

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6361

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6373

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6362

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6374

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6363

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6375

indx = find(fout > fin(end),1,'first');

6364

indx = find(fout > fin(end),1,'first');

6376

H_mag_i(indx:end) = H_logmag_i(indx:end);

6365

H_mag_i(indx:end) = H_logmag_i(indx:end);

6377

end

6366

end

6378

case 'trend_to_DC'

6367

case 'trend_to_DC'

6379

% extrapolate to trend value at DC.

6368

% extrapolate to trend value at DC.

6380

if -iscolumn(H_mag), H_mag=H_mag.';end

6369

if -iscolumn(H_mag), H_mag=H_mag.';end

6381

if -iscolumn(fin), fin=fin.';end

6370

if -iscolumn(fin), fin=fin.';end

6382

fin_x=fin;

6371

fin_x=fin;

6383

H_mag_x=H_mag;

6372

H_mag_x=H_mag;

6384

if fin(1)>0

6373

if fin(1)>0

6385

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6374

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6386

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6375

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6387

dc_trend_val=10^polyval(p, 0);

6376

dc_trend_val=10^polyval(p, 0);

6388

fin_x=[0, fin_x];

6377

fin_x=[0, fin_x];

6389

H_mag_x = [dc_trend_val H_mag_x];

6378

H_mag_x = [dc_trend_val H_mag_x];

6390

end

6379

end

6391

if fin(end)<fout(end)

6380

if fin(end)<fout(end)

6392

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6381

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6393

mid_freq_ind=round(length(fin)/2);

6382

mid_freq_ind=round(length(fin)/2);

6394

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6383

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6395

warning(warn_state);

6384

warning(warn_state);

6396

hf_trend_val=10^polyval(p, fout(end));

6385

hf_trend_val=10^polyval(p, fout(end));

6397

if hf_trend_val>H_mag(end)

6386

if hf_trend_val>H_mag(end)

6398

hf_trend_val=H_mag(end);

6387

hf_trend_val=H_mag(end);

6399

end

6388

end

6400

fin_x=[fin_x, fout(end)];

6389

fin_x=[fin_x, fout(end)];

6401

H_mag_x = [H_mag_x hf_trend_val];

6390

H_mag_x = [H_mag_x hf_trend_val];

6402

end

6391

end

6403

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6392

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6404

case 'extrap_to_DC_or_zero'

6393

case 'extrap_to_DC_or_zero'

6405

% same as extrap_to_DC but detect AC-coupled channels and

6394

% same as extrap_to_DC but detect AC-coupled channels and

6406

% extrapolate them to 0.

6395

% extrapolate them to 0.

6407

if fin(1)>0 && 20*log10(H_mag(1))<-20

6396

if fin(1)>0 && 20*log10(H_mag(1))<-20

6408

% assume AC coupling, with 0 at DC

6397

% assume AC coupling, with 0 at DC

6409

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6398

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6410

else

6399

else

6411

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6400

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6412

end

6401

end

6413

H_mag_i(fout>fin(end)) = H_mag(end);

6402

H_mag_i(fout>fin(end)) = H_mag(end);

6414

case 'extrap_to_DC'

6403

case 'extrap_to_DC'

6415

% first extrapolate down to DC, then use highest available frequency

6404

% first extrapolate down to DC, then use highest available frequency

6416

% for higher frequencies

6405

% for higher frequencies

6417

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6406

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6418

H_mag_i(fout>fin(end)) = H_mag(end);

6407

H_mag_i(fout>fin(end)) = H_mag(end);

6419

case 'old'

6408

case 'old'

6420

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6409

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6421

otherwise

6410

otherwise

6422

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6411

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6423

end

6412

end

6424

6413

6425

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6414

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6426

6415

6427

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6416

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6428

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6417

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6429

switch opt_interp_Sparam_phase

6418

switch opt_interp_Sparam_phase

6430

case 'old'

6419

case 'old'

6431

H_ph_i = H_ph_i-H_ph_i(1);

6420

H_ph_i = H_ph_i-H_ph_i(1);

6432

case 'zero_DC'

6421

case 'zero_DC'

6433

H_ph_i(1) = 0;

6422

H_ph_i(1) = 0;

6434

case 'interp_to_DC'

6423

case 'interp_to_DC'

6435

if fin(1) ~= 0

6424

if fin(1) ~= 0

6436

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6425

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6437

end

6426

end

6438

case 'extrap_cubic_to_dc_linear_to_inf'

6427

case 'extrap_cubic_to_dc_linear_to_inf'

6439

if fin(1) ~= 0

6428

if fin(1) ~= 0

6440

% estimate low frequency group delay

6429

% estimate low frequency group delay

6441

group_delay = -diff(H_ph(:))./diff(fin(:));

6430

group_delay = -diff(H_ph(:))./diff(fin(:));

6442

low_freq_gd = group_delay(1:50);

6431

low_freq_gd = group_delay(1:50);

6443

% calculate trend, throwing away outliers

6432

% calculate trend, throwing away outliers

6444

m = median(low_freq_gd); sigma = std(low_freq_gd);

6433

m = median(low_freq_gd); sigma = std(low_freq_gd);

6445

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6434

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6446

% correct outliers in first 10 phase samples

6435

% correct outliers in first 10 phase samples

6447

for k=10:-1:1

6436

for k=10:-1:1

6448

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6437

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6449

end

6438

end

6450

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6439

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6451

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6440

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6452

% modification - trend to inf

6441

% modification - trend to inf

6453

if (1)

6442

if (1)

6454

high_freq_gd = group_delay(end-50:end);

6443

high_freq_gd = group_delay(end-50:end);

6455

% calculate trend, throwing away outliers

6444

% calculate trend, throwing away outliers

6456

m = median(high_freq_gd); sigma = std(high_freq_gd);

6445

m = median(high_freq_gd); sigma = std(high_freq_gd);

6457

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6446

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6458

hf_extrap_range = find(fout>fin(end));

6447

hf_extrap_range = find(fout>fin(end));

6459

last_data_sample = hf_extrap_range(1)-1;

6448

last_data_sample = hf_extrap_range(1)-1;

6460

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6449

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6461

% for k=hf_range

6450

% for k=hf_range

6462

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6451

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6463

% end

6452

% end

6464

end

6453

end

6465

6454

6466

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6455

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6467

H_ph_i=H_ph_cubic;

6456

H_ph_i=H_ph_cubic;

6468

H_ph_i(indx:end) = H_ph_linear(indx:end);

6457

H_ph_i(indx:end) = H_ph_linear(indx:end);

6469

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6458

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6470

end

6459

end

6471

case 'interp_and_shift_to_DC'

6460

case 'interp_and_shift_to_DC'

6472

if fin(1) ~= 0

6461

if fin(1) ~= 0

6473

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6462

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6474

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6463

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6475

end

6464

end

6476

case 'trend_and_shift_to_DC'

6465

case 'trend_and_shift_to_DC'

6477

% estimate low frequency group delay

6466

% estimate low frequency group delay

6478

group_delay = -diff(H_ph(:))./diff(fin(:));

6467

group_delay = -diff(H_ph(:))./diff(fin(:));

6479

low_freq_gd = group_delay(1:50);

6468

low_freq_gd = group_delay(1:50);

6480

% calculate trend, throwing away outliers

6469

% calculate trend, throwing away outliers

6481

m = median(low_freq_gd); sigma = std(low_freq_gd);

6470

m = median(low_freq_gd); sigma = std(low_freq_gd);

6482

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6471

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6483

fin_x=fin;

6472

fin_x=fin;

6484

H_ph_x=H_ph(:);

6473

H_ph_x=H_ph(:);

6485

if fin(1) ~= 0

6474

if fin(1) ~= 0

6486

% correct outliers in first 10 phase samples

6475

% correct outliers in first 10 phase samples

6487

for k=10:-1:1

6476

for k=10:-1:1

6488

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6477

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6489

end

6478

end

6490

6479

6491

% shift all phase data so that DC extrapolation to 0 follows trend

6480

% shift all phase data so that DC extrapolation to 0 follows trend

6492

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6481

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6493

fin_x=[0, fin_x];

6482

fin_x=[0, fin_x];

6494

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6483

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6495

end

6484

end

6496

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6485

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6497

% the last two samples, so noise can create an inverted slope and

6486

% the last two samples, so noise can create an inverted slope and

6498

% non-causal response).

6487

% non-causal response).

6499

if fout(end)>fin(end)

6488

if fout(end)>fin(end)

6500

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6489

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6501

% p=polyfit(fin_x', H_ph_x, 1);

6490

% p=polyfit(fin_x', H_ph_x, 1);

6502

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6491

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6503

% hf_phase_trend=polyval(p,max(fout));

6492

% hf_phase_trend=polyval(p,max(fout));

6504

fin_x=[fin_x, fout(end)];

6493

fin_x=[fin_x, fout(end)];

6505

H_ph_x=[H_ph_x; hf_phase_trend];

6494

H_ph_x=[H_ph_x; hf_phase_trend];

6506

end

6495

end

6507

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6496

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6508

6497

6509

otherwise

6498

otherwise

6510

error('COM:Extrap:InvalidOption', ...

6499

error('COM:Extrap:InvalidOption', ...

6511

'debug_interp_Sparam valid values are "old", "zero_DC", "interp_to_DC", "interp_and_shift_to_DC", "trend_and_shift_to_DC", "interp_cubic_to_dc_linear_to_inf"');

6500

'debug_interp_Sparam valid values are "old", "zero_DC", "interp_to_DC", "interp_and_shift_to_DC", "trend_and_shift_to_DC", "interp_cubic_to_dc_linear_to_inf"');

6512

end

6501

end

6513

H_i = H_mag_i.*exp(1j*H_ph_i);

6502

H_i = H_mag_i.*exp(1j*H_ph_i);

6514

Sout=H_i;

6503

Sout=H_i;

6515

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6504

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6516

6505

6517

%This function makes the TX or RX package. The type input must be

6506

%This function makes the TX or RX package. The type input must be

6518

%'TX' or 'RX'

6507

%'TX' or 'RX'

6519

%If the mode argument is omitted, mode='dd' is assumed. Currently

6508

%If the mode argument is omitted, mode='dd' is assumed. Currently

6520

%mode='dc' is only used when making the TX package for AC CM noise

6509

%mode='dc' is only used when making the TX package for AC CM noise

6521

%inclusion. The Rx package for 'dc' mode is still generated using

6510

%inclusion. The Rx package for 'dc' mode is still generated using

6522

%the same parameters as 'dd' mode

6511

%the same parameters as 'dd' mode

6523

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6512

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6524

%

6513

%

6525

%One instance of package block looks like this (if no elements are set to 0):

6514

%One instance of package block looks like this (if no elements are set to 0):

6526

%-------------Lcomp----------Tline---------------

6515

%-------------Lcomp----------Tline---------------

6527

% | | |

6516

% | | |

6528

% Cpad Cbump Cball

6517

% Cpad Cbump Cball

6529

% | | |

6518

% | | |

6530

%------------------------------------------------

6519

%------------------------------------------------

6531

6520

6532

if nargin<6

6521

if nargin<6

6533

%optional input "include_die"=0 allows die parameters to be forced to 0

6522

%optional input "include_die"=0 allows die parameters to be forced to 0

6534

%this includes Cpad, Lcomp, and Cbump

6523

%this includes Cpad, Lcomp, and Cbump

6535

include_die=1;

6524

include_die=1;

6536

end

6525

end

6537

if nargin<5

6526

if nargin<5

6538

mode='dd';

6527

mode='dd';

6539

end

6528

end

6540

6529

6541

6530

6542

if ~isempty(param.PKG_NAME)

6531

if ~isempty(param.PKG_NAME)

6543

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6532

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6544

%so they are swapped in depending on if Tx or Rx is set for type

6533

%so they are swapped in depending on if Tx or Rx is set for type

6545

%Note that param is not returned from this function, so the swap does not persist

6534

%Note that param is not returned from this function, so the swap does not persist

6546

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6535

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6547

if strcmpi(type,'tx')

6536

if strcmpi(type,'tx')

6548

pkg_name = param.PKG_NAME{1};

6537

pkg_name = param.PKG_NAME{1};

6549

elseif strcmpi(type,'rx')

6538

elseif strcmpi(type,'rx')

6550

pkg_name = param.PKG_NAME{2};

6539

pkg_name = param.PKG_NAME{2};

6551

else

6540

else

6552

error('Pkg type must be Tx or Rx');

6541

error('Pkg type must be Tx or Rx');

6553

end

6542

end

6554

pkg_parameter_struct = param.PKG.(pkg_name);

6543

pkg_parameter_struct = param.PKG.(pkg_name);

6555

6544

6556

6545

6557

for j=1:length(swap_fields)

6546

for j=1:length(swap_fields)

6558

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6547

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6559

end

6548

end

6560

6549

6561

end

6550

end

6562

6551

6563

C_diepad = param.C_diepad;

6552

C_diepad = param.C_diepad;

6564

C_pkg_board = param.C_pkg_board;

6553

C_pkg_board = param.C_pkg_board;

6565

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6554

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6566

L_comp = param.L_comp;

6555

L_comp = param.L_comp;

6567

C_bump = param.C_bump;

6556

C_bump = param.C_bump;

6568

if ~include_die

6557

if ~include_die

6569

%best to multiply by 0. that way vectors maintain original size

6558

%best to multiply by 0. that way vectors maintain original size

6570

C_diepad=C_diepad*0;

6559

C_diepad=C_diepad*0;

6571

L_comp=L_comp*0;

6560

L_comp=L_comp*0;

6572

C_bump=C_bump*0;

6561

C_bump=C_bump*0;

6573

end

6562

end

6574

% [ahealey] End of modifications.

6563

% [ahealey] End of modifications.

6575

% generate TX package according to channel type.

6564

% generate TX package according to channel type.

6576

[ncases, mele]=size(param.z_p_next_cases);

6565

[ncases, mele]=size(param.z_p_next_cases);

6577

6566

6578

%Syntax update for C_diepad and L_comp

6567

%Syntax update for C_diepad and L_comp

6579

%Allow a chain of values to be entered as a matrix:

6568

%Allow a chain of values to be entered as a matrix:

6580

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6569

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6581

if isvector(C_diepad)

6570

if isvector(C_diepad)

6582

Cd_Tx=C_diepad(1);

6571

Cd_Tx=C_diepad(1);

6583

Cd_Rx=C_diepad(2);

6572

Cd_Rx=C_diepad(2);

6584

L_comp_Tx=L_comp(1);

6573

L_comp_Tx=L_comp(1);

6585

L_comp_Rx=L_comp(2);

6574

L_comp_Rx=L_comp(2);

6586

num_blocks=mele;

6575

num_blocks=mele;

6587

else

6576

else

6588

Cd_Tx=C_diepad(1,:);

6577

Cd_Tx=C_diepad(1,:);

6589

Cd_Rx=C_diepad(2,:);

6578

Cd_Rx=C_diepad(2,:);

6590

L_comp_Tx=L_comp(1,:);

6579

L_comp_Tx=L_comp(1,:);

6591

L_comp_Rx=L_comp(2,:);

6580

L_comp_Rx=L_comp(2,:);

6592

num_blocks=mele+length(Cd_Tx)-1;

6581

num_blocks=mele+length(Cd_Tx)-1;

6593

end

6582

end

6594

extra_LC=length(Cd_Tx)-1;

6583

extra_LC=length(Cd_Tx)-1;

6595

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6584

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6596

insert_zeros=zeros([1 extra_LC]);

6585

insert_zeros=zeros([1 extra_LC]);

6597

6586

6598

%Updated technique of building Tx/Rx packages

6587

%Updated technique of building Tx/Rx packages

6599

%each index corresponds to the package segment

6588

%each index corresponds to the package segment

6600

switch type

6589

switch type

6601

case 'TX'

6590

case 'TX'

6602

switch mele

6591

switch mele

6603

case 1

6592

case 1

6604

Cpad=Cd_Tx;

6593

Cpad=Cd_Tx;

6605

Lcomp=L_comp_Tx;

6594

Lcomp=L_comp_Tx;

6606

Cbump=C_bump(1);

6595

Cbump=C_bump(1);

6607

Cball=C_pkg_board(1);

6596

Cball=C_pkg_board(1);

6608

Zpkg=param.pkg_Z_c(1);

6597

Zpkg=param.pkg_Z_c(1);

6609

case 4

6598

case 4

6610

Cpad=[Cd_Tx 0 0 0];

6599

Cpad=[Cd_Tx 0 0 0];

6611

Lcomp=[L_comp_Tx 0 0 0];

6600

Lcomp=[L_comp_Tx 0 0 0];

6612

Cbump=[C_bump(1) 0 0 0];

6601

Cbump=[C_bump(1) 0 0 0];

6613

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6602

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6614

Zpkg=param.pkg_Z_c(1,:);

6603

Zpkg=param.pkg_Z_c(1,:);

6615

otherwise

6604

otherwise

6616

error('package syntax error')

6605

error('package syntax error')

6617

end

6606

end

6618

switch upper(channel_type)

6607

switch upper(channel_type)

6619

case 'THRU'

6608

case 'THRU'

6620

Len=param.Pkg_len_TX;

6609

Len=param.Pkg_len_TX;

6621

case 'NEXT'

6610

case 'NEXT'

6622

Len=param.Pkg_len_NEXT;

6611

Len=param.Pkg_len_NEXT;

6623

case 'FEXT'

6612

case 'FEXT'

6624

Len=param.Pkg_len_FEXT;

6613

Len=param.Pkg_len_FEXT;

6625

end

6614

end

6626

case 'RX'

6615

case 'RX'

6627

switch mele

6616

switch mele

6628

case 1

6617

case 1

6629

Cpad=Cd_Rx;

6618

Cpad=Cd_Rx;

6630

Lcomp=L_comp_Rx;

6619

Lcomp=L_comp_Rx;

6631

Cbump=C_bump(2);

6620

Cbump=C_bump(2);

6632

Cball=C_pkg_board(2);

6621

Cball=C_pkg_board(2);

6633

Zpkg=param.pkg_Z_c(2);

6622

Zpkg=param.pkg_Z_c(2);

6634

case 4

6623

case 4

6635

Cpad=[Cd_Rx 0 0 0];

6624

Cpad=[Cd_Rx 0 0 0];

6636

Lcomp=[L_comp_Rx 0 0 0];

6625

Lcomp=[L_comp_Rx 0 0 0];

6637

Cbump=[C_bump(2) 0 0 0];

6626

Cbump=[C_bump(2) 0 0 0];

6638

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6627

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6639

Zpkg=param.pkg_Z_c(2,:);

6628

Zpkg=param.pkg_Z_c(2,:);

6640

otherwise

6629

otherwise

6641

error('package syntax error')

6630

error('package syntax error')

6642

end

6631

end

6643

switch upper(channel_type)

6632

switch upper(channel_type)

6644

case 'THRU'

6633

case 'THRU'

6645

Len=param.Pkg_len_RX;

6634

Len=param.Pkg_len_RX;

6646

case 'NEXT'

6635

case 'NEXT'

6647

Len=param.Pkg_len_RX;

6636

Len=param.Pkg_len_RX;

6648

case 'FEXT'

6637

case 'FEXT'

6649

Len=param.Pkg_len_RX;

6638

Len=param.Pkg_len_RX;

6650

end

6639

end

6651

end

6640

end

6652

6641

6653

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6642

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6654

Cball=[insert_zeros Cball];

6643

Cball=[insert_zeros Cball];

6655

Cbump=[insert_zeros Cbump];

6644

Cbump=[insert_zeros Cbump];

6656

Len=[insert_zeros Len];

6645

Len=[insert_zeros Len];

6657

Zpkg=[insert_zeros Zpkg];

6646

Zpkg=[insert_zeros Zpkg];

6658

6647

6659

% debug_string='';

6648

% debug_string='';

6660

% for j=1:length(Zpkg)

6649

% for j=1:length(Zpkg)

6661

% if Cpad(j)~=0

6650

% if Cpad(j)~=0

6662

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6651

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6663

% end

6652

% end

6664

% if Lcomp(j)~=0

6653

% if Lcomp(j)~=0

6665

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6654

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6666

% end

6655

% end

6667

% if Cbump(j)~=0

6656

% if Cbump(j)~=0

6668

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6657

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6669

% end

6658

% end

6670

% if Len(j)~=0

6659

% if Len(j)~=0

6671

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6660

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6672

% end

6661

% end

6673

% if Cball(j)~=0

6662

% if Cball(j)~=0

6674

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6663

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6675

% end

6664

% end

6676

% end

6665

% end

6677

% if length(debug_string)>2

6666

% if length(debug_string)>2

6678

% debug_string=debug_string(3:end);

6667

% debug_string=debug_string(3:end);

6679

% end

6668

% end

6680

6669

6681

% tx package

6670

% tx package

6682

pkg_param=param;

6671

pkg_param=param;

6683

if strcmpi(mode,'dc')

6672

if strcmpi(mode,'dc')

6684

% change tx package to CC mode

6673

% change tx package to CC mode

6685

pkg_param.Z0=pkg_param.Z0/2;

6674

pkg_param.Z0=pkg_param.Z0/2;

6686

Cpad=Cpad*2;

6675

Cpad=Cpad*2;

6687

Cball=Cball*2;

6676

Cball=Cball*2;

6688

Zpkg=Zpkg*2;

6677

Zpkg=Zpkg*2;

6689

Lcomp=Lcomp/2;

6678

Lcomp=Lcomp/2;

6690

Cbump=Cbump*2;

6679

Cbump=Cbump*2;

6691

end

6680

end

6692

switch num_blocks

6681

switch num_blocks

6693

case 1

6682

case 1

6694

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6683

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6695

otherwise

6684

otherwise

6696

for j=1:num_blocks

6685

for j=1:num_blocks

6697

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6686

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6698

if j==1

6687

if j==1

6699

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6688

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6700

else

6689

else

6701

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6690

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6702

end

6691

end

6703

end

6692

end

6704

end

6693

end

6705

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6694

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6706

f(f<eps)=eps;

6695

f(f<eps)=eps;

6707

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6696

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6708

%% Equation 93A-8

6697

%% Equation 93A-8

6709

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6698

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6710

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6699

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6711

6700

6712

% [ahealey] Add compensating L and shunt C (bump) when requested.

6701

% [ahealey] Add compensating L and shunt C (bump) when requested.

6713

s12pad = s21pad;

6702

s12pad = s21pad;

6714

s22pad = s11pad;

6703

s22pad = s11pad;

6715

if nargin > 6

6704

if nargin > 6

6716

lcomp = varargin{1};

6705

lcomp = varargin{1};

6717

if lcomp>0

6706

if lcomp>0

6718

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6707

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6719

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6708

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6720

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6709

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6721

s11pad, s12pad, s21pad, s22pad, ...

6710

s11pad, s12pad, s21pad, s22pad, ...

6722

s11comp, s21comp, s21comp, s11comp);

6711

s11comp, s21comp, s21comp, s11comp);

6723

end

6712

end

6724

end

6713

end

6725

if nargin > 7

6714

if nargin > 7

6726

cbump = varargin{2};

6715

cbump = varargin{2};

6727

if cbump>0

6716

if cbump>0

6728

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

6717

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

6729

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

6718

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

6730

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6719

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6731

s11pad, s12pad, s21pad, s22pad, ...

6720

s11pad, s12pad, s21pad, s22pad, ...

6732

s11bump, s21bump, s21bump, s11bump);

6721

s11bump, s21bump, s21bump, s11bump);

6733

end

6722

end

6734

end

6723

end

6735

% [ahealey] End of modifications.

6724

% [ahealey] End of modifications.

6736

6725

6737

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

6726

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

6738

% [ahealey] Symmetry cannot be assumed with more complex termination models.

6727

% [ahealey] Symmetry cannot be assumed with more complex termination models.

6739

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

6728

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

6740

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

6729

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

6741

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

6730

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

6742

s11pad, s12pad, s21pad, s22pad, ...

6731

s11pad, s12pad, s21pad, s22pad, ...

6743

S11, S21, S21, S11);

6732

S11, S21, S21, S11);

6744

% [ahealey] End of modifications.

6733

% [ahealey] End of modifications.

6745

6734

6746

%% Equation 93A-8

6735

%% Equation 93A-8

6747

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

6736

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

6748

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

6737

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

6749

[ s11out, s12out, s21out, s22out ]= ...

6738

[ s11out, s12out, s21out, s22out ]= ...

6750

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

6739

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

6751

6740

6752

function missingParameter (parameterName)

6741

function missingParameter (parameterName)

6753

error( 'error:badParameterInformation', ...

6742

error( 'error:badParameterInformation', ...

6754

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

6743

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

6755

6744

6756

function pdf = normal_dist(sigma,nsigma,binsize)

6745

function pdf = normal_dist(sigma,nsigma,binsize)

6757

pdf.BinSize=binsize;

6746

pdf.BinSize=binsize;

6758

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

6747

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

6759

pdf.x=(pdf.Min:-pdf.Min)*binsize;

6748

pdf.x=(pdf.Min:-pdf.Min)*binsize;

6760

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

6749

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

6761

pdf.y=pdf.y/sum(pdf.y);

6750

pdf.y=pdf.y/sum(pdf.y);

6762

6751

6763

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

6752

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

6764

%% input

6753

%% input

6765

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

6754

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

6766

% baud_rate - baud rate in seconds

6755

% baud_rate - baud rate in seconds

6767

% param.samples_per_ui = samples per UI of IR

6756

% param.samples_per_ui = samples per UI of IR

6768

% param.max_ctle - maximum ac to dc gain in dB

6757

% param.max_ctle - maximum ac to dc gain in dB

6769

% param.tx_ffe(1) - maximum pre cursor (positive value)

6758

% param.tx_ffe(1) - maximum pre cursor (positive value)

6770

% param.tx_ffe(2) - maximum post cursor (positive value)

6759

% param.tx_ffe(2) - maximum post cursor (positive value)

6771

% param.tx_ffe_step - sweep step size for tx pre and post taps

6760

% param.tx_ffe_step - sweep step size for tx pre and post taps

6772

% param.ndfe - number of reference dfe taps

6761

% param.ndfe - number of reference dfe taps

6773

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

6762

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

6774

% output

6763

% output

6775

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

6764

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

6776

% result.eq.ctle - index of CTLE parameters in table

6765

% result.eq.ctle - index of CTLE parameters in table

6777

% result.IR - impulse response

6766

% result.IR - impulse response

6778

% result.avail_signal - maximum signal after equalization

6767

% result.avail_signal - maximum signal after equalization

6779

% result.avail_sig_index - index in result.IR of max signal

6768

% result.avail_sig_index - index in result.IR of max signal

6780

% result.best_FOM - best raw ISI

6769

% result.best_FOM - best raw ISI

6781

6770

6782

min_number_of_UI_in_response=40;

6771

min_number_of_UI_in_response=40;

6783

baud_rate=1/param.ui;

6772

baud_rate=1/param.ui;

6784

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

6773

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

6785

f=chdata(1).faxis;

6774

f=chdata(1).faxis;

6786

6775

6787

%Read user input of ts_sample_adj_range

6776

%Read user input of ts_sample_adj_range

6788

%if one value was entered, go from 0 to that value

6777

%if one value was entered, go from 0 to that value

6789

%if 2 values were entered, go from the 1st value to the 2nd value

6778

%if 2 values were entered, go from the 1st value to the 2nd value

6790

if length(param.ts_sample_adj_range)==1

6779

if length(param.ts_sample_adj_range)==1

6791

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

6780

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

6792

param.ts_sample_adj_range(1)=0;

6781

param.ts_sample_adj_range(1)=0;

6793

end

6782

end

6794

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

6783

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

6795

6784

6796

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

6785

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

6797

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

6786

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

6798

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

6787

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

6799

% need to include H_RCos in noise and when computing the system ir for thru

6788

% need to include H_RCos in noise and when computing the system ir for thru

6800

% and crosstalk

6789

% and crosstalk

6801

H_r=H_bw.*H_bt.*H_RCos;

6790

H_r=H_bw.*H_bt.*H_RCos;

6802

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

6791

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

6803

% Get f vector from 0 to Fs/2-delta_f.

6792

% Get f vector from 0 to Fs/2-delta_f.

6804

N_fft_by2 = 512;

6793

N_fft_by2 = 512;

6805

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

6794

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

6806

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

6795

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

6807

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

6796

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

6808

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

6797

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

6809

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

6798

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

6810

%%

6799

%%

6811

6800

6812

% system noise H_sy PSD

6801

% system noise H_sy PSD

6813

if OP.USE_ETA0_PSD

6802

if OP.USE_ETA0_PSD

6814

fspike=1e9;

6803

fspike=1e9;

6815

% requires communication tool box if used

6804

% requires communication tool box if used

6816

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

6805

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

6817

else

6806

else

6818

H_sy=ones(1,length(chdata(1).faxis));

6807

H_sy=ones(1,length(chdata(1).faxis));

6819

end

6808

end

6820

6809

6821

%Build txffe values dynamically

6810

%Build txffe values dynamically

6822

%any param field that is "tx_ffe_cm<X>_values" is a precursor

6811

%any param field that is "tx_ffe_cm<X>_values" is a precursor

6823

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

6812

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

6824

%where <X> is any integer

6813

%where <X> is any integer

6825

param_fields=fieldnames(param);

6814

param_fields=fieldnames(param);

6826

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

6815

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

6827

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

6816

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

6828

num_taps=num_pre+num_post;

6817

num_taps=num_pre+num_post;

6829

cur=num_pre+1;

6818

cur=num_pre+1;

6830

%txffe_cell combines all the txffe values into a single cell array

6819

%txffe_cell combines all the txffe values into a single cell array

6831

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

6820

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

6832

txffe_cell=cell(1,num_taps);

6821

txffe_cell=cell(1,num_taps);

6833

for k=num_pre:-1:1

6822

for k=num_pre:-1:1

6834

idx=num_pre-k+1;

6823

idx=num_pre-k+1;

6835

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

6824

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

6836

txffe_cell{idx}=param.(this_tx_field);

6825

txffe_cell{idx}=param.(this_tx_field);

6837

end

6826

end

6838

for k=1:num_post

6827

for k=1:num_post

6839

idx=k+num_pre;

6828

idx=k+num_pre;

6840

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

6829

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

6841

txffe_cell{idx}=param.(this_tx_field);

6830

txffe_cell{idx}=param.(this_tx_field);

6842

end

6831

end

6843

%total number of txffe runs is the product of the lengths of each tap

6832

%total number of txffe runs is the product of the lengths of each tap

6844

txffe_lengths=cellfun('length',txffe_cell);

6833

txffe_lengths=cellfun('length',txffe_cell);

6845

if isempty(txffe_cell)

6834

if isempty(txffe_cell)

6846

num_txffe_runs=1;

6835

num_txffe_runs=1;

6847

else

6836

else

6848

num_txffe_runs=prod(txffe_lengths);

6837

num_txffe_runs=prod(txffe_lengths);

6849

end

6838

end

6850

%txffe_sweep_indices are used in the LOCAL_SEARCH block

6839

%txffe_sweep_indices are used in the LOCAL_SEARCH block

6851

%any tap with length=1 can be ignored

6840

%any tap with length=1 can be ignored

6852

%Also is statistically likely that taps with greater number of values

6841

%Also is statistically likely that taps with greater number of values

6853

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

6842

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

6854

txffe_sweep_indices=find(txffe_lengths>1);

6843

txffe_sweep_indices=find(txffe_lengths>1);

6855

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

6844

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

6856

txffe_sweep_indices=txffe_sweep_indices(length_sort);

6845

txffe_sweep_indices=txffe_sweep_indices(length_sort);

6857

num_txffe_sweep_indices=length(txffe_sweep_indices);

6846

num_txffe_sweep_indices=length(txffe_sweep_indices);

6858

6847

6859

gdc_values = param.ctle_gdc_values;

6848

gdc_values = param.ctle_gdc_values;

6860

Gffe_values = param.cursor_gain;

6849

Gffe_values = param.cursor_gain;

6861

switch param.CTLE_type

6850

switch param.CTLE_type

6862

case 'CL93'

6851

case 'CL93'

6863

case 'CL120d'

6852

case 'CL120d'

6864

g_DC_HP_values =param.g_DC_HP_values;

6853

g_DC_HP_values =param.g_DC_HP_values;

6865

case 'CL120e'

6854

case 'CL120e'

6866

f_HP_Z=param.f_HP_Z;

6855

f_HP_Z=param.f_HP_Z;

6867

f_HP_P=param.f_HP_P;

6856

f_HP_P=param.f_HP_P;

6868

6857

6869

end

6858

end

6870

best_ctle = [];

6859

best_ctle = [];

6871

best_FOM = -inf;

6860

best_FOM = -inf;

6872

best_txffe = [];

6861

best_txffe = [];

6873

delta_sbr = [];

6862

delta_sbr = [];

6874

PSD_results=[];

6863

PSD_results=[];

6875

MMSE_results=[];

6864

MMSE_results=[];

6876

best_bmax=param.bmax;

6865

best_bmax=param.bmax;

6877

%AJG021820

6866

%AJG021820

6878

best_bmin=param.bmin;

6867

best_bmin=param.bmin;

6879

h_J=[];

6868

h_J=[];

6880

pxi=0;

6869

pxi=0;

6881

if OP.DISPLAY_WINDOW

6870

if OP.DISPLAY_WINDOW

6882

hwaitbar=waitbar(0);

6871

hwaitbar=waitbar(0);

6883

else

6872

else

6884

fprintf('FOM search ');

6873

fprintf('FOM search ');

6885

end

6874

end

6886

FOM=0;

6875

FOM=0;

6887

if ~OP.RxFFE

6876

if ~OP.RxFFE

6888

Gffe_values=0;

6877

Gffe_values=0;

6889

end

6878

end

6890

param.ndfe_passed=param.ndfe;

6879

param.ndfe_passed=param.ndfe;

6891

old_loops=0;

6880

old_loops=0;

6892

new_loops=0;

6881

new_loops=0;

6893

6882

6894

%GDC Qual construction

6883

%GDC Qual construction

6895

gqual= param.gqual;

6884

gqual= param.gqual;

6896

g2qual=param.g2qual;

6885

g2qual=param.g2qual;

6897

if ~strcmp(param.CTLE_type,'CL120d')

6886

if ~strcmp(param.CTLE_type,'CL120d')

6898

qual=ones(1,length(gdc_values));

6887

qual=ones(1,length(gdc_values));

6899

else

6888

else

6900

if isempty(gqual) && isempty(g2qual)

6889

if isempty(gqual) && isempty(g2qual)

6901

qual=ones(length(g_DC_HP_values),length(gdc_values));

6890

qual=ones(length(g_DC_HP_values),length(gdc_values));

6902

else

6891

else

6903

qual=zeros(length(g_DC_HP_values),length(gdc_values));

6892

qual=zeros(length(g_DC_HP_values),length(gdc_values));

6904

6893

6905

%prepare gqual and g2qual

6894

%prepare gqual and g2qual

6906

[g2qual,si]=sort(g2qual,'descend');

6895

[g2qual,si]=sort(g2qual,'descend');

6907

gqual=gqual(si,:);

6896

gqual=gqual(si,:);

6908

tmp=g2qual;

6897

tmp=g2qual;

6909

g2qual=zeros(length(tmp),2);

6898

g2qual=zeros(length(tmp),2);

6910

for kk=1:length(tmp)

6899

for kk=1:length(tmp)

6911

if kk==1

6900

if kk==1

6912

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

6901

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

6913

else

6902

else

6914

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

6903

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

6915

end

6904

end

6916

gqual(kk,:)=sort(gqual(kk,:),'descend');

6905

gqual(kk,:)=sort(gqual(kk,:),'descend');

6917

end

6906

end

6918

6907

6919

%Qual Construction

6908

%Qual Construction

6920

for jj=1:length(g_DC_HP_values)

6909

for jj=1:length(g_DC_HP_values)

6921

for ii=1:length(gdc_values)

6910

for ii=1:length(gdc_values)

6922

for kk=1:size(gqual,1)

6911

for kk=1:size(gqual,1)

6923

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

6912

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

6924

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

6913

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

6925

qual(jj,ii)=1;

6914

qual(jj,ii)=1;

6926

break;

6915

break;

6927

end

6916

end

6928

end

6917

end

6929

end

6918

end

6930

end

6919

end

6931

end

6920

end

6932

end

6921

end

6933

end

6922

end

6934

6923

6935

progress_interval=0.025;

6924

progress_interval=0.025;

6936

if do_C2M

6925

if do_C2M

6937

loop_count=[1 2];

6926

loop_count=[1 2];

6938

T_O=floor((param.T_O/1000)*param.samples_per_ui);

6927

T_O=floor((param.T_O/1000)*param.samples_per_ui);

6939

T_O=max(0,T_O);

6928

T_O=max(0,T_O);

6940

else

6929

else

6941

loop_count=1;

6930

loop_count=1;

6942

T_O=0;

6931

T_O=0;

6943

end

6932

end

6944

switch param.CTLE_type

6933

switch param.CTLE_type

6945

case 'CL93'

6934

case 'CL93'

6946

lf_indx=1;

6935

lf_indx=1;

6947

case 'CL120d'

6936

case 'CL120d'

6948

lf_indx=length(g_DC_HP_values);

6937

lf_indx=length(g_DC_HP_values);

6949

case 'CL120e'

6938

case 'CL120e'

6950

lf_indx=1;

6939

lf_indx=1;

6951

end

6940

end

6952

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

6941

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

6953

if OP.Optimize_loop_speed_up == 1

6942

if OP.Optimize_loop_speed_up == 1

6954

OP.BinSize = 1e-4;

6943

OP.BinSize = 1e-4;

6955

OP.impulse_response_truncation_threshold = 1e-3;

6944

OP.impulse_response_truncation_threshold = 1e-3;

6956

end

6945

end

6957

6946

6958

%Used to speed up FFE by only performing circshift when necessary

6947

%Used to speed up FFE by only performing circshift when necessary

6959

pulse_struc(1).pulse_ctle_circshift=[];

6948

pulse_struc(1).pulse_ctle_circshift=[];

6960

ctle_response_updated=1;

6949

ctle_response_updated=1;

6961

6950

6962

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

6951

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

6963

calc_exp_phase=0;

6952

calc_exp_phase=0;

6964

6953

6965

%calculate cur index and pre/post indices outside of the loop

6954

%calculate cur index and pre/post indices outside of the loop

6966

cur_start=cur;

6955

cur_start=cur;

6967

precursor_indices=[];

6956

precursor_indices=[];

6968

postcursor_indices=[];

6957

postcursor_indices=[];

6969

auto_count_trigger=0;

6958

auto_count_trigger=0;

6970

for kv=1:num_taps

6959

for kv=1:num_taps

6971

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

6960

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

6972

%precursor values fill the beginning of the vector. Any empty precursor means

6961

%precursor values fill the beginning of the vector. Any empty precursor means

6973

%cursor position must be subtracted by 1

6962

%cursor position must be subtracted by 1

6974

if kv<cur_start

6963

if kv<cur_start

6975

cur=cur-1;

6964

cur=cur-1;

6976

end

6965

end

6977

else

6966

else

6978

%non empty value: add to precursor or postcursor indices depending on position

6967

%non empty value: add to precursor or postcursor indices depending on position

6979

%in the vector

6968

%in the vector

6980

if kv<cur_start

6969

if kv<cur_start

6981

auto_count_trigger=1;

6970

auto_count_trigger=1;

6982

precursor_indices=[precursor_indices kv];

6971

precursor_indices=[precursor_indices kv];

6983

else

6972

else

6984

auto_count_trigger=0;

6973

auto_count_trigger=0;

6985

postcursor_indices=[postcursor_indices kv];

6974

postcursor_indices=[postcursor_indices kv];

6986

end

6975

end

6987

end

6976

end

6988

end

6977

end

6989

if ~isempty(postcursor_indices)

6978

if ~isempty(postcursor_indices)

6990

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

6979

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

6991

end

6980

end

6992

6981

6993

%Calculate the full grid matrix of all txffe combinations

6982

%Calculate the full grid matrix of all txffe combinations

6994

if isempty(txffe_cell)

6983

if isempty(txffe_cell)

6995

TXFFE_grid=0;

6984

TXFFE_grid=0;

6996

FULL_tx_index_vector=1;

6985

FULL_tx_index_vector=1;

6997

else

6986

else

6998

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

6987

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

6999

%Also calculate the full grid matrix for the index used in each txffe combination

6988

%Also calculate the full grid matrix for the index used in each txffe combination

7000

%(the index is used in the LOCAL SEARCH block)

6989

%(the index is used in the LOCAL SEARCH block)

7001

for k=1:num_taps

6990

for k=1:num_taps

7002

txffe_index_cell{k}=1:txffe_lengths(k);

6991

txffe_index_cell{k}=1:txffe_lengths(k);

7003

end

6992

end

7004

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

6993

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

7005

end

6994

end

7006

6995

7007

%pre-calculate cursor to save time

6996

%pre-calculate cursor to save time

7008

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

6997

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

7009

6998

7010

%pre-calculate full txffe for each iteration to save time

6999

%pre-calculate full txffe for each iteration to save time

7011

precursor_matrix=TXFFE_grid(:,precursor_indices);

7000

precursor_matrix=TXFFE_grid(:,precursor_indices);

7012

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7001

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7013

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7002

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7014

7003

7015

if OP.TDMODE

7004

if OP.TDMODE

7016

uneq_field='uneq_pulse_response';

7005

uneq_field='uneq_pulse_response';

7017

ctle_field='ctle_pulse_response';

7006

ctle_field='ctle_pulse_response';

7018

else

7007

else

7019

uneq_field='uneq_imp_response';

7008

uneq_field='uneq_imp_response';

7020

ctle_field='ctle_imp_response';

7009

ctle_field='ctle_imp_response';

7021

end

7010

end

7022

7011

7023

%Speed up search for max(sbr)

7012

%Speed up search for max(sbr)

7024

if OP.TDMODE

7013

if OP.TDMODE

7025

[~,init_max]=max(chdata(1).uneq_pulse_response);

7014

[~,init_max]=max(chdata(1).uneq_pulse_response);

7026

else

7015

else

7027

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7016

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7028

end

7017

end

7029

UI_max_window=20;

7018

UI_max_window=20;

7030

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7019

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7031

if start_max_idx<1

7020

if start_max_idx<1

7032

start_max_idx=1;

7021

start_max_idx=1;

7033

end

7022

end

7034

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7023

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7035

if end_max_idx>length(chdata(1).(uneq_field))

7024

if end_max_idx>length(chdata(1).(uneq_field))

7036

end_max_idx=length(chdata(1).(uneq_field));

7025

end_max_idx=length(chdata(1).(uneq_field));

7037

end

7026

end

7038

7027

7039

itick_skips=0;

7028

itick_skips=0;

7040

itick_cases=0;

7029

itick_cases=0;

7041

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7030

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7042

for i=loop_count

7031

for i=loop_count

7043

7032

7044

for Gffe_index=1:length(Gffe_values)

7033

for Gffe_index=1:length(Gffe_values)

7045

param.current_ffegain=Gffe_values(Gffe_index);

7034

param.current_ffegain=Gffe_values(Gffe_index);

7046

for ctle_index=1:length(gdc_values)

7035

for ctle_index=1:length(gdc_values)

7047

g_dc = gdc_values(ctle_index);

7036

g_dc = gdc_values(ctle_index);

7048

kacdc = 10^(g_dc/20);

7037

kacdc = 10^(g_dc/20);

7049

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7038

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7050

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7039

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7051

CTLE_fz = param.CTLE_fz(ctle_index);

7040

CTLE_fz = param.CTLE_fz(ctle_index);

7052

switch param.CTLE_type

7041

switch param.CTLE_type

7053

case 'CL93'

7042

case 'CL93'

7054

%

7043

%

7055

case 'CL120d'

7044

case 'CL120d'

7056

%

7045

%

7057

case 'CL120e'

7046

case 'CL120e'

7058

HP_Z = param.f_HP_Z(ctle_index);

7047

HP_Z = param.f_HP_Z(ctle_index);

7059

HP_P = param.f_HP_P(ctle_index);

7048

HP_P = param.f_HP_P(ctle_index);

7060

end

7049

end

7061

%% HF Boost

7050

%% HF Boost

7062

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7051

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7063

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7052

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7064

%% Mid Frequency Boost

7053

%% Mid Frequency Boost

7065

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7054

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7066

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7055

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7067

for g_LP_index=1:lf_indx

7056

for g_LP_index=1:lf_indx

7068

7057

7069

%GDC Qual Check

7058

%GDC Qual Check

7070

if qual(g_LP_index,ctle_index)==0

7059

if qual(g_LP_index,ctle_index)==0

7071

pxi=pxi+num_txffe_runs;

7060

pxi=pxi+num_txffe_runs;

7072

continue;

7061

continue;

7073

end

7062

end

7074

7063

7075

switch param.CTLE_type

7064

switch param.CTLE_type

7076

case 'CL93'

7065

case 'CL93'

7077

H_low=1;

7066

H_low=1;

7078

kacde_DC_low=1;

7067

kacde_DC_low=1;

7079

case 'CL120d'

7068

case 'CL120d'

7080

g_DC_low = g_DC_HP_values(g_LP_index);

7069

g_DC_low = g_DC_HP_values(g_LP_index);

7081

f_HP=param.f_HP(g_LP_index);

7070

f_HP=param.f_HP(g_LP_index);

7082

kacde_DC_low = 10^(g_DC_low/20);

7071

kacde_DC_low = 10^(g_DC_low/20);

7083

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7072

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7084

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7073

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7085

case 'CL120e' % z1 has been adusted on read in

7074

case 'CL120e' % z1 has been adusted on read in

7086

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7075

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7087

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7076

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7088

end

7077

end

7089

H_ctf=H_low.*ctle_gain;

7078

H_ctf=H_low.*ctle_gain;

7090

switch upper(OP.FFE_OPT_METHOD)

7079

switch upper(OP.FFE_OPT_METHOD)

7091

case 'WIENER-HOPF'

7080

case 'WIENER-HOPF'

7092

%% Bill Kirkland

7081

%% Bill Kirkland

7093

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7082

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7094

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7083

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7095

% use Fourier Transform pair for correlation as we have to

7084

% use Fourier Transform pair for correlation as we have to

7096

% take ifft of H_r anyways.

7085

% take ifft of H_r anyways.

7097

% onesided and two sided responses - tricky, tricky, tricky

7086

% onesided and two sided responses - tricky, tricky, tricky

7098

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7087

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7099

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7088

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7100

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7089

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7101

7090

7102

if OP.Do_White_Noise

7091

if OP.Do_White_Noise

7103

Noise_XC = Noise_XC(1);

7092

Noise_XC = Noise_XC(1);

7104

end

7093

end

7105

otherwise

7094

otherwise

7106

Noise_XC=[];

7095

Noise_XC=[];

7107

end

7096

end

7108

7097

7109

7098

7110

7099

7111

if OP.INCLUDE_CTLE==1

7100

if OP.INCLUDE_CTLE==1

7112

for k=1:param.num_s4p_files

7101

for k=1:param.num_s4p_files

7113

ir_peak = max(abs(chdata(k).(uneq_field)));

7102

ir_peak = max(abs(chdata(k).(uneq_field)));

7114

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7103

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7115

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7104

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7116

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7105

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7117

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7106

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7118

switch param.CTLE_type

7107

switch param.CTLE_type

7119

case 'CL93'

7108

case 'CL93'

7120

case 'CL120d'

7109

case 'CL120d'

7121

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7110

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7122

case 'CL120e' % z1 has been adusted on read in

7111

case 'CL120e' % z1 has been adusted on read in

7123

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7112

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7124

end

7113

end

7125

end

7114

end

7126

%set the flag to show ctle response was updated

7115

%set the flag to show ctle response was updated

7127

ctle_response_updated=1;

7116

ctle_response_updated=1;

7128

else

7117

else

7129

for k=1:param.num_s4p_files

7118

for k=1:param.num_s4p_files

7130

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7119

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7131

end

7120

end

7132

end

7121

end

7133

for k=1:param.num_s4p_files

7122

for k=1:param.num_s4p_files

7134

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7123

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7135

end

7124

end

7136

%% Equation 93A-22 %%

7125

%% Equation 93A-22 %%

7137

% figure(1000)

7126

% figure(1000)

7138

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7127

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7139

% hold on

7128

% hold on

7140

if OP.RX_CALIBRATION

7129

if OP.RX_CALIBRATION

7141

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7130

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7142

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7131

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7143

switch param.CTLE_type

7132

switch param.CTLE_type

7144

case 'CL93'

7133

case 'CL93'

7145

H_low2=1;

7134

H_low2=1;

7146

case 'CL120d'

7135

case 'CL120d'

7147

g_DC_low = g_DC_HP_values(g_LP_index);

7136

g_DC_low = g_DC_HP_values(g_LP_index);

7148

f_HP=param.f_HP(g_LP_index);

7137

f_HP=param.f_HP(g_LP_index);

7149

kacde_DC_low = 10^(g_DC_low/20);

7138

kacde_DC_low = 10^(g_DC_low/20);

7150

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7139

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7151

case 'CL120e' % z1 has been adusted on read in

7140

case 'CL120e' % z1 has been adusted on read in

7152

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7141

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7153

end

7142

end

7154

H_ctf2=H_low2.*ctle_gain2;

7143

H_ctf2=H_low2.*ctle_gain2;

7155

end

7144

end

7156

% RIM 11-30-2020 moved to a subfunction

7145

% RIM 11-30-2020 moved to a subfunction

7157

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7146

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7158

if OP.RX_CALIBRATION

7147

if OP.RX_CALIBRATION

7159

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7148

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7160

sigma_NEXT=sqrt(param.eta_0*sum( abs(H_sy(2:end).^2 .* H_r(2:end).*2 .* H_ctf(2:end).^2 ) .* diff(chdata(1).faxis)/1e9));% changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7149

sigma_NEXT=sqrt(param.eta_0*sum( abs(H_sy(2:end).^2 .* H_r(2:end).*2 .* H_ctf(2:end).^2 ) .* diff(chdata(1).faxis)/1e9));% changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7161

else

7150

else

7162

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7151

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7163

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7152

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7164

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7153

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7165

sigma_ne=0;

7154

sigma_ne=0;

7166

end

7155

end

7167

7156

7168

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7157

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7169

pxi=pxi+num_txffe_runs;

7158

pxi=pxi+num_txffe_runs;

7170

continue; % change per 0.3k draft 2.3

7159

continue; % change per 0.3k draft 2.3

7171

end

7160

end

7172

%%

7161

%%

7173

PSD_results=[];

7162

PSD_results=[];

7174

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7163

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7175

OP.WO_TXFFE=1;

7164

OP.WO_TXFFE=1;

7176

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7165

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7177

end

7166

end

7178

%TXFFE Loop

7167

%TXFFE Loop

7179

%Originally this was a separate for loop for each tap, but it is now all contained in the TXFFE_grid matrix to use a single modular loop

7168

%Originally this was a separate for loop for each tap, but it is now all contained in the TXFFE_grid matrix to use a single modular loop

7180

for TK=1:size(TXFFE_grid,1)

7169

for TK=1:size(TXFFE_grid,1)

7181

7170

7182

pxi=pxi+1;

7171

pxi=pxi+1;

7183

progress = pxi/runs;

7172

progress = pxi/runs;

7184

if OP.DISPLAY_WINDOW

7173

if OP.DISPLAY_WINDOW

7185

if ~mod(pxi,floor(runs*progress_interval))

7174

if ~mod(pxi,floor(runs*progress_interval))

7186

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7175

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7187

end

7176

end

7188

else

7177

else

7189

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7178

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7190

end

7179

end

7191

7180

7192

%get the cursor for this iteration

7181

%get the cursor for this iteration

7193

txffe_cur=txffe_cursor_vector(TK);

7182

txffe_cur=txffe_cursor_vector(TK);

7194

7183

7195

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7184

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7196

if txffe_cur<param.tx_ffe_c0_min

7185

if txffe_cur<param.tx_ffe_c0_min

7197

continue;

7186

continue;

7198

end

7187

end

7199

old_loops=old_loops+1;

7188

old_loops=old_loops+1;

7200

7189

7201

%get the index used for each tap on this iteration

7190

%get the index used for each tap on this iteration

7202

%this is needed for the LOCAL SEARCH block

7191

%this is needed for the LOCAL SEARCH block

7203

tx_index_vector=FULL_tx_index_vector(TK,:);

7192

tx_index_vector=FULL_tx_index_vector(TK,:);

7204

7193

7205

%Original LOCAL SEARCH Block:

7194

%Original LOCAL SEARCH Block:

7206

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7195

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7207

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7196

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7208

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7197

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7209

% % skip configurations more than

7198

% % skip configurations more than

7210

% % 2 steps away from current "best" point on any grid direction

7199

% % 2 steps away from current "best" point on any grid direction

7211

% % Matt Brown 11/19/2021 for cp2 and cp3

7200

% % Matt Brown 11/19/2021 for cp2 and cp3

7212

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7201

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7213

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7202

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7214

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7203

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7215

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7204

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7216

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7205

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7217

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7206

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7218

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7207

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7219

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7208

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7220

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7209

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7221

%

7210

%

7222

% continue;

7211

% continue;

7223

% end

7212

% end

7224

7213

7225

%Modular LOCAL_SEARCH block:

7214

%Modular LOCAL_SEARCH block:

7226

% speedup "local search" heuristic - Adee Ran 03-17-2020

7215

% speedup "local search" heuristic - Adee Ran 03-17-2020

7227

% skip configurations more than 2 steps away from current "best" point on any grid direction

7216

% skip configurations more than 2 steps away from current "best" point on any grid direction

7228

skip_it=0;

7217

skip_it=0;

7229

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7218

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7230

%instead of looping across all taps, only loop across

7219

%instead of looping across all taps, only loop across

7231

%those with length>1 (txffe_sweep_indices).

7220

%those with length>1 (txffe_sweep_indices).

7232

%It saves time since this block is encountered so often

7221

%It saves time since this block is encountered so often

7233

for kj=1:num_txffe_sweep_indices

7222

for kj=1:num_txffe_sweep_indices

7234

kv=txffe_sweep_indices(kj);

7223

kv=txffe_sweep_indices(kj);

7235

if kv==1

7224

if kv==1

7236

previous_loop_val=g_LP_index;

7225

previous_loop_val=g_LP_index;

7237

else

7226

else

7238

previous_loop_val=tx_index_vector(kv-1);

7227

previous_loop_val=tx_index_vector(kv-1);

7239

end

7228

end

7240

if previous_loop_val>1

7229

if previous_loop_val>1

7241

best_index_this_tap=best_txffe_index(kv);

7230

best_index_this_tap=best_txffe_index(kv);

7242

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7231

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7243

skip_it=1;

7232

skip_it=1;

7244

break;

7233

break;

7245

end

7234

end

7246

end

7235

end

7247

end

7236

end

7248

7237

7249

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7238

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7250

skip_it=1;

7239

skip_it=1;

7251

end

7240

end

7252

end

7241

end

7253

if skip_it

7242

if skip_it

7254

continue;

7243

continue;

7255

end

7244

end

7256

%End Modular LOCAL SEARCH block

7245

%End Modular LOCAL SEARCH block

7257

7246

7258

new_loops=new_loops+1;

7247

new_loops=new_loops+1;

7259

7248

7260

%fetch txffe for this iteration

7249

%fetch txffe for this iteration

7261

txffe=txffe_matrix(TK,:);

7250

txffe=txffe_matrix(TK,:);

7262

7251

7263

%The phase shift exponentials used in get_xtlk_noise are independent of

7252

%The phase shift exponentials used in get_xtlk_noise are independent of

7264

%everything except number of taps and cursor position

7253

%everything except number of taps and cursor position

7265

%So it can be calculated 1 time here to avoid thousands of re-calcs

7254

%So it can be calculated 1 time here to avoid thousands of re-calcs

7266

if ~calc_exp_phase

7255

if ~calc_exp_phase

7267

calc_exp_phase=1;

7256

calc_exp_phase=1;

7268

for k=1:length(txffe)

7257

for k=1:length(txffe)

7269

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7258

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7270

end

7259

end

7271

if OP.RxFFE

7260

if OP.RxFFE

7272

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7261

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7273

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7262

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7274

end

7263

end

7275

phase_memory=[phase_memory phase_memoryRXFFE];

7264

phase_memory=[phase_memory phase_memoryRXFFE];

7276

end

7265

end

7277

end

7266

end

7278

7267

7279

%% Unequalized Pulse Reponse & circshift for FFE

7268

%% Unequalized Pulse Reponse & circshift for FFE

7280

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7269

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7281

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7270

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7282

if ctle_response_updated

7271

if ctle_response_updated

7283

ctle_response_updated=0;

7272

ctle_response_updated=0;

7284

num_pre=cur-1;

7273

num_pre=cur-1;

7285

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7274

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7286

%Calculating here reduces number of convolutions by thousands

7275

%Calculating here reduces number of convolutions by thousands

7287

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7276

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7288

ich=1;

7277

ich=1;

7289

else

7278

else

7290

ich=param.num_s4p_files;

7279

ich=param.num_s4p_files;

7291

end

7280

end

7292

for ii=1:ich

7281

for ii=1:ich

7293

if OP.TDMODE

7282

if OP.TDMODE

7294

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7283

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7295

else

7284

else

7296

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7285

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7297

%"conv2" is faster than filter. Just need to chop off extra points at the end

7286

%"conv2" is faster than filter. Just need to chop off extra points at the end

7298

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7287

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7299

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7288

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7300

end

7289

end

7301

for k=1:length(txffe)

7290

for k=1:length(txffe)

7302

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7291

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7303

end

7292

end

7304

end

7293

end

7305

end

7294

end

7306

7295

7307

%% Apply TXFFE to pre-shifted pulse response

7296

%% Apply TXFFE to pre-shifted pulse response

7308

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7297

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7309

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7298

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7310

sbr_from_txffe=sbr;

7299

sbr_from_txffe=sbr;

7311

for ii=1:ich

7300

for ii=1:ich

7312

% this is sbr when ii=1; to be used in get_PSDs

7301

% this is sbr when ii=1; to be used in get_PSDs

7313

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7302

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7314

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7303

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7315

else

7304

else

7316

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7305

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7317

end

7306

end

7318

end

7307

end

7319

7308

7320

%% Find Sample Location

7309

%% Find Sample Location

7321

% If RXFFE is included, the sample location will be found again below

7310

% If RXFFE is included, the sample location will be found again below

7322

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7311

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7323

if param.ts_anchor==0

7312

if param.ts_anchor==0

7324

%keep MM

7313

%keep MM

7325

elseif param.ts_anchor==1

7314

elseif param.ts_anchor==1

7326

%peak sample

7315

%peak sample

7327

cursor_i=sbr_peak_i;

7316

cursor_i=sbr_peak_i;

7328

no_zero_crossing=0;

7317

no_zero_crossing=0;

7329

elseif param.ts_anchor==2

7318

elseif param.ts_anchor==2

7330

%max DV

7319

%max DV

7331

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7320

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7332

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7321

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7333

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7322

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7334

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7323

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7335

no_zero_crossing=0;

7324

no_zero_crossing=0;

7336

else

7325

else

7337

error('ts_anchor parameter must be 0, 1, or 2');

7326

error('ts_anchor parameter must be 0, 1, or 2');

7338

end

7327

end

7339

if no_zero_crossing

7328

if no_zero_crossing

7340

continue;

7329

continue;

7341

end

7330

end

7342

raw_cursor_i=cursor_i;

7331

raw_cursor_i=cursor_i;

7343

7332

7344

%%%%%%%%%%

7333

%%%%%%%%%%

7345

%%%%%%%%%%

7334

%%%%%%%%%%

7346

%%%%%%%%%%

7335

%%%%%%%%%%

7347

%NEW ITICK LOOP (not indenting everything yet)

7336

%NEW ITICK LOOP (not indenting everything yet)

7348

[~,si]=sort(abs(full_sample_range));

7337

[~,si]=sort(abs(full_sample_range));

7349

best_positive_itick_FOM=-inf;

7338

best_positive_itick_FOM=-inf;

7350

best_negative_itick_FOM=-inf;

7339

best_negative_itick_FOM=-inf;

7351

best_positive_itick_in_loop=[];

7340

best_positive_itick_in_loop=[];

7352

best_negative_itick_in_loop=[];

7341

best_negative_itick_in_loop=[];

7353

best_itick_FOM=-inf;

7342

best_itick_FOM=-inf;

7354

best_itick_in_cluster=[];

7343

best_itick_in_cluster=[];

7355

best_cluster=[];

7344

best_cluster=[];

7356

7345

7357

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7346

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7358

%middle_search: start from itick=0 and work outwards in negative and positive direction. stop searching when FOM starts to go down (using LOCAL SEARCH)

7347

%middle_search: start from itick=0 and work outwards in negative and positive direction. stop searching when FOM starts to go down (using LOCAL SEARCH)

7359

% Commit request4p4_7 healey_3dj_COM_01_240416

7348

% Commit request4p4_7 healey_3dj_COM_01_240416

7360

%box_search=0;

7349

%box_search=0;

7361

%middle_search=1;% should set 0 so all Ts sample points are used

7350

%middle_search=1;% should set 0 so all Ts sample points are used

7362

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7351

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7363

case 'full-sweep'

7352

case 'full-sweep'

7364

box_search=0;

7353

box_search=0;

7365

middle_search=0;

7354

middle_search=0;

7366

case 'middle'

7355

case 'middle'

7367

box_search=0;

7356

box_search=0;

7368

middle_search=1;

7357

middle_search=1;

7369

otherwise

7358

otherwise

7370

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7359

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7371

end

7360

end

7372

if box_search

7361

if box_search

7373

box_size=5;

7362

box_size=5;

7374

box_mid=floor(box_size/2);

7363

box_mid=floor(box_size/2);

7375

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7364

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7376

CL=length(cluster);

7365

CL=length(cluster);

7377

loop_range=1:CL+box_mid*2;

7366

loop_range=1:CL+box_mid*2;

7378

elseif middle_search

7367

elseif middle_search

7379

loop_range=si;

7368

loop_range=si;

7380

else

7369

else

7381

loop_range=1:length(full_sample_range);

7370

loop_range=1:length(full_sample_range);

7382

end

7371

end

7383

7372

7384

for itickn=loop_range

7373

for itickn=loop_range

7385

if box_search

7374

if box_search

7386

if itickn<=CL

7375

if itickn<=CL

7387

itick=cluster(itickn);

7376

itick=cluster(itickn);

7388

else

7377

else

7389

if itickn==CL+1

7378

if itickn==CL+1

7390

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7379

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7391

end

7380

end

7392

if isempty(best_cluster)

7381

if isempty(best_cluster)

7393

continue;

7382

continue;

7394

end

7383

end

7395

itick=best_cluster(itickn-CL);

7384

itick=best_cluster(itickn-CL);

7396

end

7385

end

7397

else

7386

else

7398

itick=full_sample_range(itickn);

7387

itick=full_sample_range(itickn);

7399

end

7388

end

7400

7389

7401

itick_cases=itick_cases+1;

7390

itick_cases=itick_cases+1;

7402

7391

7403

sbr=sbr_from_txffe;

7392

sbr=sbr_from_txffe;

7404

cursor_i = raw_cursor_i+itick;

7393

cursor_i = raw_cursor_i+itick;

7405

7394

7406

%Local Search for +/- itick sweep

7395

%Local Search for +/- itick sweep

7407

if middle_search && param.LOCAL_SEARCH>0

7396

if middle_search && param.LOCAL_SEARCH>0

7408

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7397

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7409

itick_skips=itick_skips+1;

7398

itick_skips=itick_skips+1;

7410

continue;

7399

continue;

7411

end

7400

end

7412

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7401

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7413

itick_skips=itick_skips+1;

7402

itick_skips=itick_skips+1;

7414

continue;

7403

continue;

7415

end

7404

end

7416

end

7405

end

7417

7406

7418

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7407

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7419

if min_number_of_UI_in_response < triple_transit_time

7408

if min_number_of_UI_in_response < triple_transit_time

7420

min_number_of_UI_in_response = triple_transit_time;

7409

min_number_of_UI_in_response = triple_transit_time;

7421

end

7410

end

7422

7411

7423

cursor = sbr(cursor_i);

7412

cursor = sbr(cursor_i);

7424

7413

7425

%% RXFFE

7414

%% RXFFE

7426

if OP.RxFFE

7415

if OP.RxFFE

7427

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7416

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7428

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7417

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7429

%if isrow(sbr), sbr=sbr';end

7418

%if isrow(sbr), sbr=sbr';end

7430

7419

7431

%AJG: do not return sbr here (run time improvement)

7420

%AJG: do not return sbr here (run time improvement)

7432

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7421

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7433

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7422

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7434

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7423

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7435

% sbr at this point include the current setting

7424

% sbr at this point include the current setting

7436

% under consideration of txffe h21 ctf and fr

7425

% under consideration of txffe h21 ctf and fr

7437

switch upper(OP.FFE_OPT_METHOD)

7426

switch upper(OP.FFE_OPT_METHOD)

7438

case 'MMSE'

7427

case 'MMSE'

7439

OP.WO_TXFFE=0;

7428

OP.WO_TXFFE=0;

7440

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7429

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7441

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn+ PSD_results.S_qn ;

7430

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn+ PSD_results.S_qn ;

7442

if 0 % for debug

7431

if 0 % for debug

7443

figure(1010132)

7432

figure(1010132)

7444

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7433

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7445

hold on

7434

hold on

7446

if(PSD_results.S_xn~=0)

7435

if(PSD_results.S_xn~=0)

7447

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7436

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7448

end

7437

end

7449

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7438

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7450

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7439

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7451

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7440

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7452

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_qn*1000/100) ,'disp','Sqn')

7441

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_qn*1000/100) ,'disp','Sqn')

7453

xlim([0 0.5])

7442

xlim([0 0.5])

7454

% ylim([-190 -160])

7443

% ylim([-190 -160])

7455

set(gcf,'defaulttextinterpreter','none')

7444

set(gcf,'defaulttextinterpreter','none')

7456

xlabel('Normalized Frequency')

7445

xlabel('Normalized Frequency')

7457

ylabel('PSD dBm/Hz')

7446

ylabel('PSD dBm/Hz')

7458

hold on

7447

hold on

7459

grid on

7448

grid on

7460

legend show

7449

legend show

7461

title('PSD')

7450

title('PSD')

7462

end

7451

end

7463

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7452

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7464

% floating_tap_locations=MMSE_results.MLSE_results;

7453

% floating_tap_locations=MMSE_results.MLSE_results;

7465

C=MMSE_results.C;

7454

C=MMSE_results.C;

7466

FOM=MMSE_results.FOM;

7455

FOM=MMSE_results.FOM;

7467

floating_tap_locations=MMSE_results.floating_tap_locations;

7456

floating_tap_locations=MMSE_results.floating_tap_locations;

7468

otherwise

7457

otherwise

7469

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7458

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7470

end

7459

end

7471

%Now there is a stand alone function for determining if RXFFE taps are illegal

7460

%Now there is a stand alone function for determining if RXFFE taps are illegal

7472

%This is because the "force" function will also do a legality check when "backoff" is enabled

7461

%This is because the "force" function will also do a legality check when "backoff" is enabled

7473

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7462

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7474

if RXFFE_Illegal(C,param)

7463

if RXFFE_Illegal(C,param)

7475

continue;

7464

continue;

7476

end

7465

end

7477

end

7466

end

7478

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7467

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7479

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7468

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7480

if isrow(sbr), sbr=sbr';end

7469

if isrow(sbr), sbr=sbr';end

7481

7470

7482

%% second guess at cursor location (t_s) - based on approximate zero crossing

7471

%% second guess at cursor location (t_s) - based on approximate zero crossing

7483

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7472

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7484

%UPDATE: NOT RESAMPLING AFTER RXFFE

7473

%UPDATE: NOT RESAMPLING AFTER RXFFE

7485

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7474

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7486

% if no_zero_crossing

7475

% if no_zero_crossing

7487

% continue;

7476

% continue;

7488

% end

7477

% end

7489

7478

7490

cursor = sbr(cursor_i);

7479

cursor = sbr(cursor_i);

7491

end

7480

end

7492

A_p=sbr(sbr_peak_i);

7481

A_p=sbr(sbr_peak_i);

7493

%% 93A.1.6 step c defines A_s %%

7482

%% 93A.1.6 step c defines A_s %%

7494

A_s = param.R_LM*cursor/(param.levels-1);

7483

A_s = param.R_LM*cursor/(param.levels-1);

7495

if isempty(delta_sbr)

7484

if isempty(delta_sbr)

7496

delta_sbr = sbr;

7485

delta_sbr = sbr;

7497

end

7486

end

7498

sbr=sbr(:);

7487

sbr=sbr(:);

7499

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7488

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7500

7489

7501

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7490

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7502

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7491

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7503

t=((cursor_i+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:length(sbr))-(cursor_i+param.samples_per_ui*(param.ndfe+1)))*...

7492

t=((cursor_i+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:length(sbr))-(cursor_i+param.samples_per_ui*(param.ndfe+1)))*...

7504

param.ui/param.samples_per_ui;

7493

param.ui/param.samples_per_ui;

7505

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7494

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7506

precursors = precursors(end:-1:1);

7495

precursors = precursors(end:-1:1);

7507

7496

7508

% % Error message if the sbr is not long enough for the specified range of Nb

7497

% % Error message if the sbr is not long enough for the specified range of Nb

7509

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7498

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7510

% close(hwaitbar);

7499

% close(hwaitbar);

7511

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7500

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7512

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7501

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7513

% end

7502

% end

7514

7503

7515

7504

7516

7505

7517

%% skip this case if FOM has no chance of beating old FOM

7506

%% skip this case if FOM has no chance of beating old FOM

7518

%this is also done below but with excess_dfe_cursors included.

7507

%this is also done below but with excess_dfe_cursors included.

7519

%excess_dfe_cursors requires the floating DFE computation which is

7508

%excess_dfe_cursors requires the floating DFE computation which is

7520

%time consuming, so checking here can have significant run time improvements

7509

%time consuming, so checking here can have significant run time improvements

7521

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7510

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7522

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7511

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7523

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7512

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7524

continue

7513

continue

7525

end

7514

end

7526

end

7515

end

7527

7516

7528

%% Equation 93A-27, when 1<=n<=N_b

7517

%% Equation 93A-27, when 1<=n<=N_b

7529

%required length = cursor + all DFE UI + 1 additional UI

7518

%required length = cursor + all DFE UI + 1 additional UI

7530

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7519

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7531

if length(sbr)<sbr_required_length

7520

if length(sbr)<sbr_required_length

7532

sbr(end+1:sbr_required_length)=0;

7521

sbr(end+1:sbr_required_length)=0;

7533

end

7522

end

7534

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7523

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7535

if param.dfe_delta ~= 0

7524

if param.dfe_delta ~= 0

7536

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7525

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7537

7526

7538

else

7527

else

7539

dfecursors_q=dfecursors;

7528

dfecursors_q=dfecursors;

7540

end

7529

end

7541

if param.Floating_DFE

7530

if param.Floating_DFE

7542

%% floating taps

7531

%% floating taps

7543

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7532

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7544

7533

7545

[floating_tap_locations, floating_tap_coef, hisi, bmax]= floatingDFE( postcurors ,param.ndfe_passed,param.N_bf,param.N_bg,param.N_bmax, param.bmaxg, sbr(cursor_i), param.dfe_delta );

7534

[floating_tap_locations, floating_tap_coef, hisi, bmax]= floatingDFE( postcurors ,param.ndfe_passed,param.N_bf,param.N_bg,param.N_bmax, param.bmaxg, sbr(cursor_i), param.dfe_delta );

7546

7535

7547

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7536

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7548

param.use_bmax=newbmax;

7537

param.use_bmax=newbmax;

7549

%AJG021820

7538

%AJG021820

7550

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7539

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7551

else

7540

else

7552

param.use_bmax=param.bmax;

7541

param.use_bmax=param.bmax;

7553

%AJG021820

7542

%AJG021820

7554

param.use_bmin=param.bmin;

7543

param.use_bmin=param.bmin;

7555

end

7544

end

7556

7545

7557

%AJG021820

7546

%AJG021820

7558

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7547

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7559

if do_C2M

7548

if do_C2M

7560

dfecursors_windowed=sbr(cursor_i-T_O+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe)-T_O);

7549

dfecursors_windowed=sbr(cursor_i-T_O+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe)-T_O);

7561

% readjust SBR

7550

% readjust SBR

7562

if 0

7551

if 0

7563

%PR_DFE_center not currently used, so this is in "if 0" statement

7552

%PR_DFE_center not currently used, so this is in "if 0" statement

7564

PR_DFE_center=sbr;

7553

PR_DFE_center=sbr;

7565

for n=1:param.ndfe

7554

for n=1:param.ndfe

7566

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7555

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7567

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7556

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7568

% dper=sbr(i_sample)- actual_dfecursors(n);

7557

% dper=sbr(i_sample)- actual_dfecursors(n);

7569

% PR_DFE_center(i_sample)=dper;

7558

% PR_DFE_center(i_sample)=dper;

7570

% end

7559

% end

7571

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7560

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7572

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7561

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7573

end

7562

end

7574

end

7563

end

7575

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7564

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7576

else

7565

else

7577

excess_dfe_cursors=dfecursors-actual_dfecursors;

7566

excess_dfe_cursors=dfecursors-actual_dfecursors;

7578

end

7567

end

7579

dfetaps=actual_dfecursors/sbr(cursor_i);

7568

dfetaps=actual_dfecursors/sbr(cursor_i);

7580

7569

7581

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7570

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7582

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7571

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7583

if tail_RSS ~= 0

7572

if tail_RSS ~= 0

7584

if tail_RSS >= param.B_float_RSS_MAX

7573

if tail_RSS >= param.B_float_RSS_MAX

7585

param.use_bmax(param.N_tail_start:end)= ...

7574

param.use_bmax(param.N_tail_start:end)= ...

7586

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7575

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7587

%AJG021820

7576

%AJG021820

7588

param.use_bmin(param.N_tail_start:end)= ...

7577

param.use_bmin(param.N_tail_start:end)= ...

7589

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7578

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7590

end

7579

end

7591

end

7580

end

7592

7581

7593

%AJG021820

7582

%AJG021820

7594

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7583

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7595

if do_C2M

7584

if do_C2M

7596

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7585

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7597

else

7586

else

7598

excess_dfe_cursors=dfecursors-actual_dfecursors;

7587

excess_dfe_cursors=dfecursors-actual_dfecursors;

7599

end

7588

end

7600

dfetaps=actual_dfecursors/sbr(cursor_i);

7589

dfetaps=actual_dfecursors/sbr(cursor_i);

7601

7590

7602

else

7591

else

7603

tail_RSS=0;

7592

tail_RSS=0;

7604

end

7593

end

7605

%% Eq. 93A-28 %%

7594

%% Eq. 93A-28 %%

7606

sampling_offset = mod(cursor_i, param.samples_per_ui);

7595

sampling_offset = mod(cursor_i, param.samples_per_ui);

7607

%ensure we can take early sample

7596

%ensure we can take early sample

7608

if sampling_offset<=1

7597

if sampling_offset<=1

7609

sampling_offset=sampling_offset+param.samples_per_ui;

7598

sampling_offset=sampling_offset+param.samples_per_ui;

7610

end

7599

end

7611

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7600

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7612

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7601

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7613

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7602

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7614

else

7603

else

7615

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7604

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7616

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7605

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7617

end

7606

end

7618

% ensure lengths are equal

7607

% ensure lengths are equal

7619

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7608

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7620

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7609

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7621

if ~OP.SNR_TXwC0

7610

if ~OP.SNR_TXwC0

7622

%% Equation 93A-30 %%

7611

%% Equation 93A-30 %%

7623

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7612

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7624

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7613

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7625

else

7614

else

7626

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7615

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7627

end

7616

end

7628

%% Equation 93A-31 %%

7617

%% Equation 93A-31 %%

7629

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7618

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7630

ISI_N=param.sigma_X*norm( far_cursors);

7619

ISI_N=param.sigma_X*norm( far_cursors);

7631

%% break if FOM has no chance of beating old e

7620

%% break if FOM has no chance of beating old e

7632

OP.exe_mode=1;

7621

OP.exe_mode=1;

7633

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7622

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7634

switch OP.EXE_MODE

7623

switch OP.EXE_MODE

7635

case 0

7624

case 0

7636

case 1

7625

case 1

7637

if (20*log10(A_s/sigma_ISI) < best_FOM)

7626

if (20*log10(A_s/sigma_ISI) < best_FOM)

7638

continue

7627

continue

7639

end

7628

end

7640

case 2

7629

case 2

7641

if (20*log10(A_s/sigma_ISI) < best_FOM)

7630

if (20*log10(A_s/sigma_ISI) < best_FOM)

7642

break

7631

break

7643

end

7632

end

7644

end

7633

end

7645

end

7634

end

7646

%% Equation 93A-32 %%

7635

%% Equation 93A-32 %%

7647

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7636

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7648

7637

7649

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7638

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7650

if OP.RX_CALIBRATION

7639

if OP.RX_CALIBRATION

7651

sigma_XT=0;

7640

sigma_XT=0;

7652

else

7641

else

7653

if ~OP.RxFFE

7642

if ~OP.RxFFE

7654

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata,phase_memory); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7643

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata,phase_memory); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7655

%% Equation 93A-36 denominator (actually its sqrt)

7644

%% Equation 93A-36 denominator (actually its sqrt)

7656

else % John Ewen: 13/12/20018

7645

else % John Ewen: 13/12/20018

7657

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7646

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7658

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata, phase_memory,C); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7647

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata, phase_memory,C); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7659

else % use results from get_PSDs RIM 3/28/2024

7648

else % use results from get_PSDs RIM 3/28/2024

7660

sigma_XT=PSD_results.S_xn_rms;

7649

sigma_XT=PSD_results.S_xn_rms;

7661

end

7650

end

7662

end

7651

end

7663

end

7652

end

7664

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7653

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7665

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7654

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7666

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7655

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7667

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7656

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7668

f=chdata(1).faxis;

7657

f=chdata(1).faxis;

7669

H_Rx_FFE=zeros(1,length(f));

7658

H_Rx_FFE=zeros(1,length(f));

7670

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7659

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7671

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7660

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7672

if C(ii+param.RxFFE_cmx+1)==0

7661

if C(ii+param.RxFFE_cmx+1)==0

7673

%speed up: skip cases when rxffe=0

7662

%speed up: skip cases when rxffe=0

7674

continue;

7663

continue;

7675

end

7664

end

7676

if ii+1==0

7665

if ii+1==0

7677

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7666

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7678

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7667

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7679

else

7668

else

7680

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7669

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7681

end

7670

end

7682

end

7671

end

7683

sigma_N =sqrt(param.eta_0*sum(H_sy(2:end) .* abs(H_r(2:end) .* H_ctf(2:end) .*H_Rx_FFE(2:end)).^2 .* diff(chdata(1).faxis)/1e9)); % changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7672

sigma_N =sqrt(param.eta_0*sum(H_sy(2:end) .* abs(H_r(2:end) .* H_ctf(2:end) .*H_Rx_FFE(2:end)).^2 .* diff(chdata(1).faxis)/1e9)); % changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7684

end

7673

end

7685

end

7674

end

7686

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7675

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7687

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7676

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7688

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7677

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7689

else

7678

else

7690

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7679

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7691

end

7680

end

7692

if do_C2M

7681

if do_C2M

7693

if param.Noise_Crest_Factor == 0

7682

if param.Noise_Crest_Factor == 0

7694

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7683

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7695

else

7684

else

7696

ber_q=param.Noise_Crest_Factor;

7685

ber_q=param.Noise_Crest_Factor;

7697

end

7686

end

7698

if OP.force_pdf_bin_size

7687

if OP.force_pdf_bin_size

7699

delta_y = OP.BinSize;

7688

delta_y = OP.BinSize;

7700

else

7689

else

7701

delta_y = min(A_s/1000, OP.BinSize);

7690

delta_y = min(A_s/1000, OP.BinSize);

7702

end

7691

end

7703

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7692

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7704

cci_pdf = normal_dist(0, ber_q, delta_y);

7693

cci_pdf = normal_dist(0, ber_q, delta_y);

7705

chdata(1).eq_pulse_response=sbr;

7694

chdata(1).eq_pulse_response=sbr;

7706

tmp_result.t_s= cursor_i;

7695

tmp_result.t_s= cursor_i;

7707

tmp_result.A_s=A_s;

7696

tmp_result.A_s=A_s;

7708

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7697

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7709

if EH_1st <= param.Min_VEO_Test/1000 -.001

7698

if EH_1st <= param.Min_VEO_Test/1000 -.001

7710

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7699

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7711

continue

7700

continue

7712

else

7701

else

7713

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7702

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7714

end

7703

end

7715

Struct_Noise.sigma_N=sigma_N;

7704

Struct_Noise.sigma_N=sigma_N;

7716

Struct_Noise.sigma_TX=sigma_TX;

7705

Struct_Noise.sigma_TX=sigma_TX;

7717

Struct_Noise.cci_pdf=cci_pdf;

7706

Struct_Noise.cci_pdf=cci_pdf;

7718

Struct_Noise.ber_q=ber_q;

7707

Struct_Noise.ber_q=ber_q;

7719

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7708

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7720

[Left_EW,Right_EW,eye_contour,EH_T_C2M,EH_B_C2M]=COM_eye_width(chdata,delta_y,tmp_result,param,OP,Struct_Noise,1);

7709

[Left_EW,Right_EW,eye_contour,EH_T_C2M,EH_B_C2M]=COM_eye_width(chdata,delta_y,tmp_result,param,OP,Struct_Noise,1);

7721

EH=EH_T_C2M-EH_B_C2M;

7710

EH=EH_T_C2M-EH_B_C2M;

7722

N_i=(A_s*2-EH)/2;

7711

N_i=(A_s*2-EH)/2;

7723

if EH <= param.Min_VEO_Test/1000

7712

if EH <= param.Min_VEO_Test/1000

7724

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7713

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7725

continue

7714

continue

7726

else

7715

else

7727

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

7716

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

7728

end

7717

end

7729

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7718

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7730

FOM =20*log10(A_s/N_i);

7719

FOM =20*log10(A_s/N_i);

7731

end

7720

end

7732

else

7721

else

7733

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7722

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7734

FOM = 20*log10(A_s/total_noise_rms);

7723

FOM = 20*log10(A_s/total_noise_rms);

7735

end

7724

end

7736

% if strfind(param.CTLE_type,'CL120e')

7725

% if strfind(param.CTLE_type,'CL120e')

7737

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

7726

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

7738

end

7727

end

7739

if 0 % for loop analysis

7728

if 0 % for loop analysis

7740

result.FOM_array(new_loops)=FOM;

7729

result.FOM_array(new_loops)=FOM;

7741

end

7730

end

7742

7731

7743

if FOM>best_itick_FOM

7732

if FOM>best_itick_FOM

7744

best_itick_FOM=FOM;

7733

best_itick_FOM=FOM;

7745

best_itick_in_cluster=itick;

7734

best_itick_in_cluster=itick;

7746

end

7735

end

7747

7736

7748

if itick>=0 && FOM>best_positive_itick_FOM

7737

if itick>=0 && FOM>best_positive_itick_FOM

7749

best_positive_itick_FOM=FOM;

7738

best_positive_itick_FOM=FOM;

7750

best_positive_itick_in_loop=itick;

7739

best_positive_itick_in_loop=itick;

7751

end

7740

end

7752

if itick<=0 && FOM>best_negative_itick_FOM

7741

if itick<=0 && FOM>best_negative_itick_FOM

7753

best_negative_itick_FOM=FOM;

7742

best_negative_itick_FOM=FOM;

7754

best_negative_itick_in_loop=itick;

7743

best_negative_itick_in_loop=itick;

7755

end

7744

end

7756

7745

7757

itick_index=find(itick==full_sample_range);

7746

itick_index=find(itick==full_sample_range);

7758

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

7747

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

7759

7748

7760

if (FOM > best_FOM)

7749

if (FOM > best_FOM)

7761

best_current_ffegain=param.current_ffegain;

7750

best_current_ffegain=param.current_ffegain;

7762

best_txffe = txffe;

7751

best_txffe = txffe;

7763

%along with best_txffe, save the indices of the best_txffe

7752

%along with best_txffe, save the indices of the best_txffe

7764

%(saves time in LOCAL SEARCH block)

7753

%(saves time in LOCAL SEARCH block)

7765

best_txffe_index=tx_index_vector;

7754

best_txffe_index=tx_index_vector;

7766

best_sbr = sbr;

7755

best_sbr = sbr;

7767

best_ctle = ctle_index;

7756

best_ctle = ctle_index;

7768

best_G_high_pass =g_LP_index;

7757

best_G_high_pass =g_LP_index;

7769

best_FOM = FOM;

7758

best_FOM = FOM;

7770

best_cursor_i = cursor_i;

7759

best_cursor_i = cursor_i;

7771

best_itick = itick;

7760

best_itick = itick;

7772

if ~OP.TDMODE

7761

if ~OP.TDMODE

7773

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7762

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7774

best_IR=effective_channel;

7763

best_IR=effective_channel;

7775

end

7764

end

7776

best_sigma_N = sigma_N;

7765

best_sigma_N = sigma_N;

7777

best_h_J = h_J;

7766

best_h_J = h_J;

7778

best_A_s=A_s;

7767

best_A_s=A_s;

7779

best_A_p=A_p;

7768

best_A_p=A_p;

7780

best_ISI=ISI_N;

7769

best_ISI=ISI_N;

7781

best_bmax=param.use_bmax;

7770

best_bmax=param.use_bmax;

7782

%AJG021820

7771

%AJG021820

7783

best_bmin=param.use_bmin;

7772

best_bmin=param.use_bmin;

7784

best_tail_RSS=tail_RSS;

7773

best_tail_RSS=tail_RSS;

7785

best_dfetaps=dfetaps;

7774

best_dfetaps=dfetaps;

7786

if param.Floating_DFE

7775

if param.Floating_DFE

7787

best_floating_tap_locations=floating_tap_locations;

7776

best_floating_tap_locations=floating_tap_locations;

7788

best_floating_tap_coef=floating_tap_coef;

7777

best_floating_tap_coef=floating_tap_coef;

7789

end

7778

end

7790

if param.Floating_RXFFE

7779

if param.Floating_RXFFE

7791

best_floating_tap_locations=floating_tap_locations;

7780

best_floating_tap_locations=floating_tap_locations;

7792

% best_floating_tap_coef=floating_tap_coef;

7781

% best_floating_tap_coef=floating_tap_coef;

7793

end

7782

end

7794

if OP.RxFFE

7783

if OP.RxFFE

7795

best_RxFFE=C;

7784

best_RxFFE=C;

7796

best_PSD_results=PSD_results;

7785

best_PSD_results=PSD_results;

7797

best_MMSE_results=MMSE_results;

7786

best_MMSE_results=MMSE_results;

7798

end

7787

end

7799

end

7788

end

7800

end

7789

end

7801

end

7790

end

7802

7791

7803

end

7792

end

7804

end

7793

end

7805

end

7794

end

7806

if do_C2M

7795

if do_C2M

7807

if best_FOM == -inf

7796

if best_FOM == -inf

7808

param.Min_VEO_Test=0;

7797

param.Min_VEO_Test=0;

7809

else

7798

else

7810

break

7799

break

7811

end

7800

end

7812

end

7801

end

7813

end

7802

end

7814

if 0

7803

if 0

7815

fprintf('old loops = %d\n',old_loops);

7804

fprintf('old loops = %d\n',old_loops);

7816

fprintf('new loops = %d\n',new_loops);

7805

fprintf('new loops = %d\n',new_loops);

7817

display(sprintf('\n :loops = %g',pxi))

7806

display(sprintf('\n :loops = %g',pxi))

7818

end

7807

end

7819

7808

7820

%turn this on to review if FOM changes sign more than once in an itick loop

7809

%turn this on to review if FOM changes sign more than once in an itick loop

7821

if 0

7810

if 0

7822

DIR_CHANGE={};

7811

DIR_CHANGE={};

7823

for m=1:length(Gffe_values)

7812

for m=1:length(Gffe_values)

7824

for n=1:length(gdc_values)

7813

for n=1:length(gdc_values)

7825

for k=1:lf_indx

7814

for k=1:lf_indx

7826

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

7815

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

7827

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

7816

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

7828

%1 = goes up, -1=goes down

7817

%1 = goes up, -1=goes down

7829

x=sign(diff(FOM_this_mat')');

7818

x=sign(diff(FOM_this_mat')');

7830

%y = change in sign on x. the location of a "2" is where FOM changes direction

7819

%y = change in sign on x. the location of a "2" is where FOM changes direction

7831

y=abs(diff(x'))';

7820

y=abs(diff(x'))';

7832

%the goal is the FOM only changes direction once. so count the occurences of the 2

7821

%the goal is the FOM only changes direction once. so count the occurences of the 2

7833

for j=1:size(FOM_this_mat,1)

7822

for j=1:size(FOM_this_mat,1)

7834

z{j}=find(y(j,:)==2);

7823

z{j}=find(y(j,:)==2);

7835

end

7824

end

7836

zL=cellfun('length',z);

7825

zL=cellfun('length',z);

7837

%return any row where FOM changed direction more than once

7826

%return any row where FOM changed direction more than once

7838

DIR_CHANGE{j,k}=find(zL>1);

7827

DIR_CHANGE{j,k}=find(zL>1);

7839

end

7828

end

7840

end

7829

end

7841

end

7830

end

7842

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

7831

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

7843

end

7832

end

7844

7833

7845

if ~exist('best_cursor_i', 'var')% take last setting

7834

if ~exist('best_cursor_i', 'var')% take last setting

7846

result.eq_failed=true;

7835

result.eq_failed=true;

7847

display('equalization failed')

7836

display('equalization failed')

7848

best_bmax=param.bmax;

7837

best_bmax=param.bmax;

7849

%AJG021820

7838

%AJG021820

7850

best_bmin=param.bmin;

7839

best_bmin=param.bmin;

7851

best_tail_RSS=0;

7840

best_tail_RSS=0;

7852

best_current_ffegain=0;

7841

best_current_ffegain=0;

7853

best_txffe = txffe;

7842

best_txffe = txffe;

7854

best_sbr = sbr;

7843

best_sbr = sbr;

7855

best_ctle = ctle_index;

7844

best_ctle = ctle_index;

7856

if OP.RxFFE

7845

if OP.RxFFE

7857

best_PSD_results=PSD_results;

7846

best_PSD_results=PSD_results;

7858

best_MMSE_results=MMSE_results;

7847

best_MMSE_results=MMSE_results;

7859

best_RxFFE=C;

7848

best_RxFFE=C;

7860

end

7849

end

7861

best_G_high_pass =g_LP_index;

7850

best_G_high_pass =g_LP_index;

7862

best_FOM = FOM;

7851

best_FOM = FOM;

7863

%if this block is reached, the last encountered EQ parameters are used

7852

%if this block is reached, the last encountered EQ parameters are used

7864

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

7853

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

7865

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

7854

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

7866

if isempty(cursor_i)

7855

if isempty(cursor_i)

7867

[~,cursor_i]=max(sbr);

7856

[~,cursor_i]=max(sbr);

7868

end

7857

end

7869

best_cursor_i = cursor_i;

7858

best_cursor_i = cursor_i;

7870

best_itick = itick;

7859

best_itick = itick;

7871

if ~OP.TDMODE

7860

if ~OP.TDMODE

7872

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7861

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7873

best_IR=effective_channel;

7862

best_IR=effective_channel;

7874

end

7863

end

7875

best_sigma_N = sigma_N;

7864

best_sigma_N = sigma_N;

7876

best_h_J = h_J;

7865

best_h_J = h_J;

7877

best_A_p=max(sbr);

7866

best_A_p=max(sbr);

7878

best_ISI=1;

7867

best_ISI=1;

7879

best_dfetaps= sbr( cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe))/sbr(cursor_i) ;

7868

best_dfetaps= sbr( cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe))/sbr(cursor_i) ;

7880

best_A_s= sbr( cursor_i);

7869

best_A_s= sbr( cursor_i);

7881

if param.Floating_DFE

7870

if param.Floating_DFE

7882

best_floating_tap_locations=[];

7871

best_floating_tap_locations=[];

7883

best_floating_tap_coef=[];

7872

best_floating_tap_coef=[];

7884

end

7873

end

7885

if do_C2M

7874

if do_C2M

7886

return

7875

return

7887

end

7876

end

7888

% return

7877

% return

7889

else

7878

else

7890

result.eq_failed=false; % RIM 12/30/2023

7879

result.eq_failed=false; % RIM 12/30/2023

7891

end

7880

end

7892

7881

7893

best_cursor = best_sbr(best_cursor_i);

7882

best_cursor = best_sbr(best_cursor_i);

7894

% report during debug

7883

% report during debug

7895

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

7884

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

7896

%If sbr was zero padded, then PRin needs to do so as well)

7885

%If sbr was zero padded, then PRin needs to do so as well)

7897

if length(PRin)<length(best_sbr)

7886

if length(PRin)<length(best_sbr)

7898

PRin(end+1:length(best_sbr))=0;

7887

PRin(end+1:length(best_sbr))=0;

7899

end

7888

end

7900

f=1e8:1e8:100e9;

7889

f=1e8:1e8:100e9;

7901

7890

7902

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

7891

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

7903

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

7892

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

7904

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7893

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7905

% need to include H_RCos in noise and when computing the system ir for thru

7894

% need to include H_RCos in noise and when computing the system ir for thru

7906

% and crosstalk

7895

% and crosstalk

7907

H_r=H_bw.*H_bt.*H_RCos;

7896

H_r=H_bw.*H_bt.*H_RCos;

7908

7897

7909

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

7898

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

7910

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

7899

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

7911

7900

7912

switch param.CTLE_type

7901

switch param.CTLE_type

7913

case 'CL93'

7902

case 'CL93'

7914

H_low=1;

7903

H_low=1;

7915

case 'CL120d'

7904

case 'CL120d'

7916

H_low=(10^(param.g_DC_HP_values(best_G_high_pass)/20) + 1i*f/param.f_HP(best_G_high_pass))./(1 + 1i*f/param.f_HP(best_G_high_pass));

7905

H_low=(10^(param.g_DC_HP_values(best_G_high_pass)/20) + 1i*f/param.f_HP(best_G_high_pass))./(1 + 1i*f/param.f_HP(best_G_high_pass));

7917

case 'CL120e'

7906

case 'CL120e'

7918

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

7907

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

7919

end

7908

end

7920

ctle_gain=H_low.*ctle_gain1.*H_r;

7909

ctle_gain=H_low.*ctle_gain1.*H_r;

7921

7910

7922

7911

7923

7912

7924

%lsbr=length(sbr);

7913

%lsbr=length(sbr);

7925

%use length of best_sbr in case zero padding was performed

7914

%use length of best_sbr in case zero padding was performed

7926

%check "sbr_required_length" variable

7915

%check "sbr_required_length" variable

7927

lsbr=length(best_sbr);

7916

lsbr=length(best_sbr);

7928

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

7917

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

7929

7918

7930

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

7919

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

7931

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

7920

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

7932

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

7921

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

7933

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

7922

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

7934

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

7923

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

7935

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

7924

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

7936

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

7925

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

7937

if param.Floating_DFE

7926

if param.Floating_DFE

7938

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

7927

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

7939

end

7928

end

7940

% apply max tap value constraint

7929

% apply max tap value constraint

7941

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

7930

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

7942

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

7931

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

7943

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

7932

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

7944

7933

7945

%AJG021820

7934

%AJG021820

7946

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

7935

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

7947

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

7936

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

7948

if param.Floating_DFE

7937

if param.Floating_DFE

7949

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

7938

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

7950

end

7939

end

7951

7940

7952

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

7941

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

7953

Symbol_Adj = (param.levels-1);% 3A.1.6

7942

Symbol_Adj = (param.levels-1);% 3A.1.6

7954

if OP.DEBUG ~=0

7943

if OP.DEBUG ~=0

7955

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

7944

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

7956

% display pulse responses in one axis per test case.

7945

% display pulse responses in one axis per test case.

7957

switch upper(OP.TIME_AXIS)

7946

switch upper(OP.TIME_AXIS)

7958

case 'S' % RIM 11-13-2023 added user selectable xaxis

7947

case 'S' % RIM 11-13-2023 added user selectable xaxis

7959

xnorm=1;

7948

xnorm=1;

7960

xaxis_label='seconds';

7949

xaxis_label='seconds';

7961

offset=0;

7950

offset=0;

7962

case 'UI'

7951

case 'UI'

7963

xnorm=param.ui;

7952

xnorm=param.ui;

7964

xaxis_label='UI';

7953

xaxis_label='UI';

7965

offset=t(best_cursor_i)/xnorm;

7954

offset=t(best_cursor_i)/xnorm;

7966

otherwise

7955

otherwise

7967

xnorm=1;

7956

xnorm=1;

7968

xaxis_label='seconds';

7957

xaxis_label='seconds';

7969

offset=0;

7958

offset=0;

7970

end

7959

end

7971

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

7960

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

7972

fig=findobj('Name', figure_name);

7961

fig=findobj('Name', figure_name);

7973

if isempty(fig), fig=figure('Name', figure_name); end

7962

if isempty(fig), fig=figure('Name', figure_name); end

7974

figure(fig);set(gcf,'Tag','COM');

7963

figure(fig);set(gcf,'Tag','COM');

7975

movegui(fig,'north')

7964

movegui(fig,'north')

7976

%figure(fig.Number);

7965

%figure(fig.Number);

7977

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

7966

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

7978

if OP.RxFFE

7967

if OP.RxFFE

7979

ax1=subplot(2,1,1);

7968

ax1=subplot(2,1,1);

7980

end

7969

end

7981

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

7970

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

7982

hold on

7971

hold on

7983

7972

7984

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

7973

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

7985

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

7974

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

7986

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

7975

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

7987

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

7976

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

7988

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

7977

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

7989

ylabel('volts')

7978

ylabel('volts')

7990

xlabel(xaxis_label)

7979

xlabel(xaxis_label)

7991

grid on

7980

grid on

7992

legend show

7981

legend show

7993

legend( 'Location', 'best')

7982

legend( 'Location', 'best')

7994

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

7983

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

7995

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

7984

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

7996

if param.ndfe_passed ~=0

7985

if param.ndfe_passed ~=0

7997

stem((sampled_best_sbr_dfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,DFE_taps_mV(1:param.ndfe_passed)/Symbol_Adj','m', 'LineWidth',2,'disp','DFE-canceled cursors');

7986

stem((sampled_best_sbr_dfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,DFE_taps_mV(1:param.ndfe_passed)/Symbol_Adj','m', 'LineWidth',2,'disp','DFE-canceled cursors');

7998

end

7987

end

7999

if param.Floating_DFE

7988

if param.Floating_DFE

8000

stem((sampled_best_sbr_fdfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,FDFE_taps_mV/Symbol_Adj, 'MarkerFaceColor','red','MarkerEdgeColor','m','LineWidth',1,'disp','FDFE-canceled cursors');

7989

stem((sampled_best_sbr_fdfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,FDFE_taps_mV/Symbol_Adj, 'MarkerFaceColor','red','MarkerEdgeColor','m','LineWidth',1,'disp','FDFE-canceled cursors');

8001

end

7990

end

8002

if OP.RxFFE

7991

if OP.RxFFE

8003

ax2=subplot(2,1,2);

7992

ax2=subplot(2,1,2);

8004

if param.Floating_RXFFE

7993

if param.Floating_RXFFE

8005

%AJG: floating tap x-axis location needs offset by -(RxFFE_cmx+1) because the floating tap indices include precursor indices

7994

%AJG: floating tap x-axis location needs offset by -(RxFFE_cmx+1) because the floating tap indices include precursor indices

8006

stem((t(best_cursor_i+(best_floating_tap_locations-param.RxFFE_cmx-1)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

7995

stem((t(best_cursor_i+(best_floating_tap_locations-param.RxFFE_cmx-1)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

8007

,'filled','disp','RxFFE floating FFE taps')

7996

,'filled','disp','RxFFE floating FFE taps')

8008

hold on

7997

hold on

8009

end

7998

end

8010

stem((t(best_cursor_i+param.samples_per_ui*(-param.RxFFE_cmx:param.RxFFE_cpx)))/xnorm-offset,best_RxFFE(1:param.RxFFE_cmx+param.RxFFE_cpx+1)...

7999

stem((t(best_cursor_i+param.samples_per_ui*(-param.RxFFE_cmx:param.RxFFE_cpx)))/xnorm-offset,best_RxFFE(1:param.RxFFE_cmx+param.RxFFE_cpx+1)...

8011

,'filled','disp','RxFFE fixted FFE taps')

8000

,'filled','disp','RxFFE fixted FFE taps')

8012

legend show

8001

legend show

8013

zoom xon

8002

zoom xon

8014

linkaxes([ax1 ax2],'x')

8003

linkaxes([ax1 ax2],'x')

8015

end

8004

end

8016

8005

8017

8006

8018

grid on

8007

grid on

8019

legend show

8008

legend show

8020

legend( 'Location', 'best')

8009

legend( 'Location', 'best')

8021

zoom xon

8010

zoom xon

8022

% set(hax, 'tag', 'EQE');

8011

% set(hax, 'tag', 'EQE');

8023

%

8012

%

8024

figure(110);set(gcf,'Tag','COM');

8013

figure(110);set(gcf,'Tag','COM');

8025

set(gcf, 'Name', 'CTLE selection');

8014

set(gcf, 'Name', 'CTLE selection');

8026

movegui(gcf, 'southeast');

8015

movegui(gcf, 'southeast');

8027

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8016

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8028

hold on

8017

hold on

8029

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8018

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8030

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8019

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8031

fbaud_tick=find(f >= baud_rate, 1);

8020

fbaud_tick=find(f >= baud_rate, 1);

8032

fnq_tick=find(f >= baud_rate/2, 1);

8021

fnq_tick=find(f >= baud_rate/2, 1);

8033

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8022

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8034

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8023

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8035

recolor_plots(gca);

8024

recolor_plots(gca);

8036

title('CTF/w Rx Filter Response')

8025

title('CTF/w Rx Filter Response')

8037

ylabel('dB')

8026

ylabel('dB')

8038

xlabel('Hz')

8027

xlabel('Hz')

8039

legend show

8028

legend show

8040

end

8029

end

8041

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8030

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8042

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8031

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8043

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8032

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8044

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8033

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8045

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8034

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8046

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8035

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8047

end

8036

end

8048

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

8037

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

8049

eqe_axes = findobj('tag', 'EQE');

8038

eqe_axes = findobj('tag', 'EQE');

8050

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8039

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8051

end

8040

end

8052

if OP.DISPLAY_WINDOW

8041

if OP.DISPLAY_WINDOW

8053

close(hwaitbar);

8042

close(hwaitbar);

8054

else

8043

else

8055

fprintf('\n');

8044

fprintf('\n');

8056

end

8045

end

8057

8046

8058

% % eq_data

8047

% % eq_data

8059

result.cur=cur;

8048

result.cur=cur;

8060

result.txffe = best_txffe;

8049

result.txffe = best_txffe;

8061

result.ctle = best_ctle;

8050

result.ctle = best_ctle;

8062

result.best_G_high_pass=best_G_high_pass;

8051

result.best_G_high_pass=best_G_high_pass;

8063

result.DFE_taps = best_dfetaps; %relative

8052

result.DFE_taps = best_dfetaps; %relative

8064

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8053

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8065

if param.Floating_DFE

8054

if param.Floating_DFE

8066

result.floating_tap_locations=best_floating_tap_locations;

8055

result.floating_tap_locations=best_floating_tap_locations;

8067

result.floating_tap_coef=best_floating_tap_coef;

8056

result.floating_tap_coef=best_floating_tap_coef;

8068

end

8057

end

8069

if param.Floating_RXFFE

8058

if param.Floating_RXFFE

8070

result.floating_tap_locations=best_floating_tap_locations;

8059

result.floating_tap_locations=best_floating_tap_locations;

8071

end

8060

end

8072

result.A_s = best_A_s;

8061

result.A_s = best_A_s;

8073

result.t_s = best_cursor_i;

8062

result.t_s = best_cursor_i;

8074

result.itick = best_itick;

8063

result.itick = best_itick;

8075

result.sigma_N = best_sigma_N;

8064

result.sigma_N = best_sigma_N;

8076

result.h_J = best_h_J;

8065

result.h_J = best_h_J;

8077

result.FOM = best_FOM;

8066

result.FOM = best_FOM;

8078

if ~OP.TDMODE

8067

if ~OP.TDMODE

8079

%If sbr was zero padded, then best_IR needs to do so as well)

8068

%If sbr was zero padded, then best_IR needs to do so as well)

8080

if length(best_IR)<length(best_sbr)

8069

if length(best_IR)<length(best_sbr)

8081

best_IR(end+1:length(best_sbr))=0;

8070

best_IR(end+1:length(best_sbr))=0;

8082

end

8071

end

8083

result.IR = best_IR;

8072

result.IR = best_IR;

8084

end

8073

end

8085

result.t=t;

8074

result.t=t;

8086

result.sbr=best_sbr;

8075

result.sbr=best_sbr;

8087

if OP.RxFFE

8076

if OP.RxFFE

8088

result.RxFFE=best_RxFFE;

8077

result.RxFFE=best_RxFFE;

8089

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8078

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8090

result.PSD_results=best_PSD_results;

8079

result.PSD_results=best_PSD_results;

8091

result.MMSE_results=best_MMSE_results;

8080

result.MMSE_results=best_MMSE_results;

8092

end

8081

end

8093

end

8082

end

8094

8083

8095

8084

8096

8085

8097

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8086

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8098

% updated RIM 12/17/2021

8087

% updated RIM 12/17/2021

8099

result.A_p = max(chdata(1).uneq_pulse_response);

8088

result.A_p = max(chdata(1).uneq_pulse_response);

8100

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8089

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8101

PR=chdata(1).uneq_pulse_response;

8090

PR=chdata(1).uneq_pulse_response;

8102

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8091

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8103

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8092

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8104

if iend >= length(PR)

8093

if iend >= length(PR)

8105

iend = length (PR);

8094

iend = length (PR);

8106

end

8095

end

8107

if ibeg < 1

8096

if ibeg < 1

8108

ibeg = 1;

8097

ibeg = 1;

8109

end

8098

end

8110

PR=PR(ibeg:iend);

8099

PR=PR(ibeg:iend);

8111

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8100

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8112

SRn=PR;

8101

SRn=PR;

8113

for ik=1:floor(length(PR)/param.samples_per_ui)

8102

for ik=1:floor(length(PR)/param.samples_per_ui)

8114

SPR=circshift(PR,param.samples_per_ui*ik);

8103

SPR=circshift(PR,param.samples_per_ui*ik);

8115

SPR(1:ik*param.samples_per_ui)=0;

8104

SPR(1:ik*param.samples_per_ui)=0;

8116

SRn=SRn+ SPR;

8105

SRn=SRn+ SPR;

8117

end

8106

end

8118

codedebug=0;

8107

codedebug=0;

8119

if codedebug

8108

if codedebug

8120

fig=figure('Name', 'step and pulse response for code debug');

8109

fig=figure('Name', 'step and pulse response for code debug');

8121

figure(fig);set(gcf,'Tag','COM');

8110

figure(fig);set(gcf,'Tag','COM');

8122

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8111

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8123

plot(UI,SRn)

8112

plot(UI,SRn)

8124

hold on

8113

hold on

8125

plot(UI,PR)

8114

plot(UI,PR)

8126

xlim([-param.D_p param.N_v])

8115

xlim([-param.D_p param.N_v])

8127

grid on;hold off;

8116

grid on;hold off;

8128

result.step=SRn;

8117

result.step=SRn;

8129

end

8118

end

8130

i20=find(SRn>=0.20*result.A_f,1,'first');

8119

i20=find(SRn>=0.20*result.A_f,1,'first');

8131

i80=find(SRn>=0.80*result.A_f,1,'first');

8120

i80=find(SRn>=0.80*result.A_f,1,'first');

8132

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8121

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8133

result.Pmax_by_Vf=result.A_p/result.A_f;

8122

result.Pmax_by_Vf=result.A_p/result.A_f;

8134

result.ISI =best_ISI;

8123

result.ISI =best_ISI;

8135

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8124

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8136

result.best_current_ffegain=best_current_ffegain;

8125

result.best_current_ffegain=best_current_ffegain;

8137

result.best_bmax=best_bmax;

8126

result.best_bmax=best_bmax;

8138

%AJG021820

8127

%AJG021820

8139

result.best_bmin=best_bmin;

8128

result.best_bmin=best_bmin;

8140

result.tail_RSS=best_tail_RSS;

8129

result.tail_RSS=best_tail_RSS;

8141

result.sampled_best_sbr_precursors_t=sampled_best_sbr_precursors_t;

8130

result.sampled_best_sbr_precursors_t=sampled_best_sbr_precursors_t;

8142

result.sampled_best_sbr_postcursors_t=sampled_best_sbr_postcursors_t;

8131

result.sampled_best_sbr_postcursors_t=sampled_best_sbr_postcursors_t;

8143

function param=parameter_size_adjustment(param,OP)

8132

function param=parameter_size_adjustment(param,OP)

8144

8133

8145

make_length2={'C_pkg_board' 'C_diepad' 'L_comp' 'C_bump' 'tfx' 'C_v' 'C_0' 'C_1' 'pkg_Z_c' 'brd_Z_c' 'R_diepad'};

8134

make_length2={'C_pkg_board' 'C_diepad' 'L_comp' 'C_bump' 'tfx' 'C_v' 'C_0' 'C_1' 'pkg_Z_c' 'brd_Z_c' 'R_diepad'};

8146

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8135

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8147

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8136

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8148

make_length_DCHP={'f_HP'};

8137

make_length_DCHP={'f_HP'};

8149

make_length_ncases={'AC_CM_RMS'};

8138

make_length_ncases={'AC_CM_RMS'};

8150

8139

8151

%ncases used by make_length_ncases fields

8140

%ncases used by make_length_ncases fields

8152

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8141

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8153

8142

8154

%PORTZ_mult used by make_length_WCPORTZ fields

8143

%PORTZ_mult used by make_length_WCPORTZ fields

8155

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8144

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8156

if OP.WC_PORTZ

8145

if OP.WC_PORTZ

8157

PORTZ_mult=[1 1];

8146

PORTZ_mult=[1 1];

8158

else

8147

else

8159

PORTZ_mult=pkg_sel_vec;

8148

PORTZ_mult=pkg_sel_vec;

8160

end

8149

end

8161

8150

8162

%Parameters that have length = 2

8151

%Parameters that have length = 2

8163

for j=1:length(make_length2)

8152

for j=1:length(make_length2)

8164

if numel(param.(make_length2{j}))==1

8153

if numel(param.(make_length2{j}))==1

8165

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8154

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8166

end

8155

end

8167

end

8156

end

8168

8157

8169

%Parameters that have length = ncases

8158

%Parameters that have length = ncases

8170

for j=1:length(make_length_ncases)

8159

for j=1:length(make_length_ncases)

8171

if numel(param.(make_length_ncases{j}))==1

8160

if numel(param.(make_length_ncases{j}))==1

8172

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8161

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8173

end

8162

end

8174

end

8163

end

8175

8164

8176

%Parameters that have length = length(ctle_gdc_values)

8165

%Parameters that have length = length(ctle_gdc_values)

8177

for j=1:length(make_length_GDC)

8166

for j=1:length(make_length_GDC)

8178

if numel(param.(make_length_GDC{j}))==1

8167

if numel(param.(make_length_GDC{j}))==1

8179

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8168

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8180

end

8169

end

8181

end

8170

end

8182

8171

8183

%Parameters that have length = length(g_DC_HP_values)

8172

%Parameters that have length = length(g_DC_HP_values)

8184

for j=1:length(make_length_DCHP)

8173

for j=1:length(make_length_DCHP)

8185

if numel(param.(make_length_DCHP{j}))==1

8174

if numel(param.(make_length_DCHP{j}))==1

8186

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8175

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8187

end

8176

end

8188

end

8177

end

8189

8178

8190

%Parameters that have length associated with PORTZ_mult

8179

%Parameters that have length associated with PORTZ_mult

8191

for j=1:length(make_length_WCPORTZ)

8180

for j=1:length(make_length_WCPORTZ)

8192

if numel(param.(make_length_WCPORTZ{j}))==1

8181

if numel(param.(make_length_WCPORTZ{j}))==1

8193

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8182

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8194

end

8183

end

8195

end

8184

end

8196

function sgm = pdf2sgm(pdf)

8185

function sgm = pdf2sgm(pdf)

8197

avg = sum(pdf.x .* pdf.y);

8186

avg = sum(pdf.x .* pdf.y);

8198

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8187

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8199

% end yasuo patch

8188

% end yasuo patch

8200

8189

8201

8190

8202

%% adding tx packgage

8191

%% adding tx packgage

8203

function cdf=pdf_to_cdf(pdf)

8192

function cdf=pdf_to_cdf(pdf)

8204

8193

8205

%Transform PDF to CDF

8194

%Transform PDF to CDF

8206

%The CDF is natively calculated from negative-to-positive voltage.

8195

%The CDF is natively calculated from negative-to-positive voltage.

8207

%This only gives BER calculation for bottom eye. Need to also

8196

%This only gives BER calculation for bottom eye. Need to also

8208

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8197

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8209

%min of top and bottom CDF values.

8198

%min of top and bottom CDF values.

8210

%If only interested in one side, a simple cumsum on y is all that is needed.

8199

%If only interested in one side, a simple cumsum on y is all that is needed.

8211

8200

8212

cdf.yB=cumsum(pdf.y);

8201

cdf.yB=cumsum(pdf.y);

8213

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8202

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8214

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8203

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8215

cdf.x=pdf.x;

8204

cdf.x=pdf.x;

8216

function plot_bathtub_curves(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf,jitt_pdf, combined_interference_and_noise_pdf, bin_size)

8205

function plot_bathtub_curves(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf,jitt_pdf, combined_interference_and_noise_pdf, bin_size)

8217

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8206

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8218

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8207

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8219

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8208

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8220

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8209

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8221

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8210

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8222

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8211

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8223

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8212

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8224

%% Added by Bill Kirkland, June 14, 2017

8213

%% Added by Bill Kirkland, June 14, 2017

8225

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8214

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8226

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8215

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8227

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8216

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8228

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8217

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8229

8218

8230

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8219

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8231

hold on

8220

hold on

8232

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8221

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8233

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8222

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8234

semilogy(signal_and_system_noise_pdf.x, abs(cumsum(signal_and_system_noise_pdf.y)-0.5) ,'m','Disp','Jitter, SNR_TX,RL_M, eta_0 noise', 'parent', hax)

8223

semilogy(signal_and_system_noise_pdf.x, abs(cumsum(signal_and_system_noise_pdf.y)-0.5) ,'m','Disp','Jitter, SNR_TX,RL_M, eta_0 noise', 'parent', hax)

8235

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8224

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8236

8225

8237

%% Added by Bill Kirkland, June 14, 2017

8226

%% Added by Bill Kirkland, June 14, 2017

8238

% modification allows bathtub curves to cross over and hence one can

8227

% modification allows bathtub curves to cross over and hence one can

8239

% directly read the noise component.

8228

% directly read the noise component.

8240

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8229

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8241

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8230

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8242

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8231

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8243

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8232

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8244

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8233

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8245

8234

8246

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8235

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8247

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8236

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8248

8237

8249

ylabel(hax, 'Probability')

8238

ylabel(hax, 'Probability')

8250

xlabel(hax, 'volts')

8239

xlabel(hax, 'volts')

8251

legend(hax, 'show')

8240

legend(hax, 'show')

8252

% testing code

8241

% testing code

8253

if 0

8242

if 0

8254

figure_name = 'COM curves';

8243

figure_name = 'COM curves';

8255

fig=findobj('Name', figure_name);

8244

fig=findobj('Name', figure_name);

8256

if isempty(fig), fig=figure('Name', figure_name); end

8245

if isempty(fig), fig=figure('Name', figure_name); end

8257

figure(fig);set(gcf,'Tag','COM');

8246

figure(fig);set(gcf,'Tag','COM');

8258

grid on

8247

grid on

8259

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8248

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8260

hold on

8249

hold on

8261

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8250

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8262

ylim([ 1e-6 0.25])

8251

ylim([ 1e-6 0.25])

8263

xlim([0 30])

8252

xlim([0 30])

8264

grid on

8253

grid on

8265

end

8254

end

8266

function plot_pie_com(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf, combined_interference_and_noise_pdf, bin_size,param)

8255

function plot_pie_com(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf, combined_interference_and_noise_pdf, bin_size,param)

8267

BER=param.specBER;

8256

BER=param.specBER;

8268

delta_dB=param.delta_IL;

8257

delta_dB=param.delta_IL;

8269

8258

8270

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8259

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8271

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8260

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8272

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8261

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8273

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8262

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8274

8263

8275

8264

8276

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8265

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8277

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8266

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8278

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8267

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8279

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8268

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8280

8269

8281

COM=20*log10(max_signal/maxn_tot);

8270

COM=20*log10(max_signal/maxn_tot);

8282

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8271

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8283

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8272

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8284

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8273

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8285

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8274

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8286

8275

8287

pfctr=exp(-0.09054*delta_dB);% less loss

8276

pfctr=exp(-0.09054*delta_dB);% less loss

8288

mfctr=exp(0.09054*delta_dB); % more loss

8277

mfctr=exp(0.09054*delta_dB); % more loss

8289

8278

8290

%less loss

8279

%less loss

8291

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8280

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8292

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8281

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8293

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8282

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8294

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8283

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8295

plus_maxn_tot=norm(plus_maxn);

8284

plus_maxn_tot=norm(plus_maxn);

8296

8285

8297

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8286

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8298

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8287

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8299

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8288

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8300

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8289

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8301

minus_maxn_tot=norm(minus_maxn);

8290

minus_maxn_tot=norm(minus_maxn);

8302

8291

8303

% more loss

8292

% more loss

8304

COMp=20*log10(max_signal*pfctr/maxn_tot);

8293

COMp=20*log10(max_signal*pfctr/maxn_tot);

8305

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8294

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8306

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8295

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8307

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8296

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8308

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8297

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8309

% less loss

8298

% less loss

8310

COMm=20*log10(max_signal*mfctr/maxn_tot);

8299

COMm=20*log10(max_signal*mfctr/maxn_tot);

8311

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8300

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8312

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8301

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8313

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8302

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8314

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8303

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8315

8304

8316

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8305

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8317

8306

8318

8307

8319

if(COM<0)

8308

if(COM<0)

8320

return

8309

return

8321

end

8310

end

8322

8311

8323

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8312

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8324

8313

8325

% pie(COM_per_noise,labels)

8314

% pie(COM_per_noise,labels)

8326

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8315

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8327

% legend('show','Location','bestoutside')

8316

% legend('show','Location','bestoutside')

8328

nullbar= [ 0 0 0 ];

8317

nullbar= [ 0 0 0 ];

8329

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8318

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8330

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8319

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8331

hold on

8320

hold on

8332

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8321

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8333

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8322

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8334

8323

8335

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8324

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8336

% ax=gca;

8325

% ax=gca;

8337

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8326

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8338

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8327

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8339

grid on

8328

grid on

8340

legend(labels,'Location','north')

8329

legend(labels,'Location','north')

8341

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8330

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8342

ylabel('COM (dB)')

8331

ylabel('COM (dB)')

8343

hold off

8332

hold off

8344

8333

8345

8334

8346

8335

8347

8336

8348

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8337

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8349

num_files=length(chdata);

8338

num_files=length(chdata);

8350

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8339

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8351

for i=1:num_files

8340

for i=1:num_files

8352

if param.package_testcase_i==1 && i==1

8341

if param.package_testcase_i==1 && i==1

8353

if OP.TDR && i==1

8342

if OP.TDR && i==1

8354

S.Frequencies=chdata(i).faxis;

8343

S.Frequencies=chdata(i).faxis;

8355

S.Impedance=100;

8344

S.Impedance=100;

8356

if ~OP.SHOW_BRD

8345

if ~OP.SHOW_BRD

8357

Sfield='_orig';

8346

Sfield='_orig';

8358

else

8347

else

8359

Sfield='_raw';

8348

Sfield='_raw';

8360

end

8349

end

8361

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8350

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8362

if ~param.FLAG.S2P

8351

if ~param.FLAG.S2P

8363

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8352

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8364

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8353

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8365

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8354

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8366

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8355

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8367

else

8356

else

8368

S.NumPorts=1;

8357

S.NumPorts=1;

8369

end

8358

end

8370

if OP.TDR_W_TXPKG

8359

if OP.TDR_W_TXPKG

8371

if OP.ERL == 2

8360

if OP.ERL == 2

8372

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8361

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8373

end

8362

end

8374

R_diepad = param.R_diepad;

8363

R_diepad = param.R_diepad;

8375

% RX package length is assumed to be the same for all

8364

% RX package length is assumed to be the same for all

8376

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8365

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8377

% for Rx pkg

8366

% for Rx pkg

8378

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8367

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8379

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8368

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8380

combines4p( s11in, s12in, s21in, s22in, ...

8369

combines4p( s11in, s12in, s21in, s22in, ...

8381

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8370

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8382

% S=sparameters(S.Parameters,S.Frequencies,100);

8371

% S=sparameters(S.Parameters,S.Frequencies,100);

8383

S=SL(S,S.Frequencies,R_diepad(1)*2);

8372

S=SL(S,S.Frequencies,R_diepad(1)*2);

8384

chdata(i).TX_RL=S.Parameters(2,2,:);

8373

chdata(i).TX_RL=S.Parameters(2,2,:);

8385

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8374

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8386

end

8375

end

8387

8376

8388

% need to combine S wiht is page and channel

8377

% need to combine S wiht is page and channel

8389

if param.FLAG.S2P

8378

if param.FLAG.S2P

8390

port_sel=1;

8379

port_sel=1;

8391

else

8380

else

8392

port_sel=[1 2];

8381

port_sel=[1 2];

8393

if OP.AUTO_TFX

8382

if OP.AUTO_TFX

8394

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8383

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8395

pix=find(fir4del==max(fir4del),1);

8384

pix=find(fir4del==max(fir4del),1);

8396

param.tfx(2)=2*tu(pix);

8385

param.tfx(2)=2*tu(pix);

8397

end

8386

end

8398

end

8387

end

8399

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8388

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8400

for ipsl=1:length(port_sel) % do for both port if s4p

8389

for ipsl=1:length(port_sel) % do for both port if s4p

8401

for izt=1:length(param.Z_t) % do for all tdr impedances

8390

for izt=1:length(param.Z_t) % do for all tdr impedances

8402

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8391

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8403

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8392

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8404

% OP.interp_sparam_mag='trend_to_DC';

8393

% OP.interp_sparam_mag='trend_to_DC';

8405

OP.interp_sparam_mag='linear_trend_to_DC';

8394

OP.interp_sparam_mag='linear_trend_to_DC';

8406

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8395

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8407

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8396

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8408

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8397

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8409

if ipsl ==1

8398

if ipsl ==1

8410

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8399

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8411

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8400

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8412

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8401

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8413

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8402

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8414

else

8403

else

8415

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8404

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8416

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8405

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8417

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8406

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8418

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8407

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8419

end

8408

end

8420

if OP.PTDR && i==1

8409

if OP.PTDR && i==1

8421

if ipsl ==1

8410

if ipsl ==1

8422

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8411

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8423

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8412

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8424

else

8413

else

8425

if ~param.FLAG.S2P

8414

if ~param.FLAG.S2P

8426

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8415

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8427

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8416

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8428

else

8417

else

8429

chdata(i).TDR22(izt).ERL=[];

8418

chdata(i).TDR22(izt).ERL=[];

8430

chdata(i).TDR22(izt).ERLRMS=[];

8419

chdata(i).TDR22(izt).ERLRMS=[];

8431

end

8420

end

8432

end

8421

end

8433

else

8422

else

8434

chdata(i).TDR11(izt).ERL=[];

8423

chdata(i).TDR11(izt).ERL=[];

8435

chdata(i).TDR22(izt).ERL=[];

8424

chdata(i).TDR22(izt).ERL=[];

8436

chdata(i).TDR11(izt).ERLRMS=[];

8425

chdata(i).TDR11(izt).ERLRMS=[];

8437

chdata(i).TDR22(izt).ERLRMS=[];

8426

chdata(i).TDR22(izt).ERLRMS=[];

8438

end

8427

end

8439

end

8428

end

8440

end

8429

end

8441

end

8430

end

8442

8431

8443

end

8432

end

8444

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8433

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8445

h=figure(180);set(gcf,'Tag','COM');

8434

h=figure(180);set(gcf,'Tag','COM');

8446

if param.package_testcase_i==1 && i == 1

8435

if param.package_testcase_i==1 && i == 1

8447

if i==1

8436

if i==1

8448

htabgroup = uitabgroup(h);

8437

htabgroup = uitabgroup(h);

8449

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8438

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8450

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8439

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8451

hax1 = axes('Parent', htab1);

8440

hax1 = axes('Parent', htab1);

8452

hax3 = axes('Parent', htab3);

8441

hax3 = axes('Parent', htab3);

8453

if ~param.FLAG.S2P

8442

if ~param.FLAG.S2P

8454

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8443

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8455

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8444

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8456

hax2 = axes('Parent', htab2);

8445

hax2 = axes('Parent', htab2);

8457

hax4 = axes('Parent', htab4);

8446

hax4 = axes('Parent', htab4);

8458

end

8447

end

8459

end

8448

end

8460

set(h,'CurrentAxes',hax1)

8449

set(h,'CurrentAxes',hax1)

8461

hold on

8450

hold on

8462

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8451

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8463

hold off

8452

hold off

8464

legend (hax1, 'off');grid on;zoom xon;

8453

legend (hax1, 'off');grid on;zoom xon;

8465

set(legend (hax1, 'show'), 'interp', 'none');

8454

set(legend (hax1, 'show'), 'interp', 'none');

8466

8455

8467

if ~param.FLAG.S2P

8456

if ~param.FLAG.S2P

8468

set(h,'CurrentAxes',hax2)

8457

set(h,'CurrentAxes',hax2)

8469

hold on

8458

hold on

8470

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8459

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8471

hold off

8460

hold off

8472

legend (hax2, 'off');grid on;zoom xon;

8461

legend (hax2, 'off');grid on;zoom xon;

8473

set(legend (hax2, 'show'), 'interp', 'none');

8462

set(legend (hax2, 'show'), 'interp', 'none');

8474

end

8463

end

8475

8464

8476

set(h,'CurrentAxes',hax3)

8465

set(h,'CurrentAxes',hax3)

8477

hold on

8466

hold on

8478

if OP.PTDR

8467

if OP.PTDR

8479

for izt=1:length(param.Z_t)

8468

for izt=1:length(param.Z_t)

8480

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8469

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8481

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8470

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8482

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8471

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8483

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8472

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8484

end

8473

end

8485

end

8474

end

8486

hold off

8475

hold off

8487

legend (hax3, 'off');grid on;zoom xon;

8476

legend (hax3, 'off');grid on;zoom xon;

8488

set(legend (hax3, 'show'), 'interp', 'none');

8477

set(legend (hax3, 'show'), 'interp', 'none');

8489

if ~param.FLAG.S2P

8478

if ~param.FLAG.S2P

8490

set(h,'CurrentAxes',hax4)

8479

set(h,'CurrentAxes',hax4)

8491

hold on

8480

hold on

8492

if OP.PTDR

8481

if OP.PTDR

8493

for izt=1:length(param.Z_t)

8482

for izt=1:length(param.Z_t)

8494

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8483

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8495

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8484

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8496

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8485

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8497

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8486

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8498

end

8487

end

8499

end

8488

end

8500

hold off

8489

hold off

8501

legend (hax4, 'off');grid on;zoom xon;

8490

legend (hax4, 'off');grid on;zoom xon;

8502

set(legend (hax4, 'show'), 'interp', 'none');

8491

set(legend (hax4, 'show'), 'interp', 'none');

8503

end

8492

end

8504

end

8493

end

8505

end

8494

end

8506

if param.FLAG.S2P, return; end

8495

if param.FLAG.S2P, return; end

8507

end

8496

end

8508

function S =r_parrelell2(zref,f,rpad)

8497

function S =r_parrelell2(zref,f,rpad)

8509

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8498

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8510

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8499

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8511

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8500

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8512

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8501

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8513

% Sm=sparameters(S.Parameters,f,zref);

8502

% Sm=sparameters(S.Parameters,f,zref);

8514

8503

8515

8504

8516

8505

8517

8506

8518

8507

8519

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8508

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8520

8509

8521

%touchstone_file: .sNp touchstone file to read

8510

%touchstone_file: .sNp touchstone file to read

8522

%port_order: port reorder vector

8511

%port_order: port reorder vector

8523

%

8512

%

8524

%sch: sparameter matrix

8513

%sch: sparameter matrix

8525

%schFreqAxis: frequency axis

8514

%schFreqAxis: frequency axis

8526

8515

8527

[file_path,root_name,extension]=fileparts(touchstone_file);

8516

[file_path,root_name,extension]=fileparts(touchstone_file);

8528

fid=fopen(touchstone_file);

8517

fid=fopen(touchstone_file);

8529

8518

8530

%fetch number of ports from extension

8519

%fetch number of ports from extension

8531

num_ports=str2num(char(regexp(extension,'\d*','match')));

8520

num_ports=str2num(char(regexp(extension,'\d*','match')));

8532

8521

8533

%Get option line

8522

%Get option line

8534

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8523

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8535

optcell=textscan(optstr{1}{1},'%s');

8524

optcell=textscan(optstr{1}{1},'%s');

8536

optcell=optcell{1};

8525

optcell=optcell{1};

8537

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8526

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8538

%Some touchstone files need this. can't remember why now. maybe lines

8527

%Some touchstone files need this. can't remember why now. maybe lines

8539

%with whitespace but not empty but not commented

8528

%with whitespace but not empty but not commented

8540

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8529

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8541

optcell=textscan(optstr{1}{1},'%s');

8530

optcell=textscan(optstr{1}{1},'%s');

8542

optcell=optcell{1};

8531

optcell=optcell{1};

8543

end

8532

end

8544

8533

8545

%read the entire file

8534

%read the entire file

8546

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8535

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8547

raw_column_data=raw_read_data{1};

8536

raw_column_data=raw_read_data{1};

8548

fclose(fid);

8537

fclose(fid);

8549

8538

8550

%number of columns for 2D matrix

8539

%number of columns for 2D matrix

8551

columns=num_ports*num_ports*2+1;

8540

columns=num_ports*num_ports*2+1;

8552

8541

8553

%find the frequency lines by searching for the right number of NaN

8542

%find the frequency lines by searching for the right number of NaN

8554

a=sum(isnan(raw_column_data),2);

8543

a=sum(isnan(raw_column_data),2);

8555

if num_ports==3

8544

if num_ports==3

8556

b=find(a==2);

8545

b=find(a==2);

8557

elseif num_ports==1

8546

elseif num_ports==1

8558

b=find(a==6);

8547

b=find(a==6);

8559

else

8548

else

8560

b=find(a==0);

8549

b=find(a==0);

8561

end

8550

end

8562

8551

8563

num_freq=length(b);

8552

num_freq=length(b);

8564

8553

8565

%toss out the NaN and reshape into a 2D matrix

8554

%toss out the NaN and reshape into a 2D matrix

8566

raw_input = raw_column_data.';

8555

raw_input = raw_column_data.';

8567

raw_input = raw_input(~isnan(raw_input));

8556

raw_input = raw_input(~isnan(raw_input));

8568

raw_input = reshape(raw_input,columns,num_freq).';

8557

raw_input = reshape(raw_input,columns,num_freq).';

8569

8558

8570

%get the frequency mult

8559

%get the frequency mult

8571

frequency_mult_text=optcell{2};

8560

frequency_mult_text=optcell{2};

8572

if(strcmpi(frequency_mult_text,'hz'))

8561

if(strcmpi(frequency_mult_text,'hz'))

8573

frequency_mult=1;

8562

frequency_mult=1;

8574

elseif(strcmpi(frequency_mult_text,'khz'))

8563

elseif(strcmpi(frequency_mult_text,'khz'))

8575

frequency_mult=1e3;

8564

frequency_mult=1e3;

8576

elseif(strcmpi(frequency_mult_text,'mhz'))

8565

elseif(strcmpi(frequency_mult_text,'mhz'))

8577

frequency_mult=1e6;

8566

frequency_mult=1e6;

8578

elseif(strcmpi(frequency_mult_text,'ghz'))

8567

elseif(strcmpi(frequency_mult_text,'ghz'))

8579

frequency_mult=1e9;

8568

frequency_mult=1e9;

8580

else

8569

else

8581

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8570

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8582

end

8571

end

8583

8572

8584

%get the RI/MA/DB format

8573

%get the RI/MA/DB format

8585

format=optcell{4};

8574

format=optcell{4};

8586

%get Z0

8575

%get Z0

8587

port_impedance=str2double(optcell(6:end))';

8576

port_impedance=str2double(optcell(6:end))';

8588

8577

8589

8578

8590

%grab frequency

8579

%grab frequency

8591

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8580

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8592

Spar.F=raw_input(:,1);

8581

Spar.F=raw_input(:,1);

8593

Spar.F=transpose(Spar.F(:));

8582

Spar.F=transpose(Spar.F(:));

8594

8583

8595

8584

8596

%transform data to real imaginary

8585

%transform data to real imaginary

8597

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8586

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8598

if(strcmpi(format,'ri'))

8587

if(strcmpi(format,'ri'))

8599

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8588

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8600

elseif(strcmpi(format,'ma'))

8589

elseif(strcmpi(format,'ma'))

8601

mag_data=raw_input(:,2:2:end);

8590

mag_data=raw_input(:,2:2:end);

8602

rad_data=raw_input(:,3:2:end)*pi/180;

8591

rad_data=raw_input(:,3:2:end)*pi/180;

8603

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8592

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8604

elseif(strcmpi(format,'db'))

8593

elseif(strcmpi(format,'db'))

8605

mag_data=10.^(raw_input(:,2:2:end)/20);

8594

mag_data=10.^(raw_input(:,2:2:end)/20);

8606

rad_data=raw_input(:,3:2:end)*pi/180;

8595

rad_data=raw_input(:,3:2:end)*pi/180;

8607

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8596

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8608

else

8597

else

8609

error('Format %s is not supported. Use RI MA or DB',format);

8598

error('Format %s is not supported. Use RI MA or DB',format);

8610

end

8599

end

8611

8600

8612

8601

8613

8602

8614

%transform to 3D

8603

%transform to 3D

8615

%allow for upper/lower matrix specification for touchstone 2.0 support

8604

%allow for upper/lower matrix specification for touchstone 2.0 support

8616

matrix_format=0;

8605

matrix_format=0;

8617

if(matrix_format==0)

8606

if(matrix_format==0)

8618

%full

8607

%full

8619

for j=1:num_ports

8608

for j=1:num_ports

8620

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8609

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8621

end

8610

end

8622

elseif(matrix_format==1)

8611

elseif(matrix_format==1)

8623

%upper

8612

%upper

8624

used_ports=0;

8613

used_ports=0;

8625

for j=1:num_ports

8614

for j=1:num_ports

8626

stated_ports=num_ports-j+1;

8615

stated_ports=num_ports-j+1;

8627

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8616

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8628

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8617

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8629

used_ports=used_ports+stated_ports;

8618

used_ports=used_ports+stated_ports;

8630

end

8619

end

8631

elseif(matrix_format==2)

8620

elseif(matrix_format==2)

8632

%lower

8621

%lower

8633

used_ports=0;

8622

used_ports=0;

8634

for j=1:num_ports

8623

for j=1:num_ports

8635

stated_ports=j;

8624

stated_ports=j;

8636

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8625

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8637

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8626

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8638

used_ports=used_ports+stated_ports;

8627

used_ports=used_ports+stated_ports;

8639

end

8628

end

8640

else

8629

else

8641

error('Matrix format is not supported. Use Full, Lower, or Upper');

8630

error('Matrix format is not supported. Use Full, Lower, or Upper');

8642

end

8631

end

8643

8632

8644

8633

8645

%check for swapping the 2 port matrix (required on 1.x spec)

8634

%check for swapping the 2 port matrix (required on 1.x spec)

8646

two_port_swap=1;

8635

two_port_swap=1;

8647

if(num_ports==2 && two_port_swap==1)

8636

if(num_ports==2 && two_port_swap==1)

8648

temp=pre_out.sp(1,2,:);

8637

temp=pre_out.sp(1,2,:);

8649

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8638

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8650

pre_out.sp(2,1,:)=temp;

8639

pre_out.sp(2,1,:)=temp;

8651

end

8640

end

8652

8641

8653

Spar.S=pre_out.sp;

8642

Spar.S=pre_out.sp;

8654

Spar.Z0=transpose(port_impedance(:));

8643

Spar.Z0=transpose(port_impedance(:));

8655

8644

8656

if length(Spar.Z0)>1

8645

if length(Spar.Z0)>1

8657

error('Each port must have the same reference impedance');

8646

error('Each port must have the same reference impedance');

8658

end

8647

end

8659

if ~isequal(Spar.Z0,50)

8648

if ~isequal(Spar.Z0,50)

8660

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8649

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8661

%Renormalize to 50 ohms

8650

%Renormalize to 50 ohms

8662

rho=(50-Spar.Z0)/(50+Spar.Z0);

8651

rho=(50-Spar.Z0)/(50+Spar.Z0);

8663

p=num_ports;

8652

p=num_ports;

8664

s_old=Spar.S;

8653

s_old=Spar.S;

8665

for k=1:num_freq

8654

for k=1:num_freq

8666

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8655

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8667

end

8656

end

8668

end

8657

end

8669

8658

8670

%These operations sync up with COM style Spar matrix

8659

%These operations sync up with COM style Spar matrix

8671

%1: put frequency as first dimension

8660

%1: put frequency as first dimension

8672

sch=shiftdim(Spar.S,2);

8661

sch=shiftdim(Spar.S,2);

8673

%2: reorder ports according to "ports" input

8662

%2: reorder ports according to "ports" input

8674

sch=sch(:,port_order,port_order);

8663

sch=sch(:,port_order,port_order);

8675

schFreqAxis=Spar.F;

8664

schFreqAxis=Spar.F;

8676

function [chdata, param] = read_PR_files(param, OP, chdata)

8665

function [chdata, param] = read_PR_files(param, OP, chdata)

8677

%% Read in pulse response

8666

%% Read in pulse response

8678

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8667

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8679

num_files=length(chdata);

8668

num_files=length(chdata);

8680

M=param.samples_per_ui;

8669

M=param.samples_per_ui;

8681

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8670

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8682

for i=1:num_files

8671

for i=1:num_files

8683

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8672

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8684

progress = i/num_files;

8673

progress = i/num_files;

8685

if OP.DISPLAY_WINDOW

8674

if OP.DISPLAY_WINDOW

8686

[~,a]=fileparts(chdata(i).filename);

8675

[~,a]=fileparts(chdata(i).filename);

8687

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8676

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8688

else

8677

else

8689

fprintf('%i ',i);

8678

fprintf('%i ',i);

8690

end

8679

end

8691

switch chdata(i).ext

8680

switch chdata(i).ext

8692

case '.csv'

8681

case '.csv'

8693

vt=load(chdata(i).filename);

8682

vt=load(chdata(i).filename);

8694

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8683

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8695

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8684

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8696

dt=vt(2,1)-vt(1,1);

8685

dt=vt(2,1)-vt(1,1);

8697

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8686

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8698

8687

8699

8688

8700

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8689

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8701

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8690

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8702

Vf=step_response(end);

8691

Vf=step_response(end);

8703

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8692

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8704

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8693

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8705

8694

8706

end

8695

end

8707

end

8696

end

8708

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8697

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8709

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8698

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8710

[filepath,name,ext] = fileparts(paramFile);

8699

[filepath,name,ext] = fileparts(paramFile);

8711

if ~isempty(filepath)

8700

if ~isempty(filepath)

8712

filepath=[filepath '\'];

8701

filepath=[filepath '\'];

8713

end

8702

end

8714

matcongfile=[filepath name '.mat'];

8703

matcongfile=[filepath name '.mat'];

8715

try

8704

try

8716

switch upper(ext)

8705

switch upper(ext)

8717

case upper('.mat')

8706

case upper('.mat')

8718

load(matcongfile)

8707

load(matcongfile)

8719

case upper('.csv')

8708

case upper('.csv')

8720

[na1, na2, parameter] = xlsread(paramFile);

8709

[na1, na2, parameter] = xlsread(paramFile);

8721

otherwise

8710

otherwise

8722

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8711

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8723

end

8712

end

8724

8713

8725

catch ME %#ok<NASGU>

8714

catch ME %#ok<NASGU>

8726

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8715

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8727

switch upper(ext)

8716

switch upper(ext)

8728

case upper('.mat')

8717

case upper('.mat')

8729

load(matcongfile)

8718

load(matcongfile)

8730

case upper('.csv')

8719

case upper('.csv')

8731

[na1, na2, parameter] = xlsread(paramFile);

8720

[na1, na2, parameter] = xlsread(paramFile);

8732

otherwise

8721

otherwise

8733

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8722

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8734

end

8723

end

8735

end

8724

end

8736

8725

8737

%% New section to parse .START package data

8726

%% New section to parse .START package data

8738

first_column_data = parameter(:,1);

8727

first_column_data = parameter(:,1);

8739

start_data_rows = find(strcmp(first_column_data,'.START'));

8728

start_data_rows = find(strcmp(first_column_data,'.START'));

8740

if ~isempty(start_data_rows)

8729

if ~isempty(start_data_rows)

8741

end_data_rows = find(strcmp(first_column_data,'.END'));

8730

end_data_rows = find(strcmp(first_column_data,'.END'));

8742

if length(start_data_rows) ~= length(end_data_rows)

8731

if length(start_data_rows) ~= length(end_data_rows)

8743

error('Number of .START and .END must be the same');

8732

error('Number of .START and .END must be the same');

8744

end

8733

end

8745

first_start_row = start_data_rows(1);

8734

first_start_row = start_data_rows(1);

8746

special_parameter = parameter;

8735

special_parameter = parameter;

8747

parameter = parameter(1:first_start_row-1,:);

8736

parameter = parameter(1:first_start_row-1,:);

8748

for j=1:length(start_data_rows)

8737

for j=1:length(start_data_rows)

8749

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

8738

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

8750

pkg_name = special_parameter{start_data_rows(j),2};

8739

pkg_name = special_parameter{start_data_rows(j),2};

8751

8740

8752

%Read all the parameters that make up a package

8741

%Read all the parameters that make up a package

8753

PKG_param = read_package_parameters(this_block);

8742

PKG_param = read_package_parameters(this_block);

8754

8743

8755

%save the data in a field revealed by pkg_name

8744

%save the data in a field revealed by pkg_name

8756

param.PKG.(pkg_name) = PKG_param;

8745

param.PKG.(pkg_name) = PKG_param;

8757

8746

8758

8747

8759

end

8748

end

8760

end

8749

end

8761

%Allow specification of TX and RX package section through PKG_NAME keyword

8750

%Allow specification of TX and RX package section through PKG_NAME keyword

8762

%the values must match package blocks specified in .START sections

8751

%the values must match package blocks specified in .START sections

8763

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

8752

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

8764

if isnan(param.PKG_NAME)

8753

if isnan(param.PKG_NAME)

8765

param.PKG_NAME = '';

8754

param.PKG_NAME = '';

8766

end

8755

end

8767

if isempty(param.PKG_NAME)

8756

if isempty(param.PKG_NAME)

8768

param.PKG_NAME = {};

8757

param.PKG_NAME = {};

8769

else

8758

else

8770

param.PKG_NAME = strsplit(param.PKG_NAME);

8759

param.PKG_NAME = strsplit(param.PKG_NAME);

8771

end

8760

end

8772

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

8761

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

8773

error('PKG_NAME can only be used if .START blocks for package parameters are used');

8762

error('PKG_NAME can only be used if .START blocks for package parameters are used');

8774

end

8763

end

8775

for j=1:length(param.PKG_NAME)

8764

for j=1:length(param.PKG_NAME)

8776

if ~isfield(param.PKG,param.PKG_NAME{j})

8765

if ~isfield(param.PKG,param.PKG_NAME{j})

8777

error('Package Block "%s" not found',param.PKG_NAME{j});

8766

error('Package Block "%s" not found',param.PKG_NAME{j});

8778

end

8767

end

8779

end

8768

end

8780

8769

8781

%%

8770

%%

8782

% just need to define so we can pass

8771

% just need to define so we can pass

8783

param.c=[.4e-12 .4e-12];

8772

param.c=[.4e-12 .4e-12];

8784

param.alen=[ 20 30 550 ];

8773

param.alen=[ 20 30 550 ];

8785

param.az=[100 120 100];

8774

param.az=[100 120 100];

8786

8775

8787

% make control for package/channel reflection control

8776

% make control for package/channel reflection control

8788

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

8777

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

8789

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

8778

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

8790

8779

8791

% make compatible with presentation of kappa

8780

% make compatible with presentation of kappa

8792

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

8781

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

8793

8782

8794

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

8783

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

8795

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

8784

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

8796

8785

8797

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

8786

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

8798

param.f2 = xls_parameter(parameter, 'f_2', true, param.fb/1e9 )*1e9; % frequency in GHz for intergration compuation of ICN or FOM_Ild in GHz

8787

param.f2 = xls_parameter(parameter, 'f_2', true, param.fb/1e9 )*1e9; % frequency in GHz for intergration compuation of ICN or FOM_Ild in GHz

8799

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

8788

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

8800

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

8789

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

8801

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

8790

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

8802

param.tx_ffe_c0_min = xls_parameter(parameter, 'c(0)', false); % TX equalizer cursor minimum value (actual value is calculated as 1-sum(abs(tap)), Grid seat ingored for when C(0) is below this value

8791

param.tx_ffe_c0_min = xls_parameter(parameter, 'c(0)', false); % TX equalizer cursor minimum value (actual value is calculated as 1-sum(abs(tap)), Grid seat ingored for when C(0) is below this value

8803

8792

8804

if OP.dynamic_txffe

8793

if OP.dynamic_txffe

8805

found_pre=1;

8794

found_pre=1;

8806

pre_count=1;

8795

pre_count=1;

8807

while found_pre

8796

while found_pre

8808

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

8797

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

8809

if found_pre

8798

if found_pre

8810

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

8799

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

8811

param.(field_name)=p;

8800

param.(field_name)=p;

8812

pre_count=pre_count+1;

8801

pre_count=pre_count+1;

8813

end

8802

end

8814

end

8803

end

8815

found_post=1;

8804

found_post=1;

8816

post_count=1;

8805

post_count=1;

8817

while found_post

8806

while found_post

8818

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

8807

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

8819

if found_post

8808

if found_post

8820

field_name=sprintf('tx_ffe_cp%d_values',post_count);

8809

field_name=sprintf('tx_ffe_cp%d_values',post_count);

8821

param.(field_name)=p;

8810

param.(field_name)=p;

8822

post_count=post_count+1;

8811

post_count=post_count+1;

8823

end

8812

end

8824

end

8813

end

8825

else

8814

else

8826

param.tx_ffe_cm4_values = xls_parameter(parameter, 'c(-4)', true,0); % TX equalizer pre cursor tap -4 individual settings or range. If not present ignored

8815

param.tx_ffe_cm4_values = xls_parameter(parameter, 'c(-4)', true,0); % TX equalizer pre cursor tap -4 individual settings or range. If not present ignored

8827

param.tx_ffe_cm3_values = xls_parameter(parameter, 'c(-3)', true,0); % TX equalizer pre cursor tap -3 individual settings or range. If not present ignored

8816

param.tx_ffe_cm3_values = xls_parameter(parameter, 'c(-3)', true,0); % TX equalizer pre cursor tap -3 individual settings or range. If not present ignored

8828

param.tx_ffe_cm2_values = xls_parameter(parameter, 'c(-2)', true,0); % TX equalizer pre cursor tap -2 individual settings or range. If not present ignored

8817

param.tx_ffe_cm2_values = xls_parameter(parameter, 'c(-2)', true,0); % TX equalizer pre cursor tap -2 individual settings or range. If not present ignored

8829

param.tx_ffe_cm1_values = xls_parameter(parameter, 'c(-1)', true,0); % TX equalizer pre cursor tap -1 individual settings or range. If not present ignored

8818

param.tx_ffe_cm1_values = xls_parameter(parameter, 'c(-1)', true,0); % TX equalizer pre cursor tap -1 individual settings or range. If not present ignored

8830

param.tx_ffe_cp1_values = xls_parameter(parameter, 'c(1)', true,0); % TX equalizer post cursor tap 1 individual settings or range. If not present ignored

8819

param.tx_ffe_cp1_values = xls_parameter(parameter, 'c(1)', true,0); % TX equalizer post cursor tap 1 individual settings or range. If not present ignored

8831

param.tx_ffe_cp2_values = xls_parameter(parameter, 'c(2)', true,0); % TX equalizer post cursor tap 2 individual settings or range. If not present ignored

8820

param.tx_ffe_cp2_values = xls_parameter(parameter, 'c(2)', true,0); % TX equalizer post cursor tap 2 individual settings or range. If not present ignored

8832

param.tx_ffe_cp3_values = xls_parameter(parameter, 'c(3)', true,0); % TX equalizer post cursor tap 3 individual settings or range. If not present ignored

8821

param.tx_ffe_cp3_values = xls_parameter(parameter, 'c(3)', true,0); % TX equalizer post cursor tap 3 individual settings or range. If not present ignored

8833

end

8822

end

8834

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

8823

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

8835

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

8824

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

8836

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

8825

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

8837

param.N_bx = xls_parameter(parameter, 'N_bx', true, param.ndfe ); % Used for ERL to Compensate for a number of Ui assoicated with the DFE

8826

param.N_bx = xls_parameter(parameter, 'N_bx', true, param.ndfe ); % Used for ERL to Compensate for a number of Ui assoicated with the DFE

8838

% support for floating taps

8827

% support for floating taps

8839

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

8828

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

8840

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

8829

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

8841

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

8830

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

8842

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

8831

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

8843

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

8832

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

8844

if param.N_bg == 0, param.N_bmax=param.ndfe; end

8833

if param.N_bg == 0, param.N_bmax=param.ndfe; end

8845

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

8834

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

8846

8835

8847

% support for tail tap power limitations

8836

% support for tail tap power limitations

8848

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

8837

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

8849

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

8838

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

8850

%

8839

%

8851

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

8840

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

8852

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

8841

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

8853

param.RxFFE_cmx=param.ffe_pre_tap_len;

8842

param.RxFFE_cmx=param.ffe_pre_tap_len;

8854

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

8843

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

8855

param.RxFFE_cpx=param.ffe_post_tap_len;

8844

param.RxFFE_cpx=param.ffe_post_tap_len;

8856

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

8845

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

8857

param.RxFFE_stepz=param.ffe_tap_step_size;

8846

param.RxFFE_stepz=param.ffe_tap_step_size;

8858

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

8847

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

8859

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

8848

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

8860

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

8849

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

8861

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

8850

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

8862

param.ffe_backoff=xls_parameter(parameter, 'ffe_backoff', true,0); % see if better zero foreced solution is better by backing off the number specified FFE taps one at at time

8851

param.ffe_backoff=xls_parameter(parameter, 'ffe_backoff', true,0); % see if better zero foreced solution is better by backing off the number specified FFE taps one at at time

8863

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

8852

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

8864

OP.RxFFE= true;

8853

OP.RxFFE= true;

8865

else

8854

else

8866

OP.RxFFE=false;

8855

OP.RxFFE=false;

8867

end

8856

end

8868

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

8857

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

8869

8858

8870

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

8859

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

8871

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

8860

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

8872

param.f_HP_Z = 1e9*xls_parameter(parameter, 'f_HP_Z', true, []); % CFT zero fz1 is in GHz. Normally a list for 120e. Not normally use elsewise

8861

param.f_HP_Z = 1e9*xls_parameter(parameter, 'f_HP_Z', true, []); % CFT zero fz1 is in GHz. Normally a list for 120e. Not normally use elsewise

8873

param.f_HP_P = 1e9*xls_parameter(parameter, 'f_HP_P', true, []); % CFT pole fp2 is in GHz. Normally a list for 120e. Not normally use elsewise

8862

param.f_HP_P = 1e9*xls_parameter(parameter, 'f_HP_P', true, []); % CFT pole fp2 is in GHz. Normally a list for 120e. Not normally use elsewise

8874

8863

8875

8864

8876

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

8865

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

8877

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

8866

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

8878

param.Min_VEO_Test= xls_parameter(parameter, 'EH_min_test', true,0); % Older syntax. Used when PMD_type is C2M. This allow EH to go below EH_min. If set to zero it is ignored (same as Min_VEO_test)

8867

param.Min_VEO_Test= xls_parameter(parameter, 'EH_min_test', true,0); % Older syntax. Used when PMD_type is C2M. This allow EH to go below EH_min. If set to zero it is ignored (same as Min_VEO_test)

8879

param.Min_VEO_Test= xls_parameter(parameter, 'Min_VEO_Test', true,param.Min_VEO_Test); % used when PMD_type is C2M. This allow EH to go blow EH_min. If set to Zero it is ignored

8868

param.Min_VEO_Test= xls_parameter(parameter, 'Min_VEO_Test', true,param.Min_VEO_Test); % used when PMD_type is C2M. This allow EH to go blow EH_min. If set to Zero it is ignored

8880

8869

8881

param.CTLE_type= xls_parameter(parameter, 'CTLE_type', false,'CL93'); % Sets the CTLE type default is poles and zeros (i.e. not a list of poles as in 120e)

8870

param.CTLE_type= xls_parameter(parameter, 'CTLE_type', false,'CL93'); % Sets the CTLE type default is poles and zeros (i.e. not a list of poles as in 120e)

8882

if ~isempty(param.g_DC_HP_values) ; param.CTLE_type='CL120d';end % overrides CL93 if g_DC_HP_values are a spreadsheet entry. Mostly used when baud rare is >= 50Gbps

8871

if ~isempty(param.g_DC_HP_values) ; param.CTLE_type='CL120d';end % overrides CL93 if g_DC_HP_values are a spreadsheet entry. Mostly used when baud rare is >= 50Gbps

8883

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

8872

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

8884

% always read in main ctle values. They would be interpreted different baseed

8873

% always read in main ctle values. They would be interpreted different baseed

8885

% on the clause they apply because of different CTF equations

8874

% on the clause they apply because of different CTF equations

8886

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

8875

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

8887

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8876

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8888

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8877

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8889

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8878

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8890

% the contex of the poles an zeros are determined by the clause

8879

% the contex of the poles an zeros are determined by the clause

8891

switch param.CTLE_type

8880

switch param.CTLE_type

8892

case 'CL93'

8881

case 'CL93'

8893

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % Continuous time filter DC gain settings (G_DC) or range as specified in Annex 93A

8882

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % Continuous time filter DC gain settings (G_DC) or range as specified in Annex 93A

8894

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8883

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8895

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8884

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8896

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8885

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8897

case 'CL120d'

8886

case 'CL120d'

8898

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

8887

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

8899

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

8888

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

8900

case 'CL120e'

8889

case 'CL120e'

8901

% re adjust to get TD_CTLE to work with C:120e equation without

8890

% re adjust to get TD_CTLE to work with C:120e equation without

8902

% changing TD_CTLE code

8891

% changing TD_CTLE code

8903

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

8892

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

8904

end

8893

end

8905

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

8894

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

8906

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

8895

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

8907

%% addd default to support multiple packages

8896

%% addd default to support multiple packages

8908

param.a_thru = xls_parameter(parameter, 'A_v', true, 0.5); % Victim differential peak source output voltage (half of peak to peak)

8897

param.a_thru = xls_parameter(parameter, 'A_v', true, 0.5); % Victim differential peak source output voltage (half of peak to peak)

8909

param.a_fext = xls_parameter(parameter, 'A_fe', true,0.5); % FEXT aggressor differential peak source output voltage (half of peak to peak)

8898

param.a_fext = xls_parameter(parameter, 'A_fe', true,0.5); % FEXT aggressor differential peak source output voltage (half of peak to peak)

8910

param.a_next = xls_parameter(parameter, 'A_ne', true,0.5); % NEXT aggressor differential peak source output voltage (half of peak to peak)

8899

param.a_next = xls_parameter(parameter, 'A_ne', true,0.5); % NEXT aggressor differential peak source output voltage (half of peak to peak)

8911

param.a_icn_fext = xls_parameter(parameter, 'A_ft', true, param.a_fext); % FEXT aggressor amplitude for ICN. Defaults to A_fe if not specified

8900

param.a_icn_fext = xls_parameter(parameter, 'A_ft', true, param.a_fext); % FEXT aggressor amplitude for ICN. Defaults to A_fe if not specified

8912

param.a_icn_next = xls_parameter(parameter, 'A_nt', true, param.a_next );% NEXT aggressor amplitude for ICN. Defaults to A_ne if not specified

8901

param.a_icn_next = xls_parameter(parameter, 'A_nt', true, param.a_next );% NEXT aggressor amplitude for ICN. Defaults to A_ne if not specified

8913

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

8902

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

8914

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

8903

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

8915

param.DER_CDR = xls_parameter(parameter, 'DER_CDR',true,1e-2); % min DER required for a CDR

8904

param.DER_CDR = xls_parameter(parameter, 'DER_CDR',true,1e-2); % min DER required for a CDR

8916

param.N_qb = xls_parameter(parameter, 'N_qb',true,0); % adc number of bits if 0 do not apply quantization

8905

param.ENOB = xls_parameter(parameter, 'ENOB',true,0); % adc number of bits if 0 do not apply quantization

8917

param.P_qc= xls_parameter(parameter, 'P_qc',true,2*param.specBER); % adc clipping probability

8906

param.adc_clip_rate= xls_parameter(parameter, 'adc_clip_rate',true,2*param.specBER); % adc clipping probability

8918

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

8907

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

8919

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

8908

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

8920

param.VEC_pass_threshold = xls_parameter(parameter, 'VEC Pass threshold',false,0);% the pass fail threshold for VEC in dB only used when PMD_type is C2M

8909

param.VEC_pass_threshold = xls_parameter(parameter, 'VEC Pass threshold',false,0);% the pass fail threshold for VEC in dB only used when PMD_type is C2M

8921

8910

8922

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

8911

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

8923

param.A_DD = xls_parameter(parameter, 'A_DD'); % Normalized peak dual-Dirac noise, this is half of the total bound uncorrelated jitter (BUJ) in UI

8912

param.A_DD = xls_parameter(parameter, 'A_DD'); % Normalized peak dual-Dirac noise, this is half of the total bound uncorrelated jitter (BUJ) in UI

8924

param.eta_0 = xls_parameter(parameter, 'eta_0'); % One-sided noise spectral density (V^2/GHz).Input refered noise at TP5. Input referred noise at TP5

8913

param.eta_0 = xls_parameter(parameter, 'eta_0'); % One-sided noise spectral density (V^2/GHz).Input refered noise at TP5. Input referred noise at TP5

8925

% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

8914

% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

8926

param.trunc = xls_parameter(parameter, 'trunc', true, 128); % MLSE sequence truncation length

8915

param.trunc = xls_parameter(parameter, 'trunc', true, 128); % MLSE sequence truncation length

8927

param.trunc = xls_parameter(parameter, 'N_tc', true, param.trunc); % MLSE sequence truncation length

8916

param.trunc = xls_parameter(parameter, 'N_tc', true, param.trunc); % MLSE sequence truncation length

8928

8917

8929

% healey_3dj_01a_2407 adjust MLSE for COM_DFE

8918

% healey_3dj_01a_2407 adjust MLSE for COM_DFE

8930

param.Q_budget_adj = xls_parameter(parameter, 'Q_budget_adj', true, 0); % MLSE sequence truncation length

8919

param.Q_budget_adj = xls_parameter(parameter, 'Q_budget_adj', true, 0); % MLSE sequence truncation length

8931

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

8920

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

8932

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

8921

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

8933

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

8922

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

8934

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

8923

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

8935

param.ts_anchor = xls_parameter(parameter, 'ts_anchor', true, 0); %choice of sampling routine. 0=MM, 1=Peak, 2=max DV (max cursor minus precursor)

8924

param.ts_anchor = xls_parameter(parameter, 'ts_anchor', true, 0); %choice of sampling routine. 0=MM, 1=Peak, 2=max DV (max cursor minus precursor)

8936

% This will keep bmax length 0 if Nb=0

8925

% This will keep bmax length 0 if Nb=0

8937

8926

8938

%AJG021820

8927

%AJG021820

8939

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

8928

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

8940

if isempty(param.bmax)

8929

if isempty(param.bmax)

8941

param.bmin=param.bmax;

8930

param.bmin=param.bmax;

8942

else

8931

else

8943

param.bmin(1:param.ndfe) =xls_parameter(parameter, 'b_min(1)', true,-param.bmax(1) ); % DFE negative magnitude limit. If not specified it defaults to -bmax.

8932

param.bmin(1:param.ndfe) =xls_parameter(parameter, 'b_min(1)', true,-param.bmax(1) ); % DFE negative magnitude limit. If not specified it defaults to -bmax.

8944

8933

8945

end

8934

end

8946

if param.ndfe >= 2

8935

if param.ndfe >= 2

8947

param.bmax(2:param.ndfe) = xls_parameter(parameter, 'b_max(2..N_b)', true, .2); % DFE magnitude limit, second coefficient and on (ignored if Nb<2). Can be a regualar expression

8936

param.bmax(2:param.ndfe) = xls_parameter(parameter, 'b_max(2..N_b)', true, .2); % DFE magnitude limit, second coefficient and on (ignored if Nb<2). Can be a regualar expression

8948

param.bmin(2:param.ndfe) = xls_parameter(parameter, 'b_min(2..N_b)', true, -1*param.bmax(2:param.ndfe) ); % DFE negative magnitude limit, if not specified it defaults to -b_max(2..N_b)

8937

param.bmin(2:param.ndfe) = xls_parameter(parameter, 'b_min(2..N_b)', true, -1*param.bmax(2:param.ndfe) ); % DFE negative magnitude limit, if not specified it defaults to -b_max(2..N_b)

8949

end

8938

end

8950

8939

8951

param.gqual=xls_parameter(parameter, 'G_Qual', true,[]);% G_Qual are the dB ranges of g_DC g DC )which correspond tog_DC_HP (g DC2)

8940

param.gqual=xls_parameter(parameter, 'G_Qual', true,[]);% G_Qual are the dB ranges of g_DC g DC )which correspond tog_DC_HP (g DC2)

8952

param.g2qual=xls_parameter(parameter, 'G2_Qual', true,[]); % G2_Qual limit values of g_DC_HP (g DC2 ) which corresponds to ranges of g_DC g DC specified with G_QUAL

8941

param.g2qual=xls_parameter(parameter, 'G2_Qual', true,[]); % G2_Qual limit values of g_DC_HP (g DC2 ) which corresponds to ranges of g_DC g DC specified with G_QUAL

8953

%verify gqual and gqual2 input

8942

%verify gqual and gqual2 input

8954

if ~isempty(param.gqual) || ~isempty(param.g2qual)

8943

if ~isempty(param.gqual) || ~isempty(param.g2qual)

8955

if size(param.gqual,1)~=length(param.g2qual)

8944

if size(param.gqual,1)~=length(param.g2qual)

8956

error('gqual and g2qual size mismatch');

8945

error('gqual and g2qual size mismatch');

8957

end

8946

end

8958

if size(param.gqual,2)~=2

8947

if size(param.gqual,2)~=2

8959

error('gqual must be Nx2 matrix');

8948

error('gqual must be Nx2 matrix');

8960

end

8949

end

8961

end

8950

end

8962

8951

8963

8952

8964

% eval if string for all three - can use different for TX and RX

8953

% eval if string for all three - can use different for TX and RX

8965

param.C_pkg_board = xls_parameter(parameter, 'C_p', true,0)*1e-9; % C_p in nF (single sided)

8954

param.C_pkg_board = xls_parameter(parameter, 'C_p', true,0)*1e-9; % C_p in nF (single sided)

8966

param.C_diepad = xls_parameter(parameter, 'C_d', true,0)*1e-9; % C_d in nF (single sided)

8955

param.C_diepad = xls_parameter(parameter, 'C_d', true,0)*1e-9; % C_d in nF (single sided)

8967

% [ahealey] Read values for optional compensating L and "bump" C

8956

% [ahealey] Read values for optional compensating L and "bump" C

8968

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

8957

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

8969

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

8958

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

8970

% [ahealey] End of modification

8959

% [ahealey] End of modification

8971

% added default to support multiple packages

8960

% added default to support multiple packages

8972

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

8961

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

8973

param.R_diepad = xls_parameter(parameter, 'R_d', true, [50,50]); % Die source termination resistance (single sided)

8962

param.R_diepad = xls_parameter(parameter, 'R_d', true, [50,50]); % Die source termination resistance (single sided)

8974

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

8963

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

8975

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

8964

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

8976

8965

8977

8966

8978

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

8967

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

8979

% added default to support multiple packages

8968

% added default to support multiple packages

8980

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of victim transmitter package trace lengths in mm, one per case

8969

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of victim transmitter package trace lengths in mm, one per case

8981

[ncases, mele]=size(param.z_p_tx_cases);

8970

[ncases, mele]=size(param.z_p_tx_cases);

8982

if mele ==2

8971

if mele ==2

8983

param.flex=2;

8972

param.flex=2;

8984

elseif mele==4

8973

elseif mele==4

8985

param.flex=4;

8974

param.flex=4;

8986

elseif mele==1

8975

elseif mele==1

8987

param.flex=1;

8976

param.flex=1;

8988

else

8977

else

8989

error(sprintf('config file syntax error'))

8978

error(sprintf('config file syntax error'))

8990

end

8979

end

8991

8980

8992

% board parameters

8981

% board parameters

8993

param.C_0 = xls_parameter(parameter, 'C_0', true,0)*1e-9; % If Include PCB is set to 1, near device single ended capacitance C0 in nF is added

8982

param.C_0 = xls_parameter(parameter, 'C_0', true,0)*1e-9; % If Include PCB is set to 1, near device single ended capacitance C0 in nF is added

8994

param.C_1 = xls_parameter(parameter, 'C_1', true,0)*1e-9; % if Include PCB is set to 1, connector side single ended capacitance C1 in nF is added

8983

param.C_1 = xls_parameter(parameter, 'C_1', true,0)*1e-9; % if Include PCB is set to 1, connector side single ended capacitance C1 in nF is added

8995

% added default to support multiple packages

8984

% added default to support multiple packages

8996

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of NEXT transmitter package trace lengths in mm, one per case

8985

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of NEXT transmitter package trace lengths in mm, one per case

8997

[ncases1, mele1]=size(param.z_p_next_cases);

8986

[ncases1, mele1]=size(param.z_p_next_cases);

8998

if ncases ~= ncases1 || mele ~= mele1

8987

if ncases ~= ncases1 || mele ~= mele1

8999

error('All TX, NEXT, FEXT, Rx cases must agree');

8988

error('All TX, NEXT, FEXT, Rx cases must agree');

9000

else

8989

else

9001

end

8990

end

9002

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of FEXT transmitter package trace lengths in mm, one per case

8991

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of FEXT transmitter package trace lengths in mm, one per case

9003

[ncases1, mele1]=size(param.z_p_fext_cases);

8992

[ncases1, mele1]=size(param.z_p_fext_cases);

9004

if ncases ~= ncases1 || mele ~= mele1

8993

if ncases ~= ncases1 || mele ~= mele1

9005

error('All TX, NEXT, FEXT, Rx cases must agree');

8994

error('All TX, NEXT, FEXT, Rx cases must agree');

9006

else

8995

else

9007

end

8996

end

9008

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of FEXT receiver package trace lengths in mm, one per case

8997

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of FEXT receiver package trace lengths in mm, one per case

9009

[ncases1, mele1]=size(param.z_p_rx_cases);

8998

[ncases1, mele1]=size(param.z_p_rx_cases);

9010

if ncases ~= ncases1 || mele ~= mele1

8999

if ncases ~= ncases1 || mele ~= mele1

9011

error('All TX, NEXT, FEXT, Rx cases must agree');

9000

error('All TX, NEXT, FEXT, Rx cases must agree');

9012

else

9001

else

9013

end

9002

end

9014

% Table 93A-3 parameters

9003

% Table 93A-3 parameters

9015

param.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9004

param.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9016

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9005

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9017

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, '[92 92 ; 70 70; 80 80; 100 100]').';% Package model transmission line characteristic impedance [ Tx , Rx ]

9006

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, '[92 92 ; 70 70; 80 80; 100 100]').';% Package model transmission line characteristic impedance [ Tx , Rx ]

9018

[ ncases1, mele1]=size(param.pkg_Z_c);%

9007

[ ncases1, mele1]=size(param.pkg_Z_c);%

9019

if mele ~= mele1

9008

if mele ~= mele1

9020

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9009

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9021

else

9010

else

9022

end

9011

end

9023

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9012

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9024

for ii=1:ncases

9013

for ii=1:ncases

9025

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9014

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9026

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9015

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9027

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9016

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9028

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9017

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9029

end

9018

end

9030

param.z_p_fext_cases = param.z_p_fext_casesx;

9019

param.z_p_fext_cases = param.z_p_fext_casesx;

9031

param.z_p_next_cases= param.z_p_next_casesx;

9020

param.z_p_next_cases= param.z_p_next_casesx;

9032

param.z_p_tx_cases= param.z_p_tx_casesx;

9021

param.z_p_tx_cases= param.z_p_tx_casesx;

9033

param.z_p_rx_cases= param.z_p_rx_casesx;

9022

param.z_p_rx_cases= param.z_p_rx_casesx;

9034

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9023

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9035

end

9024

end

9036

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9025

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9037

9026

9038

% Table 92-12 parameters

9027

% Table 92-12 parameters

9039

param.brd_gamma0_a1_a2 = xls_parameter(parameter, 'board_tl_gamma0_a1_a2', true, [0 4.114e-4 2.547e-4]); % Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9028

param.brd_gamma0_a1_a2 = xls_parameter(parameter, 'board_tl_gamma0_a1_a2', true, [0 4.114e-4 2.547e-4]); % Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9040

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9029

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9041

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9030

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9042

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9031

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9043

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9032

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9044

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9033

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9045

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9034

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9046

9035

9047

% Unofficial parameters

9036

% Unofficial parameters

9048

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9037

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9049

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9038

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9050

% Deprecated parameters - affect only frequency domain analysis.

9039

% Deprecated parameters - affect only frequency domain analysis.

9051

param.f_v = xls_parameter(parameter, 'f_v', true, 4); % For FOM_ILD: Transiton rate cut off frequency for ICN/ILD calc in terms of fb

9040

param.f_v = xls_parameter(parameter, 'f_v', true, 4); % For FOM_ILD: Transiton rate cut off frequency for ICN/ILD calc in terms of fb

9052

param.f_f = xls_parameter(parameter, 'f_f', true, 4); % For ICN: Fext transiton rate cut off frequency for ICN calc in terms of fb

9041

param.f_f = xls_parameter(parameter, 'f_f', true, 4); % For ICN: Fext transiton rate cut off frequency for ICN calc in terms of fb

9053

param.f_n = xls_parameter(parameter, 'f_n', true, 4); % For ICN: Next transiton rate cut off frequency for ICN calc in terms of fb

9042

param.f_n = xls_parameter(parameter, 'f_n', true, 4); % For ICN: Next transiton rate cut off frequency for ICN calc in terms of fb

9054

param.f_r = xls_parameter(parameter, 'f_r', true, 4); % reference receive filter in COM and in ICN/FOM_ILD calcs in terms of fb

9043

param.f_r = xls_parameter(parameter, 'f_r', true, 4); % reference receive filter in COM and in ICN/FOM_ILD calcs in terms of fb

9055

param.fb_BT_cutoff= xls_parameter(parameter, 'TDR_f_BT_3db', true, 0.4730); % Bessel-Thomson 3 dB cut off freqeuncy in terms of fb

9044

param.fb_BT_cutoff= xls_parameter(parameter, 'TDR_f_BT_3db', true, 0.4730); % Bessel-Thomson 3 dB cut off freqeuncy in terms of fb

9056

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9045

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9057

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9046

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9058

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9047

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9059

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9048

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9060

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9049

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9061

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9050

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9062

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9051

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9063

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9052

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9064

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9053

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9065

switch param.Gx

9054

switch param.Gx

9066

case 0

9055

case 0

9067

param.Grr=param.Grr; % just use older Grr ir gx not specified

9056

param.Grr=param.Grr; % just use older Grr ir gx not specified

9068

case 1

9057

case 1

9069

param.Grr=2; % use newer Grr

9058

param.Grr=2; % use newer Grr

9070

end

9059

end

9071

9060

9072

param.LOCAL_SEARCH=xls_parameter(parameter,'Local Search',true,0); % Decreases COM compute time. Aetting to 2 seems ok ,if 0 search is full grid

9061

param.LOCAL_SEARCH=xls_parameter(parameter,'Local Search',true,0); % Decreases COM compute time. Aetting to 2 seems ok ,if 0 search is full grid

9073

% Operational control variables

9062

% Operational control variables

9074

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9063

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9075

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9064

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9076

param.Noise_Crest_Factor= xls_parameter(parameter, 'Noise_Crest_Factor', true, 0); % Normally not used. If set this is q factor used for quantized Gaussian PDFs

9065

param.Noise_Crest_Factor= xls_parameter(parameter, 'Noise_Crest_Factor', true, 0); % Normally not used. If set this is q factor used for quantized Gaussian PDFs

9077

param.AC_CM_RMS = xls_parameter(parameter, 'AC_CM_RMS', true, 0); % AC_CM_RMS is the CM BBN AWGN RMS at COM source point. Default is 0. Adds common mode noise source to the COM signal path for the through channel

9066

param.AC_CM_RMS = xls_parameter(parameter, 'AC_CM_RMS', true, 0); % AC_CM_RMS is the CM BBN AWGN RMS at COM source point. Default is 0. Adds common mode noise source to the COM signal path for the through channel

9078

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9067

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9079

param.T_O = xls_parameter(parameter, 'T_O', true, 0 ); % Units are mUI. Histogram for VEC and VEO are computed over T_s +/- T_O.

9068

param.T_O = xls_parameter(parameter, 'T_O', true, 0 ); % Units are mUI. Histogram for VEC and VEO are computed over T_s +/- T_O.

9080

param.T_O = xls_parameter(parameter, 'T_h', true, param.T_O ); % superceded with T_O but is the internal values that is used. Do not use.

9069

param.T_O = xls_parameter(parameter, 'T_h', true, param.T_O ); % superceded with T_O but is the internal values that is used. Do not use.

9081

9070

9082

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9071

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9083

9072

9084

OP.Histogram_Window_Weight=xls_parameter(parameter, 'Histogram_Window_Weight', false, 'rectangle' ); %Weighting for VEC and VEO are histogram processing. Type are Gaussian,Dual Rayleigh,Triangle, and Rectangle (default)

9073

OP.Histogram_Window_Weight=xls_parameter(parameter, 'Histogram_Window_Weight', false, 'rectangle' ); %Weighting for VEC and VEO are histogram processing. Type are Gaussian,Dual Rayleigh,Triangle, and Rectangle (default)

9085

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9074

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9086

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9075

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9087

param.QL=xls_parameter(parameter, 'QL', true, param.T_O/param.Qr/1000 ); % superceded with sigma_r but is the internal values that is used

9076

param.QL=xls_parameter(parameter, 'QL', true, param.T_O/param.Qr/1000 ); % superceded with sigma_r but is the internal values that is used

9088

9077

9089

%%

9078

%%

9090

9079

9091

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9080

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9092

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9081

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9093

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9082

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9094

param.awgn_mv=param.AC_CM_RMS;

9083

param.awgn_mv=param.AC_CM_RMS;

9095

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9084

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9096

param.f_hp=xls_parameter(parameter, 'f_hp', true, 0 ); % for rx testing for eq 162-12 if 0 (default) then rx test using rx bbn

9085

param.f_hp=xls_parameter(parameter, 'f_hp', true, 0 ); % for rx testing for eq 162-12 if 0 (default) then rx test using rx bbn

9097

param.Q=xls_parameter(parameter, 'Q', true, 0 ); % Implementation penalty for MLSE in EQ 178a-36

9086

param.Q=xls_parameter(parameter, 'Q', true, 0 ); % Implementation penalty for MLSE in EQ 178a-36

9098

9087

9099

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9088

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9100

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9089

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9101

param.Floating_RXFFE=false;

9090

param.Floating_RXFFE=false;

9102

param.Floating_DFE=false;

9091

param.Floating_DFE=false;

9103

if param.N_bg > 0

9092

if param.N_bg > 0

9104

param.Floating_DFE=true;

9093

param.Floating_DFE=true;

9105

end

9094

end

9106

if OP.RxFFE

9095

if OP.RxFFE

9107

param.Floating_DFE=false;

9096

param.Floating_DFE=false;

9108

if param.N_bg > 0

9097

if param.N_bg > 0

9109

param.Floating_RXFFE=true;

9098

param.Floating_RXFFE=true;

9110

end

9099

end

9111

end

9100

end

9112

%% for introducing Tx or Rx skew on p leg or n leg

9101

%% for introducing Tx or Rx skew on p leg or n leg

9113

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9102

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9114

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9103

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9115

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9104

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9116

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9105

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9117

9106

9118

%%

9107

%%

9119

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9108

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9120

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9109

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9121

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9110

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9122

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9111

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9123

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9112

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9124

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9113

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9125

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9114

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9126

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9115

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9127

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9116

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9128

OP.CSV_REPORT = xls_parameter(parameter, 'CSV_REPORT', false, true); % saves all the output parameters to a CSV file in the results directory, If DIAGNOSTICS is set then a mat file is also created

9117

OP.CSV_REPORT = xls_parameter(parameter, 'CSV_REPORT', false, true); % saves all the output parameters to a CSV file in the results directory, If DIAGNOSTICS is set then a mat file is also created

9129

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9118

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9130

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9119

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9131

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9120

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9132

OP.GET_FD = xls_parameter(parameter, 'Display frequency domain', false, OP.GET_FD); % Not normally set in the config file. It is normally just set to true to get FD plots

9121

OP.GET_FD = xls_parameter(parameter, 'Display frequency domain', false, OP.GET_FD); % Not normally set in the config file. It is normally just set to true to get FD plots

9133

OP.INC_PACKAGE = xls_parameter(parameter, 'INC_PACKAGE', false, true); % warning: INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1

9122

OP.INC_PACKAGE = xls_parameter(parameter, 'INC_PACKAGE', false, true); % warning: INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1

9134

if ~OP.INC_PACKAGE

9123

if ~OP.INC_PACKAGE

9135

fprintf('<strong> Warning!!! INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9124

fprintf('<strong> Warning!!! INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9136

end

9125

end

9137

9126

9138

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9127

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9139

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9128

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9140

if OP.IDEAL_TX_TERM

9129

if OP.IDEAL_TX_TERM

9141

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9130

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9142

end

9131

end

9143

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9132

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9144

if OP.IDEAL_RX_TERM

9133

if OP.IDEAL_RX_TERM

9145

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9134

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9146

end

9135

end

9147

9136

9148

OP.TDMODE = xls_parameter(parameter, 'TDMODE',false, OP.TDMODE); % Enables the the use of pulse response instead of s-parameters. Assumes no packages or the packages are included in the PR. Default is 0.

9137

OP.TDMODE = xls_parameter(parameter, 'TDMODE',false, OP.TDMODE); % Enables the the use of pulse response instead of s-parameters. Assumes no packages or the packages are included in the PR. Default is 0.

9149

9138

9150

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9139

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9151

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9140

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9152

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9141

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9153

OP.BREAD_CRUMBS = xls_parameter(parameter, 'BREAD_CRUMBS',false, false); % if DIAGNOSTICS is set then param, OP, and chdata are include in the output for each run

9142

OP.BREAD_CRUMBS = xls_parameter(parameter, 'BREAD_CRUMBS',false, false); % if DIAGNOSTICS is set then param, OP, and chdata are include in the output for each run

9154

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9143

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9155

OP.COM_CONTRIBUTION_CURVES = xls_parameter(parameter, 'COM_CONTRIBUTION',false,0); % Default is 0. If set to 1 then a bar graph of COM contributors is produce instead of bathtub curves

9144

OP.COM_CONTRIBUTION_CURVES = xls_parameter(parameter, 'COM_CONTRIBUTION',false,0); % Default is 0. If set to 1 then a bar graph of COM contributors is produce instead of bathtub curves

9156

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9145

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9157

OP.EC_REL_TOL = xls_parameter(parameter, 'Enforce Causality REL_TOL', false, 1e-2); % Relative Tolerance parameter for causality, Hard enforcement, 1e-3, Soft enforcement, 1e-2

9146

OP.EC_REL_TOL = xls_parameter(parameter, 'Enforce Causality REL_TOL', false, 1e-2); % Relative Tolerance parameter for causality, Hard enforcement, 1e-3, Soft enforcement, 1e-2

9158

OP.EC_DIFF_TOL = xls_parameter(parameter, 'Enforce Causality DIFF_TOL', false, 1e-3); % Difference Tolerance parameter for causality, Hard enforcement, 1e-4,Soft enforcement, 1e-3

9147

OP.EC_DIFF_TOL = xls_parameter(parameter, 'Enforce Causality DIFF_TOL', false, 1e-3); % Difference Tolerance parameter for causality, Hard enforcement, 1e-4,Soft enforcement, 1e-3

9159

OP.EC_PULSE_TOL = xls_parameter(parameter, 'Enforce Causality pulse start tolerance', false, 0.01); % Tolerance parameter for causality, Hard enforcement, 0.05, Soft enforcement, .01

9148

OP.EC_PULSE_TOL = xls_parameter(parameter, 'Enforce Causality pulse start tolerance', false, 0.01); % Tolerance parameter for causality, Hard enforcement, 0.05, Soft enforcement, .01

9160

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9149

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9161

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9150

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9162

OP.sigma_bn_STEP = xls_parameter(parameter, 'Sigma BBN step', false, 5e-3); % BBN step for Rx Calibration in volts. Defaults is 0.5e-3

9151

OP.sigma_bn_STEP = xls_parameter(parameter, 'Sigma BBN step', false, 5e-3); % BBN step for Rx Calibration in volts. Defaults is 0.5e-3

9163

OP.BBN_Q_factor = xls_parameter(parameter, 'BBN Q factor', false, 5); % Overrides NEXT/FEXT noise Qfactor for 'Force BBN Q factor' used for reporting. does not affect COM.

9152

OP.BBN_Q_factor = xls_parameter(parameter, 'BBN Q factor', false, 5); % Overrides NEXT/FEXT noise Qfactor for 'Force BBN Q factor' used for reporting. does not affect COM.

9164

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9153

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9165

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9154

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9166

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9155

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9167

9156

9168

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9157

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9169

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9158

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9170

OP.FORCE_TR = xls_parameter(parameter, 'FORCE_TR', false, false);% Included for earlier version support but should be set to 1 in most later config sheets.

9159

OP.FORCE_TR = xls_parameter(parameter, 'FORCE_TR', false, false);% Included for earlier version support but should be set to 1 in most later config sheets.

9171

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9160

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9172

% compatibility

9161

% compatibility

9173

if OP.FORCE_TR

9162

if OP.FORCE_TR

9174

OP.T_r_meas_point=0;

9163

OP.T_r_meas_point=0;

9175

OP.T_r_filter_type=1;

9164

OP.T_r_filter_type=1;

9176

end

9165

end

9177

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9166

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9178

OP.TDR_duration= xls_parameter(parameter, 'TDR_duration', false, 5); % only used if N*UI is longer than the TDR duration time. Default is 5 times the raw s-parameter transit time.

9167

OP.TDR_duration= xls_parameter(parameter, 'TDR_duration', false, 5); % only used if N*UI is longer than the TDR duration time. Default is 5 times the raw s-parameter transit time.

9179

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9168

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9180

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9169

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9181

OP.T_k= xls_parameter(parameter, 'T_k', false, .6)*1e-9; % Time span (ns) for which the impedance of port is determined using TDR.

9170

OP.T_k= xls_parameter(parameter, 'T_k', false, .6)*1e-9; % Time span (ns) for which the impedance of port is determined using TDR.

9182

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9171

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9183

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9172

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9184

if OP.ERL

9173

if OP.ERL

9185

OP.PTDR=1;

9174

OP.PTDR=1;

9186

else

9175

else

9187

OP.PTDR=0;

9176

OP.PTDR=0;

9188

end % ERL needs to do a TDR

9177

end % ERL needs to do a TDR

9189

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9178

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9190

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9179

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9191

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9180

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9192

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9181

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9193

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9182

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9194

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9183

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9195

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9184

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9196

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9185

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9197

OP.AUTO_TFX=xls_parameter(parameter, 'AUTO_TFX', false,0); % Mostly used for device ERL. If sent to 1 the fixture tfx will be estimated.

9186

OP.AUTO_TFX=xls_parameter(parameter, 'AUTO_TFX', false,0); % Mostly used for device ERL. If sent to 1 the fixture tfx will be estimated.

9198

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9187

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9199

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9188

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9200

OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncation threshold', false, 1e-3); % zero padding threshold in fraction of IR peak for the impulse response. Effectively controls the length of time for the PR. Larger values decrease run time and accuracy. Default is 1e-3.

9189

OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncation threshold', false, 1e-3); % zero padding threshold in fraction of IR peak for the impulse response. Effectively controls the length of time for the PR. Larger values decrease run time and accuracy. Default is 1e-3.

9201

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9190

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9202

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9191

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9203

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9192

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9204

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9193

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9205

if strcmpi(OP.PHY,'C2M')

9194

if strcmpi(OP.PHY,'C2M')

9206

OP.EW=true;

9195

OP.EW=true;

9207

else

9196

else

9208

param.T_O=0; % make sure when c2c that sample is at Ts

9197

param.T_O=0; % make sure when c2c that sample is at Ts

9209

end

9198

end

9210

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9199

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9211

OP.PHY='C2Mcom';

9200

OP.PHY='C2Mcom';

9212

end

9201

end

9213

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9202

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9214

switch lower(OP.TDECQ)

9203

switch lower(OP.TDECQ)

9215

case {false 'none' 'vma'}

9204

case {false 'none' 'vma'}

9216

otherwise

9205

otherwise

9217

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9206

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9218

end

9207

end

9219

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9208

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9220

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9209

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9221

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9210

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9222

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9211

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9223

OP.Optimize_loop_speed_up =xls_parameter(parameter, 'Optimize_loop_speed_up', true , 0);% If set to 0 (or default) normal looping, If set to 1 loop speedup by slightly reducing PD Fbin and FIR_threshold for optimize looping only

9212

OP.Optimize_loop_speed_up =xls_parameter(parameter, 'Optimize_loop_speed_up', true , 0);% If set to 0 (or default) normal looping, If set to 1 loop speedup by slightly reducing PD Fbin and FIR_threshold for optimize looping only

9224

% Parameters for error burst probability calculation. Not officially used

9213

% Parameters for error burst probability calculation. Not officially used

9225

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9214

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9226

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9215

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9227

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9216

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9228

OP.USE_ETA0_PSD = xls_parameter(parameter, 'USE_ETA0_PSD', false, 0); % Used eta_0 PSD equaiton for sigma_n. Default is 0. Do not use.

9217

OP.USE_ETA0_PSD = xls_parameter(parameter, 'USE_ETA0_PSD', false, 0); % Used eta_0 PSD equaiton for sigma_n. Default is 0. Do not use.

9229

OP.SAVE_CONFIG2MAT = xls_parameter(parameter, 'SAVE_CONFIG2MAT', false, 0); % If set to 1 (default) saves parameters in mat file. Requires DIAGNOSTICS to be set.

9218

OP.SAVE_CONFIG2MAT = xls_parameter(parameter, 'SAVE_CONFIG2MAT', false, 0); % If set to 1 (default) saves parameters in mat file. Requires DIAGNOSTICS to be set.

9230

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9219

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9231

OP.fraction_of_F_range_start_extrap_from= xls_parameter(parameter, 'fraction_of_F_range_start_extrap_from', true, 0.75); % Frequency (fb) where high frequency extropolation begins for computing IR. Helps control Gibbs phenomena. defualt is 0.75.

9220

OP.fraction_of_F_range_start_extrap_from= xls_parameter(parameter, 'fraction_of_F_range_start_extrap_from', true, 0.75); % Frequency (fb) where high frequency extropolation begins for computing IR. Helps control Gibbs phenomena. defualt is 0.75.

9232

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9221

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9233

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9222

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9234

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9223

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9235

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9224

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9236

OP.MLSD = xls_parameter(parameter, 'MLSD', false, 0); % not 0 or missing means use MLSD

9225

OP.MLSD = xls_parameter(parameter, 'MLSD', false, 0); % not 0 or missing means use MLSD

9237

OP.MLSE = xls_parameter(parameter, 'MLSE', false, OP.MLSD ); % MSLD Synonym support

9226

OP.MLSE = xls_parameter(parameter, 'MLSE', false, OP.MLSD ); % MSLD Synonym support

9238

if OP.MLSE ~=0

9227

if OP.MLSE ~=0

9239

if param.T_O ~= 0

9228

if param.T_O ~= 0

9240

error('MLSD nnot presently no supported for VEC')

9229

error('MLSD nnot presently no supported for VEC')

9241

end

9230

end

9242

if OP.COM_CONTRIBUTION_CURVES ~=0

9231

if OP.COM_CONTRIBUTION_CURVES ~=0

9243

warning('COM_CONTRIBUTION_CURVES not functional yet with MLSE')

9232

warning('COM_CONTRIBUTION_CURVES not functional yet with MLSE')

9244

OP.COM_CONTRIBUTION_CURVES=0;

9233

OP.COM_CONTRIBUTION_CURVES=0;

9245

end

9234

end

9246

end

9235

end

9247

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9236

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9248

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9237

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9249

if OP.MLSE && param.ndfe==0

9238

if OP.MLSE && param.ndfe==0

9250

error('At least DFE 1 must be set to use MLSE');

9239

error('At least DFE 1 must be set to use MLSE');

9251

end

9240

end

9252

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9241

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9253

% MNSE parameters

9242

% MNSE parameters

9254

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9243

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9255

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9244

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9256

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9245

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9257

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9246

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9258

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9247

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9259

% Commit request 4p4_7, healey_3dj_COM_01_240416

9248

% Commit request 4p4_7, healey_3dj_COM_01_240416

9260

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

9249

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

9261

% need to make sure TD mode does not invoke FD operations

9250

% need to make sure TD mode does not invoke FD operations

9262

if OP.TDMODE % need to set GET_FD false of TDMODE

9251

if OP.TDMODE % need to set GET_FD false of TDMODE

9263

OP.GET_FD=false;

9252

OP.GET_FD=false;

9264

OP.ERL_ONLY=0;

9253

OP.ERL_ONLY=0;

9265

OP.ERL=0;

9254

OP.ERL=0;

9266

OP.PTDR=0;

9255

OP.PTDR=0;

9267

OP.TDR=0;

9256

OP.TDR=0;

9268

OP.RX_CALIBRATION=0;

9257

OP.RX_CALIBRATION=0;

9269

end

9258

end

9270

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9259

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9271

save(matcongfile ,'parameter');

9260

save(matcongfile ,'parameter');

9272

end

9261

end

9273

9262

9274

9263

9275

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9264

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9276

if ~isempty(param.PKG_NAME)

9265

if ~isempty(param.PKG_NAME)

9277

if length(param.PKG_NAME) == 1

9266

if length(param.PKG_NAME) == 1

9278

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9267

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9279

end

9268

end

9280

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9269

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9281

tx_rx_fields_matrix = {'pkg_Z_c'};

9270

tx_rx_fields_matrix = {'pkg_Z_c'};

9282

tx_fields = {'z_p_tx_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9271

tx_fields = {'z_p_tx_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9283

rx_fields = {'z_p_rx_cases' 'a_next' 'z_p_next_cases'};

9272

rx_fields = {'z_p_rx_cases' 'a_next' 'z_p_next_cases'};

9284

tx_pkg_name=param.PKG_NAME{1};

9273

tx_pkg_name=param.PKG_NAME{1};

9285

rx_pkg_name=param.PKG_NAME{2};

9274

rx_pkg_name=param.PKG_NAME{2};

9286

tx_pkg_struct=param.PKG.(tx_pkg_name);

9275

tx_pkg_struct=param.PKG.(tx_pkg_name);

9287

rx_pkg_struct=param.PKG.(rx_pkg_name);

9276

rx_pkg_struct=param.PKG.(rx_pkg_name);

9288

9277

9289

%tx_rx_fields: put the value from the tx package in the Tx position and the value from the rx package in the RX position

9278

%tx_rx_fields: put the value from the tx package in the Tx position and the value from the rx package in the RX position

9290

for j=1:length(tx_rx_fields)

9279

for j=1:length(tx_rx_fields)

9291

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9280

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9292

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9281

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9293

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9282

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9294

end

9283

end

9295

9284

9296

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9285

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9297

for j=1:length(tx_rx_fields_matrix)

9286

for j=1:length(tx_rx_fields_matrix)

9298

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9287

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9299

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9288

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9300

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9289

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9301

end

9290

end

9302

9291

9303

%tx_fields: use only the tx package values

9292

%tx_fields: use only the tx package values

9304

for j=1:length(tx_fields)

9293

for j=1:length(tx_fields)

9305

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9294

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9306

end

9295

end

9307

9296

9308

%rx_fields: use only the rx package values

9297

%rx_fields: use only the rx package values

9309

for j=1:length(rx_fields)

9298

for j=1:length(rx_fields)

9310

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9299

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9311

end

9300

end

9312

9301

9313

end

9302

end

9314

9303

9315

9304

9316

%%

9305

%%

9317

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9306

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9318

%% FUNCTION :: read_sp4_sparams

9307

%% FUNCTION :: read_sp4_sparams

9319

%

9308

%

9320

% Description

9309

% Description

9321

% Read the fid of single-ended 4-port complex S-parameters

9310

% Read the fid of single-ended 4-port complex S-parameters

9322

% in Touchstone format 'file' and convert to the internal

9311

% in Touchstone format 'file' and convert to the internal

9323

% format using the port transform 'ports'

9312

% format using the port transform 'ports'

9324

%

9313

%

9325

% Created by Mike Y. He

9314

% Created by Mike Y. He

9326

% April 22, 2005

9315

% April 22, 2005

9327

%

9316

%

9328

% Reused some code from

9317

% Reused some code from

9329

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9318

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9330

% for touchstone 4-port S-matrix import.

9319

% for touchstone 4-port S-matrix import.

9331

%

9320

%

9332

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9321

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9333

% optimized for quicker parameter matching and parsing. also, separated out

9322

% optimized for quicker parameter matching and parsing. also, separated out

9334

% the plotting algorithms into their own sub-function routines

9323

% the plotting algorithms into their own sub-function routines

9335

%

9324

%

9336

% Modified December 2021 to use read_Nport_touchstone

9325

% Modified December 2021 to use read_Nport_touchstone

9337

% This is faster reader that is capable of reading touchstone with any number of ports

9326

% This is faster reader that is capable of reading touchstone with any number of ports

9338

%

9327

%

9339

% Input Variables (required)

9328

% Input Variables (required)

9340

% infile -- The s4p file to be read and converted

9329

% infile -- The s4p file to be read and converted

9341

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9330

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9342

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9331

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9343

% ports -- Re-order the port layout

9332

% ports -- Re-order the port layout

9344

%

9333

%

9345

% Output/Return Variables

9334

% Output/Return Variables

9346

% data -- structure containing network parameter data points and frequency axis

9335

% data -- structure containing network parameter data points and frequency axis

9347

% sdc -- the differential in/common-mode out s-parameter data matrix

9336

% sdc -- the differential in/common-mode out s-parameter data matrix

9348

% sdd -- the differential in/differential out s-parameter data matrix

9337

% sdd -- the differential in/differential out s-parameter data matrix

9349

%

9338

%

9350

9339

9351

9340

9352

% backwards compatibility settings. can be removed in updated code.

9341

% backwards compatibility settings. can be removed in updated code.

9353

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9342

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9354

if isempty(ports); ports = [1 2]; end % default order normally used.

9343

if isempty(ports); ports = [1 2]; end % default order normally used.

9355

ports = [1 2];

9344

ports = [1 2];

9356

9345

9357

9346

9358

if OP.DISPLAY_WINDOW

9347

if OP.DISPLAY_WINDOW

9359

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9348

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9360

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9349

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9361

end

9350

end

9362

9351

9363

%AJG: fast touchstone read for any number of ports

9352

%AJG: fast touchstone read for any number of ports

9364

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9353

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9365

9354

9366

9355

9367

9356

9368

D=NaN(size(sch));

9357

D=NaN(size(sch));

9369

% calculate differential s parameter matrix from single ended

9358

% calculate differential s parameter matrix from single ended

9370

for i=1:size(sch,1)

9359

for i=1:size(sch,1)

9371

S(:,:) = sch(i,:,:);

9360

S(:,:) = sch(i,:,:);

9372

T = [1 1 ; 1 -1 ];

9361

T = [1 1 ; 1 -1 ];

9373

W = T * (S / T);

9362

W = T * (S / T);

9374

D(i,:,:) = W(:,:);

9363

D(i,:,:) = W(:,:);

9375

end

9364

end

9376

9365

9377

% D matrix should be

9366

% D matrix should be

9378

% Scc11 Scd11 Scc12 Scd21

9367

% Scc11 Scd11 Scc12 Scd21

9379

% Sdc11 Sdd11 Sdc12 Sdd12

9368

% Sdc11 Sdd11 Sdc12 Sdd12

9380

% Scc21 Scd21 Scc22 Scd22

9369

% Scc21 Scd21 Scc22 Scd22

9381

% Sdc21 Sdd21 Sdc22 Sdd22

9370

% Sdc21 Sdd21 Sdc22 Sdd22

9382

9371

9383

% proper values

9372

% proper values

9384

%AJG: matrix can be properly referenced after fixing mapping

9373

%AJG: matrix can be properly referenced after fixing mapping

9385

SDD(:,1,1) = D(:,2,2);

9374

SDD(:,1,1) = D(:,2,2);

9386

SDC(:,1,1)= D(:,2,1);

9375

SDC(:,1,1)= D(:,2,1);

9387

SCC(:,1,1)= D(:,1,1);

9376

SCC(:,1,1)= D(:,1,1);

9388

SCD(:,1,1)= D(:,1,2);

9377

SCD(:,1,1)= D(:,1,2);

9389

9378

9390

9379

9391

9380

9392

% backwards compatibility output variables

9381

% backwards compatibility output variables

9393

data.m = sch;

9382

data.m = sch;

9394

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9383

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9395

data.freq = schFreqAxis;

9384

data.freq = schFreqAxis;

9396

colors = 'rgbk';

9385

colors = 'rgbk';

9397

9386

9398

if (plot_ini_s_params == 1)

9387

if (plot_ini_s_params == 1)

9399

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9388

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9400

for mj=1:4

9389

for mj=1:4

9401

% subplot(2,2,mj);

9390

% subplot(2,2,mj);

9402

for mi=1:4

9391

for mi=1:4

9403

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9392

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9404

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9393

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9405

hold on

9394

hold on

9406

end

9395

end

9407

xlabel('Frequency (Hz)');

9396

xlabel('Frequency (Hz)');

9408

ylabel('Magnitude (dB)');

9397

ylabel('Magnitude (dB)');

9409

legend show

9398

legend show

9410

grid on

9399

grid on

9411

title(sprintf('Output port %d', mj));

9400

title(sprintf('Output port %d', mj));

9412

end

9401

end

9413

end

9402

end

9414

plot_dif_s_params =0;

9403

plot_dif_s_params =0;

9415

if (plot_dif_s_params == 1)

9404

if (plot_dif_s_params == 1)

9416

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9405

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9417

% subplot(2,1,1);

9406

% subplot(2,1,1);

9418

for mj=1:1

9407

for mj=1:1

9419

for mi=1:1

9408

for mi=1:1

9420

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9409

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9421

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9410

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9422

hold on

9411

hold on

9423

end

9412

end

9424

end

9413

end

9425

xlabel('Frequency (Hz)');

9414

xlabel('Frequency (Hz)');

9426

ylabel('Magnitude (dB)');

9415

ylabel('Magnitude (dB)');

9427

legend show

9416

legend show

9428

grid on

9417

grid on

9429

title(infile);

9418

title(infile);

9430

9419

9431

% subplot(2,1,2);

9420

% subplot(2,1,2);

9432

% for mj=1:2

9421

% for mj=1:2

9433

% for mi=1:2

9422

% for mi=1:2

9434

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9423

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9435

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9424

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9436

% hold on

9425

% hold on

9437

% end

9426

% end

9438

% end

9427

% end

9439

% xlabel('Frequency (Hz)');

9428

% xlabel('Frequency (Hz)');

9440

% ylabel('Magnitude (dB)');

9429

% ylabel('Magnitude (dB)');

9441

% legend show

9430

% legend show

9442

% grid on

9431

% grid on

9443

end

9432

end

9444

9433

9445

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9434

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9446

% end read_sp2_sparam

9435

% end read_sp2_sparam

9447

9436

9448

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9437

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9449

%% FUNCTION :: read_sp4_sparams

9438

%% FUNCTION :: read_sp4_sparams

9450

%

9439

%

9451

% Description

9440

% Description

9452

% Read the fid of single-ended 4-port complex S-parameters

9441

% Read the fid of single-ended 4-port complex S-parameters

9453

% in Touchstone format 'file' and convert to the internal

9442

% in Touchstone format 'file' and convert to the internal

9454

% format using the port transform 'ports'

9443

% format using the port transform 'ports'

9455

%

9444

%

9456

% Created by Mike Y. He

9445

% Created by Mike Y. He

9457

% April 22, 2005

9446

% April 22, 2005

9458

%

9447

%

9459

% Reused some code from

9448

% Reused some code from

9460

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9449

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9461

% for touchstone 4-port S-matrix import.

9450

% for touchstone 4-port S-matrix import.

9462

%

9451

%

9463

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9452

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9464

% optimized for quicker parameter matching and parsing. also, separated out

9453

% optimized for quicker parameter matching and parsing. also, separated out

9465

% the plotting algorithms into their own sub-function routines

9454

% the plotting algorithms into their own sub-function routines

9466

%

9455

%

9467

% Modified December 2021 to use read_Nport_touchstone

9456

% Modified December 2021 to use read_Nport_touchstone

9468

% This is faster reader that is capable of reading touchstone with any number of ports

9457

% This is faster reader that is capable of reading touchstone with any number of ports

9469

%

9458

%

9470

% Input Variables (required)

9459

% Input Variables (required)

9471

% infile -- The s4p file to be read and converted

9460

% infile -- The s4p file to be read and converted

9472

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9461

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9473

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9462

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9474

% ports -- Re-order the port layout

9463

% ports -- Re-order the port layout

9475

% OP

9464

% OP

9476

% param

9465

% param

9477

% Output/Return Variables

9466

% Output/Return Variables

9478

% data -- structure containing network parameter data points and frequency axis

9467

% data -- structure containing network parameter data points and frequency axis

9479

% sdd -- the differential in/differential out s-parameter data matrix

9468

% sdd -- the differential in/differential out s-parameter data matrix

9480

% sdc -- the differential in/common-mode out s-parameter data matrix

9469

% sdc -- the differential in/common-mode out s-parameter data matrix

9481

% scc -- the common mode in/common-mode out s-parameter data matrix

9470

% scc -- the common mode in/common-mode out s-parameter data matrix

9482

%

9471

%

9483

%

9472

%

9484

9473

9485

9474

9486

% backwards compatibility settings. can be removed in updated code.

9475

% backwards compatibility settings. can be removed in updated code.

9487

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9476

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9488

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9477

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9489

9478

9490

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9479

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9491

% pair is reversed.

9480

% pair is reversed.

9492

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9481

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9493

9482

9494

if OP.DISPLAY_WINDOW

9483

if OP.DISPLAY_WINDOW

9495

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9484

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9496

end

9485

end

9497

9486

9498

%AJG: fast touchstone read for any number of ports

9487

%AJG: fast touchstone read for any number of ports

9499

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9488

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9500

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9489

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9501

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9490

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9502

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9491

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9503

Sigfct = ...

9492

Sigfct = ...

9504

@(sigma2,sigma1,sigma4,sigma3)reshape([sigma1.^2,sigma1.*sigma2,sigma1.*sigma3,sigma1.*sigma4,sigma1.*sigma2,sigma2.^2,sigma2.*sigma3,sigma2.*sigma4,sigma1.*sigma3,sigma2.*sigma3,sigma3.^2,sigma3.*sigma4,sigma1.*sigma4,sigma2.*sigma4,sigma3.*sigma4,sigma4.^2],[4,4]);

9493

@(sigma2,sigma1,sigma4,sigma3)reshape([sigma1.^2,sigma1.*sigma2,sigma1.*sigma3,sigma1.*sigma4,sigma1.*sigma2,sigma2.^2,sigma2.*sigma3,sigma2.*sigma4,sigma1.*sigma3,sigma2.*sigma3,sigma3.^2,sigma3.*sigma4,sigma1.*sigma4,sigma2.*sigma4,sigma3.*sigma4,sigma4.^2],[4,4]);

9505

D=NaN(size(sch));

9494

D=NaN(size(sch));

9506

% calculate differential s parameter matrix from single ended

9495

% calculate differential s parameter matrix from single ended

9507

% skew added RIM 12/29/2023

9496

% skew added RIM 12/29/2023

9508

for i=1:size(sch,1)

9497

for i=1:size(sch,1)

9509

f=schFreqAxis(i);

9498

f=schFreqAxis(i);

9510

sigma_matrix=Sigfct(exp(2i*pi*f*param.Txpskew*1e-12),exp(2i*pi*f*param.Txnskew*1e-12),exp(2i*pi*f*param.Rxpskew*1e-12),exp(2i*pi*f*param.Rxnskew*1e-12) );

9499

sigma_matrix=Sigfct(exp(2i*pi*f*param.Txpskew*1e-12),exp(2i*pi*f*param.Txnskew*1e-12),exp(2i*pi*f*param.Rxpskew*1e-12),exp(2i*pi*f*param.Rxnskew*1e-12) );

9511

S(:,:) = sch(i,:,:);

9500

S(:,:) = sch(i,:,:);

9512

Snew=sigma_matrix.*S;

9501

Snew=sigma_matrix.*S;

9513

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9502

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9514

W = T * (Snew / T);

9503

W = T * (Snew / T);

9515

D(i,:,:) = W(:,:);

9504

D(i,:,:) = W(:,:);

9516

end

9505

end

9517

9506

9518

% D matrix should be

9507

% D matrix should be

9519

% Scc11 Scd11 Scc12 Scd21

9508

% Scc11 Scd11 Scc12 Scd21

9520

% Sdc11 Sdd11 Sdc12 Sdd12

9509

% Sdc11 Sdd11 Sdc12 Sdd12

9521

% Scc21 Scd21 Scc22 Scd22

9510

% Scc21 Scd21 Scc22 Scd22

9522

% Sdc21 Sdd21 Sdc22 Sdd22

9511

% Sdc21 Sdd21 Sdc22 Sdd22

9523

9512

9524

% proper values

9513

% proper values

9525

SDD(:,1,1) = D(:,2,2);

9514

SDD(:,1,1) = D(:,2,2);

9526

SDD(:,2,2) = D(:,4,4);

9515

SDD(:,2,2) = D(:,4,4);

9527

SDD(:,1,2) = D(:,2,4);

9516

SDD(:,1,2) = D(:,2,4);

9528

SDD(:,2,1) = D(:,4,2);

9517

SDD(:,2,1) = D(:,4,2);

9529

9518

9530

SDC(:,1,1) = D(:,2,1);

9519

SDC(:,1,1) = D(:,2,1);

9531

SDC(:,2,2) = D(:,4,3);

9520

SDC(:,2,2) = D(:,4,3);

9532

SDC(:,1,2) = D(:,2,3);

9521

SDC(:,1,2) = D(:,2,3);

9533

SDC(:,2,1) = D(:,4,1);

9522

SDC(:,2,1) = D(:,4,1);

9534

9523

9535

SCC(:,1,1) = D(:,1,1);

9524

SCC(:,1,1) = D(:,1,1);

9536

SCC(:,2,2) = D(:,3,3);

9525

SCC(:,2,2) = D(:,3,3);

9537

SCC(:,1,2) = D(:,1,3);

9526

SCC(:,1,2) = D(:,1,3);

9538

SCC(:,2,1) = D(:,3,1);

9527

SCC(:,2,1) = D(:,3,1);

9539

9528

9540

% backwards compatibility output variables

9529

% backwards compatibility output variables

9541

data.m = sch;

9530

data.m = sch;

9542

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9531

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9543

data.freq = schFreqAxis;

9532

data.freq = schFreqAxis;

9544

colors = 'rgbk';

9533

colors = 'rgbk';

9545

9534

9546

if (plot_ini_s_params == 1)

9535

if (plot_ini_s_params == 1)

9547

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9536

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9548

for mj=1:4

9537

for mj=1:4

9549

subplot(2,2,mj);

9538

subplot(2,2,mj);

9550

for mi=1:4

9539

for mi=1:4

9551

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9540

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9552

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9541

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9553

hold on

9542

hold on

9554

end

9543

end

9555

xlabel('Frequency (Hz)');

9544

xlabel('Frequency (Hz)');

9556

ylabel('Magnitude (dB)');

9545

ylabel('Magnitude (dB)');

9557

legend show

9546

legend show

9558

grid on

9547

grid on

9559

title(sprintf('Output port %d', mj));

9548

title(sprintf('Output port %d', mj));

9560

end

9549

end

9561

end

9550

end

9562

plot_dif_s_params =0;

9551

plot_dif_s_params =0;

9563

if (plot_dif_s_params == 1)

9552

if (plot_dif_s_params == 1)

9564

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9553

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9565

% subplot(2,1,1);

9554

% subplot(2,1,1);

9566

for mj=1:2

9555

for mj=1:2

9567

for mi=1:2

9556

for mi=1:2

9568

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9557

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9569

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9558

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9570

hold on

9559

hold on

9571

end

9560

end

9572

end

9561

end

9573

xlabel('Frequency (Hz)');

9562

xlabel('Frequency (Hz)');

9574

ylabel('Magnitude (dB)');

9563

ylabel('Magnitude (dB)');

9575

legend show

9564

legend show

9576

grid on

9565

grid on

9577

title(infile);

9566

title(infile);

9578

%

9567

%

9579

% subplot(2,1,2);

9568

% subplot(2,1,2);

9580

% for mj=1:2

9569

% for mj=1:2

9581

% for mi=1:2

9570

% for mi=1:2

9582

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9571

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9583

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9572

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9584

% hold on

9573

% hold on

9585

% end

9574

% end

9586

% end

9575

% end

9587

% xlabel('Frequency (Hz)');

9576

% xlabel('Frequency (Hz)');

9588

% ylabel('Magnitude (dB)');

9577

% ylabel('Magnitude (dB)');

9589

% legend show

9578

% legend show

9590

% grid on

9579

% grid on

9591

end

9580

end

9592

9581

9593

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9582

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9594

% end read_sp4_sparam

9583

% end read_sp4_sparam

9595

function param_struct = read_package_parameters(parameter,param_struct)

9584

function param_struct = read_package_parameters(parameter,param_struct)

9596

9585

9597

%With the introduction of Package sections in COM spreadsheet, it makes sense to have a single function that grabs all package parameters from a parameter block

9586

%With the introduction of Package sections in COM spreadsheet, it makes sense to have a single function that grabs all package parameters from a parameter block

9598

%This block should eventually replace what is in read_ParamConfigFile

9587

%This block should eventually replace what is in read_ParamConfigFile

9599

%It can be called as: param = read_package_parameters(parameter, param)

9588

%It can be called as: param = read_package_parameters(parameter, param)

9600

9589

9601

if nargin<2

9590

if nargin<2

9602

%param_struct doesn't need to be passed when building a new package structure

9591

%param_struct doesn't need to be passed when building a new package structure

9603

%it is only needed when appending to regular param structure

9592

%it is only needed when appending to regular param structure

9604

param_struct=struct;

9593

param_struct=struct;

9605

end

9594

end

9606

9595

9607

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9596

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9608

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9597

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9609

9598

9610

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9599

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9611

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9600

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9612

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9601

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9613

9602

9614

param_struct.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9603

param_struct.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9615

[ncases, mele]=size(param_struct.z_p_tx_cases);

9604

[ncases, mele]=size(param_struct.z_p_tx_cases);

9616

if mele ==2

9605

if mele ==2

9617

param_struct.flex=2;

9606

param_struct.flex=2;

9618

elseif mele==4

9607

elseif mele==4

9619

param_struct.flex=4;

9608

param_struct.flex=4;

9620

elseif mele==1

9609

elseif mele==1

9621

param_struct.flex=1;

9610

param_struct.flex=1;

9622

else

9611

else

9623

error('config file syntax error')

9612

error('config file syntax error')

9624

end

9613

end

9625

param_struct.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9614

param_struct.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9626

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9615

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9627

if ncases ~= ncases1 || mele ~= mele1

9616

if ncases ~= ncases1 || mele ~= mele1

9628

error('All TX, NEXT, FEXT, Rx cases must agree');

9617

error('All TX, NEXT, FEXT, Rx cases must agree');

9629

else

9618

else

9630

end

9619

end

9631

param_struct.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9620

param_struct.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9632

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9621

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9633

if ncases ~= ncases1 || mele ~= mele1

9622

if ncases ~= ncases1 || mele ~= mele1

9634

error('All TX, NEXT, FEXT, Rx cases must agree');

9623

error('All TX, NEXT, FEXT, Rx cases must agree');

9635

else

9624

else

9636

end

9625

end

9637

param_struct.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9626

param_struct.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9638

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9627

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9639

if ncases ~= ncases1 || mele ~= mele1

9628

if ncases ~= ncases1 || mele ~= mele1

9640

error('All TX, NEXT, FEXT, Rx cases must agree');

9629

error('All TX, NEXT, FEXT, Rx cases must agree');

9641

else

9630

else

9642

end

9631

end

9643

% Table 93A-3 parameters

9632

% Table 93A-3 parameters

9644

param_struct.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9633

param_struct.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9645

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9634

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9646

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9635

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9647

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9636

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9648

if mele ~= mele1

9637

if mele ~= mele1

9649

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9638

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9650

else

9639

else

9651

end

9640

end

9652

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9641

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9653

for ii=1:ncases

9642

for ii=1:ncases

9654

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9643

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9655

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9644

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9656

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9645

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9657

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9646

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9658

end

9647

end

9659

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9648

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9660

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9649

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9661

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9650

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9662

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9651

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9663

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9652

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9664

end

9653

end

9665

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9654

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9666

%% extract s-parameter and convert to differential mode

9655

%% extract s-parameter and convert to differential mode

9667

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9656

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9668

num_files=length(chdata);

9657

num_files=length(chdata);

9669

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9658

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9670

for i=1:num_files

9659

for i=1:num_files

9671

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9660

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9672

progress = i/num_files;

9661

progress = i/num_files;

9673

if OP.DISPLAY_WINDOW

9662

if OP.DISPLAY_WINDOW

9674

[~,a]=fileparts(chdata(i).filename);

9663

[~,a]=fileparts(chdata(i).filename);

9675

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9664

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9676

else

9665

else

9677

fprintf('%i ',i);

9666

fprintf('%i ',i);

9678

end

9667

end

9679

9668

9680

% Skip reading file if it was already read (multiple test cases)

9669

% Skip reading file if it was already read (multiple test cases)

9681

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9670

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9682

switch lower(chdata(i).ext)

9671

switch lower(chdata(i).ext)

9683

case '.s2p' % for differential return loss

9672

case '.s2p' % for differential return loss

9684

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9673

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9685

chdata(i).fmaxi = length(Sch.freq);

9674

chdata(i).fmaxi = length(Sch.freq);

9686

chdata(i).faxis = Sch.freq;

9675

chdata(i).faxis = Sch.freq;

9687

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9676

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9688

SDDp2p(i)=NaN;

9677

SDDp2p(i)=NaN;

9689

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9678

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9690

chdata(i).sdd11=chdata(i).sdd11_raw;

9679

chdata(i).sdd11=chdata(i).sdd11_raw;

9691

case '.s4p'

9680

case '.s4p'

9692

if length(param.snpPortsOrder) ~= 4

9681

if length(param.snpPortsOrder) ~= 4

9693

error( 'warning:sNpFilePortMismatch', ...

9682

error( 'warning:sNpFilePortMismatch', ...

9694

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9683

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9695

length(param.snpPortsOrder), ...

9684

length(param.snpPortsOrder), ...

9696

chdata(i).ext ...

9685

chdata(i).ext ...

9697

);

9686

);

9698

end

9687

end

9699

% read function returns differnetial mode parameters

9688

% read function returns differnetial mode parameters

9700

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9689

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9701

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9690

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9702

% param.holdsdata(i).Sch= Sch;

9691

% param.holdsdata(i).Sch= Sch;

9703

% param.holdsdata(i).SDDch= SDDch;

9692

% param.holdsdata(i).SDDch= SDDch;

9704

% param.holdsdata(i).SDCch= SDCch;

9693

% param.holdsdata(i).SDCch= SDCch;

9705

else

9694

else

9706

error('If this line is reached, there is a logic error');

9695

error('If this line is reached, there is a logic error');

9707

% Sch=param.holdsdata(i).Sch;

9696

% Sch=param.holdsdata(i).Sch;

9708

% SDDch=param.holdsdata(i).SDDch;

9697

% SDDch=param.holdsdata(i).SDDch;

9709

% SDCch=param.holdsdata(i).SDCch;

9698

% SDCch=param.holdsdata(i).SDCch;

9710

end

9699

end

9711

chdata(i).fmaxi = length(Sch.freq);

9700

chdata(i).fmaxi = length(Sch.freq);

9712

9701

9713

9702

9714

if Sch.freq(chdata(i).fmaxi) < param.fb

9703

if Sch.freq(chdata(i).fmaxi) < param.fb

9715

warning('COM:read_s4p:MaxFreqTooLow', ...

9704

warning('COM:read_s4p:MaxFreqTooLow', ...

9716

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9705

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9717

chdata(i).filename, Sch.freq(end), param.fb);

9706

chdata(i).filename, Sch.freq(end), param.fb);

9718

end

9707

end

9719

if Sch.freq(1) > param.max_start_freq

9708

if Sch.freq(1) > param.max_start_freq

9720

warning('COM:read_s4p:StartFreqTooHigh', ...

9709

warning('COM:read_s4p:StartFreqTooHigh', ...

9721

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9710

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9722

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9711

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9723

end

9712

end

9724

freqstep=diff(Sch.freq);

9713

freqstep=diff(Sch.freq);

9725

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9714

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9726

if max(freqstep)-min(freqstep) > 1

9715

if max(freqstep)-min(freqstep) > 1

9727

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9716

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9728

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9717

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9729

end

9718

end

9730

if max(freqstep) - param.max_freq_step > 1

9719

if max(freqstep) - param.max_freq_step > 1

9731

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9720

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9732

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9721

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9733

end

9722

end

9734

9723

9735

chdata(i).faxis = Sch.freq;

9724

chdata(i).faxis = Sch.freq;

9736

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9725

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9737

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9726

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9738

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9727

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9739

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9728

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9740

% mode conversion

9729

% mode conversion

9741

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9730

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9742

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9731

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9743

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9732

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9744

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9733

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9745

%save original and add board (if required)

9734

%save original and add board (if required)

9746

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9735

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9747

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

9736

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

9748

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

9737

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

9749

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

9738

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

9750

if OP.include_pcb

9739

if OP.include_pcb

9751

% add boards to sdd

9740

% add boards to sdd

9752

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

9741

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

9753

9742

9754

end

9743

end

9755

%save final return loss (after the boards were included)

9744

%save final return loss (after the boards were included)

9756

chdata(i).sdd11=chdata(i).sdd11_raw;

9745

chdata(i).sdd11=chdata(i).sdd11_raw;

9757

chdata(i).sdd22=chdata(i).sdd22_raw;

9746

chdata(i).sdd22=chdata(i).sdd22_raw;

9758

otherwise

9747

otherwise

9759

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

9748

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

9760

end

9749

end

9761

9750

9762

%Crosstalk frequency axis must be the same as Thru

9751

%Crosstalk frequency axis must be the same as Thru

9763

if i>1

9752

if i>1

9764

%error on length difference

9753

%error on length difference

9765

if length(chdata(i).faxis)~=length(chdata(1).faxis)

9754

if length(chdata(i).faxis)~=length(chdata(1).faxis)

9766

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

9755

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

9767

end

9756

end

9768

%error if any value > 1Hz (don't want to check for exact

9757

%error if any value > 1Hz (don't want to check for exact

9769

%equality in case of floating point error)

9758

%equality in case of floating point error)

9770

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

9759

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

9771

if max(Fdiff)>1

9760

if max(Fdiff)>1

9772

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

9761

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

9773

end

9762

end

9774

end

9763

end

9775

else

9764

else

9776

SDDch(:,1,2)=chdata(i).sdd12_raw;

9765

SDDch(:,1,2)=chdata(i).sdd12_raw;

9777

SDDch(:,2,1)=chdata(i).sdd21_raw;

9766

SDDch(:,2,1)=chdata(i).sdd21_raw;

9778

SDDch(:,1,1)=chdata(i).sdd11_raw;

9767

SDDch(:,1,1)=chdata(i).sdd11_raw;

9779

SDDch(:,2,2)=chdata(i).sdd22_raw;

9768

SDDch(:,2,2)=chdata(i).sdd22_raw;

9780

end

9769

end

9781

chdata(i).sigma_ACCM_at_tp0=0;

9770

chdata(i).sigma_ACCM_at_tp0=0;

9782

if ~param.FLAG.S2P

9771

if ~param.FLAG.S2P

9783

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

9772

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

9784

if (OP.RX_CALIBRATION == 1 && i==2)

9773

if (OP.RX_CALIBRATION == 1 && i==2)

9785

chdata(i).sdd21=chdata(i).sdd21_raw;

9774

chdata(i).sdd21=chdata(i).sdd21_raw;

9786

else

9775

else

9787

%updated package construction with single function for both DD and DC

9776

%updated package construction with single function for both DD and DC

9788

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

9777

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

9789

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

9778

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

9790

chdata(i).sdd21=chdata(i).sdd21p;

9779

chdata(i).sdd21=chdata(i).sdd21p;

9791

if 1 % for AC CM noise inclusion

9780

if 1 % for AC CM noise inclusion

9792

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

9781

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

9793

chdata(i).sdc21=chdata(i).sdc21p;

9782

chdata(i).sdc21=chdata(i).sdc21p;

9794

end

9783

end

9795

end

9784

end

9796

else

9785

else

9797

chdata(i).sdd21=chdata(i).sdd21_raw;

9786

chdata(i).sdd21=chdata(i).sdd21_raw;

9798

end

9787

end

9799

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

9788

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

9800

end

9789

end

9801

end

9790

end

9802

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

9791

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

9803

9792

9804

function result = readdataSnPx(filename, nport)

9793

function result = readdataSnPx(filename, nport)

9805

%function [freq, cs] = readdataSnPx(filename, nport)

9794

%function [freq, cs] = readdataSnPx(filename, nport)

9806

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

9795

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

9807

%

9796

%

9808

% Read Touchstone file with frequencies in units of Hertz

9797

% Read Touchstone file with frequencies in units of Hertz

9809

%

9798

%

9810

% Input:

9799

% Input:

9811

% ======

9800

% ======

9812

% filename: Name of the Touchstone/SnP file

9801

% filename: Name of the Touchstone/SnP file

9813

% nport: Number of ports

9802

% nport: Number of ports

9814

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

9803

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

9815

% Touchstone file)

9804

% Touchstone file)

9816

% nheader: Number of header lines (comment lines plus option line in the

9805

% nheader: Number of header lines (comment lines plus option line in the

9817

% Touchstone file)

9806

% Touchstone file)

9818

%

9807

%

9819

% Output:

9808

% Output:

9820

% =======

9809

% =======

9821

% freq: Vector of frequencies [Hz]

9810

% freq: Vector of frequencies [Hz]

9822

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

9811

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

9823

% at frequency freq(k)

9812

% at frequency freq(k)

9824

%

9813

%

9825

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

9814

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

9826

% frequencies appropriately after reading the data.

9815

% frequencies appropriately after reading the data.

9827

%

9816

%

9828

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

9817

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

9829

% EIA/IBIS Open Forum, 2002.

9818

% EIA/IBIS Open Forum, 2002.

9830

%

9819

%

9831

% Written by Henning Braunisch, September 2004.

9820

% Written by Henning Braunisch, September 2004.

9832

% Updated by Steven Krooswyk, April 2006.

9821

% Updated by Steven Krooswyk, April 2006.

9833

9822

9834

9823

9835

fid = fopen(filename, 'r');

9824

fid = fopen(filename, 'r');

9836

9825

9837

9826

9838

% Skip header lines

9827

% Skip header lines

9839

str = ' ';

9828

str = ' ';

9840

n = 0;

9829

n = 0;

9841

while ~strcmp(str(1),'#')

9830

while ~strcmp(str(1),'#')

9842

str = fgetl(fid);

9831

str = fgetl(fid);

9843

if isempty(str)

9832

if isempty(str)

9844

str=' ' ;

9833

str=' ' ;

9845

if n > 1000

9834

if n > 1000

9846

display('error: could not find config line (#)')

9835

display('error: could not find config line (#)')

9847

break

9836

break

9848

end

9837

end

9849

end

9838

end

9850

n = n + 1;

9839

n = n + 1;

9851

end

9840

end

9852

9841

9853

% parse configuration line

9842

% parse configuration line

9854

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

9843

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

9855

p = find(A=='S'); %position of 'S'

9844

p = find(A=='S'); %position of 'S'

9856

units = lower(A(2:p-1)); %units before 'S'

9845

units = lower(A(2:p-1)); %units before 'S'

9857

format = A(p+1:p+2); %format after 'S'

9846

format = A(p+1:p+2); %format after 'S'

9858

9847

9859

% skip any more header lines

9848

% skip any more header lines

9860

%while ~str

9849

%while ~str

9861

9850

9862

nk = 0; % frequency counter

9851

nk = 0; % frequency counter

9863

while 1

9852

while 1

9864

9853

9865

[temp, count] = fscanf(fid, '%f', 1);

9854

[temp, count] = fscanf(fid, '%f', 1);

9866

if count == 0

9855

if count == 0

9867

temp2 = fscanf(fid, '%s', 1);

9856

temp2 = fscanf(fid, '%s', 1);

9868

if ~isempty(temp2), fgetl(fid); continue, end;

9857

if ~isempty(temp2), fgetl(fid); continue, end;

9869

break

9858

break

9870

end

9859

end

9871

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

9860

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

9872

for ni = 1:nport

9861

for ni = 1:nport

9873

for nj = 1:nport

9862

for nj = 1:nport

9874

switch lower(format)

9863

switch lower(format)

9875

case 'ma'

9864

case 'ma'

9876

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9865

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9877

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

9866

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

9878

case 'ri'

9867

case 'ri'

9879

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

9868

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

9880

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9869

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9881

case 'db'

9870

case 'db'

9882

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9871

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9883

M = 10^(db/20);

9872

M = 10^(db/20);

9884

%re = M*cos(ang);

9873

%re = M*cos(ang);

9885

%im = M*sin(ang);

9874

%im = M*sin(ang);

9886

re = M*cos(ang * pi / 180);

9875

re = M*cos(ang * pi / 180);

9887

im = M*sin(ang * pi / 180);

9876

im = M*sin(ang * pi / 180);

9888

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9877

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9889

otherwise

9878

otherwise

9890

error('readdataSnP: Unknown data format');

9879

error('readdataSnP: Unknown data format');

9891

end

9880

end

9892

end

9881

end

9893

end

9882

end

9894

end

9883

end

9895

9884

9896

fclose(fid);

9885

fclose(fid);

9897

9886

9898

% If 2-port then swap S_12 and S_21 per Touchstone spec

9887

% If 2-port then swap S_12 and S_21 per Touchstone spec

9899

if nport == 2

9888

if nport == 2

9900

temp = cs(2,1,:);

9889

temp = cs(2,1,:);

9901

cs(2,1,:) = cs(1,2,:);

9890

cs(2,1,:) = cs(1,2,:);

9902

cs(1,2,:) = temp;

9891

cs(1,2,:) = temp;

9903

end

9892

end

9904

9893

9905

% Update freq units to Hz

9894

% Update freq units to Hz

9906

switch lower(units)

9895

switch lower(units)

9907

case 'hz'

9896

case 'hz'

9908

9897

9909

case 'khz'

9898

case 'khz'

9910

freq=freq.*1e3;

9899

freq=freq.*1e3;

9911

case 'mhz'

9900

case 'mhz'

9912

freq=freq.*1e6;

9901

freq=freq.*1e6;

9913

case 'ghz'

9902

case 'ghz'

9914

freq=freq.*1e9;

9903

freq=freq.*1e9;

9915

end

9904

end

9916

9905

9917

% passivity check

9906

% passivity check

9918

result.freq = freq;

9907

result.freq = freq;

9919

result.cs = cs;

9908

result.cs = cs;

9920

9909

9921

function recolor_plots(ax)

9910

function recolor_plots(ax)

9922

9911

9923

if ~verLessThan('matlab', '8.4.0')

9912

if ~verLessThan('matlab', '8.4.0')

9924

return

9913

return

9925

end

9914

end

9926

colors='brgcmk';

9915

colors='brgcmk';

9927

ch=flipud(get(ax, 'children'));

9916

ch=flipud(get(ax, 'children'));

9928

9917

9929

for k=1:length(ch)

9918

for k=1:length(ch)

9930

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

9919

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

9931

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

9920

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

9932

end

9921

end

9933

legend (ax, 'off');

9922

legend (ax, 'off');

9934

warning('off', 'MATLAB:legend:PlotEmpty');

9923

warning('off', 'MATLAB:legend:PlotEmpty');

9935

set(legend (ax, 'show'), 'interp', 'none');

9924

set(legend (ax, 'show'), 'interp', 'none');

9936

9925

+9926

function result = reduce(var1)

9927

% --- Reduce 1x1xn array to 1xn (aka squeeze)

9928

out = zeros(1,length(var1));

9929

out(1,:) = var1(1,1,:);

9930

result=out;

9931

9937

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

9932

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

9938

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

9933

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

9939

% faxis is the frequency array

9934

% faxis is the frequency array

9940

% s21, s11, s22 are the corresponding array of differential parameters

9935

% s21, s11, s22 are the corresponding array of differential parameters

9941

% s21p includes the VFT and Tx filter if include_die=1

9936

% s21p includes the VFT and Tx filter if include_die=1

9942

if nargin<6

9937

if nargin<6

9943

include_die=1;

9938

include_die=1;

9944

end

9939

end

9945

if nargin<5

9940

if nargin<5

9946

mode='dd';

9941

mode='dd';

9947

end

9942

end

9948

9943

9949

s21=chdata.(['s' mode '21_raw']);

9944

s21=chdata.(['s' mode '21_raw']);

9950

s12=chdata.(['s' mode '12_raw']);

9945

s12=chdata.(['s' mode '12_raw']);

9951

s11=chdata.(['s' mode '11_raw']);

9946

s11=chdata.(['s' mode '11_raw']);

9952

s22=chdata.(['s' mode '22_raw']);

9947

s22=chdata.(['s' mode '22_raw']);

9953

faxis=chdata.faxis;

9948

faxis=chdata.faxis;

9954

channel_type=chdata.type;

9949

channel_type=chdata.type;

9955

9950

9956

if strcmpi(mode,'dd')

9951

if strcmpi(mode,'dd')

9957

s11=s11*param.kappa1;

9952

s11=s11*param.kappa1;

9958

s22=s22*param.kappa2;

9953

s22=s22*param.kappa2;

9959

end

9954

end

9960

9955

9961

9956

9962

Z0=param.Z0;

9957

Z0=param.Z0;

9963

%sigma_ACCM_at_tp0 is only used when mode=DC

9958

%sigma_ACCM_at_tp0 is only used when mode=DC

9964

sigma_ACCM_at_tp0=0;

9959

sigma_ACCM_at_tp0=0;

9965

9960

9966

% The following three parameters have possibly different valuesF for TX and

9961

% The following three parameters have possibly different valuesF for TX and

9967

% RX (so can be 2-element vectors).

9962

% RX (so can be 2-element vectors).

9968

R_diepad = param.R_diepad;

9963

R_diepad = param.R_diepad;

9969

9964

9970

%Make TX Package

9965

%Make TX Package

9971

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

9966

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

9972

9967

9973

%Make RX Package

9968

%Make RX Package

9974

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

9969

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

9975

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

9970

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

9976

9971

9977

9972

9978

% p(1 ,1, :)=s11in;

9973

% p(1 ,1, :)=s11in;

9979

% p(2 ,2, :)=s22in;

9974

% p(2 ,2, :)=s22in;

9980

% p(1 ,2, :)=s12in;

9975

% p(1 ,2, :)=s12in;

9981

% p(2 ,1, :)=s21in;

9976

% p(2 ,1, :)=s21in;

9982

%

9977

%

9983

% S=sparameters(p,faxis);

9978

% S=sparameters(p,faxis);

9984

% rfwrite(S,'temp.s4p');

9979

% rfwrite(S,'temp.s4p');

9985

9980

9986

if strcmpi(mode,'dc')

9981

if strcmpi(mode,'dc')

9987

RTX=R_diepad(param.Tx_rd_sel)/2;

9982

RTX=R_diepad(param.Tx_rd_sel)/2;

9988

RRX=R_diepad(param.Rx_rd_sel)/2;

9983

RRX=R_diepad(param.Rx_rd_sel)/2;

9989

Z0gamma=Z0/2;

9984

Z0gamma=Z0/2;

9990

else

9985

else

9991

RTX=R_diepad(param.Tx_rd_sel);

9986

RTX=R_diepad(param.Tx_rd_sel);

9992

RRX=R_diepad(param.Rx_rd_sel);

9987

RRX=R_diepad(param.Rx_rd_sel);

9993

Z0gamma=Z0;

9988

Z0gamma=Z0;

9994

end

9989

end

9995

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

9990

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

9996

gamma_tx=0;

9991

gamma_tx=0;

9997

else

9992

else

9998

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

9993

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

9999

end

9994

end

10000

if OP.IDEAL_RX_TERM

9995

if OP.IDEAL_RX_TERM

10001

gamma_rx=0;

9996

gamma_rx=0;

10002

else

9997

else

10003

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

9998

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

10004

end

9999

end

10005

10000

10006

if OP.INC_PACKAGE==0

10001

if OP.INC_PACKAGE==0

10007

s21p= s21;

10002

s21p= s21;

10008

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

10003

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

10009

else

10004

else

10010

if OP.RX_CALIBRATION == 1 && channel_number == 2

10005

if OP.RX_CALIBRATION == 1 && channel_number == 2

10011

% for calibration do not include the transmitter package

10006

% for calibration do not include the transmitter package

10012

[s11out_rx, s12out_rx, s21out_rx, s22out_rx ] = combines4p( s11, s12, s21, s22, s22out, s12out, s21out, s11out ); %#ok<ASGLU> % s22 is ball side of package

10007

[s11out_rx, s12out_rx, s21out_rx, s22out_rx ] = combines4p( s11, s12, s21, s22, s22out, s12out, s21out, s11out ); %#ok<ASGLU> % s22 is ball side of package

10013

SCH.Frequencies=faxis;

10008

SCH.Frequencies=faxis;

10014

SCH.Parameters(1,1,:)=s11out_rx;

10009

SCH.Parameters(1,1,:)=s11out_rx;

10015

SCH.Parameters(2,2,:)=s22out_rx;

10010

SCH.Parameters(2,2,:)=s22out_rx;

10016

SCH.Parameters(1,2,:)=s12out_rx;

10011

SCH.Parameters(1,2,:)=s12out_rx;

10017

SCH.Parameters(2,1,:)=s21out_rx;

10012

SCH.Parameters(2,1,:)=s21out_rx;

10018

SCH.NumPorts=2;

10013

SCH.NumPorts=2;

10019

SCH.Impedance=100;

10014

SCH.Impedance=100;

10020

%% Equation 93A-18

10015

%% Equation 93A-18

10021

if include_die

10016

if include_die

10022

s21p= s21out_rx.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11out_rx.*gamma_tx - s22out_rx.*gamma_rx -s21out_rx.^2.*gamma_tx.*gamma_rx +s11out_rx.*s22out_rx.*gamma_tx.*gamma_rx);

10017

s21p= s21out_rx.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11out_rx.*gamma_tx - s22out_rx.*gamma_rx -s21out_rx.^2.*gamma_tx.*gamma_rx +s11out_rx.*s22out_rx.*gamma_tx.*gamma_rx);

10023

else

10018

else

10024

s21p=s21out_rx; % if no die we do not want a VTF

10019

s21p=s21out_rx; % if no die we do not want a VTF

10025

end

10020

end

10026

else

10021

else

10027

%% Equations 93A-4 to 93A-7

10022

%% Equations 93A-4 to 93A-7

10028

if ~OP.IDEAL_TX_TERM

10023

if ~OP.IDEAL_TX_TERM

10029

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10024

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10030

end

10025

end

10031

H_t=ones(1,length(faxis)); % .3bj compatibility

10026

H_t=ones(1,length(faxis)); % .3bj compatibility

10032

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10027

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10033

% for RITT testing with good termination as in some instruments

10028

% for RITT testing with good termination as in some instruments

10034

% and tx filter when required

10029

% and tx filter when required

10035

if OP.T_r_filter_type==0

10030

if OP.T_r_filter_type==0

10036

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10031

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10037

else

10032

else

10038

tr=OP.transmitter_transition_time;

10033

tr=OP.transmitter_transition_time;

10039

f9=faxis/1e9;

10034

f9=faxis/1e9;

10040

if OP.T_r_meas_point == 1

10035

if OP.T_r_meas_point == 1

10041

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10036

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10042

H_t=105./(f9.^4*(k*tr)^4 - f9.^3*(k*tr)^3*10i - 45*f9.^2*(k*tr)^2 + f9*(k*tr)*105i + 105);

10037

H_t=105./(f9.^4*(k*tr)^4 - f9.^3*(k*tr)^3*10i - 45*f9.^2*(k*tr)^2 + f9*(k*tr)*105i + 105);

10043

else

10038

else

10044

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10039

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10045

end

10040

end

10046

10041

10047

end

10042

end

10048

end

10043

end

10049

if strcmpi(mode,'dc')

10044

if strcmpi(mode,'dc')

10050

% H_t=ones(1,length(faxis)); % not sure if we need a H_t or not. Is the CM noise correlated to the edge rate?

10045

% H_t=ones(1,length(faxis)); % not sure if we need a H_t or not. Is the CM noise correlated to the edge rate?

10051

end

10046

end

10052

if ~OP.IDEAL_RX_TERM

10047

if ~OP.IDEAL_RX_TERM

10053

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10048

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10054

else

10049

else

10055

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10050

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10056

end

10051

end

10057

%% Equation 93A-18 and part of 93A-1: Ht fix in V290 identified by Bill Kirkland and Ed Frlan ( s21^2 changed to s12*s21 )

10052

%% Equation 93A-18 and part of 93A-1: Ht fix in V290 identified by Bill Kirkland and Ed Frlan ( s21^2 changed to s12*s21 )

10058

if include_die

10053

if include_die

10059

s21p= H_t.*s21.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11.*gamma_tx - s22.*gamma_rx -s21.*s12.*gamma_tx.*gamma_rx +s11.*s22.*gamma_tx.*gamma_rx);

10054

s21p= H_t.*s21.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11.*gamma_tx - s22.*gamma_rx -s21.*s12.*gamma_tx.*gamma_rx +s11.*s22.*gamma_tx.*gamma_rx);

10060

else

10055

else

10061

s21p=s21; % if no die we do not want a VTF

10056

s21p=s21; % if no die we do not want a VTF

10062

end

10057

end

10063

end

10058

end

10064

10059

10065

if strcmpi(mode,'dc')

10060

if strcmpi(mode,'dc')

10066

% compute AC_CM_RMS at tp0

10061

% compute AC_CM_RMS at tp0

10067

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10062

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10068

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10063

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10069

if channel_number == 1

10064

if channel_number == 1

10070

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10065

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10071

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10066

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10072

sigma_ACCM_at_tp0= sqrt(2*param.AC_CM_RMS_TX^2*sum( abs( H_cc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end)) ;

10067

sigma_ACCM_at_tp0= sqrt(2*param.AC_CM_RMS_TX^2*sum( abs( H_cc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end)) ;

10073

% S=sparameters(p,faxis);

10068

% S=sparameters(p,faxis);

10074

% rfwrite(S,'temp.s4p');

10069

% rfwrite(S,'temp.s4p');

10075

end

10070

end

10076

end

10071

end

10077

10072

10078

SCH.Frequencies=faxis;

10073

SCH.Frequencies=faxis;

10079

SCH.Parameters(1,1,:)=s11;

10074

SCH.Parameters(1,1,:)=s11;

10080

SCH.Parameters(2,2,:)=s22;

10075

SCH.Parameters(2,2,:)=s22;

10081

SCH.Parameters(1,2,:)=s12;

10076

SCH.Parameters(1,2,:)=s12;

10082

SCH.Parameters(2,1,:)=s21;

10077

SCH.Parameters(2,1,:)=s21;

10083

SCH.NumPorts=2;

10078

SCH.NumPorts=2;

10084

if strcmpi(mode,'dc')

10079

if strcmpi(mode,'dc')

10085

SCH.Impedance=25;

10080

SCH.Impedance=25;

10086

else

10081

else

10087

SCH.Impedance=100;

10082

SCH.Impedance=100;

10088

end

10083

end

10089

10084

10090

end

10085

end

10091

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10086

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10092

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10087

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10093

% Creates a time-domain impulse response from frequency-domain IL data.

10088

% Creates a time-domain impulse response from frequency-domain IL data.

10094

% IL does not need to have DC but a corresponding frequency array

10089

% IL does not need to have DC but a corresponding frequency array

10095

% (freq_array) is required.

10090

% (freq_array) is required.

10096

%

10091

%

10097

% Causality is imposed using the Alternating Projections Method. See also:

10092

% Causality is imposed using the Alternating Projections Method. See also:

10098

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10093

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10099

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10094

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10100

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10095

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10101

10096

10102

ILin=IL;

10097

ILin=IL;

10103

fmax=1/time_step/2;

10098

fmax=1/time_step/2;

10104

freq_step=(freq_array(3)-freq_array(2))/1;

10099

freq_step=(freq_array(3)-freq_array(2))/1;

10105

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10100

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10106

if all(IL==0)

10101

if all(IL==0)

10107

%response with all zeros is problematic. set to all eps and avoid interp function

10102

%response with all zeros is problematic. set to all eps and avoid interp function

10108

IL=ones(1,length(fout))*eps;

10103

IL=ones(1,length(fout))*eps;

10109

else

10104

else

10110

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10105

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10111

IL_nan = find(isnan(IL));

10106

IL_nan = find(isnan(IL));

10112

for in=IL_nan

10107

for in=IL_nan

10113

IL(in)=IL(in-1);

10108

IL(in)=IL(in-1);

10114

end

10109

end

10115

end

10110

end

10116

IL = IL(:);

10111

IL = IL(:);

10117

% add padding for time steps

10112

% add padding for time steps

10118

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10113

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10119

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10114

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10120

impulse_response = real(ifft(IL_symmetric));

10115

impulse_response = real(ifft(IL_symmetric));

10121

L = length(impulse_response);

10116

L = length(impulse_response);

10122

t_base = (0:L-1)/(freq_step*L);

10117

t_base = (0:L-1)/(freq_step*L);

10123

10118

10124

original_impulse_response=impulse_response;

10119

original_impulse_response=impulse_response;

10125

% Correct non-causal effects frequently caused by extrapolation of IL

10120

% Correct non-causal effects frequently caused by extrapolation of IL

10126

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10121

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10127

abs_ir=abs(impulse_response);

10122

abs_ir=abs(impulse_response);

10128

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10123

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10129

start_ind = a(1);

10124

start_ind = a(1);

10130

10125

10131

err=inf;

10126

err=inf;

10132

while ~all(impulse_response==0)

10127

while ~all(impulse_response==0)

10133

impulse_response(1:start_ind)=0;

10128

impulse_response(1:start_ind)=0;

10134

impulse_response(floor(L/2):end)=0;

10129

impulse_response(floor(L/2):end)=0;

10135

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10130

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10136

ir_modified = real(ifft(IL_modified));

10131

ir_modified = real(ifft(IL_modified));

10137

delta = abs(impulse_response-ir_modified);

10132

delta = abs(impulse_response-ir_modified);

10138

10133

10139

err_prev = err;

10134

err_prev = err;

10140

err=max(delta)/max(impulse_response);

10135

err=max(delta)/max(impulse_response);

10141

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10136

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10142

break;

10137

break;

10143

end

10138

end

10144

10139

10145

impulse_response=ir_modified;

10140

impulse_response=ir_modified;

10146

end

10141

end

10147

10142

10148

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10143

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10149

10144

10150

if ~OP.ENFORCE_CAUSALITY

10145

if ~OP.ENFORCE_CAUSALITY

10151

impulse_response = original_impulse_response;

10146

impulse_response = original_impulse_response;

10152

end

10147

end

10153

% truncate final samples smaller than 1e-3 of the peak

10148

% truncate final samples smaller than 1e-3 of the peak

10154

ir_peak = max(abs(impulse_response));

10149

ir_peak = max(abs(impulse_response));

10155

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10150

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10156

10151

10157

voltage = impulse_response(1:ir_last);

10152

voltage = impulse_response(1:ir_last);

10158

t_base = t_base(1:ir_last);

10153

t_base = t_base(1:ir_last);

10159

10154

10160

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10155

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10161

10156

10162

function S =s_for_c2(zref,f,cpad)

10157

function S =s_for_c2(zref,f,cpad)

10163

% S is 2 port s parameters out

10158

% S is 2 port s parameters out

10164

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10159

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10165

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10160

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10166

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10161

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10167

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10162

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10168

S=sparameters(S_Parameters,f,zref);

10163

S=sparameters(S_Parameters,f,zref);

10169

10164

10170

function S =s_for_c4(zref,f,cpad)

10165

function S =s_for_c4(zref,f,cpad)

10171

10166

10172

S2 = s_for_c2(zref,f,cpad);

10167

S2 = s_for_c2(zref,f,cpad);

10173

S4P=s2_to_s4(S2.Parameters);

10168

S4P=s2_to_s4(S2.Parameters);

10174

S=sparameters(S4P,f,zref);

10169

S=sparameters(S4P,f,zref);

10175

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10170

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10176

10171

10177

10172

10178

10173

10179

10174

10180

%%

10175

%%

10181

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10176

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10182

% save commmend string

10177

% save commmend string

10183

% for saving from interactive queries

10178

% for saving from interactive queries

10184

10179

10185

10180

10186

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10181

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10187

for i=1:num_next+num_fext

10182

for i=1:num_next+num_fext

10188

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10183

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10189

end

10184

end

10190

cmd_str= [ cmd_str ')'];

10185

cmd_str= [ cmd_str ')'];

10191

10186

10192

10187

10193

%%%%% require the RF tool box

10188

%%%%% require the RF tool box

10194

%%

10189

%%

10195

function [ h ] = savefigs( param, OP )

10190

function [ h ] = savefigs( param, OP )

10196

10191

10197

%% find the figures

10192

%% find the figures

10198

hw = waitbar(0,'Saving figures...');

10193

hw = waitbar(0,'Saving figures...');

10199

h = findobj(0, 'Type', 'figure');

10194

h = findobj(0, 'Type', 'figure');

10200

for ii=1:length(h)

10195

for ii=1:length(h)

10201

10196

10202

figname= get(h(ii), 'Name'); % use the figure name as file name

10197

figname= get(h(ii), 'Name'); % use the figure name as file name

10203

if isempty(strfind(figname,param.base))

10198

if isempty(strfind(figname,param.base))

10204

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10199

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10205

end

10200

end

10206

if verLessThan('matlab', '8.4.0')

10201

if verLessThan('matlab', '8.4.0')

10207

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10202

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10208

else

10203

else

10209

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10204

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10210

end

10205

end

10211

figname = strrep(figname,':','-');

10206

figname = strrep(figname,':','-');

10212

figname = strrep(figname,' ','_');

10207

figname = strrep(figname,' ','_');

10213

if OP.SAVE_FIGURES==1

10208

if OP.SAVE_FIGURES==1

10214

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10209

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10215

end

10210

end

10216

%% get x y data

10211

%% get x y data

10217

if OP.SAVE_FIGURE_to_CSV==1

10212

if OP.SAVE_FIGURE_to_CSV==1

10218

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10213

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10219

M=[]; %ncol=1;

10214

M=[]; %ncol=1;

10220

for nk=1:length(h_L)

10215

for nk=1:length(h_L)

10221

% get x and data for a line.

10216

% get x and data for a line.

10222

x_data=get(h_L(nk),'xdata')';

10217

x_data=get(h_L(nk),'xdata')';

10223

y_data=get(h_L(nk),'ydata')';

10218

y_data=get(h_L(nk),'ydata')';

10224

% .........>> need to get data in the line structure (legend or label) for headers

10219

% .........>> need to get data in the line structure (legend or label) for headers

10225

M=[M; x_data; y_data]; %#ok<AGROW>

10220

M=[M; x_data; y_data]; %#ok<AGROW>

10226

end

10221

end

10227

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10222

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10228

% clear M y x header h_L

10223

% clear M y x header h_L

10229

end

10224

end

10230

waitbar(ii/length(h),hw)

10225

waitbar(ii/length(h),hw)

10231

10226

10232

end

10227

end

10233

10228

10234

close(hw)

10229

close(hw)

10235

10230

10236

%%

10231

%%

10237

function [ h ] = savefigs_png( param, OP )

10232

function [ h ] = savefigs_png( param, OP )

10238

10233

10239

%% find the figures

10234

%% find the figures

10240

hw = waitbar(0,'Saving figures...');

10235

hw = waitbar(0,'Saving figures...');

10241

h = findobj(0, 'Type', 'figure');

10236

h = findobj(0, 'Type', 'figure');

10242

for ii=1:length(h)

10237

for ii=1:length(h)

10243

10238

10244

figname= get(h(ii), 'Name'); % use the figure name as file name

10239

figname= get(h(ii), 'Name'); % use the figure name as file name

10245

if isempty(strfind(figname,param.base))

10240

if isempty(strfind(figname,param.base))

10246

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10241

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10247

end

10242

end

10248

if verLessThan('matlab', '8.4.0')

10243

if verLessThan('matlab', '8.4.0')

10249

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10244

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10250

else

10245

else

10251

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10246

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10252

end

10247

end

10253

figname = strrep(figname,':','-');

10248

figname = strrep(figname,':','-');

10254

figname = strrep(figname,' ','_');

10249

figname = strrep(figname,' ','_');

10255

if OP.SAVE_FIGURES==1

10250

if OP.SAVE_FIGURES==1

10256

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10251

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10257

end

10252

end

10258

%% get x y data

10253

%% get x y data

10259

if OP.SAVE_FIGURE_to_CSV==1

10254

if OP.SAVE_FIGURE_to_CSV==1

10260

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10255

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10261

M=[]; %ncol=1;

10256

M=[]; %ncol=1;

10262

for nk=1:length(h_L)

10257

for nk=1:length(h_L)

10263

% get x and data for a line.

10258

% get x and data for a line.

10264

x_data=get(h_L(nk),'xdata')';

10259

x_data=get(h_L(nk),'xdata')';

10265

y_data=get(h_L(nk),'ydata')';

10260

y_data=get(h_L(nk),'ydata')';

10266

% .........>> need to get data in the line structure (legend or label) for headers

10261

% .........>> need to get data in the line structure (legend or label) for headers

10267

M=[M; x_data; y_data]; %#ok<AGROW>

10262

M=[M; x_data; y_data]; %#ok<AGROW>

10268

end

10263

end

10269

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10264

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10270

% clear M y x header h_L

10265

% clear M y x header h_L

10271

end

10266

end

10272

waitbar(ii/length(h),hw)

10267

waitbar(ii/length(h),hw)

10273

10268

10274

end

10269

end

10275

10270

10276

close(hw)

10271

close(hw)

10277

10272

10278

%%

10273

%%

10279

function [pdf_out, cdf_out, scale_factor] = scaleCDF(pdf,delta_com,DER0,A_s)

10274

function [pdf_out, cdf_out, scale_factor] = scaleCDF(pdf,delta_com,DER0,A_s)

10280

% scale CDF at DER0 to delta_com

10275

% scale CDF at DER0 to delta_com

10281

pdf_out=pdf;

10276

pdf_out=pdf;

10282

P=cumsum(pdf.y);

10277

P=cumsum(pdf.y);

10283

ider0=find(P>=DER0,1,'first');

10278

ider0=find(P>=DER0,1,'first');

10284

anias=pdf.x(ider0)/A_s; % ani/as

10279

anias=pdf.x(ider0)/A_s; % ani/as

10285

new_db = 20*log10(-1/anias)-delta_com;

10280

new_db = 20*log10(-1/anias)-delta_com;

10286

new_value = -1*1/10^(new_db/20);

10281

new_value = -1*1/10^(new_db/20);

10287

scale_factor=1/10^(-delta_com/20);

10282

scale_factor=1/10^(-delta_com/20);

10288

pdf_out=scalePDF(pdf,scale_factor);

10283

pdf_out=scalePDF(pdf,scale_factor);

10289

cdf_out=cumsum(pdf_out.y);

10284

cdf_out=cumsum(pdf_out.y);

10290

function pdf_out = scalePDF(pdf,scale_factor)

10285

function pdf_out = scalePDF(pdf,scale_factor)

10291

pdf_out=pdf;

10286

pdf_out=pdf;

10292

pdf_out.Min=floor(pdf.Min*scale_factor);

10287

pdf_out.Min=floor(pdf.Min*scale_factor);

10293

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10288

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10294

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10289

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10295

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10290

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10296

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10291

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10297

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10292

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10298

function t_params = stot(s_params)

10293

function t_params = stot(s_params)

10299

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10294

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10300

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10295

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10301

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10296

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10302

delta = (s11.*s22-s12.*s21);

10297

delta = (s11.*s22-s12.*s21);

10303

s21(s21==0)=eps;

10298

s21(s21==0)=eps;

10304

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10299

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10305

10300

10306

function csv_string = str2csv(c)

10301

function csv_string = str2csv(c)

10307

% convert a cell array of strings to a csv string

10302

% convert a cell array of strings to a csv string

10308

cell_tmp = cell(2, length(c));

10303

cell_tmp = cell(2, length(c));

10309

cell_tmp(1,:)=c;

10304

cell_tmp(1,:)=c;

10310

cell_tmp(2,:) = {','};

10305

cell_tmp(2,:) = {','};

10311

cell_tmp{2,end} = '';

10306

cell_tmp{2,end} = '';

10312

csv_string=strcat(cell_tmp{:});

10307

csv_string=strcat(cell_tmp{:});

10313

10308

10314

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10309

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10315

f_GHz=f/1e9;

10310

f_GHz=f/1e9;

10316

%% Equation 93A-10 %%

10311

%% Equation 93A-10 %%

10317

gamma_1 = gamma_coeff(2)*(1+1i);

10312

gamma_1 = gamma_coeff(2)*(1+1i);

10318

%% Equation 93A-11 %%

10313

%% Equation 93A-11 %%

10319

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10314

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10320

%% Equation 93A-9 %%

10315

%% Equation 93A-9 %%

10321

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10316

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10322

gamma(f_GHz==0) = gamma_coeff(1);

10317

gamma(f_GHz==0) = gamma_coeff(1);

10323

10318

10324

%% Equation 93A-12 %%

10319

%% Equation 93A-12 %%

10325

if d==0

10320

if d==0

10326

%force matched impedance if length is 0

10321

%force matched impedance if length is 0

10327

%otherwise divide by zero can occur if Z_c=0

10322

%otherwise divide by zero can occur if Z_c=0

10328

rho_rl=0;

10323

rho_rl=0;

10329

else

10324

else

10330

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10325

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10331

end

10326

end

10332

10327

10333

exp_gamma_d = exp(-d*gamma);

10328

exp_gamma_d = exp(-d*gamma);

10334

%% Equations 93A-13 and 93A-14 %%

10329

%% Equations 93A-13 and 93A-14 %%

10335

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10330

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10336

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10331

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10337

s12 = s21;

10332

s12 = s21;

10338

s22 = s11;

10333

s22 = s11;

10339

10334

10340

function s_params = ttos(t_params)

10335

function s_params = ttos(t_params)

10341

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10336

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10342

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10337

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10343

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10338

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10344

delta = t11.*t22-t21.*t12;

10339

delta = t11.*t22-t21.*t12;

10345

t11(t11==0)=eps;

10340

t11(t11==0)=eps;

10346

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10341

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10347

10342

10348

function [out_var,varg_out]=varargin_extractor(varargin)

10343

function [out_var,varg_out]=varargin_extractor(varargin)

10349

10344

10350

if isempty(varargin)

10345

if isempty(varargin)

10351

out_var=[];

10346

out_var=[];

10352

varg_out={};

10347

varg_out={};

10353

else

10348

else

10354

out_var=varargin{1};

10349

out_var=varargin{1};

10355

varg_out=varargin;

10350

varg_out=varargin;

10356

varg_out(1)=[];

10351

varg_out(1)=[];

10357

end

10352

end

10358

10353

10359

10354

10360

function results= vma(PR, M)

10355

function results= vma(PR, M)

10361

% PR=sbr.Data;

10356

% PR=sbr.Data;

10362

% M=32;

10357

% M=32;

10363

% PR is the pulse response

10358

% PR is the pulse response

10364

% M is samples per UI

10359

% M is samples per UI

10365

[ seq, syms, syms_nrz ] = PRBS13Q( );

10360

[ seq, syms, syms_nrz ] = PRBS13Q( );

10366

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10361

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10367

symbols=seq;

10362

symbols=seq;

10368

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10363

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10369

% start end symbols index for 7 3's and 6 0's

10364

% start end symbols index for 7 3's and 6 0's

10370

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10365

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10371

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10366

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10372

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10367

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10373

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10368

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10374

% superposition code

10369

% superposition code

10375

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10370

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10376

Bit_stream_response=filter(PR,1, shifting_vector);

10371

Bit_stream_response=filter(PR,1, shifting_vector);

10377

% find center of 3's and 0's

10372

% find center of 3's and 0's

10378

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10373

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10379

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10374

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10380

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10375

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10381

% hold on

10376

% hold on

10382

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10377

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10383

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10378

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10384

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10379

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10385

VMA= P_3 - P_0;

10380

VMA= P_3 - P_0;

10386

results.P_3=P_3;

10381

results.P_3=P_3;

10387

results.P_0=P_0;

10382

results.P_0=P_0;

10388

results.VMA=VMA;

10383

results.VMA=VMA;

10389

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10384

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10390

10385

10391

%slope of the 2 sample points around vref crossing

10386

%slope of the 2 sample points around vref crossing

10392

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10387

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10393

%x-intercept for the line

10388

%x-intercept for the line

10394

b1=eye_contour(x_in,1)-m1*x_in;

10389

b1=eye_contour(x_in,1)-m1*x_in;

10395

% drawing a horizontal line through vref so slope = 0

10390

% drawing a horizontal line through vref so slope = 0

10396

m2=0;

10391

m2=0;

10397

%special case for horizontal line, b=y

10392

%special case for horizontal line, b=y

10398

b2=vref;

10393

b2=vref;

10399

%the x-value of line intersection = (b2-b1)/(m1-m2)

10394

%the x-value of line intersection = (b2-b1)/(m1-m2)

10400

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10395

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10401

%And usually vref is 0, so it further reduces to -b1/m1

10396

%And usually vref is 0, so it further reduces to -b1/m1

10402

line_intersection=(b2-b1)/(m1-m2);

10397

line_intersection=(b2-b1)/(m1-m2);

10403

10398

10404

10399

10405

10400

10406

10401

10407

10402

10408

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10403

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10409

% helper function to read parameter values from XLS file. Uses names to find values.

10404

% helper function to read parameter values from XLS file. Uses names to find values.

10410

if nargin<3, eval_if_string=0; end

10405

if nargin<3, eval_if_string=0; end

10411

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10406

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10412

if numel(row)*numel(col)==0

10407

if numel(row)*numel(col)==0

10413

if nargin<4

10408

if nargin<4

10414

missingParameter(param_name);

10409

missingParameter(param_name);

10415

else

10410

else

10416

p = default_value;

10411

p = default_value;

10417

end

10412

end

10418

elseif numel(row)*numel(col)>1

10413

elseif numel(row)*numel(col)>1

10419

% if there are several occurrences, use the first, but warn

10414

% if there are several occurrences, use the first, but warn

10420

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10415

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10421

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10416

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10422

error('COM:XLS_parameter:MultipleOccurrence', ...

10417

error('COM:XLS_parameter:MultipleOccurrence', ...

10423

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10418

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10424

p=param_sheet{row(1), col(1)+1};

10419

p=param_sheet{row(1), col(1)+1};

10425

else

10420

else

10426

p=param_sheet{row, col+1};

10421

p=param_sheet{row, col+1};

10427

end

10422

end

10428

if ischar(p) && eval_if_string

10423

if ischar(p) && eval_if_string

10429

p=eval(p);

10424

p=eval(p);

10430

end

10425

end

10431

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10426

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10432

if OP.SAVE_KEYWORD_FILE

10427

if OP.SAVE_KEYWORD_FILE

10433

10428

10434

if nargin<3 || ~exist('default_value','var')

10429

if nargin<3 || ~exist('default_value','var')

10435

default_value=p;

10430

default_value=p;

10436

end

10431

end

10437

if isempty(default_value)

10432

if isempty(default_value)

10438

default_value='-';

10433

default_value='-';

10439

end

10434

end

10440

%%

10435

%%

10441

% Get call-stack info:

10436

% Get call-stack info:

10442

stDebug = dbstack;

10437

stDebug = dbstack;

10443

callerFileName = stDebug(2).file;

10438

callerFileName = stDebug(2).file;

10444

callerLineNumber = stDebug(2).line;

10439

callerLineNumber = stDebug(2).line;

10445

% Open caller file:

10440

% Open caller file:

10446

fCaller = fopen(callerFileName);

10441

fCaller = fopen(callerFileName);

10447

% Iterate through lines to get to desired line number:

10442

% Iterate through lines to get to desired line number:

10448

for iLine = 1 : callerLineNumber

10443

for iLine = 1 : callerLineNumber

10449

% Read current line of text:

10444

% Read current line of text:

10450

currLine = fgetl(fCaller);

10445

currLine = fgetl(fCaller);

10451

end

10446

end

10452

% (currLine) now reflects calling desired code: display this code:

10447

% (currLine) now reflects calling desired code: display this code:

10453

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10448

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10454

% Close caller file:

10449

% Close caller file:

10455

left_side=currLine(1:strfind(currLine,'=')-1);

10450

left_side=currLine(1:strfind(currLine,'=')-1);

10456

cmt_side=currLine(strfind(currLine,'%')+1:end);

10451

cmt_side=currLine(strfind(currLine,'%')+1:end);

10457

if isempty(cmt_side), cmt_side=' ';end

10452

if isempty(cmt_side), cmt_side=' ';end

10458

fclose(fCaller);

10453

fclose(fCaller);

10459

10454

10460

if ~ischar(default_value)

10455

if ~ischar(default_value)

10461

default_str=sprintf('%g ',default_value);

10456

default_str=sprintf('%g ',default_value);

10462

else

10457

else

10463

default_str=default_value;

10458

default_str=default_value;

10464

end

10459

end

10465

if ~isfile('keyworklog.mat')

10460

if ~isfile('keyworklog.mat')

10466

save_p=param_name;

10461

save_p=param_name;

10467

save_d=default_str;

10462

save_d=default_str;

10468

save_r=left_side;

10463

save_r=left_side;

10469

save_c=cmt_side;

10464

save_c=cmt_side;

10470

param_name = {'keyword'};

10465

param_name = {'keyword'};

10471

default_str = {'default'};

10466

default_str = {'default'};

10472

left_side={'matlab variable'};

10467

left_side={'matlab variable'};

10473

cmt_side={'info'};

10468

cmt_side={'info'};

10474

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10469

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10475

param_name=save_p;

10470

param_name=save_p;

10476

default_str=save_d;

10471

default_str=save_d;

10477

left_side=save_r;

10472

left_side=save_r;

10478

cmt_side=save_c;

10473

cmt_side=save_c;

10479

data=load('keyworklog.mat');

10474

data=load('keyworklog.mat');

10480

else

10475

else

10481

load('keyworklog.mat');

10476

load('keyworklog.mat');

10482

end

10477

end

10483

data.left_side = [ data.left_side; left_side];

10478

data.left_side = [ data.left_side; left_side];

10484

data.param_name = [data.param_name; param_name];

10479

data.param_name = [data.param_name; param_name];

10485

data.default_str = [data.default_str; default_str ];

10480

data.default_str = [data.default_str; default_str ];

10486

data.cmt_side = [ data.cmt_side; cmt_side];

10481

data.cmt_side = [ data.cmt_side; cmt_side];

10487

if length(data.default_str)~=length(data.default_str)

10482

if length(data.default_str)~=length(data.default_str)

10488

a=1;

10483

a=1;

10489

end

10484

end

10490

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10485

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10491

save('keyworklog.mat','data');

10486

save('keyworklog.mat','data');

10492

writetable(T,[ 'keywords_' date '.csv' ]);

10487

writetable(T,[ 'keywords_' date '.csv' ]);

10493

end

10488

end

10494

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10489

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10495

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10490

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10496

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10491

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10497

10492

10498

found=1;

10493

found=1;

10499

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10494

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10500

if numel(row)*numel(col)==0

10495

if numel(row)*numel(col)==0

10501

p = 0;

10496

p = 0;

10502

found=0;

10497

found=0;

10503

elseif numel(row)*numel(col)>1

10498

elseif numel(row)*numel(col)>1

10504

% if there are several occurrences, use the first, but warn

10499

% if there are several occurrences, use the first, but warn

10505

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10500

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10506

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10501

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10507

error('COM:XLS_parameter:MultipleOccurrence', ...

10502

error('COM:XLS_parameter:MultipleOccurrence', ...

10508

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10503

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10509

p=param_sheet{row(1), col(1)+1};

10504

p=param_sheet{row(1), col(1)+1};

10510

else

10505

else

10511

p=param_sheet{row, col+1};

10506

p=param_sheet{row, col+1};

10512

end

10507

end

10513

if ischar(p)

10508

if ischar(p)

10514

p=eval(p);

10509

p=eval(p);

10515

end

10510

end

10516

function zzz_list_of_changes

10511

function zzz_list_of_changes

10517

% structures:

10512

% structures:

10518

% chdata(i)

10513

% chdata(i)

10519

% i= 1 --> THRU index

10514

% i= 1 --> THRU index

10520

% i= 2, num_fext+1 --> FEXT channel index

10515

% i= 2, num_fext+1 --> FEXT channel index

10521

% i= num_fext+2, num_next+num_fext+1

10516

% i= num_fext+2, num_next+num_fext+1

10522

% base: name of THRU file

10517

% base: name of THRU file

10523

% A: amplitude

10518

% A: amplitude

10524

% type: 'THRU', 'NEXT', or 'FEXT'

10519

% type: 'THRU', 'NEXT', or 'FEXT'

10525

% ftr: Rise time frequency

10520

% ftr: Rise time frequency

10526

% fmaxi: max number of frequency points

10521

% fmaxi: max number of frequency points

10527

% faxis: frequency array [Hz]

10522

% faxis: frequency array [Hz]

10528

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10523

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10529

% sdd22: differential RL

10524

% sdd22: differential RL

10530

% sdd11: differential RL

10525

% sdd11: differential RL

10531

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10526

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10532

% sdd21f: raw differential IL not filtered use for FD plots

10527

% sdd21f: raw differential IL not filtered use for FD plots

10533

% added output_args.peak_uneq_pulse_mV

10528

% added output_args.peak_uneq_pulse_mV

10534

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10529

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10535

% added: tap c(-2) c(2) and c(3)

10530

% added: tap c(-2) c(2) and c(3)

10536

% added: g_DC_HP and f_HP_PZ

10531

% added: g_DC_HP and f_HP_PZ

10537

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10532

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10538

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10533

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10539

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10534

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10540

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10535

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10541

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10536

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10542

% fixed INCLUDE_CTLE=0 to really remove from computation

10537

% fixed INCLUDE_CTLE=0 to really remove from computation

10543

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10538

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10544

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10539

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10545

% r162 tx and rx package impedance {Zc)

10540

% r162 tx and rx package impedance {Zc)

10546

% r162a Gaussian equation corrected

10541

% r162a Gaussian equation corrected

10547

% r163 cast snr_tx with package test case

10542

% r163 cast snr_tx with package test case

10548

% r164 fix pdf for very low noise and lo pass filter enhancements

10543

% r164 fix pdf for very low noise and lo pass filter enhancements

10549

% r164 add zero gain at nqyist CTLE as in CL12e

10544

% r164 add zero gain at nqyist CTLE as in CL12e

10550

% r165 add simpler congfig command called FORCE_TR (force risetime)

10545

% r165 add simpler congfig command called FORCE_TR (force risetime)

10551

% r200 cm3 and cm4 added cp3 removed

10546

% r200 cm3 and cm4 added cp3 removed

10552

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10547

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10553

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10548

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10554

% r200 improved phase interpolation for return loss time conversion

10549

% r200 improved phase interpolation for return loss time conversion

10555

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10550

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10556

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10551

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10557

% r200c missed on fix for interpolation

10552

% r200c missed on fix for interpolation

10558

% r210 new ERL with time gating function

10553

% r210 new ERL with time gating function

10559

% r224 update ERL with from D3.1

10554

% r224 update ERL with from D3.1

10560

% r226 fix s2p reading problem

10555

% r226 fix s2p reading problem

10561

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10556

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10562

% Fix Rx calibration issue

10557

% Fix Rx calibration issue

10563

% added ERL limit and Nd

10558

% added ERL limit and Nd

10564

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10559

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10565

% INC_PACKAGE=0 not fully supported message

10560

% INC_PACKAGE=0 not fully supported message

10566

% if N=0 use TDR_duration

10561

% if N=0 use TDR_duration

10567

% red display text for fail ERL and COM

10562

% red display text for fail ERL and COM

10568

% r228 fixed ERL pass fail report, default Grr_limit to 1

10563

% r228 fixed ERL pass fail report, default Grr_limit to 1

10569

% r230 add rx ffe

10564

% r230 add rx ffe

10570

% r231 change crosstalk noise to icn like to speed things up

10565

% r231 change crosstalk noise to icn like to speed things up

10571

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10566

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10572

% 1e-5mof-

10567

% 1e-5mof-

10573

% r232 fix default for Rx eq so old spead sheets work

10568

% r232 fix default for Rx eq so old spead sheets work

10574

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10569

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10575

% r235 adding dfe quantization changed to normalized DFE taps reported

10570

% r235 adding dfe quantization changed to normalized DFE taps reported

10576

% r236 adding ffe gain loop and resample after RxFFE

10571

% r236 adding ffe gain loop and resample after RxFFE

10577

% r240 added output for C2M and setting defaults for some FFE eq

10572

% r240 added output for C2M and setting defaults for some FFE eq

10578

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10573

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10579

% r250 adding more complex package

10574

% r250 adding more complex package

10580

% r251 post cursor fix for DFE in force() and ffe backoff

10575

% r251 post cursor fix for DFE in force() and ffe backoff

10581

% r251 remove TDR threshold noise filter

10576

% r251 remove TDR threshold noise filter

10582

% r252 add rx FFE filter to receiver noise filter

10577

% r252 add rx FFE filter to receiver noise filter

10583

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10578

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10584

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10579

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10585

% r254 precursor check fix in optimize_fom % mod fix in force

10580

% r254 precursor check fix in optimize_fom % mod fix in force

10586

% r254 help to align columns in csv file

10581

% r254 help to align columns in csv file

10587

% r254 accept syntax for 2 tline flex package model

10582

% r254 accept syntax for 2 tline flex package model

10588

% r256 speed up optimize FOM

10583

% r256 speed up optimize FOM

10589

% r256 fix problem reading in config file from q/a

10584

% r256 fix problem reading in config file from q/a

10590

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10585

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10591

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10586

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10592

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10587

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10593

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10588

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10594

% r258 CDR switch 'MM' or 'mod-MM'

10589

% r258 CDR switch 'MM' or 'mod-MM'

10595

% r258 correction for asymentirc tx/Rx packages

10590

% r258 correction for asymentirc tx/Rx packages

10596

% r258 revamped display results display window

10591

% r258 revamped display results display window

10597

% r259 fix problem if Min_VEO is set in spreadsheet.

10592

% r259 fix problem if Min_VEO is set in spreadsheet.

10598

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10593

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10599

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10594

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10600

% r259 putting COM_db and IL last in output to terminal

10595

% r259 putting COM_db and IL last in output to terminal

10601

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10596

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10602

% r259 use N_bx for ERL rather than Nb (ndfe))

10597

% r259 use N_bx for ERL rather than Nb (ndfe))

10603

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10598

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10604

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10599

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10605

% r260 used eta_0 PSD equation for sigma_n

10600

% r260 used eta_0 PSD equation for sigma_n

10606

% r260 fix IL graph legend to w/pkg and Tr

10601

% r260 fix IL graph legend to w/pkg and Tr

10607

% r260 define tfx for each port

10602

% r260 define tfx for each port

10608

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10603

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10609

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10604

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10610

% r262 reset on exit default text interpreter to tex

10605

% r262 reset on exit default text interpreter to tex

10611

% r262 localize run timer (John Buck 1/17/19)

10606

% r262 localize run timer (John Buck 1/17/19)

10612

% r262 set db as internal function in force to avoid tool box

10607

% r262 set db as internal function in force to avoid tool box

10613

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10608

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10614

% r263 added to output_args RL structure and report "struct" in csv file

10609

% r263 added to output_args RL structure and report "struct" in csv file

10615

% r264 added EW estimate

10610

% r264 added EW estimate

10616

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10611

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10617

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10612

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10618

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10613

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10619

% r269 changed param.N_bmax to param.N_f

10614

% r269 changed param.N_bmax to param.N_f

10620

% r270 implement JingBo Li's and Howard Heck's floating tap method

10615

% r270 implement JingBo Li's and Howard Heck's floating tap method

10621

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10616

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10622

% r270 added c_0 and c_1 for CA in add_brd

10617

% r270 added c_0 and c_1 for CA in add_brd

10623

% r272 fixed version syntax problem in output_args RL report

10618

% r272 fixed version syntax problem in output_args RL report

10624

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10619

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10625

% r272 removed eye width report if doing a Rx calibration

10620

% r272 removed eye width report if doing a Rx calibration

10626

% r273 better alignment and control for ICN reporting

10621

% r273 better alignment and control for ICN reporting

10627

% r273 fixed PSXTK graph

10622

% r273 fixed PSXTK graph

10628

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10623

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10629

% r276 go back to reporting channel IL results (output_args.IL_dB_channel_only_at_Fnq) with board added read_s4p_files (as in r270)

10624

% r276 go back to reporting channel IL results (output_args.IL_dB_channel_only_at_Fnq) with board added read_s4p_files (as in r270)

10630

% r276 chdata(i).Aicn=param.a_icn_fext should have been chdata(i).Aicn=param.a_icn_next for the next selection. Since in most spec's they are the same there is little no impact in results

10625

% r276 chdata(i).Aicn=param.a_icn_fext should have been chdata(i).Aicn=param.a_icn_next for the next selection. Since in most spec's they are the same there is little no impact in results

10631

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10626

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10632

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10627

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10633

% r276 C_1 was instantiated as C_0. This was fixed

10628

% r276 C_1 was instantiated as C_0. This was fixed

10634

% r276 fixed rounding problem in reporting of loss at f_nq

10629

% r276 fixed rounding problem in reporting of loss at f_nq

10635

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10630

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10636

% r277 added nv for deterining steady state voltage for fitting compatibility

10631

% r277 added nv for deterining steady state voltage for fitting compatibility

10637

% r278 added b_min to support asymmetric bmax

10632

% r278 added b_min to support asymmetric bmax

10638

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10633

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10639

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10634

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10640

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10635

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10641

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10636

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10642

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10637

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10643

% r292 eq. 93A-19 and 93-20 code implementation bug when include .3by change% to fix edge rate equation 93A-46 (h_T). no effect if Rd=50 or IL > 5 dB

10638

% r292 eq. 93A-19 and 93-20 code implementation bug when include .3by change% to fix edge rate equation 93A-46 (h_T). no effect if Rd=50 or IL > 5 dB

10644

% r292 H_t implemented in s21_pkg

10639

% r292 H_t implemented in s21_pkg

10645

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10640

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10646

% r292 add GDC_MIN to optimize_FOM

10641

% r292 add GDC_MIN to optimize_FOM

10647

% r293 fix if ndfe-0 and ERL only and s2p issue

10642

% r293 fix if ndfe-0 and ERL only and s2p issue

10648

% r293a investigate the Tukey filtering

10643

% r293a investigate the Tukey filtering

10649

% r293a if fix if bmin is missing

10644

% r293a if fix if bmin is missing

10650

% r294 fix problems reading s2p files for ERL computation

10645

% r294 fix problems reading s2p files for ERL computation

10651

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10646

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10652

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10647

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10653

% r294 add gdc and gdc2 range limitations

10648

% r294 add gdc and gdc2 range limitations

10654

% r295 add VEC Pass threshold

10649

% r295 add VEC Pass threshold

10655

% r295 removed close force all. Tagged all figures with "COM"

10650

% r295 removed close force all. Tagged all figures with "COM"

10656

% r295 consolidated print in new function "end_display_control"

10651

% r295 consolidated print in new function "end_display_control"

10657

% r295 report pre/pmax for Txffe

10652

% r295 report pre/pmax for Txffe

10658

% r295 speed up test cases by not re-reading in s4p files

10653

% r295 speed up test cases by not re-reading in s4p files

10659

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10654

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10660

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10655

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10661

% r310 refine VEC and EH for C2M from Adam Gregory in

10656

% r310 refine VEC and EH for C2M from Adam Gregory in

10662

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10657

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10663

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10658

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10664

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10659

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10665

% r311 added RILN

10660

% r311 added RILN

10666

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10661

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10667

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10662

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10668

% r316 remove DC computation for RX Calibration loops

10663

% r316 remove DC computation for RX Calibration loops

10669

% r317 for SAVE_TD to include EQ and unEQ FIR

10664

% r317 for SAVE_TD to include EQ and unEQ FIR

10670

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10665

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10671

% r318 if min_VEO_test fails to find a solution the loop is restarted with min_VEO_test to near zero. Makes sure COM returns results

10666

% r318 if min_VEO_test fails to find a solution the loop is restarted with min_VEO_test to near zero. Makes sure COM returns results

10672

% r320 fixed RX_CALIBRATION which was broken in r310

10667

% r320 fixed RX_CALIBRATION which was broken in r310

10673

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10668

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10674

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10669

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10675

% r320 removed external feature and replace with TDMODE

10670

% r320 removed external feature and replace with TDMODE

10676

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10671

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10677

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10672

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10678

% r335 fixed typo in when processing the bessel thompson filter option

10673

% r335 fixed typo in when processing the bessel thompson filter option

10679

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10674

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10680

% r335 compute and report CD_CM_RMS

10675

% r335 compute and report CD_CM_RMS

10681

% r335 fixed where output_arg is save i.e. move to end

10676

% r335 fixed where output_arg is save i.e. move to end

10682

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10677

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10683

% r335 change raw IL plot to not include boards

10678

% r335 change raw IL plot to not include boards

10684

% r335 set T_0 to zero if not C2M

10679

% r335 set T_0 to zero if not C2M

10685

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10680

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10686

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10681

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10687

% r335 TD_RILN changes from Hansel Dsilva

10682

% r335 TD_RILN changes from Hansel Dsilva

10688

% r335 Fixed sigma_N for RxFFE

10683

% r335 Fixed sigma_N for RxFFE

10689

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10684

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10690

% r335 added c(2) and C(3) back to read_ParamConfigFile

10685

% r335 added c(2) and C(3) back to read_ParamConfigFile

10691

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10686

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10692

% r335 corrected GDC_MIN per 0.3ck D2.3

10687

% r335 corrected GDC_MIN per 0.3ck D2.3

10693

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10688

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10694

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10689

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10695

% r370 speed up

10690

% r370 speed up

10696

% r370 fix for floating tap missing locations

10691

% r370 fix for floating tap missing locations

10697

% r370 variable Tx FFE taps

10692

% r370 variable Tx FFE taps

10698

% r370 package die load with ladder circuit

10693

% r370 package die load with ladder circuit

10699

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10694

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10700

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10695

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10701

% r380 added capabablity to enable a raised cosine Rx filter0

10696

% r380 added capabablity to enable a raised cosine Rx filter0

10702

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10697

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10703

% r380 added plot for VTF

10698

% r380 added plot for VTF

10704

% r385 added capability for additional Tx FFE per package

10699

% r385 added capability for additional Tx FFE per package

10705

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10700

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10706

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10701

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10707

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10702

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10708

% r389 Improvement by A. Ran for reporting loss at Nq

10703

% r389 Improvement by A. Ran for reporting loss at Nq

10709

% r389 Fixed typo: changed VIM to VMP

10704

% r389 Fixed typo: changed VIM to VMP

10710

% r400 fixed PR with zero pad extension

10705

% r400 fixed PR with zero pad extension

10711

% r400 keyword MLSE and SNRADJ_EQUA for future work

10706

% r400 keyword MLSE and SNRADJ_EQUA for future work

10712

% r400 replaced function db with instances of 20*log10(abs(...))

10707

% r400 replaced function db with instances of 20*log10(abs(...))

10713

% r410 widen voltage distriution for normal_dist doubled max Q

10708

% r410 widen voltage distriution for normal_dist doubled max Q

10714

% r410 improve reading in of config files

10709

% r410 improve reading in of config files

10715

% r410 renormalize s-parameter if not 50 ohm ref

10710

% r410 renormalize s-parameter if not 50 ohm ref

10716

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10711

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10717

% r410 remove RL from output_args bc not need and too much storage allocation

10712

% r410 remove RL from output_args bc not need and too much storage allocation

10718

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10713

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10719

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10714

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10720

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10715

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10721

% r420 updade force to account for pulse responces with short delays in force

10716

% r420 updade force to account for pulse responces with short delays in force

10722

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10717

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10723

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10718

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10724

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10719

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10725

% r420 Wiener-Kofp MMSE optimization for RxFFE

10720

% r420 Wiener-Kofp MMSE optimization for RxFFE

10726

% r430 first pass at healey_3dj_01_2401

10721

% r430 first pass at healey_3dj_01_2401

10727

% r430 RxFFE fixed taps

10722

% r430 RxFFE fixed taps

10728

% r440 RxffE fixed tap index corrections and floating taps

10723

% r440 RxffE fixed tap index corrections and floating taps

10729

% r440 first pass implemenation of MLSE U3

10724

% r440 first pass implemenation of MLSE U3

10730

% r450 fix MLSE_FOM typos, sigma_e,and FOM.

10725

% r450 fix MLSE_FOM typos, sigma_e,and FOM.

10731

% r450 incude Hisi in PSD in get_PSDs

10726

% r450 incude Hisi in PSD in get_PSDs

10732

% r460 is working out reporting bug from RxFFE and package A,B invocations

10727

% r460 is working out reporting bug from RxFFE and package A,B invocations

10733

% r460 align package config Tx and Rx cases with selected casting 4p5_3

10728

% r460 align package config Tx and Rx cases with selected casting 4p5_3

10734

% r460 fix RxFFE floating taps display (indexing error) 4p5_4

10729

% r460 fix RxFFE floating taps display (indexing error) 4p5_4

10735

% r470 beta1 added MLSE truncation inclusion using N_tc

10730

% r470 beta1 added MLSE truncation inclusion using N_tc

10736

% r470 beta1 add MLSE Q_budget_adj

10731

% r470 beta1 add MLSE Q_budget_adj

10737

% r470 added parameter defaults to support multiple packages

10732

% r470 added parameter defaults to support multiple packages

10738

% r470 beta2 added MLSD proposal from healey_3dj_01_2409

10733

% r470 beta2 added MLSD proposal from healey_3dj_01_2409

10739

% r470 remOved support for MLSE_Q

10734

% r470 remOved support for MLSE_Q

10740

% r480 beta1 added new keyword ENOB for quantization. if 0 or missing ignored

10735

% r480 beta1 added new keyword ENOB for quantization. if 0 or missing ignored

10741

% r480 beta1 added function adjust_Rx_noise_for_quantization

10736

% r480 beta1 added function adjust_Rx_noise_for_quantization

10742

% r480 beta2 fixed typo's and updated from shakiba_3dj_COM_02_241001 to shakiba_3dj_COM_01_241029

10737

% r480 beta2 fixed typo's and updated from shakiba_3dj_COM_02_241001 to shakiba_3dj_COM_01_241029

10743

10738