VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
power_util.c
Go to the documentation of this file.
1 /*********************************************************************
2  * The following code is part of the power modelling feature of VTR.
3  *
4  * For support:
5  * http://code.google.com/p/vtr-verilog-to-routing/wiki/Power
6  *
7  * or email:
8  * vtr.power.estimation@gmail.com
9  *
10  * If you are using power estimation for your researach please cite:
11  *
12  * Jeffrey Goeders and Steven Wilton. VersaPower: Power Estimation
13  * for Diverse FPGA Architectures. In International Conference on
14  * Field Programmable Technology, 2012.
15  *
16  ********************************************************************/
17 
18 /**
19  * This file provides utility functions used by power estimation.
20  */
21 
22 /************************* INCLUDES *********************************/
23 #include <cstring>
24 #include <map>
25 using namespace std;
26 
27 #include <assert.h>
28 
29 #include "power_util.h"
30 #include "globals.h"
31 
32 /************************* GLOBALS **********************************/
33 
34 /************************* FUNCTION DECLARATIONS*********************/
35 static void log_msg(t_log * log_ptr, char * msg);
36 static void int_2_binary_str(char * binary_str, int value, int str_length);
37 static void init_mux_arch_default(t_mux_arch * mux_arch, int levels,
38  int num_inputs, float transistor_size);
40  int num_primary_inputs, int level, int starting_pin_idx);
41 static t_mux_node * alloc_and_load_mux_graph(int num_inputs, int levels);
42 
43 /************************* FUNCTION DEFINITIONS *********************/
44 void power_zero_usage(t_power_usage * power_usage) {
45  power_usage->dynamic = 0.;
46  power_usage->leakage = 0.;
47 }
48 
49 void power_add_usage(t_power_usage * dest, const t_power_usage * src) {
50  dest->dynamic += src->dynamic;
51  dest->leakage += src->leakage;
52 }
53 
54 void power_scale_usage(t_power_usage * power_usage, float scale_factor) {
55  power_usage->dynamic *= scale_factor;
56  power_usage->leakage *= scale_factor;
57 }
58 
59 float power_sum_usage(t_power_usage * power_usage) {
60  return power_usage->dynamic + power_usage->leakage;
61 }
62 
63 float power_perc_dynamic(t_power_usage * power_usage) {
64  return power_usage->dynamic / power_sum_usage(power_usage);
65 }
66 
67 void power_log_msg(e_power_log_type log_type, char * msg) {
68  log_msg(&g_power_output->logs[log_type], msg);
69 }
70 
72  if (type == NMOS) {
73  return "NMOS";
74  } else if (type == PMOS) {
75  return "PMOS";
76  } else {
77  return "Unknown";
78  }
79 }
80 
81 float pin_dens(t_pb * pb, t_pb_graph_pin * pin) {
82  float density = 0.;
83 
84  if (pb) {
85  int net_num;
86  net_num = pb->rr_graph[pin->pin_count_in_cluster].net_num;
87 
88  if (net_num != OPEN) {
89  density = vpack_net[net_num].net_power->density;
90  }
91  }
92 
93  return density;
94 }
95 
96 float pin_prob(t_pb * pb, t_pb_graph_pin * pin) {
97  /* Assumed pull-up on unused interconnect */
98  float prob = 1.;
99 
100  if (pb) {
101  int net_num;
102  net_num = pb->rr_graph[pin->pin_count_in_cluster].net_num;
103 
104  if (net_num != OPEN) {
105  prob = vpack_net[net_num].net_power->probability;
106  }
107  }
108 
109  return prob;
110 }
111 
112 /**
113  * This function determines the values of the selectors in a static mux, based
114  * on the routing information.
115  * - selector_values: (Return values) selected index at each mux level
116  * - mux_node:
117  * - selected_input_pin: The input index to the multi-level mux that is chosen
118  */
119 boolean mux_find_selector_values(int * selector_values, t_mux_node * mux_node,
120  int selected_input_pin) {
121  if (mux_node->level == 0) {
122  if ((selected_input_pin >= mux_node->starting_pin_idx)
123  && (selected_input_pin
124  <= (mux_node->starting_pin_idx + mux_node->num_inputs))) {
125  selector_values[mux_node->level] = selected_input_pin
126  - mux_node->starting_pin_idx;
127  return TRUE;
128  }
129  } else {
130  int input_idx;
131  for (input_idx = 0; input_idx < mux_node->num_inputs; input_idx++) {
132  if (mux_find_selector_values(selector_values,
133  &mux_node->children[input_idx], selected_input_pin)) {
134  selector_values[mux_node->level] = input_idx;
135  return TRUE;
136  }
137  }
138  }
139  return FALSE;
140 }
141 
142 static void log_msg(t_log * log_ptr, char * msg) {
143  int msg_idx;
144 
145  /* Check if this message is already in the log */
146  for (msg_idx = 0; msg_idx < log_ptr->num_messages; msg_idx++) {
147  if (strcmp(log_ptr->messages[msg_idx], msg) == 0) {
148  return;
149  }
150  }
151 
152  if (log_ptr->num_messages <= MAX_LOGS) {
153  log_ptr->num_messages++;
154  log_ptr->messages = (char**) my_realloc(log_ptr->messages,
155  log_ptr->num_messages * sizeof(char*));
156  } else {
157  /* Can't add any more messages */
158  return;
159  }
160 
161  if (log_ptr->num_messages == (MAX_LOGS + 1)) {
162  const char * full_msg = "\n***LOG IS FULL***\n";
163  log_ptr->messages[log_ptr->num_messages - 1] = (char*) my_calloc(
164  strlen(full_msg) + 1, sizeof(char));
165  strncpy(log_ptr->messages[log_ptr->num_messages - 1], full_msg,
166  strlen(full_msg));
167  } else {
168  log_ptr->messages[log_ptr->num_messages - 1] = (char*) my_calloc(
169  strlen(msg) + 1, sizeof(char));
170  strncpy(log_ptr->messages[log_ptr->num_messages - 1], msg, strlen(msg));
171  }
172 }
173 
174 /**
175  * Calculates the number of buffer stages required, to achieve a given buffer fanout
176  * final_stage_size: Size of the final inverter in the buffer, relative to a min size
177  * desired_stage_effort: The desired gain between stages, typically 4
178  */
179 int power_calc_buffer_num_stages(float final_stage_size,
180  float desired_stage_effort) {
181  int N = 1;
182 
183  if (final_stage_size <= 1.0) {
184  N = 1;
185  } else if (final_stage_size < desired_stage_effort)
186  N = 2;
187  else {
188  N = (int) (log(final_stage_size) / log(desired_stage_effort) + 1);
189 
190  /* We always round down.
191  * Perhaps N+1 would be closer to the desired stage effort, but the delay savings
192  * would likely not be worth the extra power/area
193  */
194  }
195 
196  return N;
197 }
198 
199 /**
200  * Calculates the required effort of each stage of a buffer
201  * - N: The number of stages of the buffer
202  * - final_stage_size: Size of the final inverter in the buffer, relative to a min size
203  */
204 float calc_buffer_stage_effort(int N, float final_stage_size) {
205  if (N > 1)
206  return pow((double) final_stage_size, (1.0 / ((double) N - 1)));
207  else
208  return 1.0;
209 }
210 
211 #if 0
212 void integer_to_SRAMvalues(int SRAM_num, int input_integer, char SRAM_values[]) {
213  char binary_str[20];
214  int binary_str_counter;
215  int local_integer;
216  int i;
217 
218  binary_str_counter = 0;
219 
220  local_integer = input_integer;
221 
222  while (local_integer > 0) {
223  if (local_integer % 2 == 0) {
224  SRAM_values[binary_str_counter++] = '0';
225  } else {
226  SRAM_values[binary_str_counter++] = '1';
227  }
228  local_integer = local_integer / 2;
229  }
230 
231  while (binary_str_counter < SRAM_num) {
232  SRAM_values[binary_str_counter++] = '0';
233  }
234 
235  SRAM_values[binary_str_counter] = '\0';
236 
237  for (i = 0; i < binary_str_counter; i++) {
238  binary_str[i] = SRAM_values[binary_str_counter - 1 - i];
239  }
240 
241  binary_str[binary_str_counter] = '\0';
242 
243 }
244 #endif
245 
246 /**
247  * This function converts an integer to a binary string
248  * - binary_str: (Return value) The created binary string
249  * - value: The integer value to convert
250  * - str_length: The length of the binary string
251  */
252 static void int_2_binary_str(char * binary_str, int value, int str_length) {
253  int i;
254  int odd;
255 
256  binary_str[str_length] = '\0';
257 
258  for (i = str_length - 1; i >= 0; i--, value >>= 1) {
259  odd = value % 2;
260  if (odd == 0) {
261  binary_str[i] = '0';
262  } else {
263  binary_str[i] = '1';
264  }
265  }
266 }
267 
268 /**
269  * This functions returns the LUT SRAM values from the given logic terms
270  * - LUT_size: The number of LUT inputs
271  * - truth_table: The logic terms saved from the BLIF file, in a linked list format
272  */
274  t_linked_vptr * truth_table) {
275  char * SRAM_values;
276  int i;
277  int num_SRAM_bits;
278  char * binary_str;
279  char ** terms;
280  char * buffer;
281  char * str_loc;
282  boolean on_set;
283  t_linked_vptr * list_ptr;
284  int num_terms;
285  int term_idx;
286  int bit_idx;
287  int dont_care_start_pos;
288 
289  num_SRAM_bits = 1 << LUT_size;
290  SRAM_values = (char*) my_calloc(num_SRAM_bits + 1, sizeof(char));
291  SRAM_values[num_SRAM_bits] = '\0';
292 
293  if (!truth_table) {
294  for (i = 0; i < num_SRAM_bits; i++) {
295  SRAM_values[i] = '1';
296  }
297  return SRAM_values;
298  }
299 
300  binary_str = (char*) my_calloc(LUT_size + 1, sizeof(char));
301  buffer = (char*) my_calloc(LUT_size + 10, sizeof(char));
302 
303  strcpy(buffer, (char*) truth_table->data_vptr);
304 
305  /* Check if this is an unconnected node - hopefully these will be
306  * ignored by VPR in the future
307  */
308  if (strcmp(buffer, " 0") == 0) {
309  free(binary_str);
310  free(buffer);
311  return SRAM_values;
312  } else if (strcmp(buffer, " 1") == 0) {
313  for (i = 0; i < num_SRAM_bits; i++) {
314  SRAM_values[i] = '1';
315  }
316  free(binary_str);
317  free(buffer);
318  return SRAM_values;
319  }
320 
321  /* If the LUT is larger than the terms, the lower significant bits will be don't cares */
322  str_loc = strtok(buffer, " \t");
323  dont_care_start_pos = strlen(str_loc);
324 
325  /* Find out if the truth table provides the ON-set or OFF-set */
326  str_loc = strtok(NULL, " \t");
327  on_set = TRUE;
328  if (str_loc[0] == '1') {
329  } else if (str_loc[0] == '0') {
330  on_set = FALSE;
331  } else {
332  assert(0);
333  }
334 
335  /* Count truth table terms */
336  num_terms = 0;
337  for (list_ptr = truth_table; list_ptr != NULL; list_ptr = list_ptr->next) {
338  num_terms++;
339  }
340  terms = (char**) my_calloc(num_terms, sizeof(char *));
341 
342  /* Extract truth table terms */
343  for (list_ptr = truth_table, term_idx = 0; list_ptr != NULL; list_ptr =
344  list_ptr->next, term_idx++) {
345  terms[term_idx] = (char*) my_calloc(LUT_size + 1, sizeof(char));
346 
347  strcpy(buffer, (char*) list_ptr->data_vptr);
348  str_loc = strtok(buffer, " \t");
349  strcpy(terms[term_idx], str_loc);
350 
351  /* Fill don't cares for lower bits (when LUT is larger than term size) */
352  for (bit_idx = dont_care_start_pos; bit_idx < LUT_size; bit_idx++) {
353  terms[term_idx][bit_idx] = '-';
354  }
355 
356  /* Verify on/off consistency */
357  str_loc = strtok(NULL, " \t");
358  if (on_set) {
359  assert(str_loc[0] == '1');
360  } else {
361  assert(str_loc[0] == '0');
362  }
363  }
364 
365  /* Loop through all SRAM bits */
366  for (i = 0; i < num_SRAM_bits; i++) {
367  /* Set default value */
368  if (on_set) {
369  SRAM_values[i] = '0';
370  } else {
371  SRAM_values[i] = '1';
372  }
373 
374  /* Get binary number representing this SRAM index */
375  int_2_binary_str(binary_str, i, LUT_size);
376 
377  /* Loop through truth table terms */
378  for (term_idx = 0; term_idx < num_terms; term_idx++) {
379  boolean match = TRUE;
380 
381  for (bit_idx = 0; bit_idx < LUT_size; bit_idx++) {
382  if ((terms[term_idx][bit_idx] != '-')
383  && (terms[term_idx][bit_idx] != binary_str[bit_idx])) {
384  match = FALSE;
385  break;
386  }
387  }
388 
389  if (match) {
390  if (on_set) {
391  SRAM_values[i] = '1';
392  } else {
393  SRAM_values[i] = '0';
394  }
395 
396  /* No need to check the other terms, already matched */
397  break;
398  }
399  }
400 
401  }
402  free(binary_str);
403  free(buffer);
404  for (term_idx = 0; term_idx < num_terms; term_idx++) {
405  free(terms[term_idx]);
406  }
407  free(terms);
408 
409  return SRAM_values;
410 }
411 
412 /* Reduce mux levels for multiplexers that are too small for the preset number of levels */
413 void mux_arch_fix_levels(t_mux_arch * mux_arch) {
414  while (((1 << mux_arch->levels) > mux_arch->num_inputs)
415  && (mux_arch->levels > 1)) {
416  mux_arch->levels--;
417  }
418 }
419 
420 float clb_net_density(int net_idx) {
421  if (net_idx == OPEN) {
422  return 0.;
423  } else {
424  return clb_net[net_idx].net_power->density;
425  }
426 }
427 
428 float clb_net_prob(int net_idx) {
429  if (net_idx == OPEN) {
430  return 0.;
431  } else {
432  return clb_net[net_idx].net_power->probability;
433  }
434 }
435 
437  switch (type) {
438  case COMPLETE_INTERC:
439  return "complete";
440  case MUX_INTERC:
441  return "mux";
442  case DIRECT_INTERC:
443  return "direct";
444  default:
445  return "";
446  }
447 }
448 
449 void output_log(t_log * log_ptr, FILE * fp) {
450  int msg_idx;
451 
452  for (msg_idx = 0; msg_idx < log_ptr->num_messages; msg_idx++) {
453  fprintf(fp, "%s\n", log_ptr->messages[msg_idx]);
454  }
455 }
456 
457 void output_logs(FILE * fp, t_log * logs, int num_logs) {
458  int log_idx;
459 
460  for (log_idx = 0; log_idx < num_logs; log_idx++) {
461  if (logs[log_idx].num_messages) {
462  power_print_title(fp, logs[log_idx].name);
463  output_log(&logs[log_idx], fp);
464  fprintf(fp, "\n");
465  }
466  }
467 }
468 
470  return max(1.0f,
473 }
474 
475 void power_print_title(FILE * fp, char * title) {
476  int i;
477  const int width = 80;
478 
479  int firsthalf = (width - strlen(title) - 2) / 2;
480  int secondhalf = width - strlen(title) - 2 - firsthalf;
481 
482  for (i = 1; i <= firsthalf; i++)
483  fprintf(fp, "-");
484  fprintf(fp, " %s ", title);
485  for (i = 1; i <= secondhalf; i++)
486  fprintf(fp, "-");
487  fprintf(fp, "\n");
488 }
489 
490 t_mux_arch * power_get_mux_arch(int num_mux_inputs, float transistor_size) {
491  int i;
492 
493  t_power_mux_info * mux_info = NULL;
494 
495  /* Find the mux archs for the given transistor size */
496  std::map<float, t_power_mux_info*>::iterator it;
497 
498  it = g_power_commonly_used->mux_info.find(transistor_size);
499 
500  if (it == g_power_commonly_used->mux_info.end()) {
501  mux_info = new t_power_mux_info;
502  mux_info->mux_arch = NULL;
503  mux_info->mux_arch_max_size = 0;
504  g_power_commonly_used->mux_info[transistor_size] = mux_info;
505  } else {
506  mux_info = it->second;
507  }
508 
509  if (num_mux_inputs > mux_info->mux_arch_max_size) {
510  mux_info->mux_arch = (t_mux_arch*) my_realloc(mux_info->mux_arch,
511  (num_mux_inputs + 1) * sizeof(t_mux_arch));
512 
513  for (i = mux_info->mux_arch_max_size + 1; i <= num_mux_inputs; i++) {
514  init_mux_arch_default(&mux_info->mux_arch[i], 2, i,
515  transistor_size);
516  }
517  mux_info->mux_arch_max_size = num_mux_inputs;
518  }
519  return &mux_info->mux_arch[num_mux_inputs];
520 }
521 
522 /**
523  * Generates a default multiplexer architecture of given size and number of levels
524  */
525 static void init_mux_arch_default(t_mux_arch * mux_arch, int levels,
526  int num_inputs, float transistor_size) {
527 
528  mux_arch->levels = levels;
529  mux_arch->num_inputs = num_inputs;
530 
531  mux_arch_fix_levels(mux_arch);
532 
533  mux_arch->transistor_size = transistor_size;
534 
535  mux_arch->mux_graph_head = alloc_and_load_mux_graph(num_inputs,
536  mux_arch->levels);
537 }
538 
539 /**
540  * Allocates a builds a multiplexer graph with given # inputs and levels
541  */
542 static t_mux_node * alloc_and_load_mux_graph(int num_inputs, int levels) {
543  t_mux_node * node;
544 
545  node = (t_mux_node*) my_malloc(sizeof(t_mux_node));
546  alloc_and_load_mux_graph_recursive(node, num_inputs, levels - 1, 0);
547 
548  return node;
549 }
550 
552  int num_primary_inputs, int level, int starting_pin_idx) {
553  int child_idx;
554  int pin_idx = starting_pin_idx;
555 
556  node->num_inputs = (int) (pow(num_primary_inputs, 1 / ((float) level + 1))
557  + 0.5);
558  node->level = level;
559  node->starting_pin_idx = starting_pin_idx;
560 
561  if (level != 0) {
562  node->children = (t_mux_node*) my_calloc(node->num_inputs,
563  sizeof(t_mux_node));
564  for (child_idx = 0; child_idx < node->num_inputs; child_idx++) {
565  int num_child_pi = num_primary_inputs / node->num_inputs;
566  if (child_idx < (num_primary_inputs % node->num_inputs)) {
567  num_child_pi++;
568  }
570  num_child_pi, level - 1, pin_idx);
571  pin_idx += num_child_pi;
572  }
573  }
574 }
575 
577  e_power_estimation_method estimation_method) {
578  switch (estimation_method) {
581  return TRUE;
582  default:
583  return FALSE;
584  }
585 }
586 
588  switch (method) {
589  case POWER_METHOD_IGNORE:
593  return FALSE;
597  return TRUE;
599  default:
600  assert(0);
601  }
602 
603 // to get rid of warning
604  return FALSE;
605 }
606 
int num_inputs
Definition: power.h:281
t_power_arch * g_power_arch
Definition: power.c:68
static void alloc_and_load_mux_graph_recursive(t_mux_node *node, int num_primary_inputs, int level, int starting_pin_idx)
Definition: power_util.c:551
t_mux_arch * mux_arch
Definition: power.h:214
void power_print_title(FILE *fp, char *title)
Definition: power_util.c:475
enum e_power_estimation_method_ e_power_estimation_method
boolean power_method_is_recursive(e_power_estimation_method method)
Definition: power_util.c:587
Definition: power.h:89
int net_num
Definition: vpr_types.h:917
float clb_net_prob(int net_idx)
Definition: power_util.c:428
struct s_rr_node * rr_graph
Definition: vpr_types.h:188
static void log_msg(t_log *log_ptr, char *msg)
Definition: power_util.c:142
float logical_effort_factor
float power_buffer_size_from_logical_effort(float C_load)
Definition: power_util.c:469
static void int_2_binary_str(char *binary_str, int value, int str_length)
Definition: power_util.c:252
t_power_commonly_used * g_power_commonly_used
Definition: power.c:66
void * my_calloc(size_t nelem, size_t size)
Definition: util.c:132
int power_calc_buffer_num_stages(float final_stage_size, float desired_stage_effort)
Definition: power_util.c:179
struct s_mux_arch t_mux_arch
Definition: power.h:75
#define MAX_LOGS
Definition: power.h:33
char * alloc_SRAM_values_from_truth_table(int LUT_size, t_linked_vptr *truth_table)
Definition: power_util.c:273
e_power_log_type
Definition: power.h:47
std::map< float, t_power_mux_info * > mux_info
Definition: power.h:245
t_log * logs
Definition: power.h:201
char * interconnect_type_name(enum e_interconnect type)
Definition: power_util.c:436
Definition: util.h:12
t_power_output * g_power_output
Definition: power.c:65
t_mux_arch * power_get_mux_arch(int num_mux_inputs, float transistor_size)
Definition: power_util.c:490
boolean power_method_is_transistor_level(e_power_estimation_method estimation_method)
Definition: power_util.c:576
float probability
Definition: vpr_types.h:485
float pin_prob(t_pb *pb, t_pb_graph_pin *pin)
Definition: power_util.c:96
void power_add_usage(t_power_usage *dest, const t_power_usage *src)
Definition: power_util.c:49
static void * my_malloc(int ibytes)
Definition: graphics.c:499
int level
Definition: power.h:295
#define max(a, b)
Definition: graphics.c:171
int mux_arch_max_size
Definition: power.h:213
t_net_power * net_power
Definition: vpr_types.h:512
struct s_net * clb_net
Definition: globals.c:28
static t_mux_node * alloc_and_load_mux_graph(int num_inputs, int levels)
Definition: power_util.c:542
void power_zero_usage(t_power_usage *power_usage)
Definition: power_util.c:44
int starting_pin_idx
Definition: power.h:294
float transistor_size
Definition: power.h:282
struct s_linked_vptr * next
Definition: util.h:36
int num_messages
Definition: power.h:208
void * data_vptr
Definition: util.h:35
void output_log(t_log *log_ptr, FILE *fp)
Definition: power_util.c:449
float pin_dens(t_pb *pb, t_pb_graph_pin *pin)
Definition: power_util.c:81
Definition: power.h:89
int levels
Definition: power.h:280
void mux_arch_fix_levels(t_mux_arch *mux_arch)
Definition: power_util.c:413
float clb_net_density(int net_idx)
Definition: power_util.c:420
float power_sum_usage(t_power_usage *power_usage)
Definition: power_util.c:59
static void * my_realloc(void *memblk, int ibytes)
Definition: graphics.c:512
struct s_power_mux_info t_power_mux_info
Definition: power.h:79
static void init_mux_arch_default(t_mux_arch *mux_arch, int levels, int num_inputs, float transistor_size)
Definition: power_util.c:525
Definition: slre.c:50
int num_inputs
Definition: power.h:292
float power_perc_dynamic(t_power_usage *power_usage)
Definition: power_util.c:63
float density
Definition: vpr_types.h:490
void power_scale_usage(t_power_usage *power_usage, float scale_factor)
Definition: power_util.c:54
struct s_net * vpack_net
Definition: globals.c:19
boolean mux_find_selector_values(int *selector_values, t_mux_node *mux_node, int selected_input_pin)
Definition: power_util.c:119
t_mux_node * mux_graph_head
Definition: power.h:284
e_interconnect
char * transistor_type_name(e_tx_type type)
Definition: power_util.c:71
Definition: power.h:205
static const char * match(const struct slre *, int, const char *, int, int *, struct cap *)
Definition: slre.c:404
float calc_buffer_stage_effort(int N, float final_stage_size)
Definition: power_util.c:204
t_mux_node * children
Definition: power.h:293
Definition: util.h:12
void power_log_msg(e_power_log_type log_type, char *msg)
Definition: power_util.c:67
char ** messages
Definition: power.h:207
void output_logs(FILE *fp, t_log *logs, int num_logs)
Definition: power_util.c:457
e_tx_type
Definition: power.h:88