3D-ICE 3.0.0
thermal_data.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 <stdio.h> // For the file type FILE
40
41#include "thermal_data.h"
42#include "macros.h"
43#include "connection_list.h"
44
45/******************************************************************************/
46
47static void init_data (double* data, uint32_t size, double init_value)
48{
49 while (size--) *data++ = init_value ;
50}
51
52/******************************************************************************/
53
55{
56 tdata->Size = (CellIndex_t) 0u ;
57
58 tdata->Temperatures = NULL ;
59
61 power_grid_init (&tdata->PowerGrid) ;
62 system_matrix_init (&tdata->SM_A) ;
63
64 tdata->SLUMatrix_B.Store = NULL ;
65}
66
67/******************************************************************************/
68// update the numver of cells in non-uniform grid scenario
69void update_number_of_cells (Dimensions_t *dimensions, StackElementList_t *stack_elements_list)
70{
71 CellIndex_t cell_num_non_uniform = 0;
72 CellIndex_t cell_num_die;
73 CellIndex_t discr_x_element = 0;
74 CellIndex_t discr_y_element = 0;
75 // enumerate all the stack elements (dies)
76 StackElementListNode_t *stkeln ;
77 for (stkeln = stack_elements_list->First ;
78 stkeln != NULL ;
79 stkeln = stkeln->Next)
80 {
81 StackElement_t *stkel = &stkeln->Data ;
82 switch (stkel->SEType)
83 {
85 {
86 CellIndex_t discr_x_die = stkel->Pointer.Die->Discr_X;
87 CellIndex_t discr_y_die = stkel->Pointer.Die->Discr_Y;
88
89 // enumerate all the floorplan elements
90 FloorplanElementListNode_t *ele_flp ;
91 cell_num_die = 0;
92 for (ele_flp = stkel->Pointer.Die->Floorplan.ElementsList.First ;
93 ele_flp != NULL ;
94 ele_flp = ele_flp->Next)
95 {
96 FloorplanElement_t *ele_flpi = &ele_flp->Data ;
97 discr_x_element = ele_flpi->ICElements.First->Data.Discr_X;
98 discr_y_element = ele_flpi->ICElements.First->Data.Discr_Y;
99 if (discr_x_element != 0 && discr_y_element != 0)
100 {
101 cell_num_die += discr_x_element*discr_y_element;
102 }
103 else
104 {
105 cell_num_die += discr_x_die*discr_y_die;
106 ele_flpi->ICElements.First->Data.Discr_X = discr_x_die;
107 ele_flpi->ICElements.First->Data.Discr_Y = discr_y_die;
108 }
109 }
110 cell_num_die = cell_num_die*stkel->NLayers;
111 cell_num_non_uniform += cell_num_die;
112 break ;
113 }
115 {
116 CellIndex_t discr_x = stkel->Pointer.Layer->Discr_X;
117 CellIndex_t discr_y = stkel->Pointer.Layer->Discr_Y;
118 cell_num_non_uniform += discr_x*discr_y;
119 break ;
120 }
122 {
123 cell_num_non_uniform += stkel->NLayers * dimensions->Grid.NRows * dimensions->Grid.NColumns;
124 break ;
125 }
127 {
128 fprintf (stderr, "Unsupported stack element type\n") ;
129 break ;
130 }
131 default :
132 {
133 fprintf (stderr, "Unsupported stack element type\n") ;
134 break ;
135 }
136 }
137 // if(stkel->SEType!=TDICE_STACK_ELEMENT_DIE)
138 // {
139 // continue;
140 // }
141
142 // Total cell number in all the layers the die has
143 }
144
145 if(stack_elements_list->First->Data.TopSink->SinkModel == TDICE_HEATSINK_TOP_PLUGGABLE)
146 {
147 cell_num_non_uniform += dimensions->Grid.NRows * dimensions->Grid.NColumns;
148 }
149 dimensions->Grid.NCells = cell_num_non_uniform;
150}
151
152/******************************************************************************/
153// get cell position for each cell and save info to arrays position_info and layer_cell_record
154void get_cell_position(ChipDimension_t (*position_info)[4], CellIndex_t *layer_cell_record, CellIndex_t *layer_type_record, StackElementList_t *stack_elements_list, Dimensions_t* dimensions)
155{
156 CellIndex_t current_layer = 0;
157 CellIndex_t cell_num_non_uniform = 0;
158 CellIndex_t cell_num_layer;
159 // enumerate all the stack elements (dies)
160 StackElementListNode_t *stkeln ;
161 for (stkeln = stack_elements_list->Last ;
162 stkeln != NULL ;
163 stkeln = stkeln->Prev)
164 {
165 StackElement_t *stkel = &stkeln->Data ;
166 // Darong_TODO: support more layer types
167 // default discretization level for the die
168 switch (stkel->SEType)
169 {
171 {
172 CellIndex_t discr_x_element = 0;
173 CellIndex_t discr_y_element = 0;
174 CellIndex_t discr_x_die = stkel->Pointer.Die->Discr_X;
175 CellIndex_t discr_y_die = stkel->Pointer.Die->Discr_Y;
176 // enumerate all the layers in the die
177 CellIndex_t total_layer_number_die = stkel->Pointer.Die->NLayers;
178 for (CellIndex_t layer_index = 0; layer_index< total_layer_number_die; layer_index++)
179 {
180 // enumerate all the floorplan elements
181 FloorplanElementListNode_t *ele_flp ;
182 for (ele_flp = stkel->Pointer.Die->Floorplan.ElementsList.First ;
183 ele_flp != NULL ;
184 ele_flp = ele_flp->Next)
185 {
186 FloorplanElement_t *ele_flpi = &ele_flp->Data ;
187 discr_x_element = ele_flpi->ICElements.First->Data.Discr_X;
188 discr_y_element = ele_flpi->ICElements.First->Data.Discr_Y;
189 // take default discretization level if the floorplan unit does not define the disretization level
190 if (discr_x_element == 0 || discr_y_element == 0)
191 {
192 discr_x_element = discr_x_die;
193 discr_y_element = discr_y_die;
194 }
195 cell_num_layer = discr_x_element*discr_y_element;
196
197 // fill position info
198 // generate the thermal grid first from left to right (x->), bottom to up (y->) for each floorplan element
199 ChipDimension_t ori_element_x = ele_flpi->ICElements.First->Data.SW_X;
200 ChipDimension_t ori_element_y = ele_flpi->ICElements.First->Data.SW_Y;
201 ChipDimension_t ori_element_length = ele_flpi->ICElements.First->Data.Length;
202 ChipDimension_t ori_element_width = ele_flpi->ICElements.First->Data.Width;
203 CellIndex_t position_info_index;
204 CellIndex_t discr_x_position;
205 CellIndex_t discr_y_position;
206 for (CellIndex_t sub_element = 0; sub_element < cell_num_layer; sub_element++)
207 {
208 position_info_index = sub_element+cell_num_non_uniform;
209 discr_x_position = sub_element % discr_x_element;
210 discr_y_position = sub_element / discr_x_element;
211 // left corner coordinate (left_x, left_y)
212 position_info[position_info_index][0] = ori_element_x + (ori_element_length/discr_x_element)*discr_x_position;
213 position_info[position_info_index][1] = ori_element_y + (ori_element_width/discr_y_element)*discr_y_position;
214 // right corner coordinate (right_x, right_y)
215 position_info[position_info_index][2] = ori_element_x + (ori_element_length/discr_x_element)*(discr_x_position + 1);
216 position_info[position_info_index][3] = ori_element_y + (ori_element_width/discr_y_element)*(discr_y_position + 1);
217 Non_uniform_cell_t new_cell;
218 non_uniform_cell_init(&new_cell);
219 new_cell.layer_info = current_layer;
220 new_cell.left_x = position_info[position_info_index][0] ;
221 new_cell.left_y = position_info[position_info_index][1] ;
222 new_cell.length = position_info[position_info_index][2] - position_info[position_info_index][0];
223 new_cell.width = position_info[position_info_index][3] - position_info[position_info_index][1];
224 non_uniform_cell_list_insert_end(&dimensions->Cell_list, &new_cell);
225 }
226
227 cell_num_non_uniform += cell_num_layer;
228
229 // In the non-uniform scenario, record start and end index of the element in thermal cells
230 if (layer_index == stkel->Pointer.Die->SourceLayerOffset)
231 {
232 ele_flpi->ICElements.First->Data.Index_start = cell_num_non_uniform-cell_num_layer;
233 ele_flpi->ICElements.First->Data.Index_end = cell_num_non_uniform-1;
234 }
235 }
236 // record the end index of cell number in the layer
237 layer_cell_record[current_layer] = cell_num_non_uniform;
238 layer_type_record[current_layer] = 0;
239 current_layer++;
240 }
241
242 break ;
243 }
245 {
246 CellIndex_t discr_x = stkel->Pointer.Layer->Discr_X;
247 CellIndex_t discr_y = stkel->Pointer.Layer->Discr_Y;
248 cell_num_layer = discr_x*discr_y;
249
250 CellIndex_t position_info_index;
251 CellIndex_t discr_x_position;
252 CellIndex_t discr_y_position;
253 ChipDimension_t ori_element_x = 0.0;
254 ChipDimension_t ori_element_y = 0.0;
255 ChipDimension_t ori_element_length = dimensions->Chip.Length;
256 ChipDimension_t ori_element_width = dimensions->Chip.Width;
257 for (CellIndex_t sub_element = 0; sub_element < cell_num_layer; sub_element++)
258 {
259 position_info_index = sub_element+cell_num_non_uniform;
260 discr_x_position = sub_element % discr_x;
261 discr_y_position = sub_element / discr_x;
262 // left corner coordinate (left_x, left_y)
263 position_info[position_info_index][0] = ori_element_x + (ori_element_length/discr_x)*discr_x_position;
264 position_info[position_info_index][1] = ori_element_y + (ori_element_width/discr_y)*discr_y_position;
265 // right corner coordinate (right_x, right_y)
266 position_info[position_info_index][2] = ori_element_x + (ori_element_length/discr_x)*(discr_x_position + 1);
267 position_info[position_info_index][3] = ori_element_y + (ori_element_width/discr_y)*(discr_y_position + 1);
268 Non_uniform_cell_t new_cell;
269 non_uniform_cell_init(&new_cell);
270 new_cell.layer_info = current_layer;
271 new_cell.left_x = position_info[position_info_index][0] ;
272 new_cell.left_y = position_info[position_info_index][1] ;
273 new_cell.length = position_info[position_info_index][2] - position_info[position_info_index][0];
274 new_cell.width = position_info[position_info_index][3] - position_info[position_info_index][1];
275 non_uniform_cell_list_insert_end(&dimensions->Cell_list, &new_cell);
276 }
277
278 cell_num_non_uniform += cell_num_layer;
279 layer_cell_record[current_layer] = cell_num_non_uniform;
280 layer_type_record[current_layer] = 0;
281 current_layer++;
282 break ;
283 }
285 {
287 {
288 CellIndex_t discr_x = dimensions->Grid.NColumns;
289 CellIndex_t discr_y = dimensions->Grid.NRows;
290 cell_num_layer = discr_x*discr_y;
291
292 CellIndex_t isChannel = 0;
293 CellIndex_t position_info_index;
294 CellIndex_t discr_x_position;
295 CellIndex_t discr_y_position;
296 // ChipDimension_t ori_element_x = 0.0;
297 ChipDimension_t ori_element_y = 0.0;
298 // ChipDimension_t ori_element_length = dimensions->Chip.Length;
299 ChipDimension_t ori_element_width = dimensions->Chip.Width;
300 for (CellIndex_t layer_i = 0; layer_i < stkel->Pointer.Channel->NLayers; layer_i++)
301 {
302 if (layer_i == 2)
303 isChannel = 1;
304 else
305 isChannel = 0;
306
307 for (CellIndex_t sub_element = 0; sub_element < cell_num_layer; sub_element++)
308 {
309
310 position_info_index = sub_element+cell_num_non_uniform;
311 discr_x_position = sub_element % discr_x;
312 discr_y_position = sub_element / discr_x;
313 if (discr_x_position == 0) //first column (wall)
314 {
315 // left corner coordinate (left_x, left_y)
316 position_info[position_info_index][0] = 0.0;
317 position_info[position_info_index][1] = ori_element_y + (ori_element_width/discr_y)*discr_y_position;
318 // right corner coordinate (right_x, right_y)
319 position_info[position_info_index][2] = dimensions->Cell.FirstWallLength;
320 position_info[position_info_index][3] = ori_element_y + (ori_element_width/discr_y)*(discr_y_position + 1);
321 }
322 else if (discr_x_position == discr_x-1) //last column (wall)
323 {
324 // left corner coordinate (left_x, left_y)
325 position_info[position_info_index][0] = dimensions->Chip.Length - dimensions->Cell.LastWallLength;
326 position_info[position_info_index][1] = ori_element_y + (ori_element_width/discr_y)*discr_y_position;
327 // right corner coordinate (right_x, right_y)
328 position_info[position_info_index][2] = dimensions->Chip.Length;
329 position_info[position_info_index][3] = ori_element_y + (ori_element_width/discr_y)*(discr_y_position + 1);
330 }
331 else
332 {
333 if (discr_x_position % 2 != 0) //channel position
334 {
335 // left corner coordinate (left_x, left_y)
336 CellIndex_t index_channel = (discr_x_position-1)/2;
337 position_info[position_info_index][0] = dimensions->Cell.FirstWallLength + index_channel*(dimensions->Cell.WallLength+dimensions->Cell.ChannelLength);
338 position_info[position_info_index][1] = ori_element_y + (ori_element_width/discr_y)*discr_y_position;
339 // right corner coordinate (right_x, right_y)
340 position_info[position_info_index][2] = position_info[position_info_index][0] + dimensions->Cell.ChannelLength;;
341 position_info[position_info_index][3] = ori_element_y + (ori_element_width/discr_y)*(discr_y_position + 1);
342
343 }
344 else //wall
345 {
346 // left corner coordinate (left_x, left_y)
347 CellIndex_t index_wall = (discr_x_position-2)/2;
348 position_info[position_info_index][0] = (dimensions->Cell.FirstWallLength + dimensions->Cell.ChannelLength) + index_wall*(dimensions->Cell.WallLength+dimensions->Cell.ChannelLength);
349 position_info[position_info_index][1] = ori_element_y + (ori_element_width/discr_y)*discr_y_position;
350 // right corner coordinate (right_x, right_y)
351 position_info[position_info_index][2] = position_info[position_info_index][0] + dimensions->Cell.WallLength;
352 position_info[position_info_index][3] = ori_element_y + (ori_element_width/discr_y)*(discr_y_position + 1);
353 }
354
355 }
356
357 Non_uniform_cell_t new_cell;
358 non_uniform_cell_init(&new_cell);
359 new_cell.layer_info = current_layer;
360 new_cell.left_x = position_info[position_info_index][0] ;
361 new_cell.left_y = position_info[position_info_index][1] ;
362 new_cell.length = position_info[position_info_index][2] - position_info[position_info_index][0];
363 new_cell.width = position_info[position_info_index][3] - position_info[position_info_index][1];
364 if (isChannel)
365 new_cell.isChannel = 1;
366 non_uniform_cell_list_insert_end(&dimensions->Cell_list, &new_cell);
367 }
368
369 cell_num_non_uniform += cell_num_layer;
370 layer_cell_record[current_layer] = cell_num_non_uniform;
371 if (layer_i == 0 || layer_i == 3)
372 layer_type_record[current_layer] = 1;
373 else
374 layer_type_record[current_layer] = 2;
375 current_layer++;
376 }
377
378 break ;
379 }
381 {
382 CellIndex_t discr_x = dimensions->Grid.NColumns;
383 CellIndex_t discr_y = dimensions->Grid.NRows;
384 cell_num_layer = discr_x*discr_y;
385
386 CellIndex_t isChannel = 0;
387 CellIndex_t position_info_index;
388 CellIndex_t discr_x_position;
389 CellIndex_t discr_y_position;
390 // ChipDimension_t ori_element_x = 0.0;
391 ChipDimension_t ori_element_y = 0.0;
392 // ChipDimension_t ori_element_length = dimensions->Chip.Length;
393 ChipDimension_t ori_element_width = dimensions->Chip.Width;
394 for (CellIndex_t layer_i = 0; layer_i < stkel->Pointer.Channel->NLayers; layer_i++)
395 {
396 if (layer_i == 2)
397 isChannel = 1;
398 else
399 isChannel = 0;
400
401 for (CellIndex_t sub_element = 0; sub_element < cell_num_layer; sub_element++)
402 {
403
404 position_info_index = sub_element+cell_num_non_uniform;
405 discr_x_position = sub_element % discr_x;
406 discr_y_position = sub_element / discr_x;
407 if (discr_x_position == 0) //first column (wall)
408 {
409 // left corner coordinate (left_x, left_y)
410 position_info[position_info_index][0] = 0.0;
411 position_info[position_info_index][1] = ori_element_y + (ori_element_width/discr_y)*discr_y_position;
412 // right corner coordinate (right_x, right_y)
413 position_info[position_info_index][2] = dimensions->Cell.FirstWallLength;
414 position_info[position_info_index][3] = ori_element_y + (ori_element_width/discr_y)*(discr_y_position + 1);
415 }
416 else if (discr_x_position == discr_x-1) //last column (wall)
417 {
418 // left corner coordinate (left_x, left_y)
419 position_info[position_info_index][0] = dimensions->Chip.Length - dimensions->Cell.LastWallLength;
420 position_info[position_info_index][1] = ori_element_y + (ori_element_width/discr_y)*discr_y_position;
421 // right corner coordinate (right_x, right_y)
422 position_info[position_info_index][2] = dimensions->Chip.Length;
423 position_info[position_info_index][3] = ori_element_y + (ori_element_width/discr_y)*(discr_y_position + 1);
424 }
425 else
426 {
427 if (discr_x_position % 2 != 0) //channel position
428 {
429 // left corner coordinate (left_x, left_y)
430 CellIndex_t index_channel = (discr_x_position-1)/2;
431 position_info[position_info_index][0] = dimensions->Cell.FirstWallLength + index_channel*(dimensions->Cell.WallLength+dimensions->Cell.ChannelLength);
432 position_info[position_info_index][1] = ori_element_y + (ori_element_width/discr_y)*discr_y_position;
433 // right corner coordinate (right_x, right_y)
434 position_info[position_info_index][2] = position_info[position_info_index][0] + dimensions->Cell.ChannelLength;;
435 position_info[position_info_index][3] = ori_element_y + (ori_element_width/discr_y)*(discr_y_position + 1);
436
437 }
438 else //wall
439 {
440 // left corner coordinate (left_x, left_y)
441 CellIndex_t index_wall = (discr_x_position-2)/2;
442 position_info[position_info_index][0] = (dimensions->Cell.FirstWallLength + dimensions->Cell.ChannelLength) + index_wall*(dimensions->Cell.WallLength+dimensions->Cell.ChannelLength);
443 position_info[position_info_index][1] = ori_element_y + (ori_element_width/discr_y)*discr_y_position;
444 // right corner coordinate (right_x, right_y)
445 position_info[position_info_index][2] = position_info[position_info_index][0] + dimensions->Cell.WallLength;
446 position_info[position_info_index][3] = ori_element_y + (ori_element_width/discr_y)*(discr_y_position + 1);
447 }
448
449 }
450
451 Non_uniform_cell_t new_cell;
452 non_uniform_cell_init(&new_cell);
453 new_cell.layer_info = current_layer;
454 new_cell.left_x = position_info[position_info_index][0] ;
455 new_cell.left_y = position_info[position_info_index][1] ;
456 new_cell.length = position_info[position_info_index][2] - position_info[position_info_index][0];
457 new_cell.width = position_info[position_info_index][3] - position_info[position_info_index][1];
458 if (isChannel)
459 new_cell.isChannel = 1;
460 non_uniform_cell_list_insert_end(&dimensions->Cell_list, &new_cell);
461 }
462
463 cell_num_non_uniform += cell_num_layer;
464 layer_cell_record[current_layer] = cell_num_non_uniform;
465 if (layer_i == 0 || layer_i == 3)
466 {
467 layer_type_record[current_layer] = 1;
468 }
469 else if (layer_i == 1)
470 {
471 layer_type_record[current_layer] = 3;
472 }
473 else
474 {
475 layer_type_record[current_layer] = 2;
476 }
477 current_layer++;
478 }
479
480 break ;
481 }
482 else
483 {
484 CellIndex_t discr_x = dimensions->Grid.NColumns;
485 CellIndex_t discr_y = dimensions->Grid.NRows;
486 cell_num_layer = discr_x*discr_y;
487
488 CellIndex_t isChannel = 0;
489 CellIndex_t position_info_index;
490 CellIndex_t discr_x_position;
491 CellIndex_t discr_y_position;
492 // ChipDimension_t ori_element_x = 0.0;
493 ChipDimension_t ori_element_y = 0.0;
494 // ChipDimension_t ori_element_length = dimensions->Chip.Length;
495 ChipDimension_t ori_element_width = dimensions->Chip.Width;
496 for (CellIndex_t sub_element = 0; sub_element < cell_num_layer; sub_element++)
497 {
498 position_info_index = sub_element+cell_num_non_uniform;
499 discr_x_position = sub_element % discr_x;
500 discr_y_position = sub_element / discr_x;
501 if (discr_x_position == 0) //first column (wall)
502 {
503 isChannel = 0; //first wall
504 // left corner coordinate (left_x, left_y)
505 position_info[position_info_index][0] = 0.0;
506 position_info[position_info_index][1] = ori_element_y + (ori_element_width/discr_y)*discr_y_position;
507 // right corner coordinate (right_x, right_y)
508 position_info[position_info_index][2] = dimensions->Cell.FirstWallLength;
509 position_info[position_info_index][3] = ori_element_y + (ori_element_width/discr_y)*(discr_y_position + 1);
510 }
511 else if (discr_x_position == discr_x-1) //last column (wall)
512 {
513 isChannel = 0; //last wall
514 // left corner coordinate (left_x, left_y)
515 position_info[position_info_index][0] = dimensions->Chip.Length - dimensions->Cell.LastWallLength;
516 position_info[position_info_index][1] = ori_element_y + (ori_element_width/discr_y)*discr_y_position;
517 // right corner coordinate (right_x, right_y)
518 position_info[position_info_index][2] = dimensions->Chip.Length;
519 position_info[position_info_index][3] = ori_element_y + (ori_element_width/discr_y)*(discr_y_position + 1);
520 }
521 else
522 {
523 if (discr_x_position % 2 != 0) //channel
524 {
525 isChannel = 1;
526 // left corner coordinate (left_x, left_y)
527 CellIndex_t index_channel = (discr_x_position-1)/2;
528 position_info[position_info_index][0] = dimensions->Cell.FirstWallLength + index_channel*(dimensions->Cell.WallLength+dimensions->Cell.ChannelLength);
529 position_info[position_info_index][1] = ori_element_y + (ori_element_width/discr_y)*discr_y_position;
530 // right corner coordinate (right_x, right_y)
531 position_info[position_info_index][2] = position_info[position_info_index][0] + dimensions->Cell.ChannelLength;;
532 position_info[position_info_index][3] = ori_element_y + (ori_element_width/discr_y)*(discr_y_position + 1);
533
534 }
535 else //wall
536 {
537 isChannel = 0;
538 // left corner coordinate (left_x, left_y)
539 CellIndex_t index_wall = (discr_x_position-2)/2;
540 position_info[position_info_index][0] = (dimensions->Cell.FirstWallLength + dimensions->Cell.ChannelLength) + index_wall*(dimensions->Cell.WallLength+dimensions->Cell.ChannelLength);
541 position_info[position_info_index][1] = ori_element_y + (ori_element_width/discr_y)*discr_y_position;
542 // right corner coordinate (right_x, right_y)
543 position_info[position_info_index][2] = position_info[position_info_index][0] + dimensions->Cell.WallLength;
544 position_info[position_info_index][3] = ori_element_y + (ori_element_width/discr_y)*(discr_y_position + 1);
545 }
546
547 }
548
549 Non_uniform_cell_t new_cell;
550 non_uniform_cell_init(&new_cell);
551 new_cell.layer_info = current_layer;
552 new_cell.left_x = position_info[position_info_index][0] ;
553 new_cell.left_y = position_info[position_info_index][1] ;
554 new_cell.length = position_info[position_info_index][2] - position_info[position_info_index][0];
555 new_cell.width = position_info[position_info_index][3] - position_info[position_info_index][1];
556 if (isChannel)
557 new_cell.isChannel = 1;
558 non_uniform_cell_list_insert_end(&dimensions->Cell_list, &new_cell);
559 }
560
561 cell_num_non_uniform += cell_num_layer;
562 layer_cell_record[current_layer] = cell_num_non_uniform;
563 layer_type_record[current_layer] = 0;
564 current_layer++;
565 break ;
566 }
567
568 }
570 {
571 fprintf (stderr, "Unsupported stack element type\n") ;
572 break ;
573 }
574 default :
575 {
576 fprintf (stderr, "Unsupported stack element type\n") ;
577 break ;
578 }
579 }
580 // if(stkel->SEType!=TDICE_STACK_ELEMENT_DIE)
581 // {
582 // continue;
583 // }
584 }
585 if(stack_elements_list->First->Data.TopSink->SinkModel == TDICE_HEATSINK_TOP_PLUGGABLE)
586 {
587 CellIndex_t discr_x = dimensions->Grid.NColumns;
588 CellIndex_t discr_y = dimensions->Grid.NRows;
589 cell_num_layer = discr_x*discr_y;
590
591 CellIndex_t position_info_index;
592 CellIndex_t discr_x_position;
593 CellIndex_t discr_y_position;
594 ChipDimension_t ori_element_x = 0.0;
595 ChipDimension_t ori_element_y = 0.0;
596 ChipDimension_t ori_element_length = dimensions->Chip.Length;
597 ChipDimension_t ori_element_width = dimensions->Chip.Width;
598 for (CellIndex_t sub_element = 0; sub_element < cell_num_layer; sub_element++)
599 {
600 position_info_index = sub_element+cell_num_non_uniform;
601 discr_x_position = sub_element % discr_x;
602 discr_y_position = sub_element / discr_x;
603 // left corner coordinate (left_x, left_y)
604 position_info[position_info_index][0] = ori_element_x + (ori_element_length/discr_x)*discr_x_position;
605 position_info[position_info_index][1] = ori_element_y + (ori_element_width/discr_y)*discr_y_position;
606 // right corner coordinate (right_x, right_y)
607 position_info[position_info_index][2] = ori_element_x + (ori_element_length/discr_x)*(discr_x_position + 1);
608 position_info[position_info_index][3] = ori_element_y + (ori_element_width/discr_y)*(discr_y_position + 1);
609 Non_uniform_cell_t new_cell;
610 non_uniform_cell_init(&new_cell);
611 new_cell.layer_info = current_layer;
612 new_cell.left_x = position_info[position_info_index][0] ;
613 new_cell.left_y = position_info[position_info_index][1] ;
614 new_cell.length = position_info[position_info_index][2] - position_info[position_info_index][0];
615 new_cell.width = position_info[position_info_index][3] - position_info[position_info_index][1];
616 non_uniform_cell_list_insert_end(&dimensions->Cell_list, &new_cell);
617 }
618
619 cell_num_non_uniform += cell_num_layer;
620 layer_cell_record[current_layer] = cell_num_non_uniform;
621 layer_type_record[current_layer] = 4;
622 current_layer++;
623 }
624}
625
626
627/******************************************************************************/
628// Get the Minkowski difference between two cells
629void get_minkowski_difference(ChipDimension_t *minkowski_diff, ChipDimension_t (*position_info)[4], int i_x, int i_y)
630{
631 minkowski_diff[0] = position_info[i_x][0] - position_info[i_y][2];
632 minkowski_diff[1] = position_info[i_x][1] - position_info[i_y][3];
633 minkowski_diff[2] = position_info[i_x][2] - position_info[i_y][0];
634 minkowski_diff[3] = position_info[i_x][3] - position_info[i_y][1];
635}
636
637/******************************************************************************/
638// Get the overlap area between two cells
639ChipDimension_t get_overlap_area(ChipDimension_t *minkowski_diff, ChipDimension_t (*position_info_ptr)[4], int i_x, int i_y)
640{
641 ChipDimension_t length = (fabs(minkowski_diff[0]) <= fabs(minkowski_diff[2])) ? fabs(minkowski_diff[0]) : fabs(minkowski_diff[2]);
642 ChipDimension_t width = (fabs(minkowski_diff[1]) <= fabs(minkowski_diff[3])) ? fabs(minkowski_diff[1]) : fabs(minkowski_diff[3]);
643 ChipDimension_t node1_length = position_info_ptr[i_x][2]-position_info_ptr[i_x][0];
644 ChipDimension_t node1_width = position_info_ptr[i_x][3]-position_info_ptr[i_x][1];
645 ChipDimension_t node2_length = position_info_ptr[i_y][2]-position_info_ptr[i_y][0];
646 ChipDimension_t node2_width = position_info_ptr[i_y][3]-position_info_ptr[i_y][1];
647
648 ChipDimension_t node_length = (node1_length <= node2_length) ? node1_length : node2_length;
649 ChipDimension_t node_width = (node1_width <= node2_width) ? node1_width : node2_width;
650
651
652 length = (length <= node_length) ? length : node_length;
653 width = (width <= node_width) ? width : node_width;
654 return length*width;
655
656}
657
658/******************************************************************************/
659// get connections of each grid in the same layer
661(
662 CellIndex_t* layer_cell_record,
663 CellIndex_t* layer_type_record,
664 ChipDimension_t (*position_info_ptr)[4],
665 Dimensions_t* dimensions
666)
667{
668 ConnectionList_t* connections_list = &dimensions->connections_list;
669 CellIndex_t layer_start_index = 0;
670 ChipDimension_t minkowski_diff[4];
671 CellIndex_t layer_end_index;
672 CellIndex_t layer_type;
673 for (CellIndex_t layer_index = 0; layer_index < dimensions->Grid.NLayers+1; layer_index++)
674 {
675
676 layer_end_index = layer_cell_record[layer_index];
677 layer_type = layer_type_record[layer_index];
678 if(layer_index == dimensions->Grid.NLayers && layer_type != 4)
679 continue;
680
681 for (CellIndex_t i_x = layer_start_index; i_x < layer_end_index; i_x++)
682 {
683 for (CellIndex_t i_y = i_x+1; i_y < layer_end_index; i_y++)
684 {
685 // a simplified GJK algorithm to detect interconnect cells in a single layer
686 // first compute the Minkowski difference
687 get_minkowski_difference(minkowski_diff, position_info_ptr, i_x, i_y);
688 // if two rectangles interconnect with each other, Minkowski difference should contain the origin point (0, 0)
689 if (minkowski_diff[0] == 0 || minkowski_diff[1] == 0 || minkowski_diff[2] == 0 || minkowski_diff[3] == 0)
690 {
691 // furthermore, it should cross the origin point
692 if (minkowski_diff[0] * minkowski_diff[2] + minkowski_diff[1] * minkowski_diff[3] < 0)
693 {
694 Connection_t new_connection;
695 connection_init(&new_connection);
696 new_connection.node1 = i_x;
697 new_connection.node2 = i_y;
698 new_connection.node1_layer = layer_index;
699 new_connection.node2_layer = layer_index;
700 // Find the interconnect length
701 if (minkowski_diff[0] * minkowski_diff[2] == 0)
702 {
703 if (layer_type == 1 || layer_type == 2 || layer_type == 3)
704 continue;
705 new_connection.value = (fabs(minkowski_diff[1])<=fabs(minkowski_diff[3])) ? fabs(minkowski_diff[1]) : fabs(minkowski_diff[3]);
706 new_connection.direction = 1; //two nodes interconect in direction x
707 }
708 else if (minkowski_diff[1] * minkowski_diff[3] == 0)
709 {
710 if (layer_type == 1 || layer_type == 3)
711 continue;
712 new_connection.value = (fabs(minkowski_diff[0])<=fabs(minkowski_diff[2])) ? fabs(minkowski_diff[0]) : fabs(minkowski_diff[2]);
713 new_connection.direction = 2; //two nodes interconect in direction y
714 }
715 else
716 fprintf (stderr, "Cannot determine interconnect length\n") ;
717
718 // printf("Node%d in layer %d <-> Node%d in layer %d\n", new_connection.node1, new_connection.node1_layer, new_connection.node2, new_connection.node2_layer) ;
719 // printf("Direction %d, Value %f\n", new_connection.direction, new_connection.value) ;
720 // add the connection information to the connections variable
721 connection_list_insert_end(connections_list, &new_connection);
722
723 }
724 }
725 }
726 }
727 layer_start_index = layer_end_index;
728 }
729}
730
731/******************************************************************************/
732// get connections between layers (bottom->top)
734(
735 CellIndex_t* layer_cell_record,
736 CellIndex_t* layer_type_record,
737 ChipDimension_t (*position_info_ptr)[4],
738 Dimensions_t* dimensions
739)
740{
741 ConnectionList_t* connections_list = &dimensions->connections_list;
742 // First define the information between the bottom layer and its upper layer
743 CellIndex_t botom_layer_start_index = 0;
744 ChipDimension_t minkowski_diff[4];
745 CellIndex_t botom_layer_end_index;
746 CellIndex_t top_layer_start_index;
747 CellIndex_t top_layer_end_index;
748 CellIndex_t bottom_layer_type;
749 CellIndex_t top_layer_type;
750 // enumerate all the layers
751 for (CellIndex_t layer_index = 1; layer_index < dimensions->Grid.NLayers + 1; layer_index++)
752 {
753 bottom_layer_type = layer_type_record[layer_index-1];
754 top_layer_type = layer_type_record[layer_index];
755 if(layer_index == dimensions->Grid.NLayers && top_layer_type != 4)
756 continue;
757 if ( (bottom_layer_type == 2 && top_layer_type == 2) || (bottom_layer_type == 3 && top_layer_type == 2))
758 {
759 botom_layer_start_index = layer_cell_record[layer_index-3];
760 botom_layer_end_index = layer_cell_record[layer_index-2];
761 top_layer_start_index = layer_cell_record[layer_index-1];
762 top_layer_end_index = layer_cell_record[layer_index];
763
764 // enumerate all the elements in a bottom layer
765 for (CellIndex_t i_x = botom_layer_start_index; i_x < botom_layer_end_index; i_x++)
766 {
767 // enumerate all the elements in an upper layer
768 for (CellIndex_t i_y = top_layer_start_index; i_y < top_layer_end_index; i_y++)
769 {
770 // first compute Minkowski difference
771 get_minkowski_difference(minkowski_diff, position_info_ptr, i_x, i_y);
772 // Minkowski difference should contain the origin point (0, 0) if two cells have overlap area
773 if (minkowski_diff[0] * minkowski_diff[2] < 0 && minkowski_diff[1] * minkowski_diff[3] < 0)
774 {
775 // add the connection information to the connections variable
776 Connection_t new_connection;
777 connection_init(&new_connection);
778 new_connection.node1 = i_x;
779 new_connection.node2 = i_y;
780 new_connection.node1_layer = layer_index-1;
781 new_connection.node2_layer = layer_index;
782
783 // overlap area is the minum area
784 new_connection.value = get_overlap_area(minkowski_diff, position_info_ptr, i_x, i_y);
785
786 new_connection.direction = 0; //connect direction is Z(=0) for two nodes in different layers;
787 // printf("Node%d in layer %d <-> Node%d in layer %d\n", new_connection.node1, new_connection.node1_layer, new_connection.node2, new_connection.node2_layer) ;
788 // printf("Direction %d, Value %f\n", new_connection.direction, new_connection.value) ;
789 // add the connection information to the connections variable
790 connection_list_insert_end(connections_list, &new_connection);
791 }
792 }
793 }
794
795 botom_layer_start_index = layer_cell_record[layer_index-2];
796 botom_layer_end_index = layer_cell_record[layer_index-1];
797 top_layer_start_index = layer_cell_record[layer_index];
798 top_layer_end_index = layer_cell_record[layer_index+1];
799
800 // enumerate all the elements in a bottom layer
801 for (CellIndex_t i_x = botom_layer_start_index; i_x < botom_layer_end_index; i_x++)
802 {
803 // enumerate all the elements in an upper layer
804 for (CellIndex_t i_y = top_layer_start_index; i_y < top_layer_end_index; i_y++)
805 {
806 // first compute Minkowski difference
807 get_minkowski_difference(minkowski_diff, position_info_ptr, i_x, i_y);
808 // Minkowski difference should contain the origin point (0, 0) if two cells have overlap area
809 if (minkowski_diff[0] * minkowski_diff[2] < 0 && minkowski_diff[1] * minkowski_diff[3] < 0)
810 {
811 // add the connection information to the connections variable
812 Connection_t new_connection;
813 connection_init(&new_connection);
814 new_connection.node1 = i_x;
815 new_connection.node2 = i_y;
816 new_connection.node1_layer = layer_index-1;
817 new_connection.node2_layer = layer_index;
818
819 // overlap area is the minum area
820 new_connection.value = get_overlap_area(minkowski_diff, position_info_ptr, i_x, i_y);
821
822 new_connection.direction = 0; //connect direction is Z(=0) for two nodes in different layers;
823 // printf("Node%d in layer %d <-> Node%d in layer %d\n", new_connection.node1, new_connection.node1_layer, new_connection.node2, new_connection.node2_layer) ;
824 // printf("Direction %d, Value %f\n", new_connection.direction, new_connection.value) ;
825 // add the connection information to the connections variable
826 connection_list_insert_end(connections_list, &new_connection);
827 }
828 }
829 }
830 botom_layer_start_index = botom_layer_end_index;
831 }
832 else
833 {
834 botom_layer_end_index = layer_cell_record[layer_index-1];
835 top_layer_start_index = layer_cell_record[layer_index-1];
836 top_layer_end_index = layer_cell_record[layer_index];
837
838 // enumerate all the elements in a bottom layer
839 for (CellIndex_t i_x = botom_layer_start_index; i_x < botom_layer_end_index; i_x++)
840 {
841 // enumerate all the elements in an upper layer
842 for (CellIndex_t i_y = top_layer_start_index; i_y < top_layer_end_index; i_y++)
843 {
844 // first compute Minkowski difference
845 get_minkowski_difference(minkowski_diff, position_info_ptr, i_x, i_y);
846 // Minkowski difference should contain the origin point (0, 0) if two cells have overlap area
847 if (minkowski_diff[0] * minkowski_diff[2] < 0 && minkowski_diff[1] * minkowski_diff[3] < 0)
848 {
849 // add the connection information to the connections variable
850 Connection_t new_connection;
851 connection_init(&new_connection);
852 new_connection.node1 = i_x;
853 new_connection.node2 = i_y;
854 new_connection.node1_layer = layer_index-1;
855 new_connection.node2_layer = layer_index;
856
857 // overlap area is the minum area
858 new_connection.value = get_overlap_area(minkowski_diff, position_info_ptr, i_x, i_y);
859
860 new_connection.direction = 0; //connect direction is Z(=0) for two nodes in different layers;
861 // printf("Node%d in layer %d <-> Node%d in layer %d\n", new_connection.node1, new_connection.node1_layer, new_connection.node2, new_connection.node2_layer) ;
862 // printf("Direction %d, Value %f\n", new_connection.direction, new_connection.value) ;
863 // add the connection information to the connections variable
864 connection_list_insert_end(connections_list, &new_connection);
865 }
866 }
867 }
868 botom_layer_start_index = top_layer_start_index;
869 }
870
871 }
872}
873
874/******************************************************************************/
875
877(
878 ThermalData_t *tdata,
879 StackElementList_t *stack_elements_list,
880 Dimensions_t *dimensions,
881 Analysis_t *analysis
882)
883{
884 Error_t result ;
885
886 // re-evaluate the number of thermal grids
887 // update number of connections in non-uniform grid scenario
888 if (dimensions->NonUniform == 1)
889 {
890 update_number_of_cells (dimensions, stack_elements_list);
891
892 ChipDimension_t position_info[dimensions->Grid.NCells][4]; // position info contains "left_x, left_y, right_x, right_y" for each thermal cell
893 ChipDimension_t (*position_info_ptr)[4] = position_info;
894 CellIndex_t layer_cell_record[dimensions->Grid.NLayers+1]; // record the end index of each layer in the position_info
895 memset(layer_cell_record, 0, sizeof layer_cell_record);
896 // 0: caculate surroding
897 // 1: TDICE_LAYER_BOTTOM_WALL, TDICE_LAYER_TOP_WALL, : they don't have connections in x and y directions
898 // 2: TDICE_LAYER_VWALL_CHANNEL (2RM), TDICE_LAYER_CHANNEL_2RM: they don't have connections in the x direction
899 // 3: TDICE_LAYER_VWALL_CHANNEL (pin) : it doesn't have connections in x and y directions
900 // 4: spreader
901 CellIndex_t layer_type_record[dimensions->Grid.NLayers+1];
902 memset(layer_type_record, 0, sizeof layer_type_record);
903 // get cell position for each cell and sace info to arrays position_info and layer_cell_record
904 get_cell_position(position_info_ptr, layer_cell_record, layer_type_record, stack_elements_list, dimensions);
905
906 // // initalize connections variable to store connections info
907 // ConnectionList_t connections_list;
908 // connection_list_init(&connections_list);
909
910 // get connections of each grid in the same layer
911 // printf("\n Node1 Node2 Number \n");
912 get_connections_in_layer(layer_cell_record, layer_type_record, position_info_ptr, dimensions);
913 // get connections between layers (bottom->top)
914 get_connections_between_layer(layer_cell_record, layer_type_record, position_info_ptr, dimensions);
915 // update number of connections
916 dimensions->Grid.NConnections = 2*(dimensions->connections_list.Size)+dimensions->Grid.NCells;
917 }
918
919 tdata->Size = get_number_of_cells (dimensions) ;
920
921 /* Alloc and set temperatures */
922
923 tdata->Temperatures =
924
925 (Temperature_t*) malloc (sizeof(Temperature_t) * tdata->Size) ;
926
927 if (tdata->Temperatures == NULL)
928 {
929 fprintf (stderr, "Cannot malloc temperature array\n") ;
930
931 return TDICE_FAILURE ;
932 }
933
934 /* Set Temperatures to the initial thermal state and builds SLU vector B */
935
936 init_data (tdata->Temperatures, tdata->Size, analysis->InitialTemperature) ;
937
938 dCreate_Dense_Matrix /* Vector B */
939
940 (&tdata->SLUMatrix_B, tdata->Size, 1,
941 tdata->Temperatures, tdata->Size,
942 SLU_DN, SLU_D, SLU_GE) ;
943
944 /* Alloc and fill the thermal grid */
945
946 result = thermal_grid_build (&tdata->ThermalGrid, dimensions) ;
947
948 if (result == TDICE_FAILURE)
949 {
950 fprintf (stderr, "Cannot malloc thermal grid\n") ;
951
952 Destroy_SuperMatrix_Store (&tdata->SLUMatrix_B) ;
953
954 free (tdata->Temperatures) ;
955
956 return TDICE_FAILURE ;
957 }
958
959 result = thermal_grid_fill (&tdata->ThermalGrid, stack_elements_list) ;
960
961 if (result == TDICE_FAILURE)
962 {
963 Destroy_SuperMatrix_Store (&tdata->SLUMatrix_B) ;
964
965 free (tdata->Temperatures) ;
966
967 return TDICE_FAILURE ;
968 }
969
970 /* Alloc and fill the power grid */
971
972 result = power_grid_build (&tdata->PowerGrid, dimensions) ;
973
974 if (result == TDICE_FAILURE)
975 {
976 fprintf (stderr, "Cannot malloc power grid\n") ;
977
978 Destroy_SuperMatrix_Store (&tdata->SLUMatrix_B) ;
979
980 free (tdata->Temperatures) ;
981
983
984 return TDICE_FAILURE ;
985 }
986
988
989 (&tdata->PowerGrid, &tdata->ThermalGrid, stack_elements_list, dimensions) ;
990
991
992 /* Alloc and fill the system matrix and builds the SLU wrapper */
993 result = system_matrix_build
994
995 (&tdata->SM_A, tdata->Size, get_number_of_connections (dimensions)) ;
996
997 if (result == TDICE_FAILURE)
998 {
999 fprintf (stderr, "Cannot malloc syatem matrix\n") ;
1000
1001 Destroy_SuperMatrix_Store (&tdata->SLUMatrix_B) ;
1002
1003 free (tdata->Temperatures) ;
1004
1006 power_grid_destroy (&tdata->PowerGrid) ;
1007
1008 return TDICE_FAILURE ;
1009 }
1010
1012
1013 (&tdata->SM_A, &tdata->ThermalGrid, analysis, dimensions) ;
1014
1015 result = do_factorization (&tdata->SM_A) ;
1016
1017 if (result == TDICE_FAILURE)
1018 {
1019 thermal_data_destroy (tdata) ;
1020
1021 return TDICE_FAILURE ;
1022 }
1023
1024 return TDICE_SUCCESS ;
1025}
1026
1027/******************************************************************************/
1028
1030{
1031 free (tdata->Temperatures) ;
1032
1034 power_grid_destroy (&tdata->PowerGrid) ;
1035
1036 system_matrix_destroy (&tdata->SM_A) ;
1037
1038 Destroy_SuperMatrix_Store (&tdata->SLUMatrix_B) ;
1039
1040 thermal_data_init (tdata) ;
1041}
1042
1043/******************************************************************************/
1044
1046{
1047 init_data (tdata->Temperatures, tdata->Size, analysis->InitialTemperature) ;
1048}
1049
1050/******************************************************************************/
1051
1052static void fill_system_vector
1053(
1054 Dimensions_t *dimensions,
1055 HeatSink_t *topSink,
1056 double *vector,
1057 Source_t *sources,
1058 Capacity_t *capacities,
1059 Temperature_t *temperatures,
1060 Time_t step_time
1061)
1062{
1063#ifdef PRINT_SYSTEM_VECTOR
1064 Temperature_t old ;
1065#endif
1066 if (dimensions->NonUniform == 1)
1067 {
1068 for (CellIndex_t i = 0; i<dimensions->Cell_list.Size; i++)
1069 *vector++ = *sources++
1070 + (*capacities++ / step_time)
1071 * *temperatures++ ;
1072 }
1073 else
1074 {
1075 CellIndex_t layer ;
1076 CellIndex_t row ;
1077 CellIndex_t column ;
1078
1079 for (layer = first_layer (dimensions) ; layer <= last_layer (dimensions) ; layer++)
1080 {
1081 for (row = first_row (dimensions) ; row <= last_row (dimensions) ; row++)
1082 {
1083 for (column = first_column (dimensions) ; column <= last_column (dimensions) ; column++)
1084 {
1085
1086 #ifdef PRINT_SYSTEM_VECTOR
1087 old = *temperatures ;
1088 #endif
1089
1090 *vector++ = *sources++
1091 + (*capacities++ / step_time)
1092 * *temperatures++ ;
1093
1094 #ifdef PRINT_SYSTEM_VECTOR
1095 fprintf (stderr,
1096 " l %2d r %4d c %4d [%7d] | %e [b] = %e [s] + %e [c] * %e [t]\n",
1097 layer, row, column,
1098 get_cell_offset_in_stack (dimensions, layer, row, column),
1099 *(vector-1), *(sources-1), *(capacities-1), old) ;
1100 #endif
1101
1102 } // FOR_EVERY_COLUMN
1103 } // FOR_EVERY_ROW
1104 } // FOR_EVERY_LAYER
1105
1106 // Copy the rest of the vector
1107 if(topSink && topSink->SinkModel == TDICE_HEATSINK_TOP_PLUGGABLE)
1108 {
1109 for(row = 0; row < topSink->NRows; row++)
1110 {
1111 for(column = 0; column < topSink->NColumns; column++)
1112 {
1113 #ifdef PRINT_SYSTEM_VECTOR
1114 old = *temperatures ;
1115 #endif
1116
1117 *vector++ = *sources++
1118 + (*capacities++ / step_time)
1119 * *temperatures++ ;
1120
1121 #ifdef PRINT_SYSTEM_VECTOR
1122 fprintf (stderr,
1123 " r %4d c %4d [%7d] | %e [b] = %e [s] + %e [c] * %e [t]\n",
1124 row, column,
1125 get_spreader_cell_offset (dimensions, topSink, row, column),
1126 *(vector-1), *(sources-1), *(capacities-1), old) ;
1127 #endif
1128 }
1129 }
1130 }
1131 }
1132}
1133
1134/******************************************************************************/
1135
1136static void fill_system_vector_steady
1137(
1138 Dimensions_t *dimensions,
1139 double *vector,
1140 Source_t *sources
1141)
1142{
1143 CellIndex_t layer ;
1144 CellIndex_t row ;
1145 CellIndex_t column ;
1146
1147 if (dimensions->NonUniform == 1)
1148 {
1149 for (CellIndex_t i = 0; i<dimensions->Cell_list.Size; i++)
1150 *vector++ = *sources++ ;
1151 }
1152 else
1153 {
1154 for (layer = first_layer (dimensions) ; layer <= last_layer (dimensions) ; layer++)
1155 {
1156 for (row = first_row (dimensions) ; row <= last_row (dimensions) ; row++)
1157 {
1158 for (column = first_column (dimensions) ; column <= last_column (dimensions) ; column++)
1159 {
1160 *vector++ = *sources++ ;
1161
1162 #ifdef PRINT_SYSTEM_VECTOR
1163 fprintf (stderr,
1164 " l %2d r %4d c %4d [%7d] | %e [b] = %e [s]\n",
1165 layer, row, column,
1166 get_cell_offset_in_stack (dimensions, layer, row, column),
1167 *(vector-1), *(sources-1)) ;
1168 #endif
1169
1170 } // FOR_EVERY_COLUMN
1171 } // FOR_EVERY_ROW
1172 } // FOR_EVERY_LAYER
1173 }
1174
1175}
1176
1177Error_t pluggable_heatsink(ThermalData_t *tdata, Dimensions_t *dimensions)
1178{
1179 // We have something to do only if we're using the pluggable heatsink model
1180 HeatSink_t *sink = tdata->ThermalGrid.TopHeatSink;
1181 if(sink == NULL || sink->SinkModel != TDICE_HEATSINK_TOP_PLUGGABLE)
1182 return TDICE_SUCCESS;
1183
1184 //Get a pointer to the spreader temperatures
1185 double *SpreaderTemperatures = tdata->Temperatures;
1186 SpreaderTemperatures += get_spreader_cell_offset(dimensions,sink,0,0);
1187
1188 Source_t *sources = tdata->PowerGrid.Sources;
1189 sources += get_spreader_cell_offset(dimensions,sink,0,0);
1190
1191 // Call the pluggable heat sink function to compute the heat flows to
1192 // the heatsink
1193 if(sink->PluggableHeatsink(SpreaderTemperatures,sources))
1194 {
1195 fprintf(stderr, "Error: pluggable heatsink callback failed\n");
1196 return TDICE_FAILURE;
1197 }
1198
1199 // Both 3D-ICE and plugin use passive sign convention
1200 unsigned int size = sink->NColumns * sink->NRows;
1201 unsigned int i;
1202 for(i = 0; i < size; i++)
1203 sources[i] = - sources[i];
1204
1205 return TDICE_SUCCESS;
1206}
1207
1208/******************************************************************************/
1209
1211(
1212 ThermalData_t *tdata,
1213 Dimensions_t *dimensions,
1214 Analysis_t *analysis
1215)
1216{
1218
1219 return TDICE_WRONG_CONFIG ;
1220
1221 if (slot_completed (analysis) == true)
1222 {
1223 Error_t result = update_source_vector (&tdata->PowerGrid, dimensions) ;
1224 #ifdef PRINT_DEBUG_INFO
1225 printf("sources info:\n");
1226 for(CellIndex_t i = 0; i < dimensions->Grid.NCells; i++)
1227 printf("%d:\t%f\n", i, *(tdata->PowerGrid.Sources+i));
1228 #endif
1229
1230 if (result == TDICE_FAILURE)
1231
1233 }
1234
1235 if(pluggable_heatsink(tdata, dimensions) == TDICE_FAILURE)
1236 return TDICE_SOLVER_ERROR ;
1237
1238 fill_system_vector
1239
1240 (dimensions, tdata->ThermalGrid.TopHeatSink, tdata->Temperatures, tdata->PowerGrid.Sources,
1241 tdata->PowerGrid.CellsCapacities, tdata->Temperatures, analysis->StepTime) ;
1242
1243 Error_t res = solve_sparse_linear_system (&tdata->SM_A, &tdata->SLUMatrix_B) ;
1244
1245 if (res != TDICE_SUCCESS)
1246
1247 return TDICE_SOLVER_ERROR ;
1248
1249 increase_by_step_time (analysis) ;
1250
1251 if (slot_completed (analysis) == false)
1252
1253 return TDICE_STEP_DONE ;
1254
1255 else
1256
1257 return TDICE_SLOT_DONE ;
1258}
1259
1260/******************************************************************************/
1261
1263(
1264 ThermalData_t *tdata,
1265 Dimensions_t *dimensions,
1266 Analysis_t *analysis
1267)
1268{
1269 SimResult_t result ;
1270
1271 do
1272 {
1273
1274 result = emulate_step (tdata, dimensions, analysis) ;
1275
1276 } while (result == TDICE_STEP_DONE) ;
1277
1278 return result ;
1279}
1280
1281/******************************************************************************/
1282
1284(
1285 ThermalData_t *tdata,
1286 Dimensions_t *dimensions,
1287 Analysis_t *analysis
1288)
1289{
1291
1292 return TDICE_WRONG_CONFIG ;
1293
1294 if(tdata->ThermalGrid.TopHeatSink &&
1296
1297 return TDICE_SOLVER_ERROR ; //TODO: support steady state pluggable sink
1298
1299 Error_t result = update_source_vector (&tdata->PowerGrid, dimensions) ;
1300 #ifdef PRINT_DEBUG_INFO
1301 printf("sources info:\n");
1302 for(CellIndex_t i = 0; i < dimensions->Grid.NCells; i++)
1303 printf("%d:\t%f\n", i, *(tdata->PowerGrid.Sources+i));
1304 #endif
1305 if (result == TDICE_FAILURE)
1306 {
1307 fprintf (stderr,
1308
1309 "Warning: no power trace given for steady state simulation\n") ;
1310
1312 }
1313
1314 fill_system_vector_steady (dimensions, tdata->Temperatures, tdata->PowerGrid.Sources) ;
1315
1316 // printf("system matrix info:\n");
1317 // for(CellIndex_t i = 0; i < dimensions->Grid.NConnections; i++)
1318 // printf("%d:\t%f\n", i, *(tdata->SM_A.Values+i));
1319
1320 Error_t res = solve_sparse_linear_system (&tdata->SM_A, &tdata->SLUMatrix_B) ;
1321
1322 if (res != TDICE_SUCCESS)
1323
1324 return TDICE_SOLVER_ERROR ;
1325
1327}
1328
1329/******************************************************************************/
1330
1332(
1333 ThermalData_t *tdata,
1334 Dimensions_t *dimensions,
1335 Analysis_t *analysis,
1336 CoolantFR_t new_flow_rate
1337)
1338{
1340
1341 FLOW_RATE_FROM_MLMIN_TO_UM3SEC(new_flow_rate) ;
1342
1343 // TODO replace with "update"
1344
1345 fill_system_matrix (&tdata->SM_A, &tdata->ThermalGrid, analysis, dimensions) ;
1346
1347 if (do_factorization (&tdata->SM_A) == TDICE_FAILURE)
1348
1349 return TDICE_FAILURE ;
1350
1351 update_channel_sources (&tdata->PowerGrid, dimensions) ;
1352
1353 return TDICE_SUCCESS ;
1354}
1355
1356/******************************************************************************/
1357
1359(
1360 ThermalData_t *tdata,
1361 Dimensions_t *dimensions,
1362 CellIndex_t layer_index,
1363 CellIndex_t row_index,
1364 CellIndex_t column_index
1365)
1366{
1368
1369 (dimensions, layer_index, row_index, column_index) ;
1370
1371 if (id >= get_number_of_cells (dimensions))
1372
1373 return 0.0 ;
1374
1375 else
1376
1377 return *(tdata->Temperatures + id) ;
1378}
1379
1380/******************************************************************************/
1381
1383(
1384 ThermalData_t *tdata,
1385 StackElementList_t *list,
1386 Dimensions_t *dimensions,
1387 String_t stack_element_id,
1388 String_t file_name
1389)
1390{
1391 StackElement_t stkel ;
1392
1393 stack_element_init (&stkel) ;
1394
1395 string_copy (&stkel.Id, &stack_element_id) ;
1396
1397 StackElement_t *tmp = stack_element_list_find (list, &stkel) ;
1398
1399 if (tmp == NULL)
1400 {
1401 stack_element_destroy (&stkel) ;
1402
1403 return TDICE_FAILURE ;
1404 }
1405
1406 stack_element_destroy (&stkel) ;
1407
1408 FILE *output_file = fopen (file_name, "w") ;
1409
1410 if (output_file == NULL)
1411 {
1412 fprintf (stderr, "Unable to open output file %s\n", file_name) ;
1413
1414 return TDICE_FAILURE ;
1415 }
1416
1418
1419 (tmp, dimensions, tdata->Temperatures, output_file) ;
1420
1421 fclose (output_file) ;
1422
1423 return TDICE_SUCCESS ;
1424}
void increase_by_step_time(Analysis_t *analysis)
Definition: analysis.c:152
bool slot_completed(Analysis_t *analysis)
Definition: analysis.c:159
void connection_init(Connection_t *connection)
Definition: connection.c:43
CellIndex_t get_number_of_connections(Dimensions_t *dimensions)
Definition: dimensions.c:659
CellIndex_t get_cell_offset_in_stack(Dimensions_t *dimensions, CellIndex_t layer_index, CellIndex_t row_index, CellIndex_t column_index)
Definition: dimensions.c:686
CellIndex_t get_spreader_cell_offset(Dimensions_t *dimensions, struct HeatSink_t *hsink, CellIndex_t row_index, CellIndex_t column_index)
Definition: dimensions.c:721
CellIndex_t last_column(Dimensions_t *dimensions)
Definition: dimensions.c:456
CellIndex_t get_number_of_cells(Dimensions_t *dimensions)
Definition: dimensions.c:652
CellIndex_t last_layer(Dimensions_t *dimensions)
Definition: dimensions.c:470
CellIndex_t first_layer(Dimensions_t *dimensions)
CellIndex_t first_column(Dimensions_t *dimensions)
CellIndex_t first_row(Dimensions_t *dimensions)
CellIndex_t last_row(Dimensions_t *dimensions)
Definition: dimensions.c:442
#define FLOW_RATE_FROM_MLMIN_TO_UM3SEC(fr)
Definition: macros.h:221
void non_uniform_cell_init(Non_uniform_cell_t *non_uniform_cell)
void power_grid_fill(PowerGrid_t *pgrid, ThermalGrid_t *tgrid, StackElementList_t *list, Dimensions_t *dimensions)
Definition: power_grid.c:222
void update_channel_sources(PowerGrid_t *pgrid, Dimensions_t *dimensions)
Definition: power_grid.c:928
Error_t power_grid_build(PowerGrid_t *pgrid, Dimensions_t *dimensions)
Definition: power_grid.c:64
Error_t update_source_vector(PowerGrid_t *pgrid, Dimensions_t *dimensions)
Definition: power_grid.c:528
void power_grid_init(PowerGrid_t *pgrid)
Definition: power_grid.c:46
void power_grid_destroy(PowerGrid_t *pgrid)
Definition: power_grid.c:202
void stack_element_destroy(StackElement_t *stkel)
Definition: stack_element.c:93
void stack_element_init(StackElement_t *stkel)
Definition: stack_element.c:45
void stack_element_print_thermal_map(StackElement_t *stkel, Dimensions_t *dimensions, Temperature_t *temperatures, FILE *stream)
char * String_t
Definition: string_t.h:55
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
AnalysisType_t AnalysisType
Definition: analysis.h:68
Time_t StepTime
Definition: analysis.h:72
Temperature_t InitialTemperature
Definition: analysis.h:88
CellDimension_t LastWallLength
Definition: dimensions.h:102
CellDimension_t ChannelLength
Definition: dimensions.h:96
CellDimension_t FirstWallLength
Definition: dimensions.h:85
CellDimension_t WallLength
Definition: dimensions.h:91
Coolant_t Coolant
Definition: channel.h:106
CellIndex_t NLayers
Definition: channel.h:98
ChannelModel_t ChannelModel
Definition: channel.h:74
ChipDimension_t Length
Definition: dimensions.h:258
ChipDimension_t Width
Definition: dimensions.h:262
CoolantFR_t FlowRate
Definition: coolant.h:89
CellIndex_t NLayers
Definition: die.h:77
CellIndex_t SourceLayerOffset
Definition: die.h:81
Floorplan_t Floorplan
Definition: die.h:94
CellIndex_t Discr_X
Definition: die.h:98
CellIndex_t Discr_Y
Definition: die.h:102
Collections of all the structures that are needed for the thermal simulation.
Definition: dimensions.h:311
GridDimensions_t Grid
Definition: dimensions.h:318
ConnectionList_t connections_list
Definition: dimensions.h:340
uint8_t NonUniform
Definition: dimensions.h:326
ChipDimensions_t Chip
Definition: dimensions.h:322
CellDimensions_t Cell
Definition: dimensions.h:314
Non_uniform_cellList_t Cell_list
Definition: dimensions.h:337
Structure containing information about a floorplan element.
ICElementList_t ICElements
FloorplanElementList_t ElementsList
Definition: floorplan.h:80
CellIndex_t NCells
Definition: dimensions.h:203
CellIndex_t NLayers
Definition: dimensions.h:173
CellIndex_t NRows
Definition: dimensions.h:182
CellIndex_t NColumns
Definition: dimensions.h:197
CellIndex_t NConnections
Definition: dimensions.h:207
Structure used to store data about the heat dissipation through the top or bottom surfaces of the 2D/...
Definition: heat_sink.h:69
CellIndex_t NColumns
Definition: heat_sink.h:114
HeatSinkModel_t SinkModel
Definition: heat_sink.h:72
int(* PluggableHeatsink)(const double *spreadertemperatures, double *sinkheatflows)
Definition: heat_sink.h:137
CellIndex_t NRows
Definition: heat_sink.h:110
CellIndex_t Discr_X
Definition: layer.h:95
CellIndex_t Discr_Y
Definition: layer.h:99
Source_t * Sources
Definition: power_grid.h:93
Capacity_t * CellsCapacities
Definition: power_grid.h:129
Structure used to store data about the stack element that compose the 2D/3D stack.
Definition: stack_element.h:93
StackElement_p Pointer
CellIndex_t NLayers
StackElementType_t SEType
Structure to collect data to run thermal simulations.
Definition: thermal_data.h:73
ThermalGrid_t ThermalGrid
Definition: thermal_data.h:80
SystemMatrix_t SM_A
Definition: thermal_data.h:97
PowerGrid_t PowerGrid
Definition: thermal_data.h:84
CellIndex_t Size
Definition: thermal_data.h:88
Temperature_t * Temperatures
Definition: thermal_data.h:76
SuperMatrix SLUMatrix_B
Definition: thermal_data.h:101
Channel_t * Channel
Definition: thermal_grid.h:84
HeatSink_t * TopHeatSink
Definition: thermal_grid.h:88
Error_t system_matrix_build(SystemMatrix_t *sysmatrix, CellIndex_t size, CellIndex_t nnz)
Definition: system_matrix.c:86
void system_matrix_init(SystemMatrix_t *sysmatrix)
Definition: system_matrix.c:46
void system_matrix_destroy(SystemMatrix_t *sysmatrix)
Error_t do_factorization(SystemMatrix_t *sysmatrix)
void fill_system_matrix(SystemMatrix_t *sysmatrix, ThermalGrid_t *thermal_grid, Analysis_t *analysis, Dimensions_t *dimensions)
Error_t solve_sparse_linear_system(SystemMatrix_t *sysmatrix, SuperMatrix *b)
void get_cell_position(ChipDimension_t(*position_info)[4], CellIndex_t *layer_cell_record, CellIndex_t *layer_type_record, StackElementList_t *stack_elements_list, Dimensions_t *dimensions)
Definition: thermal_data.c:154
void get_minkowski_difference(ChipDimension_t *minkowski_diff, ChipDimension_t(*position_info)[4], int i_x, int i_y)
Definition: thermal_data.c:629
void reset_thermal_state(ThermalData_t *tdata, Analysis_t *analysis)
void get_connections_in_layer(CellIndex_t *layer_cell_record, CellIndex_t *layer_type_record, ChipDimension_t(*position_info_ptr)[4], Dimensions_t *dimensions)
Definition: thermal_data.c:661
void get_connections_between_layer(CellIndex_t *layer_cell_record, CellIndex_t *layer_type_record, ChipDimension_t(*position_info_ptr)[4], Dimensions_t *dimensions)
Definition: thermal_data.c:734
SimResult_t emulate_slot(ThermalData_t *tdata, Dimensions_t *dimensions, Analysis_t *analysis)
SimResult_t emulate_step(ThermalData_t *tdata, Dimensions_t *dimensions, Analysis_t *analysis)
Temperature_t get_cell_temperature(ThermalData_t *tdata, Dimensions_t *dimensions, CellIndex_t layer_index, CellIndex_t row_index, CellIndex_t column_index)
void thermal_data_destroy(ThermalData_t *tdata)
void update_number_of_cells(Dimensions_t *dimensions, StackElementList_t *stack_elements_list)
Definition: thermal_data.c:69
Error_t update_coolant_flow_rate(ThermalData_t *tdata, Dimensions_t *dimensions, Analysis_t *analysis, CoolantFR_t new_flow_rate)
Error_t print_thermal_map(ThermalData_t *tdata, StackElementList_t *list, Dimensions_t *dimensions, String_t stack_element_id, String_t file_name)
Error_t thermal_data_build(ThermalData_t *tdata, StackElementList_t *list, Dimensions_t *dimensions, Analysis_t *analysis)
Definition: thermal_data.c:877
void thermal_data_init(ThermalData_t *tdata)
Definition: thermal_data.c:54
SimResult_t emulate_steady(ThermalData_t *tdata, Dimensions_t *dimensions, Analysis_t *analysis)
Error_t thermal_grid_build(ThermalGrid_t *tgrid, Dimensions_t *dimensions)
Definition: thermal_grid.c:59
Error_t thermal_grid_fill(ThermalGrid_t *tgrid, StackElementList_t *list)
Definition: thermal_grid.c:117
void thermal_grid_destroy(ThermalGrid_t *tgrid)
Definition: thermal_grid.c:96
void thermal_grid_init(ThermalGrid_t *tgrid)
Definition: thermal_grid.c:47
double Capacity_t
Definition: types.h:119
double CoolantFR_t
Definition: types.h:149
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
@ TDICE_CHANNEL_MODEL_PF_INLINE
Inline pin fins - 2 Resistors model.
Definition: types.h:350
@ TDICE_CHANNEL_MODEL_PF_STAGGERED
Staggered pin fins - 2 Resistors model.
Definition: types.h:351
@ TDICE_CHANNEL_MODEL_MC_2RM
Microchannel - 2 Resistors model.
Definition: types.h:349
double Time_t
Definition: types.h:65
double ChipDimension_t
Definition: types.h:187
double Temperature_t
Definition: types.h:71
double Source_t
Definition: types.h:77
@ TDICE_ANALYSIS_TYPE_TRANSIENT
Transient analysis.
Definition: types.h:457
@ TDICE_ANALYSIS_TYPE_STEADY
Steady state analysis.
Definition: types.h:458
@ TDICE_STACK_ELEMENT_NONE
Undefined type.
Definition: types.h:326
@ TDICE_STACK_ELEMENT_LAYER
Layer.
Definition: types.h:327
@ TDICE_STACK_ELEMENT_CHANNEL
Channel.
Definition: types.h:328
@ TDICE_STACK_ELEMENT_DIE
Die.
Definition: types.h:329
uint32_t CellIndex_t
Definition: types.h:213
@ TDICE_HEATSINK_TOP_PLUGGABLE
Top pluggable heat sink.
Definition: types.h:228
SimResult_t
Definition: types.h:418
@ TDICE_END_OF_SIMULATION
Definition: types.h:421
@ TDICE_SOLVER_ERROR
Definition: types.h:429
@ TDICE_SLOT_DONE
Definition: types.h:437
@ TDICE_WRONG_CONFIG
Definition: types.h:425
@ TDICE_STEP_DONE
Definition: types.h:433
Channel_t * Channel
Definition: stack_element.h:74
Layer_t * Layer
Definition: stack_element.h:72