3D-ICE 3.0.0
heat_sink.c
1/******************************************************************************
2 * This file is part of 3D-ICE, version 3.1.0 . *
3 * *
4 * 3D-ICE is free software: you can redistribute it and/or modify it under *
5 * the terms of the GNU General Public License as published by the Free *
6 * Software Foundation, either version 3 of the License, or any later *
7 * version. *
8 * *
9 * 3D-ICE is distributed in the hope that it will be useful, but WITHOUT *
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
12 * more details. *
13 * *
14 * You should have received a copy of the GNU General Public License along *
15 * with 3D-ICE. If not, see <http://www.gnu.org/licenses/>. *
16 * *
17 * Copyright (C) 2021 *
18 * Embedded Systems Laboratory - Ecole Polytechnique Federale de Lausanne *
19 * All Rights Reserved. *
20 * *
21 * Authors: Arvind Sridhar Alessandro Vincenzi *
22 * Giseong Bak Martino Ruggiero *
23 * Thomas Brunschwiler Eder Zulian *
24 * Federico Terraneo Darong Huang *
25 * Luis Costero Marina Zapater *
26 * David Atienza *
27 * *
28 * For any comment, suggestion or request about 3D-ICE, please register and *
29 * write to the mailing list (see http://listes.epfl.ch/doc.cgi?liste=3d-ice) *
30 * Any usage of 3D-ICE for research, commercial or other purposes must be *
31 * properly acknowledged in the resulting products or publications. *
32 * *
33 * EPFL-STI-IEL-ESL Mail : 3d-ice@listes.epfl.ch *
34 * Batiment ELG, ELG 130 (SUBSCRIPTION IS NECESSARY) *
35 * Station 11 *
36 * 1015 Lausanne, Switzerland Url : http://esl.epfl.ch/3d-ice *
37 ******************************************************************************/
38
39#include <math.h> // Fo the math function sqrt
40#include <stdlib.h> // For the memory functions malloc/free
41#include <string.h>
42#include <assert.h>
43#include <unistd.h>
44#include <dlfcn.h>
45
46#include "heat_sink.h"
47#include "macros.h"
48
49/******************************************************************************/
50
52{
54 hsink->AmbientHTC = (AmbientHTC_t) 0.0 ;
55 hsink->AmbientTemperature = (Temperature_t) 0.0 ;
56
57 hsink->SpreaderLength = 0.0;
58 hsink->SpreaderWidth = 0.0;
59 hsink->SpreaderHeight = 0.0;
60
62 string_init(&hsink->Plugin);
63 string_init(&hsink->Args);
64
65 hsink->CellLength = 0.0;
66 hsink->CellWidth = 0.0;
67 hsink->NRows = 0;
68 hsink->NColumns = 0;
69 hsink->NumRowsBorder = 0;
70 hsink->NumColumnsBorder = 0;
71
72 hsink->PluggableHeatsink = NULL;
73}
74
75/******************************************************************************/
76
77void *array_alloc_copy(const void *src, size_t size)
78{
79 void *result=malloc(size);
80 // TODO: It would be better to report the error in a better way, but
81 // heat_sink_copy returns void and not an error code
82 assert(result != NULL);
83 memcpy(result,src,size);
84 return result;
85}
86
87/******************************************************************************/
88
90{
91 heat_sink_destroy (dst) ;
92
93 dst->SinkModel = src->SinkModel ;
94 dst->AmbientHTC = src->AmbientHTC ;
95 dst->AmbientTemperature = src->AmbientTemperature ;
96
97 dst->SpreaderLength = src->SpreaderLength;
98 dst->SpreaderWidth = src->SpreaderWidth;
99 dst->SpreaderHeight = src->SpreaderHeight;
100
101 material_copy(&dst->SpreaderMaterial,&src->SpreaderMaterial);
102 string_copy(&dst->Plugin,&src->Plugin);
103 string_copy(&dst->Args, &src->Args);
104
105 dst->CellLength = src->CellLength;
106 dst->CellWidth = src->CellWidth;
107 dst->NRows = src->NRows;
108 dst->NColumns = src->NColumns;
109 dst->NumRowsBorder = src->NumRowsBorder;
110 dst->NumColumnsBorder = src->NumColumnsBorder;
111
112 dst->PluggableHeatsink = src->PluggableHeatsink;
113}
114
115/******************************************************************************/
116
118{
120 string_destroy (&hsink->Plugin);
121 string_destroy (&hsink->Args);
122
123 heat_sink_init (hsink) ;
124}
125
126/******************************************************************************/
127
129{
130 HeatSink_t *hsink = (HeatSink_t *) malloc (sizeof(HeatSink_t)) ;
131
132 if (hsink != NULL)
133
134 heat_sink_init (hsink) ;
135
136 return hsink ;
137}
138
139/******************************************************************************/
140
142{
143 if (hsink == NULL)
144
145 return NULL ;
146
147 HeatSink_t *newh = heat_sink_calloc ( ) ;
148
149 if (newh != NULL)
150
151 heat_sink_copy (newh, hsink) ;
152
153 return newh ;
154}
155
156/******************************************************************************/
157
159{
160 if (hsink == NULL)
161
162 return ;
163
164 heat_sink_destroy (hsink) ;
165
166 free (hsink) ;
167}
168
169/******************************************************************************/
170
172(
173 HeatSink_t *hsink,
174 Dimensions_t *dimensions,
175 CellIndex_t row_index,
176 CellIndex_t column_index
177)
178{
179 assert(hsink->SinkModel != TDICE_HEATSINK_TOP_PLUGGABLE);
180
181 return hsink->AmbientHTC
182 * get_cell_length (dimensions, column_index)
183 * get_cell_width (dimensions, row_index) ;
184}
185
186/******************************************************************************/
187
188void heat_sink_print (HeatSink_t *hsink, FILE *stream, String_t prefix)
189{
190 int format=0;
191
192 if (hsink->SinkModel == TDICE_HEATSINK_TOP)
193
194 fprintf (stream, "%stop heat sink :\n", prefix) ;
195
196 else if (hsink->SinkModel == TDICE_HEATSINK_BOTTOM)
197
198 fprintf (stream, "%sbottom heat sink :\n", prefix) ;
199
200 else if (hsink->SinkModel == TDICE_HEATSINK_TOP_PLUGGABLE)
201 {
202 fprintf (stream, "%stop pluggable heat sink :\n", prefix) ;
203 format=1;
204 }
205 else
206 {
207 fprintf (stream, "wrong heat sink model\n") ;
208
209 return ;
210 }
211
212 if(format==0)
213 {
214 fprintf (stream,
215 "%s heat transfer coefficient %.4e ;\n",
216 prefix, hsink->AmbientHTC) ;
217
218 fprintf (stream,
219 "%s temperature %.2f ;\n",
220 prefix, hsink->AmbientTemperature) ;
221 }
222 else
223 {
224 fprintf (stream,
225 "%s spreader length %.0f ;\n",
226 prefix, hsink->SpreaderLength) ;
227
228 fprintf (stream,
229 "%s spreader width %.0f ;\n",
230 prefix, hsink->SpreaderWidth) ;
231
232 fprintf (stream,
233 "%s spreader height %.0f ;\n",
234 prefix, hsink->SpreaderHeight) ;
235
236 material_print(&hsink->SpreaderMaterial, stream, prefix);
237
238 fprintf (stream,
239 "%s plugin %s ;\n",
240 prefix, hsink->Plugin) ;
241
242 fprintf (stream,
243 "%s plugin args %s ;\n",
244 prefix, hsink->Args) ;
245
246 fprintf (stream,
247 "%s cell length %.0f ;\n",
248 prefix, hsink->CellLength) ;
249
250 fprintf (stream,
251 "%s cell width %.0f ;\n",
252 prefix, hsink->CellWidth) ;
253
254 fprintf (stream,
255 "%s num rows %d ;\n",
256 prefix, hsink->NRows) ;
257
258 fprintf (stream,
259 "%s num columns %d ;\n",
260 prefix, hsink->NColumns) ;
261
262 fprintf (stream,
263 "%s num rows border %d ;\n",
264 prefix, hsink->NumRowsBorder) ;
265
266 fprintf (stream,
267 "%s num columns border %d ;\n",
268 prefix, hsink->NumColumnsBorder) ;
269 }
270}
271
272// Need a static variable because atexit doesn't allow parameters
273static void *so = NULL;
274
275static void close_shared_object()
276{
277 if(so) dlclose(so);
278}
279
281{
283 return TDICE_SUCCESS;
284
285 // If the spreader dimensions are not within 0.1 of the cell size print a warning
286 const double maxSlack = 0.1;
287
288 double borderLength = (hsink->SpreaderLength - chip->Chip.Length) / 2.0;
289 hsink->CellLength = chip->Chip.Length / get_number_of_columns(chip);
290
291 double numColumnsBorderDouble = borderLength / hsink->CellLength;
292 if(numColumnsBorderDouble<0.0)
293 {
294 fprintf (stderr, "ERROR: spreader length is smaller than the chip\n") ;
295 return TDICE_FAILURE;
296 }
297 hsink->NumColumnsBorder = numColumnsBorderDouble;
298 if(numColumnsBorderDouble - hsink->NumColumnsBorder > maxSlack)
299 fprintf (stderr, "WARNING: spreader length not a multiple of cell length\n") ;
300
301 hsink->NColumns = 2 * hsink->NumColumnsBorder + get_number_of_columns(chip);
302
303
304 double borderWidth = (hsink->SpreaderWidth - chip->Chip.Width) / 2.0;
305 hsink->CellWidth = chip->Chip.Width / get_number_of_rows(chip);
306
307 double numRowsBorderDouble = borderWidth / hsink->CellWidth;
308 if(numRowsBorderDouble<0.0)
309 {
310 fprintf (stderr, "ERROR: spreader width is smaller than the chip\n") ;
311 return TDICE_FAILURE;
312 }
313 hsink->NumRowsBorder = numRowsBorderDouble;
314 if(numRowsBorderDouble - hsink->NumRowsBorder > maxSlack)
315 fprintf (stderr, "WARNING: spreader length not a multiple of cell length\n") ;
316
317 hsink->NRows = 2 * hsink->NumRowsBorder + get_number_of_rows(chip);
318
319 char path[2048];
320 memset(path,0,sizeof(path));
321
322 if(strlen(hsink->Plugin)>0 && hsink->Plugin[0]!='/')
323 {
324 // Plugin has relative path, add <pwd>/ to path
325 if(getcwd(path,sizeof(path)-1)==NULL)
326 {
327 fprintf (stderr, "ERROR: getcwd() failed\n") ;
328 return TDICE_FAILURE;
329 }
330 strncat(path,"/",sizeof(path)-1);
331 }
332
333 strncat(path,hsink->Plugin,sizeof(path)-1);
334 so = dlopen(path, RTLD_LAZY | RTLD_GLOBAL);
335 if(so == NULL)
336 {
337 fprintf (stderr, "ERROR: could not load heatsink plugin %s\n", path) ;
338 return TDICE_FAILURE;
339 }
340 atexit(close_shared_object);
341
342 hsink->PluggableHeatsinkInit =
343 (int (*)(unsigned int, unsigned int, double, double, double, double, double, const char*))
344 dlsym(so, "heatsink_init");
345 if(hsink->PluggableHeatsinkInit == NULL)
346 {
347 fprintf (stderr, "ERROR: heatsink plugin reported %s\n", dlerror()) ;
348 return TDICE_FAILURE;
349 }
350
351 hsink->PluggableHeatsink =
352 (int (*)(const double*, double*))
353 dlsym(so, "heatsink_simulate_step");
354 if(hsink->PluggableHeatsink == NULL)
355 {
356 fprintf (stderr, "ERROR: heatsink plugin reported %s\n", dlerror()) ;
357 return TDICE_FAILURE;
358 }
359
360 return TDICE_SUCCESS;
361}
362
364{
365 double spreaderConductance = get_spreader_conductance_top_bottom(hsink);
366 if(hsink->PluggableHeatsinkInit(
367 hsink->NRows, hsink->NColumns,
368 hsink->CellWidth, hsink->CellLength,
369 analysis->InitialTemperature,
370 spreaderConductance,
371 analysis->StepTime,
372 hsink->Args) != 0)
373 return TDICE_FAILURE;
374 return TDICE_SUCCESS;
375}
376
378{
379 assert(hsink->SinkModel == TDICE_HEATSINK_TOP_PLUGGABLE);
380
382 * hsink->CellLength
383 * hsink->CellWidth
384 * hsink->SpreaderHeight;
385}
386
388{
389 assert(hsink->SinkModel == TDICE_HEATSINK_TOP_PLUGGABLE);
390
392 * hsink->SpreaderHeight
393 * hsink->CellWidth) / (hsink->CellLength / 2.0);
394}
395
397{
398 assert(hsink->SinkModel == TDICE_HEATSINK_TOP_PLUGGABLE);
399
401 * hsink->CellLength
402 * hsink->SpreaderHeight) / (hsink->CellWidth / 2.0);
403}
404
406{
407 assert(hsink->SinkModel == TDICE_HEATSINK_TOP_PLUGGABLE);
408
410 * hsink->CellLength
411 * hsink->CellWidth) / (hsink->SpreaderHeight / 2.0);
412}
413
414
416{
417 assert(hsink->SinkModel == TDICE_HEATSINK_TOP_PLUGGABLE);
418
420 * area ) / (hsink->SpreaderHeight / 2.0);
421}
422
423/******************************************************************************/
CellDimension_t get_cell_length(Dimensions_t *dimensions, CellIndex_t column_index)
Definition: dimensions.c:478
CellDimension_t get_cell_width(Dimensions_t *dimensions, CellIndex_t row_index)
Definition: dimensions.c:515
CellIndex_t get_number_of_rows(Dimensions_t *dimensions)
Definition: dimensions.c:638
CellIndex_t get_number_of_columns(Dimensions_t *dimensions)
Definition: dimensions.c:645
void heat_sink_init(HeatSink_t *hsink)
Definition: heat_sink.c:51
HeatSink_t * heat_sink_clone(HeatSink_t *hsink)
Definition: heat_sink.c:141
void heat_sink_copy(HeatSink_t *dst, HeatSink_t *src)
Definition: heat_sink.c:89
Conductance_t get_spreader_conductance_top_bottom(HeatSink_t *hsink)
Definition: heat_sink.c:405
Conductance_t get_spreader_conductance_north_south(HeatSink_t *hsink)
Definition: heat_sink.c:396
void heat_sink_free(HeatSink_t *hsink)
Definition: heat_sink.c:158
Capacity_t get_spreader_capacity(HeatSink_t *hsink)
Definition: heat_sink.c:377
Error_t initialize_pluggable_heatsink(HeatSink_t *hsink, Analysis_t *analysis)
Definition: heat_sink.c:363
void heat_sink_print(HeatSink_t *hsink, FILE *stream, String_t prefix)
Definition: heat_sink.c:188
Error_t initialize_heat_spreader(HeatSink_t *hsink, Dimensions_t *chip)
Definition: heat_sink.c:280
void heat_sink_destroy(HeatSink_t *hsink)
Definition: heat_sink.c:117
HeatSink_t * heat_sink_calloc(void)
Definition: heat_sink.c:128
Conductance_t get_spreader_conductance_east_west(HeatSink_t *hsink)
Definition: heat_sink.c:387
Conductance_t heat_sink_conductance(HeatSink_t *hsink, Dimensions_t *dimensions, CellIndex_t row_index, CellIndex_t column_index)
Definition: heat_sink.c:172
Conductance_t get_spreader_conductance_top_bottom_nonuniform(HeatSink_t *hsink, ChipDimension_t area)
Definition: heat_sink.c:415
void material_copy(Material_t *dst, Material_t *src)
Definition: material.c:55
void material_destroy(Material_t *material)
Definition: material.c:67
void material_print(Material_t *material, FILE *stream, String_t prefix)
Definition: material.c:126
void material_init(Material_t *material)
Definition: material.c:45
char * String_t
Definition: string_t.h:55
void string_init(String_t *string)
Definition: string_t.c:46
void string_destroy(String_t *string)
Definition: string_t.c:78
void string_copy(String_t *dst, String_t *src)
Definition: string_t.c:53
Informations about the type of thermal simulation to be run, timing and its initial settings.
Definition: analysis.h:65
Time_t StepTime
Definition: analysis.h:72
Temperature_t InitialTemperature
Definition: analysis.h:88
ChipDimension_t Length
Definition: dimensions.h:258
ChipDimension_t Width
Definition: dimensions.h:262
Collections of all the structures that are needed for the thermal simulation.
Definition: dimensions.h:311
ChipDimensions_t Chip
Definition: dimensions.h:322
Structure used to store data about the heat dissipation through the top or bottom surfaces of the 2D/...
Definition: heat_sink.h:69
Temperature_t AmbientTemperature
Definition: heat_sink.h:82
CellDimension_t CellWidth
Definition: heat_sink.h:106
CellIndex_t NColumns
Definition: heat_sink.h:114
CellIndex_t NumColumnsBorder
Definition: heat_sink.h:126
SpreaderDimension_t SpreaderLength
Definition: heat_sink.h:86
int(* PluggableHeatsinkInit)(unsigned int nrows, unsigned int ncols, double cellwidth, double celllength, double initialtemperature, double spreaderconductance, double timestep, const char *args)
Definition: heat_sink.h:129
HeatSinkModel_t SinkModel
Definition: heat_sink.h:72
CellIndex_t NumRowsBorder
Definition: heat_sink.h:120
CellDimension_t CellLength
Definition: heat_sink.h:102
int(* PluggableHeatsink)(const double *spreadertemperatures, double *sinkheatflows)
Definition: heat_sink.h:137
Material_t SpreaderMaterial
Definition: heat_sink.h:90
AmbientHTC_t AmbientHTC
Definition: heat_sink.h:77
String_t Args
Definition: heat_sink.h:98
CellIndex_t NRows
Definition: heat_sink.h:110
String_t Plugin
Definition: heat_sink.h:94
SolidVHC_t VolumetricHeatCapacity
Definition: material.h:80
SolidTC_t ThermalConductivity
Definition: material.h:87
double Capacity_t
Definition: types.h:119
double AmbientHTC_t
Definition: types.h:91
double Conductance_t
Definition: types.h:113
Error_t
Definition: types.h:401
@ TDICE_SUCCESS
The function returns with success.
Definition: types.h:402
@ TDICE_FAILURE
The function retuerns with a generic error.
Definition: types.h:403
double ChipDimension_t
Definition: types.h:187
double Temperature_t
Definition: types.h:71
uint32_t CellIndex_t
Definition: types.h:213
@ TDICE_HEATSINK_BOTTOM
Bottom heat sink (bottom-most layer)
Definition: types.h:227
@ TDICE_HEATSINK_TOP
Top heat sink (top-most layer)
Definition: types.h:226
@ TDICE_HEATSINK_NONE
Undefined type.
Definition: types.h:225
@ TDICE_HEATSINK_TOP_PLUGGABLE
Top pluggable heat sink.
Definition: types.h:228