Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
uvahotspot
GitHub Repository: uvahotspot/HotSpot
Path: blob/master/temperature.c
612 views
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
#ifdef _MSC_VER
5
#define strcasecmp _stricmp
6
#define strncasecmp _strnicmp
7
#else
8
#include <strings.h>
9
#endif
10
#include <math.h>
11
12
#include "temperature.h"
13
#include "temperature_block.h"
14
#include "temperature_grid.h"
15
#include "flp.h"
16
#include "util.h"
17
18
/* default thermal configuration parameters */
19
thermal_config_t default_thermal_config(void)
20
{
21
thermal_config_t config;
22
23
/* chip specs */
24
config.t_chip = 0.15e-3; /* chip thickness in meters */
25
config.k_chip = 100.0; /* chip thermal conductivity in W/(m-K) */
26
config.p_chip = 1.75e6; /* chip specific heat in J/(m^3-K) */
27
/* temperature threshold for DTM (Kelvin)*/
28
config.thermal_threshold = 81.8 + 273.15;
29
30
/* heat sink specs */
31
config.c_convec = 140.4; /* convection capacitance in J/K */
32
config.r_convec = 0.1; /* convection resistance in K/W */
33
config.s_sink = 60e-3; /* heatsink side in m */
34
config.t_sink = 6.9e-3; /* heatsink thickness in m */
35
config.k_sink = 400.0; /* heatsink thermal conductivity in W/(m-K) */
36
config.p_sink = 3.55e6; /* heatsink specific heat in J/(m^3-K) */
37
38
39
/* heat spreader specs */
40
config.s_spreader = 30e-3; /* spreader side in m */
41
config.t_spreader = 1e-3; /* spreader thickness in m */
42
config.k_spreader = 400.0; /* heat spreader thermal conductivity in W/(m-K) */
43
config.p_spreader = 3.55e6; /* heat spreader specific heat in J/(m^3-K) */
44
45
/* interface material specs */
46
config.t_interface = 20e-6; /* interface material thickness in m */
47
config.k_interface = 4.0; /* interface material thermal conductivity in W/(m-K) */
48
config.p_interface = 4.0e6; /* interface material specific heat in J/(m^3-K) */
49
50
/* secondary heat transfer path */
51
config.model_secondary = FALSE;
52
config.r_convec_sec = 1.0;
53
config.c_convec_sec = 140.4; //FIXME! need updated value.
54
config.n_metal = 8;
55
config.t_metal = 10.0e-6;
56
config.t_c4 = 0.0001;
57
config.s_c4 = 20.0e-6;
58
config.n_c4 = 400;
59
config.s_sub = 0.021;
60
config.t_sub = 0.001;
61
config.s_solder = 0.021;
62
config.t_solder = 0.00094;
63
config.s_pcb = 0.1;
64
config.t_pcb = 0.002;
65
66
/* others */
67
config.ambient = 45 + 273.15; /* in kelvin */
68
/* initial temperatures from file */
69
strcpy(config.init_file, NULLFILE);
70
config.init_temp = 60 + 273.15; /* in Kelvin */
71
/* steady state temperatures to file */
72
strcpy(config.steady_file, NULLFILE);
73
/* transient grid temperatures to file */
74
strcpy(config.grid_transient_file, NULLFILE);
75
/* 3.33 us sampling interval = 10K cycles at 3GHz */
76
config.sampling_intvl = 3.333e-6;
77
config.base_proc_freq = 3e9; /* base processor frequency in Hz */
78
config.dtm_used = FALSE; /* set accordingly */
79
80
config.leakage_used = 0;
81
config.leakage_mode = 0;
82
83
config.package_model_used = 0;
84
strcpy(config.package_config_file, NULLFILE);
85
86
/* set block model as default */
87
strcpy(config.model_type, BLOCK_MODEL_STR);
88
89
/* block model specific parameters */
90
config.block_omit_lateral = FALSE; /* omit lateral chip resistances? */
91
92
/* grid model specific parameters */
93
config.grid_rows = 64; /* grid resolution - no. of rows */
94
config.grid_cols = 64; /* grid resolution - no. of cols */
95
/* layer configuration from file */
96
strcpy(config.grid_layer_file, NULLFILE);
97
/* output steady state grid temperatures apart from block temperatures */
98
strcpy(config.grid_steady_file, NULLFILE);
99
/*
100
* mapping mode between block and grid models.
101
* default: use the temperature of the center
102
* grid cell as that of the entire block
103
*/
104
strcpy(config.grid_map_mode, GRID_CENTER_STR);
105
106
config.detailed_3D_used = 0; //BU_3D: by default detailed 3D modeling is disabled.
107
108
return config;
109
}
110
111
/*
112
* parse a table of name-value string pairs and add the configuration
113
* parameters to 'config'
114
*/
115
void thermal_config_add_from_strs(thermal_config_t *config, materials_list_t *materials_list, str_pair *table, int size)
116
{
117
int idx;
118
if ((idx = get_str_index(table, size, "t_chip")) >= 0)
119
if(sscanf(table[idx].value, "%lf", &config->t_chip) != 1)
120
fatal("invalid format for configuration parameter t_chip\n");
121
if ((idx = get_str_index(table, size, "k_chip")) >= 0)
122
if(sscanf(table[idx].value, "%lf", &config->k_chip) != 1)
123
fatal("invalid format for configuration parameter k_chip\n");
124
if ((idx = get_str_index(table, size, "p_chip")) >= 0)
125
if(sscanf(table[idx].value, "%lf", &config->p_chip) != 1)
126
fatal("invalid format for configuration parameter p_chip\n");
127
if ((idx = get_str_index(table, size, "thermal_threshold")) >= 0)
128
if(sscanf(table[idx].value, "%lf", &config->thermal_threshold) != 1)
129
fatal("invalid format for configuration parameter thermal_threshold\n");
130
if ((idx = get_str_index(table, size, "c_convec")) >= 0)
131
if(sscanf(table[idx].value, "%lf", &config->c_convec) != 1)
132
fatal("invalid format for configuration parameter c_convec\n");
133
if ((idx = get_str_index(table, size, "r_convec")) >= 0)
134
if(sscanf(table[idx].value, "%lf", &config->r_convec) != 1)
135
fatal("invalid format for configuration parameter r_convec\n");
136
if ((idx = get_str_index(table, size, "s_sink")) >= 0)
137
if(sscanf(table[idx].value, "%lf", &config->s_sink) != 1)
138
fatal("invalid format for configuration parameter s_sink\n");
139
if ((idx = get_str_index(table, size, "t_sink")) >= 0)
140
if(sscanf(table[idx].value, "%lf", &config->t_sink) != 1)
141
fatal("invalid format for configuration parameter t_sink\n");
142
if ((idx = get_str_index(table, size, "k_sink")) >= 0)
143
if(sscanf(table[idx].value, "%lf", &config->k_sink) != 1)
144
fatal("invalid format for configuration parameter k_sink\n");
145
if ((idx = get_str_index(table, size, "p_sink")) >= 0)
146
if(sscanf(table[idx].value, "%lf", &config->p_sink) != 1)
147
fatal("invalid format for configuration parameter p_sink\n");
148
if ((idx = get_str_index(table, size, "s_spreader")) >= 0)
149
if(sscanf(table[idx].value, "%lf", &config->s_spreader) != 1)
150
fatal("invalid format for configuration parameter s_spreader\n");
151
if ((idx = get_str_index(table, size, "t_spreader")) >= 0)
152
if(sscanf(table[idx].value, "%lf", &config->t_spreader) != 1)
153
fatal("invalid format for configuration parameter t_spreader\n");
154
if ((idx = get_str_index(table, size, "k_spreader")) >= 0)
155
if(sscanf(table[idx].value, "%lf", &config->k_spreader) != 1)
156
fatal("invalid format for configuration parameter k_spreader\n");
157
if ((idx = get_str_index(table, size, "p_spreader")) >= 0)
158
if(sscanf(table[idx].value, "%lf", &config->p_spreader) != 1)
159
fatal("invalid format for configuration parameter p_spreader\n");
160
if ((idx = get_str_index(table, size, "t_interface")) >= 0)
161
if(sscanf(table[idx].value, "%lf", &config->t_interface) != 1)
162
fatal("invalid format for configuration parameter t_interface\n");
163
if ((idx = get_str_index(table, size, "k_interface")) >= 0)
164
if(sscanf(table[idx].value, "%lf", &config->k_interface) != 1)
165
fatal("invalid format for configuration parameter k_interface\n");
166
if ((idx = get_str_index(table, size, "p_interface")) >= 0)
167
if(sscanf(table[idx].value, "%lf", &config->p_interface) != 1)
168
fatal("invalid format for configuration parameter p_interface\n");
169
if ((idx = get_str_index(table, size, "model_secondary")) >= 0)
170
if(sscanf(table[idx].value, "%d", &config->model_secondary) != 1)
171
fatal("invalid format for configuration parameter model_secondary\n");
172
if ((idx = get_str_index(table, size, "r_convec_sec")) >= 0)
173
if(sscanf(table[idx].value, "%lf", &config->r_convec_sec) != 1)
174
fatal("invalid format for configuration parameter r_convec_sec\n");
175
if ((idx = get_str_index(table, size, "c_convec_sec")) >= 0)
176
if(sscanf(table[idx].value, "%lf", &config->c_convec_sec) != 1)
177
fatal("invalid format for configuration parameter c_convec_sec\n");
178
if ((idx = get_str_index(table, size, "n_metal")) >= 0)
179
if(sscanf(table[idx].value, "%d", &config->n_metal) != 1)
180
fatal("invalid format for configuration parameter n_metal\n");
181
if ((idx = get_str_index(table, size, "t_metal")) >= 0)
182
if(sscanf(table[idx].value, "%lf", &config->t_metal) != 1)
183
fatal("invalid format for configuration parameter t_metal\n");
184
if ((idx = get_str_index(table, size, "t_c4")) >= 0)
185
if(sscanf(table[idx].value, "%lf", &config->t_c4) != 1)
186
fatal("invalid format for configuration parameter t_c4\n");
187
if ((idx = get_str_index(table, size, "s_c4")) >= 0)
188
if(sscanf(table[idx].value, "%lf", &config->s_c4) != 1)
189
fatal("invalid format for configuration parameter s_c4\n");
190
if ((idx = get_str_index(table, size, "n_c4")) >= 0)
191
if(sscanf(table[idx].value, "%d", &config->n_c4) != 1)
192
fatal("invalid format for configuration parameter n_c4\n");
193
if ((idx = get_str_index(table, size, "s_sub")) >= 0)
194
if(sscanf(table[idx].value, "%lf", &config->s_sub) != 1)
195
fatal("invalid format for configuration parameter s_sub\n");
196
if ((idx = get_str_index(table, size, "t_sub")) >= 0)
197
if(sscanf(table[idx].value, "%lf", &config->t_sub) != 1)
198
fatal("invalid format for configuration parameter t_sub\n");
199
if ((idx = get_str_index(table, size, "s_solder")) >= 0)
200
if(sscanf(table[idx].value, "%lf", &config->s_solder) != 1)
201
fatal("invalid format for configuration parameter s_solder\n");
202
if ((idx = get_str_index(table, size, "t_solder")) >= 0)
203
if(sscanf(table[idx].value, "%lf", &config->t_solder) != 1)
204
fatal("invalid format for configuration parameter t_solder\n");
205
if ((idx = get_str_index(table, size, "s_pcb")) >= 0)
206
if(sscanf(table[idx].value, "%lf", &config->s_pcb) != 1)
207
fatal("invalid format for configuration parameter s_pcb\n");
208
if ((idx = get_str_index(table, size, "t_pcb")) >= 0)
209
if(sscanf(table[idx].value, "%lf", &config->t_pcb) != 1)
210
fatal("invalid format for configuration parameter t_pcb\n");
211
if ((idx = get_str_index(table, size, "ambient")) >= 0)
212
if(sscanf(table[idx].value, "%lf", &config->ambient) != 1)
213
fatal("invalid format for configuration parameter ambient\n");
214
if ((idx = get_str_index(table, size, "init_file")) >= 0)
215
if(sscanf(table[idx].value, "%s", config->init_file) != 1)
216
fatal("invalid format for configuration parameter init_file\n");
217
if ((idx = get_str_index(table, size, "init_temp")) >= 0)
218
if(sscanf(table[idx].value, "%lf", &config->init_temp) != 1)
219
fatal("invalid format for configuration parameter init_temp\n");
220
if ((idx = get_str_index(table, size, "steady_file")) >= 0)
221
if(sscanf(table[idx].value, "%s", config->steady_file) != 1)
222
fatal("invalid format for configuration parameter steady_file\n");
223
if ((idx = get_str_index(table, size, "grid_transient_file")) >= 0)
224
if(sscanf(table[idx].value, "%s", config->grid_transient_file) != 1)
225
fatal("invalid format for configuration parameter grid_transient_file\n");
226
if ((idx = get_str_index(table, size, "sampling_intvl")) >= 0)
227
if(sscanf(table[idx].value, "%lf", &config->sampling_intvl) != 1)
228
fatal("invalid format for configuration parameter sampling_intvl\n");
229
if ((idx = get_str_index(table, size, "base_proc_freq")) >= 0)
230
if(sscanf(table[idx].value, "%lf", &config->base_proc_freq) != 1)
231
fatal("invalid format for configuration parameter base_proc_freq\n");
232
if ((idx = get_str_index(table, size, "dtm_used")) >= 0)
233
if(sscanf(table[idx].value, "%d", &config->dtm_used) != 1)
234
fatal("invalid format for configuration parameter dtm_used\n");
235
if ((idx = get_str_index(table, size, "model_type")) >= 0)
236
if(sscanf(table[idx].value, "%s", config->model_type) != 1)
237
fatal("invalid format for configuration parameter model_type\n");
238
if ((idx = get_str_index(table, size, "leakage_used")) >= 0)
239
if(sscanf(table[idx].value, "%d", &config->leakage_used) != 1)
240
fatal("invalid format for configuration parameter leakage_used\n");
241
if ((idx = get_str_index(table, size, "leakage_mode")) >= 0)
242
if(sscanf(table[idx].value, "%d", &config->leakage_mode) != 1)
243
fatal("invalid format for configuration parameter leakage_mode\n");
244
if ((idx = get_str_index(table, size, "package_model_used")) >= 0)
245
if(sscanf(table[idx].value, "%d", &config->package_model_used) != 1)
246
fatal("invalid format for configuration parameter package_model_used\n");
247
if ((idx = get_str_index(table, size, "package_config_file")) >= 0)
248
if(sscanf(table[idx].value, "%s", config->package_config_file) != 1)
249
fatal("invalid format for configuration parameter package_config_file\n");
250
if ((idx = get_str_index(table, size, "block_omit_lateral")) >= 0)
251
if(sscanf(table[idx].value, "%d", &config->block_omit_lateral) != 1)
252
fatal("invalid format for configuration parameter block_omit_lateral\n");
253
if ((idx = get_str_index(table, size, "grid_rows")) >= 0)
254
if(sscanf(table[idx].value, "%d", &config->grid_rows) != 1)
255
fatal("invalid format for configuration parameter grid_rows\n");
256
if ((idx = get_str_index(table, size, "grid_cols")) >= 0)
257
if(sscanf(table[idx].value, "%d", &config->grid_cols) != 1)
258
fatal("invalid format for configuration parameter grid_cols\n");
259
if ((idx = get_str_index(table, size, "grid_layer_file")) >= 0)
260
if(sscanf(table[idx].value, "%s", config->grid_layer_file) != 1)
261
fatal("invalid format for configuration parameter grid_layer_file\n");
262
if ((idx = get_str_index(table, size, "grid_steady_file")) >= 0)
263
if(sscanf(table[idx].value, "%s", config->grid_steady_file) != 1)
264
fatal("invalid format for configuration parameter grid_steady_file\n");
265
if ((idx = get_str_index(table, size, "grid_map_mode")) >= 0)
266
if(sscanf(table[idx].value, "%s", config->grid_map_mode) != 1)
267
fatal("invalid format for configuration parameter grid_map_mode\n");
268
269
if ((config->t_chip <= 0) || (config->s_sink <= 0) || (config->t_sink <= 0) ||
270
(config->s_spreader <= 0) || (config->t_spreader <= 0) ||
271
(config->t_interface <= 0))
272
fatal("chip and package dimensions should be greater than zero\n");
273
if ((config->t_metal <= 0) || (config->n_metal <= 0) || (config->t_c4 <= 0) ||
274
(config->s_c4 <= 0) || (config->n_c4 <= 0) || (config->s_sub <= 0) || (config->t_sub <= 0) ||
275
(config->s_solder <= 0) || (config->t_solder <= 0) || (config->s_pcb <= 0) ||
276
(config->t_solder <= 0) || (config->r_convec_sec <= 0) || (config->c_convec_sec <= 0))
277
fatal("secondary heat tranfer layer dimensions should be greater than zero\n");
278
/* leakage iteration is not supported in transient mode in this release */
279
if (config->leakage_used == 1) {
280
printf("Warning: transient leakage iteration is not supported in this release...\n");
281
printf(" ...all transient results are without thermal-leakage loop.\n");
282
}
283
if ((config->model_secondary == 1) && (!strcasecmp(config->model_type, BLOCK_MODEL_STR)))
284
fatal("secondary heat tranfer path is supported only in the grid mode\n");
285
if ((config->thermal_threshold < 0) || (config->c_convec < 0) ||
286
(config->r_convec < 0) || (config->ambient < 0) ||
287
(config->base_proc_freq <= 0) || (config->sampling_intvl <= 0))
288
fatal("invalid thermal simulation parameters\n");
289
if (strcasecmp(config->model_type, BLOCK_MODEL_STR) &&
290
strcasecmp(config->model_type, GRID_MODEL_STR))
291
fatal("invalid model type. use 'block' or 'grid'\n");
292
if(config->grid_rows <= 0 || config->grid_cols <= 0)
293
fatal("grid rows and columns should both be greater than zero\n");
294
if (strcasecmp(config->grid_map_mode, GRID_AVG_STR) &&
295
strcasecmp(config->grid_map_mode, GRID_MIN_STR) &&
296
strcasecmp(config->grid_map_mode, GRID_MAX_STR) &&
297
strcasecmp(config->grid_map_mode, GRID_CENTER_STR))
298
fatal("invalid mapping mode. use 'avg', 'min', 'max' or 'center'\n");
299
300
if ((idx = get_str_index(table, size, "material_chip")) >= 0) {
301
char material_name[STR_SIZE];
302
if(sscanf(table[idx].value, "%s", material_name) != 1)
303
fatal("invalid format for configuration parameter material_chip\n");
304
config->k_chip = get_material_thermal_conductivity(materials_list, material_name);
305
config->p_chip = get_material_volumetric_heat_capacity(materials_list, material_name);
306
if(config->k_chip < 0 || config->p_chip < 0)
307
fatal("material name specified in configuration parameter material_chip not found\n");
308
}
309
if ((idx = get_str_index(table, size, "material_sink")) >= 0) {
310
char material_name[STR_SIZE];
311
if(sscanf(table[idx].value, "%s", material_name) != 1)
312
fatal("invalid format for configuration parameter material_sink\n");
313
config->k_sink = get_material_thermal_conductivity(materials_list, material_name);
314
config->p_sink = get_material_volumetric_heat_capacity(materials_list, material_name);
315
316
if(config->k_sink < 0 || config->p_sink < 0)
317
fatal("material name specified in configuration parameter material_sink not found\n");
318
}
319
if ((idx = get_str_index(table, size, "material_spreader")) >= 0) {
320
char material_name[STR_SIZE];
321
if(sscanf(table[idx].value, "%s", material_name) != 1)
322
fatal("invalid format for configuration parameter material_spreader\n");
323
config->k_spreader = get_material_thermal_conductivity(materials_list, material_name);
324
config->p_spreader = get_material_volumetric_heat_capacity(materials_list, material_name);
325
326
if(config->k_spreader < 0 || config->p_spreader < 0)
327
fatal("material name specified in configuration parameter material_spreader not found\n");
328
}
329
if ((idx = get_str_index(table, size, "material_interface")) >= 0) {
330
char material_name[STR_SIZE];
331
if(sscanf(table[idx].value, "%s", material_name) != 1)
332
fatal("invalid format for configuration parameter material_interface\n");
333
config->k_interface = get_material_thermal_conductivity(materials_list, material_name);
334
config->p_interface = get_material_volumetric_heat_capacity(materials_list, material_name);
335
336
if(config->k_interface < 0 || config->p_interface < 0)
337
fatal("material name specified in configuration parameter material_interface not found\n");
338
}
339
}
340
341
/*
342
* convert config into a table of name-value pairs. returns the no.
343
* of parameters converted
344
*/
345
int thermal_config_to_strs(thermal_config_t *config, str_pair *table, int max_entries)
346
{
347
if (max_entries < 51)
348
fatal("not enough entries in table\n");
349
350
sprintf(table[0].name, "t_chip");
351
sprintf(table[1].name, "k_chip");
352
sprintf(table[2].name, "p_chip");
353
sprintf(table[3].name, "thermal_threshold");
354
sprintf(table[4].name, "c_convec");
355
sprintf(table[5].name, "r_convec");
356
sprintf(table[6].name, "s_sink");
357
sprintf(table[7].name, "t_sink");
358
sprintf(table[8].name, "k_sink");
359
sprintf(table[9].name, "p_sink");
360
sprintf(table[10].name, "s_spreader");
361
sprintf(table[11].name, "t_spreader");
362
sprintf(table[12].name, "k_spreader");
363
sprintf(table[13].name, "p_spreader");
364
sprintf(table[14].name, "t_interface");
365
sprintf(table[15].name, "k_interface");
366
sprintf(table[16].name, "p_interface");
367
sprintf(table[17].name, "model_secondary");
368
sprintf(table[18].name, "r_convec_sec");
369
sprintf(table[19].name, "c_convec_sec");
370
sprintf(table[20].name, "n_metal");
371
sprintf(table[21].name, "t_metal");
372
sprintf(table[22].name, "t_c4");
373
sprintf(table[23].name, "s_c4");
374
sprintf(table[24].name, "n_c4");
375
sprintf(table[25].name, "s_sub");
376
sprintf(table[26].name, "t_sub");
377
sprintf(table[27].name, "s_solder");
378
sprintf(table[28].name, "t_solder");
379
sprintf(table[29].name, "s_pcb");
380
sprintf(table[30].name, "t_pcb");
381
sprintf(table[31].name, "ambient");
382
sprintf(table[32].name, "init_file");
383
sprintf(table[33].name, "init_temp");
384
sprintf(table[34].name, "steady_file");
385
sprintf(table[35].name, "sampling_intvl");
386
sprintf(table[36].name, "base_proc_freq");
387
sprintf(table[37].name, "dtm_used");
388
sprintf(table[38].name, "model_type");
389
sprintf(table[39].name, "leakage_used");
390
sprintf(table[40].name, "leakage_mode");
391
sprintf(table[41].name, "package_model_used");
392
sprintf(table[42].name, "package_config_file");
393
sprintf(table[43].name, "block_omit_lateral");
394
sprintf(table[44].name, "grid_rows");
395
sprintf(table[45].name, "grid_cols");
396
sprintf(table[46].name, "grid_layer_file");
397
sprintf(table[47].name, "grid_steady_file");
398
sprintf(table[48].name, "grid_map_mode");
399
sprintf(table[49].name, "grid_transient_file");
400
sprintf(table[50].name, "detailed_3D_used");
401
402
sprintf(table[0].value, "%lg", config->t_chip);
403
sprintf(table[1].value, "%lg", config->k_chip);
404
sprintf(table[2].value, "%lg", config->p_chip);
405
sprintf(table[3].value, "%lg", config->thermal_threshold);
406
sprintf(table[4].value, "%lg", config->c_convec);
407
sprintf(table[5].value, "%lg", config->r_convec);
408
sprintf(table[6].value, "%lg", config->s_sink);
409
sprintf(table[7].value, "%lg", config->t_sink);
410
sprintf(table[8].value, "%lg", config->k_sink);
411
sprintf(table[9].value, "%lg", config->p_sink);
412
sprintf(table[10].value, "%lg", config->s_spreader);
413
sprintf(table[11].value, "%lg", config->t_spreader);
414
sprintf(table[12].value, "%lg", config->k_spreader);
415
sprintf(table[13].value, "%lg", config->p_spreader);
416
sprintf(table[14].value, "%lg", config->t_interface);
417
sprintf(table[15].value, "%lg", config->k_interface);
418
sprintf(table[16].value, "%lg", config->p_interface);
419
sprintf(table[17].value, "%d", config->model_secondary);
420
sprintf(table[18].value, "%lg", config->r_convec_sec);
421
sprintf(table[19].value, "%lg", config->c_convec_sec);
422
sprintf(table[20].value, "%d", config->n_metal);
423
sprintf(table[21].value, "%lg", config->t_metal);
424
sprintf(table[22].value, "%lg", config->t_c4);
425
sprintf(table[23].value, "%lg", config->s_c4);
426
sprintf(table[24].value, "%d", config->n_c4);
427
sprintf(table[25].value, "%lg", config->s_sub);
428
sprintf(table[26].value, "%lg", config->t_sub);
429
sprintf(table[27].value, "%lg", config->s_solder);
430
sprintf(table[28].value, "%lg", config->t_solder);
431
sprintf(table[29].value, "%lg", config->s_pcb);
432
sprintf(table[30].value, "%lg", config->t_pcb);
433
sprintf(table[31].value, "%lg", config->ambient);
434
sprintf(table[32].value, "%s", config->init_file);
435
sprintf(table[33].value, "%lg", config->init_temp);
436
sprintf(table[34].value, "%s", config->steady_file);
437
sprintf(table[35].value, "%lg", config->sampling_intvl);
438
sprintf(table[36].value, "%lg", config->base_proc_freq);
439
sprintf(table[37].value, "%d", config->dtm_used);
440
sprintf(table[38].value, "%s", config->model_type);
441
sprintf(table[39].value, "%d", config->leakage_used);
442
sprintf(table[40].value, "%d", config->leakage_mode);
443
sprintf(table[41].value, "%d", config->package_model_used);
444
sprintf(table[42].value, "%s", config->package_config_file);
445
sprintf(table[43].value, "%d", config->block_omit_lateral);
446
sprintf(table[44].value, "%d", config->grid_rows);
447
sprintf(table[45].value, "%d", config->grid_cols);
448
sprintf(table[46].value, "%s", config->grid_layer_file);
449
sprintf(table[47].value, "%s", config->grid_steady_file);
450
sprintf(table[48].value, "%s", config->grid_map_mode);
451
sprintf(table[49].value, "%s", config->grid_transient_file);
452
sprintf(table[50].value, "%d", config->detailed_3D_used);
453
454
return 51;
455
}
456
457
/* package parameter routines */
458
void populate_package_R(package_RC_t *p, thermal_config_t *config, double width, double height)
459
{
460
double s_spreader = config->s_spreader;
461
double t_spreader = config->t_spreader;
462
double s_sink = config->s_sink;
463
double t_sink = config->t_sink;
464
double r_convec = config->r_convec;
465
466
double s_sub = config->s_sub;
467
double t_sub = config->t_sub;
468
double s_solder = config->s_solder;
469
double t_solder = config->t_solder;
470
double s_pcb = config->s_pcb;
471
double t_pcb = config->t_pcb;
472
double r_convec_sec = config->r_convec_sec;
473
474
double k_sink = config->k_sink;
475
double k_spreader = config->k_spreader;
476
477
478
/* lateral R's of spreader and sink */
479
p->r_sp1_x = getr(k_spreader, (s_spreader-width)/4.0, (s_spreader+3*height)/4.0 * t_spreader);
480
p->r_sp1_y = getr(k_spreader, (s_spreader-height)/4.0, (s_spreader+3*width)/4.0 * t_spreader);
481
p->r_hs1_x = getr(k_sink, (s_spreader-width)/4.0, (s_spreader+3*height)/4.0 * t_sink);
482
p->r_hs1_y = getr(k_sink, (s_spreader-height)/4.0, (s_spreader+3*width)/4.0 * t_sink);
483
p->r_hs2_x = getr(k_sink, (s_spreader-width)/4.0, (3*s_spreader+height)/4.0 * t_sink);
484
p->r_hs2_y = getr(k_sink, (s_spreader-height)/4.0, (3*s_spreader+width)/4.0 * t_sink);
485
p->r_hs = getr(k_sink, (s_sink-s_spreader)/4.0, (s_sink+3*s_spreader)/4.0 * t_sink);
486
487
/* vertical R's of spreader and sink */
488
p->r_sp_per_x = getr(k_spreader, t_spreader, (s_spreader+height) * (s_spreader-width) / 4.0);
489
p->r_sp_per_y = getr(k_spreader, t_spreader, (s_spreader+width) * (s_spreader-height) / 4.0);
490
p->r_hs_c_per_x = getr(k_sink, t_sink, (s_spreader+height) * (s_spreader-width) / 4.0);
491
p->r_hs_c_per_y = getr(k_sink, t_sink, (s_spreader+width) * (s_spreader-height) / 4.0);
492
p->r_hs_per = getr(k_sink, t_sink, (s_sink*s_sink - s_spreader*s_spreader) / 4.0);
493
494
/* vertical R's to ambient (divide r_convec proportional to area) */
495
p->r_amb_c_per_x = r_convec * (s_sink * s_sink) / ((s_spreader+height) * (s_spreader-width) / 4.0);
496
p->r_amb_c_per_y = r_convec * (s_sink * s_sink) / ((s_spreader+width) * (s_spreader-height) / 4.0);
497
p->r_amb_per = r_convec * (s_sink * s_sink) / ((s_sink*s_sink - s_spreader*s_spreader) / 4.0);
498
499
/* lateral R's of package substrate, solder and PCB */
500
p->r_sub1_x = getr(K_SUB, (s_sub-width)/4.0, (s_sub+3*height)/4.0 * t_sub);
501
p->r_sub1_y = getr(K_SUB, (s_sub-height)/4.0, (s_sub+3*width)/4.0 * t_sub);
502
p->r_solder1_x = getr(K_SOLDER, (s_solder-width)/4.0, (s_solder+3*height)/4.0 * t_solder);
503
p->r_solder1_y = getr(K_SOLDER, (s_solder-height)/4.0, (s_solder+3*width)/4.0 * t_solder);
504
p->r_pcb1_x = getr(K_PCB, (s_solder-width)/4.0, (s_solder+3*height)/4.0 * t_pcb);
505
p->r_pcb1_y = getr(K_PCB, (s_solder-height)/4.0, (s_solder+3*width)/4.0 * t_pcb);
506
p->r_pcb2_x = getr(K_PCB, (s_solder-width)/4.0, (3*s_solder+height)/4.0 * t_pcb);
507
p->r_pcb2_y = getr(K_PCB, (s_solder-height)/4.0, (3*s_solder+width)/4.0 * t_pcb);
508
p->r_pcb = getr(K_PCB, (s_pcb-s_solder)/4.0, (s_pcb+3*s_solder)/4.0 * t_pcb);
509
510
/* vertical R's of package substrate, solder balls and PCB */
511
p->r_sub_per_x = getr(K_SUB, t_sub, (s_sub+height) * (s_sub-width) / 4.0);
512
p->r_sub_per_y = getr(K_SUB, t_sub, (s_sub+width) * (s_sub-height) / 4.0);
513
p->r_solder_per_x = getr(K_SOLDER, t_solder, (s_solder+height) * (s_solder-width) / 4.0);
514
p->r_solder_per_y = getr(K_SOLDER, t_solder, (s_solder+width) * (s_solder-height) / 4.0);
515
p->r_pcb_c_per_x = getr(K_PCB, t_pcb, (s_solder+height) * (s_solder-width) / 4.0);
516
p->r_pcb_c_per_y = getr(K_PCB, t_pcb, (s_solder+width) * (s_solder-height) / 4.0);
517
p->r_pcb_per = getr(K_PCB, t_pcb, (s_pcb*s_pcb - s_solder*s_solder) / 4.0);
518
519
/* vertical R's to ambient at PCB (divide r_convec_sec proportional to area) */
520
p->r_amb_sec_c_per_x = r_convec_sec * (s_pcb * s_pcb) / ((s_solder+height) * (s_solder-width) / 4.0);
521
p->r_amb_sec_c_per_y = r_convec_sec * (s_pcb * s_pcb) / ((s_solder+width) * (s_solder-height) / 4.0);
522
p->r_amb_sec_per = r_convec_sec * (s_pcb * s_pcb) / ((s_pcb*s_pcb - s_solder*s_solder) / 4.0);
523
}
524
525
void populate_package_C(package_RC_t *p, thermal_config_t *config, double width, double height)
526
{
527
double s_spreader = config->s_spreader;
528
double t_spreader = config->t_spreader;
529
double s_sink = config->s_sink;
530
double t_sink = config->t_sink;
531
double c_convec = config->c_convec;
532
533
double s_sub = config->s_sub;
534
double t_sub = config->t_sub;
535
double s_solder = config->s_solder;
536
double t_solder = config->t_solder;
537
double s_pcb = config->s_pcb;
538
double t_pcb = config->t_pcb;
539
double c_convec_sec = config->c_convec_sec;
540
541
double p_sink = config->p_sink;
542
double p_spreader = config->p_spreader;
543
544
/* vertical C's of spreader and sink */
545
p->c_sp_per_x = getcap(p_spreader, t_spreader, (s_spreader+height) * (s_spreader-width) / 4.0);
546
p->c_sp_per_y = getcap(p_spreader, t_spreader, (s_spreader+width) * (s_spreader-height) / 4.0);
547
p->c_hs_c_per_x = getcap(p_sink, t_sink, (s_spreader+height) * (s_spreader-width) / 4.0);
548
p->c_hs_c_per_y = getcap(p_sink, t_sink, (s_spreader+width) * (s_spreader-height) / 4.0);
549
p->c_hs_per = getcap(p_sink, t_sink, (s_sink*s_sink - s_spreader*s_spreader) / 4.0);
550
551
/* vertical C's to ambient (divide c_convec proportional to area) */
552
p->c_amb_c_per_x = C_FACTOR * c_convec / (s_sink * s_sink) * ((s_spreader+height) * (s_spreader-width) / 4.0);
553
p->c_amb_c_per_y = C_FACTOR * c_convec / (s_sink * s_sink) * ((s_spreader+width) * (s_spreader-height) / 4.0);
554
p->c_amb_per = C_FACTOR * c_convec / (s_sink * s_sink) * ((s_sink*s_sink - s_spreader*s_spreader) / 4.0);
555
556
/* vertical C's of package substrate, solder balls, and PCB */
557
p->c_sub_per_x = getcap(SPEC_HEAT_SUB, t_sub, (s_sub+height) * (s_sub-width) / 4.0);
558
p->c_sub_per_y = getcap(SPEC_HEAT_SUB, t_sub, (s_sub+width) * (s_sub-height) / 4.0);
559
p->c_solder_per_x = getcap(SPEC_HEAT_SOLDER, t_solder, (s_solder+height) * (s_solder-width) / 4.0);
560
p->c_solder_per_y = getcap(SPEC_HEAT_SOLDER, t_solder, (s_solder+width) * (s_solder-height) / 4.0);
561
p->c_pcb_c_per_x = getcap(SPEC_HEAT_PCB, t_pcb, (s_solder+height) * (s_solder-width) / 4.0);
562
p->c_pcb_c_per_y = getcap(SPEC_HEAT_PCB, t_pcb, (s_solder+width) * (s_solder-height) / 4.0);
563
p->c_pcb_per = getcap(SPEC_HEAT_PCB, t_pcb, (s_pcb*s_pcb - s_solder*s_solder) / 4.0);
564
565
/* vertical C's to ambient at PCB (divide c_convec_sec proportional to area) */
566
p->c_amb_sec_c_per_x = C_FACTOR * c_convec_sec / (s_pcb * s_pcb) * ((s_solder+height) * (s_solder-width) / 4.0);
567
p->c_amb_sec_c_per_y = C_FACTOR * c_convec_sec / (s_pcb * s_pcb) * ((s_solder+width) * (s_solder-height) / 4.0);
568
p->c_amb_sec_per = C_FACTOR * c_convec_sec / (s_pcb * s_pcb) * ((s_pcb*s_pcb - s_solder*s_solder) / 4.0);
569
}
570
571
/* debug print */
572
void debug_print_package_RC(package_RC_t *p)
573
{
574
fprintf(stdout, "printing package RC information...\n");
575
fprintf(stdout, "r_sp1_x: %f\tr_sp1_y: %f\n", p->r_sp1_x, p->r_sp1_y);
576
fprintf(stdout, "r_sp_per_x: %f\tr_sp_per_y: %f\n", p->r_sp_per_x, p->r_sp_per_y);
577
fprintf(stdout, "c_sp_per_x: %f\tc_sp_per_y: %f\n", p->c_sp_per_x, p->c_sp_per_y);
578
fprintf(stdout, "r_hs1_x: %f\tr_hs1_y: %f\n", p->r_hs1_x, p->r_hs1_y);
579
fprintf(stdout, "r_hs2_x: %f\tr_hs2_y: %f\n", p->r_hs2_x, p->r_hs2_y);
580
fprintf(stdout, "r_hs_c_per_x: %f\tr_hs_c_per_y: %f\n", p->r_hs_c_per_x, p->r_hs_c_per_y);
581
fprintf(stdout, "c_hs_c_per_x: %f\tc_hs_c_per_y: %f\n", p->c_hs_c_per_x, p->c_hs_c_per_y);
582
fprintf(stdout, "r_hs: %f\tr_hs_per: %f\n", p->r_hs, p->r_hs_per);
583
fprintf(stdout, "c_hs_per: %f\n", p->c_hs_per);
584
fprintf(stdout, "r_amb_c_per_x: %f\tr_amb_c_per_y: %f\n", p->r_amb_c_per_x, p->r_amb_c_per_y);
585
fprintf(stdout, "c_amb_c_per_x: %f\tc_amb_c_per_y: %f\n", p->c_amb_c_per_x, p->c_amb_c_per_y);
586
fprintf(stdout, "r_amb_per: %f\n", p->r_amb_per);
587
fprintf(stdout, "c_amb_per: %f\n", p->c_amb_per);
588
fprintf(stdout, "r_sub1_x: %f\tr_sub1_y: %f\n", p->r_sub1_x, p->r_sub1_y);
589
fprintf(stdout, "r_sub_per_x: %f\tr_sub_per_y: %f\n", p->r_sub_per_x, p->r_sub_per_y);
590
fprintf(stdout, "c_sub_per_x: %f\tc_sub_per_y: %f\n", p->c_sub_per_x, p->c_sub_per_y);
591
fprintf(stdout, "r_solder1_x: %f\tr_solder1_y: %f\n", p->r_solder1_x, p->r_solder1_y);
592
fprintf(stdout, "r_solder_per_x: %f\tr_solder_per_y: %f\n", p->r_solder_per_x, p->r_solder_per_y);
593
fprintf(stdout, "c_solder_per_x: %f\tc_solder_per_y: %f\n", p->c_solder_per_x, p->c_solder_per_y);
594
fprintf(stdout, "r_pcb1_x: %f\tr_pcb1_y: %f\n", p->r_pcb1_x, p->r_pcb1_y);
595
fprintf(stdout, "r_pcb2_x: %f\tr_pcb2_y: %f\n", p->r_pcb2_x, p->r_pcb2_y);
596
fprintf(stdout, "r_pcb_c_per_x: %f\tr_pcb_c_per_y: %f\n", p->r_pcb_c_per_x, p->r_pcb_c_per_y);
597
fprintf(stdout, "c_pcb_c_per_x: %f\tc_pcb_c_per_y: %f\n", p->c_pcb_c_per_x, p->c_pcb_c_per_y);
598
fprintf(stdout, "r_pcb: %f\tr_pcb_per: %f\n", p->r_pcb, p->r_pcb_per);
599
fprintf(stdout, "c_pcb_per: %f\n", p->c_pcb_per);
600
fprintf(stdout, "r_amb_sec_c_per_x: %f\tr_amb_sec_c_per_y: %f\n", p->r_amb_sec_c_per_x, p->r_amb_sec_c_per_y);
601
fprintf(stdout, "c_amb_sec_c_per_x: %f\tc_amb_sec_c_per_y: %f\n", p->c_amb_sec_c_per_x, p->c_amb_sec_c_per_y);
602
fprintf(stdout, "r_amb_sec_per: %f\n", p->r_amb_sec_per);
603
fprintf(stdout, "c_amb_sec_per: %f\n", p->c_amb_sec_per);
604
}
605
606
/*
607
* wrapper routines interfacing with those of the corresponding
608
* thermal model (block or grid)
609
*/
610
611
/*
612
* allocate memory for the matrices. for the block model, placeholder
613
* can be an empty floorplan frame with only the names of the functional
614
* units. for the grid model, it is the default floorplan
615
*/
616
RC_model_t *alloc_RC_model(thermal_config_t *config, flp_t *placeholder, microchannel_config_t *microchannel_config, materials_list_t *materials_list,
617
int do_detailed_3D, int use_microchannels) //BU_3D: do_detailed_3D option added.
618
{
619
RC_model_t *model= (RC_model_t *) calloc (1, sizeof(RC_model_t));
620
if (!model)
621
fatal("memory allocation error\n");
622
if(!(strcasecmp(config->model_type, BLOCK_MODEL_STR))) {
623
model->type = BLOCK_MODEL;
624
model->block = alloc_block_model(config, placeholder);
625
model->config = &model->block->config;
626
} else if(!(strcasecmp(config->model_type, GRID_MODEL_STR))) {
627
model->type = GRID_MODEL;
628
model->grid = alloc_grid_model(config, placeholder, microchannel_config, materials_list, do_detailed_3D, use_microchannels);
629
model->config = &model->grid->config;
630
} else
631
fatal("unknown model type\n");
632
return model;
633
}
634
635
/* populate the thermal restistance values */
636
void populate_R_model(RC_model_t *model, flp_t *flp)
637
{
638
if (model->type == BLOCK_MODEL)
639
populate_R_model_block(model->block, flp);
640
else if (model->type == GRID_MODEL)
641
populate_R_model_grid(model->grid, flp);
642
else fatal("unknown model type\n");
643
}
644
645
/* populate the thermal capacitance values */
646
void populate_C_model(RC_model_t *model, flp_t *flp)
647
{
648
if (model->type == BLOCK_MODEL)
649
populate_C_model_block(model->block, flp);
650
else if (model->type == GRID_MODEL)
651
populate_C_model_grid(model->grid, flp);
652
else fatal("unknown model type\n");
653
}
654
655
/* steady state temperature */
656
void steady_state_temp(RC_model_t *model, double *power, double *temp)
657
{
658
int leak_convg_true = 0;
659
int leak_iter = 0;
660
int n, base=0;
661
//int idx=0;
662
double blk_height, blk_width;
663
int i, j, k;
664
665
double *d_temp = NULL;
666
double *temp_old = NULL;
667
double *power_new = NULL;
668
double d_max=0.0;
669
670
if (model->type == BLOCK_MODEL) {
671
n = model->block->flp->n_units;
672
if (model->config->leakage_used) { // if considering leakage-temperature loop
673
d_temp = hotspot_vector(model);
674
temp_old = hotspot_vector(model);
675
power_new = hotspot_vector(model);
676
for (leak_iter=0;(!leak_convg_true)&&(leak_iter<=LEAKAGE_MAX_ITER);leak_iter++){
677
for(i=0; i < n; i++) {
678
blk_height = model->block->flp->units[i].height;
679
blk_width = model->block->flp->units[i].width;
680
power_new[i] = power[i] + calc_leakage(model->config->leakage_mode,blk_height,blk_width,temp[i]);
681
temp_old[i] = temp[i]; //copy temp before update
682
}
683
steady_state_temp_block(model->block, power_new, temp); // update temperature
684
d_max = 0.0;
685
for(i=0; i < n; i++) {
686
d_temp[i] = temp[i] - temp_old[i]; //temperature increase due to leakage
687
if (d_temp[i]>d_max) {
688
d_max = d_temp[i];
689
}
690
}
691
if (d_max < LEAK_TOL) {// check convergence
692
leak_convg_true = 1;
693
}
694
if (d_max > TEMP_HIGH && leak_iter > 1) {// check to make sure d_max is not "nan" (esp. in natural convection)
695
fatal("temperature is too high, possible thermal runaway. Double-check power inputs and package settings.\n");
696
}
697
}
698
free(d_temp);
699
free(temp_old);
700
free(power_new);
701
/* if no convergence after max number of iterations, thermal runaway */
702
if (!leak_convg_true)
703
fatal("too many iterations before temperature-leakage convergence -- possible thermal runaway\n");
704
} else // if leakage-temperature loop is not considered
705
steady_state_temp_block(model->block, power, temp);
706
}
707
else if (model->type == GRID_MODEL) {
708
if (model->config->leakage_used) { // if considering leakage-temperature loop
709
d_temp = hotspot_vector(model);
710
temp_old = hotspot_vector(model);
711
power_new = hotspot_vector(model);
712
for (leak_iter=0;(!leak_convg_true)&&(leak_iter<=LEAKAGE_MAX_ITER);leak_iter++){
713
for(k=0, base=0; k < model->grid->n_layers; k++) {
714
if(model->grid->layers[k].has_power)
715
for(j=0; j < model->grid->layers[k].flp->n_units; j++) {
716
blk_height = model->grid->layers[k].flp->units[j].height;
717
blk_width = model->grid->layers[k].flp->units[j].width;
718
power_new[base+j] = power[base+j] + calc_leakage(model->config->leakage_mode,blk_height,blk_width,temp[base+j]);
719
temp_old[base+j] = temp[base+j]; //copy temp before update
720
}
721
base += model->grid->layers[k].flp->n_units;
722
}
723
steady_state_temp_grid(model->grid, power_new, temp);
724
d_max = 0.0;
725
for(k=0, base=0; k < model->grid->n_layers; k++) {
726
if(model->grid->layers[k].has_power)
727
for(j=0; j < model->grid->layers[k].flp->n_units; j++) {
728
d_temp[base+j] = temp[base+j] - temp_old[base+j]; //temperature increase due to leakage
729
if (d_temp[base+j]>d_max)
730
d_max = d_temp[base+j];
731
}
732
base += model->grid->layers[k].flp->n_units;
733
}
734
if (d_max < LEAK_TOL) {// check convergence
735
leak_convg_true = 1;
736
}
737
if (d_max > TEMP_HIGH && leak_iter > 0) {// check to make sure d_max is not "nan" (esp. in natural convection)
738
fatal("temperature is too high, possible thermal runaway. Double-check power inputs and package settings.\n");
739
}
740
}
741
free(d_temp);
742
free(temp_old);
743
free(power_new);
744
/* if no convergence after max number of iterations, thermal runaway */
745
if (!leak_convg_true)
746
fatal("too many iterations before temperature-leakage convergence -- possible thermal runaway\n");
747
} else // if leakage-temperature loop is not considered
748
steady_state_temp_grid(model->grid, power, temp);
749
}
750
else fatal("unknown model type\n");
751
}
752
753
/* transient (instantaneous) temperature */
754
void compute_temp(RC_model_t *model, double *power, double *temp, double time_elapsed)
755
{
756
if (model->type == BLOCK_MODEL)
757
compute_temp_block(model->block, power, temp, time_elapsed);
758
else if (model->type == GRID_MODEL)
759
compute_temp_grid(model->grid, power, temp, time_elapsed);
760
else fatal("unknown model type\n");
761
}
762
763
/* differs from 'dvector()' in that memory for internal nodes is also allocated */
764
double *hotspot_vector(RC_model_t *model)
765
{
766
if (model->type == BLOCK_MODEL)
767
return hotspot_vector_block(model->block);
768
else if (model->type == GRID_MODEL)
769
return hotspot_vector_grid(model->grid);
770
else fatal("unknown model type\n");
771
return NULL;
772
}
773
774
/* copy 'src' to 'dst' except for a window of 'size'
775
* elements starting at 'at'. useful in floorplan
776
* compaction
777
*/
778
void trim_hotspot_vector(RC_model_t *model, double *dst, double *src,
779
int at, int size)
780
{
781
if (model->type == BLOCK_MODEL)
782
trim_hotspot_vector_block(model->block, dst, src, at, size);
783
else if (model->type == GRID_MODEL)
784
trim_hotspot_vector_grid(model->grid, dst, src, at, size);
785
else fatal("unknown model type\n");
786
}
787
788
/* update the model's node count */
789
void resize_thermal_model(RC_model_t *model, int n_units)
790
{
791
if (model->type == BLOCK_MODEL)
792
resize_thermal_model_block(model->block, n_units);
793
else if (model->type == GRID_MODEL)
794
resize_thermal_model_grid(model->grid, n_units);
795
else fatal("unknown model type\n");
796
}
797
798
/* sets the temperature of a vector 'temp' allocated using 'hotspot_vector' */
799
void set_temp(RC_model_t *model, double *temp, double val)
800
{
801
if (model->type == BLOCK_MODEL)
802
set_temp_block(model->block, temp, val);
803
else if (model->type == GRID_MODEL)
804
set_temp_grid(model->grid, temp, val);
805
else fatal("unknown model type\n");
806
}
807
808
/* dump temperature vector alloced using 'hotspot_vector' to 'file' */
809
void dump_temp(RC_model_t *model, double *temp, char *file)
810
{
811
if (model->type == BLOCK_MODEL)
812
dump_temp_block(model->block, temp, file);
813
else if (model->type == GRID_MODEL)
814
dump_temp_grid(model->grid, temp, file);
815
else fatal("unknown model type\n");
816
}
817
818
/* calculate average heatsink temperature for natural convection package */
819
double calc_sink_temp(RC_model_t *model, double *temp)
820
{
821
if (model->type == BLOCK_MODEL)
822
return calc_sink_temp_block(model->block, temp, model->config);
823
else if (model->type == GRID_MODEL)
824
return calc_sink_temp_grid(model->grid, temp, model->config);
825
else fatal("unknown model type\n");
826
return 0.0;
827
}
828
829
/* copy temperature vector from src to dst */
830
void copy_temp(RC_model_t *model, double *dst, double *src)
831
{
832
if (model->type == BLOCK_MODEL)
833
copy_temp_block(model->block, dst, src);
834
else if (model->type == GRID_MODEL)
835
copy_temp_grid(model->grid, dst, src);
836
else fatal("unknown model type\n");
837
}
838
839
/*
840
* read temperature vector alloced using 'hotspot_vector' from 'file'
841
* which was dumped using 'dump_temp'. values are clipped to thermal
842
* threshold based on 'clip'
843
*/
844
void read_temp(RC_model_t *model, double *temp, char *file, int clip)
845
{
846
if (model->type == BLOCK_MODEL)
847
read_temp_block(model->block, temp, file, clip);
848
else if (model->type == GRID_MODEL)
849
read_temp_grid(model->grid, temp, file, clip);
850
else fatal("unknown model type\n");
851
}
852
853
/* dump power numbers to file */
854
void dump_power(RC_model_t *model, double *power, char *file)
855
{
856
if (model->type == BLOCK_MODEL)
857
dump_power_block(model->block, power, file);
858
else if (model->type == GRID_MODEL)
859
dump_power_grid(model->grid, power, file);
860
else fatal("unknown model type\n");
861
}
862
863
/*
864
* read power vector alloced using 'hotspot_vector' from 'file'
865
* which was dumped using 'dump_power'.
866
*/
867
void read_power(RC_model_t *model, double *power, char *file)
868
{
869
if (model->type == BLOCK_MODEL)
870
read_power_block(model->block, power, file);
871
else if (model->type == GRID_MODEL)
872
read_power_grid(model->grid, power, file);
873
else fatal("unknown model type\n");
874
}
875
876
/* peak temperature on chip */
877
double find_max_temp(RC_model_t *model, double *temp)
878
{
879
if (model->type == BLOCK_MODEL)
880
return find_max_temp_block(model->block, temp);
881
else if (model->type == GRID_MODEL)
882
return find_max_temp_grid(model->grid, temp);
883
else fatal("unknown model type\n");
884
return 0.0;
885
}
886
887
/* average temperature on chip */
888
double find_avg_temp(RC_model_t *model, double *temp)
889
{
890
if (model->type == BLOCK_MODEL)
891
return find_avg_temp_block(model->block, temp);
892
else if (model->type == GRID_MODEL)
893
return find_avg_temp_grid(model->grid, temp);
894
else fatal("unknown model type\n");
895
return 0.0;
896
}
897
898
/* debug print */
899
void debug_print_model(RC_model_t *model)
900
{
901
if (model->type == BLOCK_MODEL)
902
debug_print_block(model->block);
903
else if (model->type == GRID_MODEL)
904
debug_print_grid(model->grid);
905
else fatal("unknown model type\n");
906
}
907
908
/* calculate temperature-dependent leakage power */
909
/* will support HotLeakage in future releases */
910
double calc_leakage(int mode, double h, double w, double temp)
911
{
912
/* a simple leakage model.
913
* Be aware -- this model may not be accurate in some cases.
914
* You may want to use your own temperature-dependent leakage model here.
915
*/
916
double leak_alpha = 1.5e+4;
917
double leak_beta = 0.036;
918
double leak_Tbase = 383.15; /* 110C according to the above paper */
919
920
double leakage_power;
921
922
if (mode)
923
fatal("HotLeakage currently is not implemented in this release of HotSpot, please check back later.\n");
924
925
leakage_power = leak_alpha*h*w*exp(leak_beta*(temp-leak_Tbase));
926
return leakage_power;
927
}
928
929
/* destructor */
930
void delete_RC_model(RC_model_t *model)
931
{
932
if (model->type == BLOCK_MODEL)
933
delete_block_model(model->block);
934
else if (model->type == GRID_MODEL)
935
delete_grid_model(model->grid);
936
else fatal("unknown model type\n");
937
free(model);
938
}
939
940