VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
power.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 is the top-level file for power estimation in VTR
20  */
21 
22 /************************* INCLUDES *********************************/
23 #include <cstdio>
24 #include <cstdlib>
25 #include <cstring>
26 #include <csignal>
27 #include <ctime>
28 #include <cmath>
29 using namespace std;
30 
31 #include <ctype.h>
32 #include <assert.h>
33 
34 #include "power.h"
35 #include "power_components.h"
36 #include "power_util.h"
37 #include "power_lowlevel.h"
38 #include "power_sizing.h"
39 #include "power_callibrate.h"
40 #include "power_cmos_tech.h"
41 
42 #include "physical_types.h"
43 #include "globals.h"
44 #include "rr_graph.h"
45 #include "vpr_utils.h"
46 #include "ezxml.h"
47 #include "read_xml_util.h"
48 
49 /************************* DEFINES **********************************/
50 #define CONVERT_NM_PER_M 1000000000
51 #define CONVERT_UM_PER_M 1000000
52 
53 /************************* ENUMS ************************************/
54 typedef enum {
62 
63 /************************* GLOBALS **********************************/
70 
71 /************************* Function Declarations ********************/
72 /* Routing */
73 static void power_usage_routing(t_power_usage * power_usage,
74  t_det_routing_arch * routing_arch, t_segment_inf * segment_inf);
75 
76 /* Tiles */
77 static void power_usage_blocks(t_power_usage * power_usage);
78 static void power_usage_pb(t_power_usage * power_usage, t_pb * pb,
79  t_pb_graph_node * pb_node);
80 static void power_usage_primitive(t_power_usage * power_usage, t_pb * pb,
81  t_pb_graph_node * pb_graph_node);
82 static void power_reset_tile_usage(void);
83 static void power_reset_pb_type(t_pb_type * pb_type);
84 static void power_usage_local_buffers_and_wires(t_power_usage * power_usage,
85  t_pb * pb, t_pb_graph_node * pb_node);
86 
87 /* Clock */
88 static void power_usage_clock(t_power_usage * power_usage,
89  t_clock_arch * clock_arch);
90 static void power_usage_clock_single(t_power_usage * power_usage,
91  t_clock_network * clock_inf);
92 
93 /* Init/Uninit */
94 static void dealloc_mux_graph(t_mux_node * node);
95 static void dealloc_mux_graph_rec(t_mux_node * node);
96 
97 /* Printing */
98 static void power_print_breakdown_pb_rec(FILE * fp, t_pb_type * pb_type,
99  int indent);
100 static void power_print_summary(FILE * fp, t_vpr_setup vpr_setup);
101 //static void power_print_stats(FILE * fp);
102 static void power_print_breakdown_summary(FILE * fp);
103 static void power_print_breakdown_entry(FILE * fp, int indent,
104  e_power_breakdown_entry_type type, char * name, float power,
105  float total_power, float perc_dyn, char * method);
106 static void power_print_breakdown_component(FILE * fp, char * name,
107  e_power_component_type type, int indent_level);
108 static void power_print_breakdown_pb(FILE * fp);
109 
110 static char * power_estimation_method_name(
111  e_power_estimation_method power_method);
112 
113 /************************* FUNCTION DEFINITIONS *********************/
114 /**
115  * This function calculates the power of primitives (ff, lut, etc),
116  * by calling the appropriate primitive function.
117  * - power_usage: (Return value)
118  * - pb: The pysical block
119  * - pb_graph_node: The physical block graph node
120  * - calc_dynamic: Calculate dynamic power? Otherwise ignore
121  * - calc_static: Calculate static power? Otherwise ignore
122  */
123 static void power_usage_primitive(t_power_usage * power_usage, t_pb * pb,
124  t_pb_graph_node * pb_graph_node) {
125  t_power_usage sub_power_usage;
126 
127  power_zero_usage(power_usage);
128  power_zero_usage(&sub_power_usage);
129 
130  if (strcmp(pb_graph_node->pb_type->blif_model, ".names") == 0) {
131  /* LUT */
132 
133  char * SRAM_values;
134  float * input_probabilities;
135  float * input_densities;
136  int LUT_size;
137  int pin_idx;
138 
139  assert(pb_graph_node->num_input_ports == 1);
140 
141  LUT_size = pb_graph_node->num_input_pins[0];
142 
143  input_probabilities = (float*) my_calloc(LUT_size, sizeof(float));
144  input_densities = (float*) my_calloc(LUT_size, sizeof(float));
145 
146  for (pin_idx = 0; pin_idx < LUT_size; pin_idx++) {
147  t_pb_graph_pin * pin = &pb_graph_node->input_pins[0][pin_idx];
148 
149  input_probabilities[pin_idx] = pin_prob(pb, pin);
150  input_densities[pin_idx] = pin_dens(pb, pin);
151  }
152 
153  if (pb) {
154  SRAM_values = alloc_SRAM_values_from_truth_table(LUT_size,
156  } else {
157  SRAM_values = alloc_SRAM_values_from_truth_table(LUT_size, NULL);
158  }
159  power_usage_lut(&sub_power_usage, LUT_size,
160  g_power_arch->LUT_transistor_size, SRAM_values,
161  input_probabilities, input_densities, g_solution_inf.T_crit);
162  power_add_usage(power_usage, &sub_power_usage);
163  free(SRAM_values);
164  free(input_probabilities);
165  free(input_densities);
166  } else if (strcmp(pb_graph_node->pb_type->blif_model, ".latch") == 0) {
167  /* Flip-Flop */
168 
169  t_pb_graph_pin * D_pin = &pb_graph_node->input_pins[0][0];
170  t_pb_graph_pin * Q_pin = &pb_graph_node->output_pins[0][0];
171 
172  float D_dens = 0.;
173  float D_prob = 0.;
174  float Q_prob = 0.;
175  float Q_dens = 0.;
176  float clk_dens = 0.;
177  float clk_prob = 0.;
178 
179  D_dens = pin_dens(pb, D_pin);
180  D_prob = pin_prob(pb, D_pin);
181  Q_dens = pin_dens(pb, Q_pin);
182  Q_prob = pin_prob(pb, Q_pin);
183 
184  clk_prob = g_clock_arch->clock_inf[0].prob;
185  clk_dens = g_clock_arch->clock_inf[0].dens;
186 
187  power_usage_ff(&sub_power_usage, g_power_arch->FF_size, D_prob, D_dens,
188  Q_prob, Q_dens, clk_prob, clk_dens, g_solution_inf.T_crit);
189  power_add_usage(power_usage, &sub_power_usage);
190 
191  } else {
192  char msg[BUFSIZE];
193  sprintf(msg, "No dynamic power defined for BLIF model: %s",
194  pb_graph_node->pb_type->blif_model);
196 
197  sprintf(msg, "No leakage power defined for BLIF model: %s",
198  pb_graph_node->pb_type->blif_model);
200 
201  }
202 }
203 
205  t_pb_graph_pin * pin) {
206  float scale_factor;
207 
208  power_zero_usage(power_usage);
209 
210  if (pin->pin_power->scaled_by_pin) {
211  scale_factor = pin_prob(pb, pin->pin_power->scaled_by_pin);
212  if (pin->port->port_power->reverse_scaled) {
213  scale_factor = 1 - scale_factor;
214  }
215  } else {
216  scale_factor = 1.0;
217  }
218 
219  /* Divide by 2 because density is switches/cycle, but a toggle is 2 switches */
220  power_usage->dynamic += scale_factor
221  * pin->port->port_power->energy_per_toggle * pin_dens(pb, pin) / 2.0
223 }
224 
226  t_pb * pb, t_pb_graph_pin * pin) {
227  t_power_usage sub_power_usage;
228  float buffer_size = 0.;
229  double C_wire;
230 
231  power_zero_usage(power_usage);
232 
233  /* Wire switching */
234  C_wire = pin->pin_power->C_wire;
235  power_usage_wire(&sub_power_usage, C_wire, pin_dens(pb, pin),
237  power_add_usage(power_usage, &sub_power_usage);
238 
239  /* Buffer power */
240  buffer_size = pin->pin_power->buffer_size;
241  if (buffer_size) {
242  power_usage_buffer(&sub_power_usage, buffer_size, pin_prob(pb, pin),
243  pin_dens(pb, pin), FALSE, g_solution_inf.T_crit);
244  power_add_usage(power_usage, &sub_power_usage);
245  }
246 }
247 
249  t_pb * pb, t_pb_graph_node * pb_node) {
250  int port_idx;
251  int pin_idx;
252  t_power_usage pin_power;
253 
254  power_zero_usage(power_usage);
255 
256  /* Input pins */
257  for (port_idx = 0; port_idx < pb_node->num_input_ports; port_idx++) {
258  for (pin_idx = 0; pin_idx < pb_node->num_input_pins[port_idx];
259  pin_idx++) {
261  &pb_node->input_pins[port_idx][pin_idx]);
262  power_add_usage(power_usage, &pin_power);
263  }
264  }
265 
266  /* Output pins */
267  for (port_idx = 0; port_idx < pb_node->num_output_ports; port_idx++) {
268  for (pin_idx = 0; pin_idx < pb_node->num_output_pins[port_idx];
269  pin_idx++) {
271  &pb_node->output_pins[port_idx][pin_idx]);
272  power_add_usage(power_usage, &pin_power);
273  }
274  }
275 
276  /* Clock pins */
277  for (port_idx = 0; port_idx < pb_node->num_clock_ports; port_idx++) {
278  for (pin_idx = 0; pin_idx < pb_node->num_clock_pins[port_idx];
279  pin_idx++) {
281  &pb_node->clock_pins[port_idx][pin_idx]);
282  power_add_usage(power_usage, &pin_power);
283  }
284  }
285 }
286 
287 /** Calculates the power of a pb:
288  * First checks if dynamic/static power is provided by user in arch file. If not:
289  * - Calculate power of all interconnect
290  * - Call recursively for children
291  * - If no children, must be a primitive. Call primitive hander.
292  */
293 static void power_usage_pb(t_power_usage * power_usage, t_pb * pb,
294  t_pb_graph_node * pb_node) {
295 
296  t_power_usage power_usage_bufs_wires;
297  t_power_usage power_usage_local_muxes;
298  t_power_usage power_usage_children;
299  t_power_usage power_usage_pin_toggle;
300  t_power_usage power_usage_sub;
301 
302  int pb_type_idx;
303  int pb_idx;
304  int interc_idx;
305  int pb_mode;
306  int port_idx;
307  int pin_idx;
308  float dens_avg;
309  int num_pins;
310 
311  power_zero_usage(power_usage);
312 
313  t_pb_type * pb_type = pb_node->pb_type;
314  t_pb_type_power * pb_power = pb_node->pb_type->pb_type_power;
315 
316  boolean estimate_buffers_and_wire = FALSE;
317  boolean estimate_multiplexers = FALSE;
318  boolean estimate_primitives = FALSE;
319  boolean recursive_children;
320 
321  /* Get mode */
322  if (pb) {
323  pb_mode = pb->mode;
324  } else {
325  /* Default mode if not initialized (will only affect leakage power) */
326  pb_mode = pb_type->pb_type_power->leakage_default_mode;
327  }
328 
329  recursive_children = power_method_is_recursive(
331 
332  power_zero_usage(&power_usage_sub);
333 
334  switch (pb_node->pb_type->pb_type_power->estimation_method) {
335  case POWER_METHOD_IGNORE:
337  break;
338 
340  power_add_usage(power_usage, &pb_power->absolute_power_per_instance);
343  break;
344 
346  power_zero_usage(&power_usage_sub);
347 
348  /* Just take the average density of inputs pins and use
349  * that with user-defined block capacitance and leakage */
350 
351  /* Average the activity of all pins */
352  num_pins = 0;
353  dens_avg = 0.;
354  for (port_idx = 0; port_idx < pb_node->num_input_ports; port_idx++) {
355  for (pin_idx = 0; pin_idx < pb_node->num_input_pins[port_idx];
356  pin_idx++) {
357  dens_avg += pin_dens(pb,
358  &pb_node->input_pins[port_idx][pin_idx]);
359  num_pins++;
360  }
361  }
362  if (num_pins != 0) {
363  dens_avg = dens_avg / num_pins;
364  }
365  power_usage_sub.dynamic += power_calc_node_switching(
366  pb_power->C_internal, dens_avg, g_solution_inf.T_crit);
367 
368  /* Leakage is an absolute */
369  power_usage_sub.leakage +=
371 
372  /* Add to power of this PB */
373  power_add_usage(power_usage, &power_usage_sub);
374 
375  // Add to component type
377  break;
378 
380  power_zero_usage(&power_usage_pin_toggle);
381 
382  /* Add toggle power of each input pin */
383  for (port_idx = 0; port_idx < pb_node->num_input_ports; port_idx++) {
384  for (pin_idx = 0; pin_idx < pb_node->num_input_pins[port_idx];
385  pin_idx++) {
386  t_power_usage pin_power;
387  power_usage_local_pin_toggle(&pin_power, pb,
388  &pb_node->input_pins[port_idx][pin_idx]);
389  power_add_usage(&power_usage_pin_toggle, &pin_power);
390  }
391  }
392 
393  /* Add toggle power of each output pin */
394  for (port_idx = 0; port_idx < pb_node->num_output_ports; port_idx++) {
395  for (pin_idx = 0; pin_idx < pb_node->num_output_pins[port_idx];
396  pin_idx++) {
397  t_power_usage pin_power;
398  power_usage_local_pin_toggle(&pin_power, pb,
399  &pb_node->output_pins[port_idx][pin_idx]);
400  power_add_usage(&power_usage_pin_toggle, &pin_power);
401  }
402  }
403 
404  /* Add toggle power of each clock pin */
405  for (port_idx = 0; port_idx < pb_node->num_clock_ports; port_idx++) {
406  for (pin_idx = 0; pin_idx < pb_node->num_clock_pins[port_idx];
407  pin_idx++) {
408  t_power_usage pin_power;
409  power_usage_local_pin_toggle(&pin_power, pb,
410  &pb_node->clock_pins[port_idx][pin_idx]);
411  power_add_usage(&power_usage_pin_toggle, &pin_power);
412  }
413  }
414 
415  /* Static is supplied as an absolute */
416  power_usage_pin_toggle.leakage +=
418 
419  // Add to this PB power
420  power_add_usage(power_usage, &power_usage_pin_toggle);
421 
422  // Add to component type power
423  power_component_add_usage(&power_usage_pin_toggle,
425  break;
427  estimate_buffers_and_wire = TRUE;
428  estimate_multiplexers = TRUE;
429  estimate_primitives = TRUE;
430  break;
432  estimate_buffers_and_wire = TRUE;
433  estimate_multiplexers = TRUE;
434  estimate_primitives = TRUE;
435  break;
437  default:
438  assert(0);
439  break;
440  }
441 
442  if (pb_node->pb_type->class_type == LUT_CLASS) {
443  /* LUTs will have a child node that is used to indicate pin
444  * equivalence for routing purposes.
445  * There is a crossbar to the child node; however,
446  * this interconnect does not exist in FPGA hardware and should
447  * be ignored for power calculations. */
448  estimate_buffers_and_wire = FALSE;
449  estimate_multiplexers = FALSE;
450  }
451 
452  if (pb_node->pb_type->num_modes == 0) {
453  /* This is a leaf node, which is a primitive (lut, ff, etc) */
454  if (estimate_primitives) {
455  assert(pb_node->pb_type->blif_model);
456  power_usage_primitive(&power_usage_sub, pb, pb_node);
457 
458  // Add to power of this PB
459  power_add_usage(power_usage, &power_usage_sub);
460 
461  // Add to power of component type
462  power_component_add_usage(&power_usage_sub,
464 
465  }
466 
467  } else {
468  /* This node had children. The power of this node is the sum of:
469  * - Buffers/Wires in Interconnect from Parent to children
470  * - Multiplexers in Interconnect from Parent to children
471  * - Child nodes
472  */
473 
474  if (estimate_buffers_and_wire) {
475  /* Check pins of all interconnect */
476  power_usage_local_buffers_and_wires(&power_usage_bufs_wires, pb,
477  pb_node);
478  power_component_add_usage(&power_usage_bufs_wires,
482  &power_usage_bufs_wires);
483  power_add_usage(power_usage, &power_usage_bufs_wires);
484  }
485 
486  /* Interconnect Structures (multiplexers) */
487  if (estimate_multiplexers) {
488  power_zero_usage(&power_usage_local_muxes);
489  for (interc_idx = 0;
490  interc_idx < pb_type->modes[pb_mode].num_interconnect;
491  interc_idx++) {
492  power_usage_local_interc_mux(&power_usage_sub, pb,
493  &pb_node->interconnect_pins[pb_mode][interc_idx]);
494  power_add_usage(&power_usage_local_muxes, &power_usage_sub);
495 
496  }
497  // Add to power of this PB
498  power_add_usage(power_usage, &power_usage_local_muxes);
499 
500  // Add to component type power
501  power_component_add_usage(&power_usage_local_muxes,
503 
504  // Add to power of this mode
506  &pb_node->pb_type->modes[pb_mode].mode_power->power_usage,
507  &power_usage_local_muxes);
508  }
509 
510  /* Add power for children */
511  if (recursive_children) {
512  power_zero_usage(&power_usage_children);
513  for (pb_type_idx = 0;
514  pb_type_idx
515  < pb_node->pb_type->modes[pb_mode].num_pb_type_children;
516  pb_type_idx++) {
517  for (pb_idx = 0;
518  pb_idx
519  < pb_node->pb_type->modes[pb_mode].pb_type_children[pb_type_idx].num_pb;
520  pb_idx++) {
521  t_pb * child_pb = NULL;
522  t_pb_graph_node * child_pb_graph_node;
523 
524  if (pb && pb->child_pbs[pb_type_idx][pb_idx].name) {
525  /* Child is initialized */
526  child_pb = &pb->child_pbs[pb_type_idx][pb_idx];
527  }
528  child_pb_graph_node =
529  &pb_node->child_pb_graph_nodes[pb_mode][pb_type_idx][pb_idx];
530 
531  power_usage_pb(&power_usage_sub, child_pb,
532  child_pb_graph_node);
533  power_add_usage(&power_usage_children, &power_usage_sub);
534  }
535  }
536  // Add to power of this PB
537  power_add_usage(power_usage, &power_usage_children);
538 
539  // Add to power of this mode
541  &pb_node->pb_type->modes[pb_mode].mode_power->power_usage,
542  &power_usage_children);
543  }
544  }
545 
546  power_add_usage(&pb_node->pb_type->pb_type_power->power_usage, power_usage);
547 }
548 
549 /* Resets the power stats for all physical blocks */
550 static void power_reset_pb_type(t_pb_type * pb_type) {
551  int mode_idx;
552  int child_idx;
553  int interc_idx;
554 
557 
558  for (mode_idx = 0; mode_idx < pb_type->num_modes; mode_idx++) {
559  power_zero_usage(&pb_type->modes[mode_idx].mode_power->power_usage);
560 
561  for (child_idx = 0;
562  child_idx < pb_type->modes[mode_idx].num_pb_type_children;
563  child_idx++) {
565  &pb_type->modes[mode_idx].pb_type_children[child_idx]);
566  }
567  for (interc_idx = 0;
568  interc_idx < pb_type->modes[mode_idx].num_interconnect;
569  interc_idx++) {
571  &pb_type->modes[mode_idx].interconnect[interc_idx].interconnect_power->power_usage);
572  }
573  }
574 }
575 
576 /**
577  * Resets the power usage for all tile types
578  */
579 static void power_reset_tile_usage(void) {
580  int type_idx;
581 
582  for (type_idx = 0; type_idx < num_types; type_idx++) {
583  if (type_descriptors[type_idx].pb_type) {
584  power_reset_pb_type(type_descriptors[type_idx].pb_type);
585  }
586  }
587 }
588 
589 /*
590  * Calcultes the power usage of all tiles in the FPGA
591  */
592 static void power_usage_blocks(t_power_usage * power_usage) {
593  int x, y, z;
594 
595  power_zero_usage(power_usage);
596 
598 
599  /* Loop through all grid locations */
600  for (x = 0; x < nx + 2; x++) {
601  for (y = 0; y < ny + 2; y++) {
602 
603  if ((grid[x][y].offset != 0) || (grid[x][y].type == EMPTY_TYPE)) {
604  continue;
605  }
606 
607  for (z = 0; z < grid[x][y].type->capacity; z++) {
608  t_pb * pb = NULL;
609  t_power_usage pb_power;
610 
611  if (grid[x][y].blocks[z] != OPEN) {
612  pb = block[grid[x][y].blocks[z]].pb;
613  }
614 
615  /* Calculate power of this CLB */
616  power_usage_pb(&pb_power, pb, grid[x][y].type->pb_graph_head);
617  power_add_usage(power_usage, &pb_power);
618  }
619  }
620  }
621  return;
622 }
623 
624 /**
625  * Calculates the total power usage from the clock network
626  */
627 static void power_usage_clock(t_power_usage * power_usage,
628  t_clock_arch * clock_arch) {
629  int clock_idx;
630 
631  /* Initialization */
632  power_usage->dynamic = 0.;
633  power_usage->leakage = 0.;
634 
635  /* if no global clock, then return */
636  if (clock_arch->num_global_clocks == 0) {
637  return;
638  }
639 
640  for (clock_idx = 0; clock_idx < clock_arch->num_global_clocks;
641  clock_idx++) {
642  t_power_usage clock_power;
643 
644  /* Assume the global clock is active even for combinational circuits */
645  if (clock_arch->num_global_clocks == 1) {
646  if (clock_arch->clock_inf[clock_idx].dens == 0) {
647  clock_arch->clock_inf[clock_idx].dens = 2;
648  clock_arch->clock_inf[clock_idx].prob = 0.5;
649 
650  // This will need to change for multi-clock
651  clock_arch->clock_inf[clock_idx].period = g_solution_inf.T_crit;
652  }
653  }
654  /* find the power dissipated by each clock network */
655  power_usage_clock_single(&clock_power,
656  &clock_arch->clock_inf[clock_idx]);
657  power_add_usage(power_usage, &clock_power);
658  }
659 
660  return;
661 }
662 
663 /**
664  * Calculates the power from a single spine-and-rib global clock
665  */
666 static void power_usage_clock_single(t_power_usage * power_usage,
667  t_clock_network * single_clock) {
668 
669  /*
670  *
671  * The following code assumes a spine-and-rib clock network as shown below.
672  * This is comprised of 3 main combonents:
673  * 1. A single wire from the io pad to the center of the chip
674  * 2. A H-structure which provides a 'spine' to all 4 quadrants
675  * 3. Ribs connect each spine with an entire column of blocks
676 
677  ___________________
678  | |
679  | |_|_|_2__|_|_|_ |
680  | | | | | | | | |
681  | |3| | | | | | |
682  | | |
683  | | | | | | | | |
684  | |_|_|__|_|_|_|_ |
685  | | | | | | | | |
686  |_______1|________|
687  * It is assumed that there are a single-inverter buffers placed along each wire,
688  * with spacing equal to the FPGA block size (1 buffer/block) */
689  t_power_usage clock_buffer_power;
690  int length;
691  t_power_usage buffer_power;
692  t_power_usage wire_power;
693  float C_segment;
694  float buffer_size;
695 
696  power_usage->dynamic = 0.;
697  power_usage->leakage = 0.;
698 
699  /* Check if this clock is active - this is used for calculating leakage */
700  if (single_clock->dens) {
701  } else {
702  assert(0);
703  }
704 
705  C_segment = g_power_commonly_used->tile_length * single_clock->C_wire;
706  if (single_clock->autosize_buffer) {
707  buffer_size = 1 + C_segment / g_power_commonly_used->INV_1X_C_in;
708  } else {
709  buffer_size = single_clock->buffer_size;
710  }
711 
712  /* Calculate the capacitance and leakage power for the clock buffer */
713  power_usage_inverter(&clock_buffer_power, single_clock->dens,
714  single_clock->prob, buffer_size, single_clock->period);
715 
716  length = 0;
717 
718  /* 1. IO to chip center */
719  length += (ny + 2) / 2;
720 
721  /* 2. H-Tree to 4 quadrants */
722  length += ny / 2 + 2 * nx;
723 
724  /* 3. Ribs - to */
725  length += nx / 2 * ny;
726 
727  buffer_power.dynamic = length * clock_buffer_power.dynamic;
728  buffer_power.leakage = length * clock_buffer_power.leakage;
729 
730  power_add_usage(power_usage, &buffer_power);
732 
733  power_usage_wire(&wire_power, length * C_segment, single_clock->dens,
734  single_clock->period);
735  power_add_usage(power_usage, &wire_power);
737 
738  return;
739 }
740 
741 /* Frees a multiplexer graph */
742 static void dealloc_mux_graph(t_mux_node * node) {
743  dealloc_mux_graph_rec(node);
744  free(node);
745 }
746 
747 static void dealloc_mux_graph_rec(t_mux_node * node) {
748  int child_idx;
749 
750  /* Dealloc Children */
751  if (node->level != 0) {
752  for (child_idx = 0; child_idx < node->num_inputs; child_idx++) {
753  dealloc_mux_graph_rec(&node->children[child_idx]);
754  }
755  free(node->children);
756  }
757 }
758 
759 /**
760  * Calculates the power of the entire routing fabric (not local routing
761  */
762 static void power_usage_routing(t_power_usage * power_usage,
763  t_det_routing_arch * routing_arch, t_segment_inf * segment_inf) {
764  int rr_node_idx;
765  int net_idx;
766  int edge_idx;
767 
768  power_zero_usage(power_usage);
769 
770  /* Reset routing statistics */
775 
776  /* Reset rr graph net indices */
777  for (rr_node_idx = 0; rr_node_idx < num_rr_nodes; rr_node_idx++) {
778  rr_node[rr_node_idx].net_num = OPEN;
779  rr_node_power[rr_node_idx].num_inputs = 0;
780  rr_node_power[rr_node_idx].selected_input = 0;
781  }
782 
783  /* Populate net indices into rr graph */
784  for (net_idx = 0; net_idx < num_nets; net_idx++) {
785  struct s_trace * trace;
786 
787  for (trace = trace_head[net_idx]; trace != NULL; trace = trace->next) {
788  rr_node_power[trace->index].visited = FALSE;
789  }
790  }
791 
792  /* Populate net indices into rr graph */
793  for (net_idx = 0; net_idx < num_nets; net_idx++) {
794  struct s_trace * trace;
795 
796  for (trace = trace_head[net_idx]; trace != NULL; trace = trace->next) {
797  t_rr_node * node = &rr_node[trace->index];
798  t_rr_node_power * node_power = &rr_node_power[trace->index];
799 
800  if (node_power->visited) {
801  continue;
802  }
803 
804  node->net_num = net_idx;
805 
806  for (edge_idx = 0; edge_idx < node->num_edges; edge_idx++) {
807  if (node->edges[edge_idx] != OPEN) {
808  t_rr_node * next_node = &rr_node[node->edges[edge_idx]];
809  t_rr_node_power * next_node_power =
810  &rr_node_power[node->edges[edge_idx]];
811 
812  switch (next_node->type) {
813  case CHANX:
814  case CHANY:
815  case IPIN:
816  if (next_node->net_num == node->net_num) {
817  next_node_power->selected_input =
818  next_node_power->num_inputs;
819  }
820  next_node_power->in_dens[next_node_power->num_inputs] =
821  clb_net_density(node->net_num);
822  next_node_power->in_prob[next_node_power->num_inputs] =
823  clb_net_prob(node->net_num);
824  next_node_power->num_inputs++;
825  if (next_node_power->num_inputs > next_node->fan_in) {
826  printf("%d %d\n", next_node_power->num_inputs,
827  next_node->fan_in);
828  fflush(0);
829  assert(0);
830  }
831  break;
832  default:
833  /* Do nothing */
834  break;
835  }
836  }
837  }
838  node_power->visited = TRUE;
839  }
840  }
841 
842  /* Calculate power of all routing entities */
843  for (rr_node_idx = 0; rr_node_idx < num_rr_nodes; rr_node_idx++) {
844  t_power_usage sub_power_usage;
845  t_rr_node * node = &rr_node[rr_node_idx];
846  t_rr_node_power * node_power = &rr_node_power[rr_node_idx];
847  float C_wire;
848  float buffer_size;
849  int switch_idx;
850  int connectionbox_fanout;
851  int switchbox_fanout;
852  //float C_per_seg_split;
853  int wire_length;
854 
855  switch (node->type) {
856  case SOURCE:
857  case SINK:
858  case OPIN:
859  /* No power usage for these types */
860  break;
861  case IPIN:
862  /* This is part of the connectionbox. The connection box is comprised of:
863  * - Driver (accounted for at end of CHANX/Y - see below)
864  * - Multiplexor */
865 
866  if (node->fan_in) {
867  assert(node_power->in_dens);
868  assert(node_power->in_prob);
869 
870  /* Multiplexor */
871  power_usage_mux_multilevel(&sub_power_usage,
874  node_power->in_prob, node_power->in_dens,
875  node_power->selected_input, TRUE,
877  power_add_usage(power_usage, &sub_power_usage);
878  power_component_add_usage(&sub_power_usage,
880  }
881  break;
882  case CHANX:
883  case CHANY:
884  /* This is a wire driven by a switchbox, which includes:
885  * - The Multiplexor at the beginning of the wire
886  * - A buffer, after the mux to drive the wire
887  * - The wire itself
888  * - A buffer at the end of the wire, going to switchbox/connectionbox */
889  assert(node_power->in_dens);
890  assert(node_power->in_prob);
891 
892  wire_length = 0;
893  if (node->type == CHANX) {
894  wire_length = node->xhigh - node->xlow + 1;
895  } else if (node->type == CHANY) {
896  wire_length = node->yhigh - node->ylow + 1;
897  }
898  C_wire =
899  wire_length
900  * segment_inf[rr_indexed_data[node->cost_index].seg_index].Cmetal;
901  //(double)g_power_commonly_used->tile_length);
902  assert(node_power->selected_input < node->fan_in);
903 
904  /* Multiplexor */
905  power_usage_mux_multilevel(&sub_power_usage,
908  node_power->in_prob, node_power->in_dens,
909  node_power->selected_input, TRUE, g_solution_inf.T_crit);
910  power_add_usage(power_usage, &sub_power_usage);
911  power_component_add_usage(&sub_power_usage,
913 
914  /* Buffer Size */
915  switch (switch_inf[node_power->driver_switch_type].power_buffer_type) {
917  /*
918  C_per_seg_split = ((float) node->num_edges
919  * g_power_commonly_used->INV_1X_C_in + C_wire);
920  // / (float) g_power_arch->seg_buffer_split;
921  buffer_size = power_buffer_size_from_logical_effort(
922  C_per_seg_split);
923  buffer_size = max(buffer_size, 1.0F);
924  */
925  buffer_size = power_calc_buffer_size_from_Cout(
926  switch_inf[node_power->driver_switch_type].Cout);
927  break;
929  buffer_size =
931  buffer_size = max(buffer_size, 1.0F);
932  break;
934  buffer_size = 0.;
935  break;
936  default:
937  buffer_size = 0.;
938  assert(0);
939  break;
940  }
941 
944 
945  /*
946  g_power_commonly_used->num_sb_buffers +=
947  g_power_arch->seg_buffer_split;
948  g_power_commonly_used->total_sb_buffer_size += buffer_size
949  * g_power_arch->seg_buffer_split;
950  */
951 
952  /* Buffer */
953  power_usage_buffer(&sub_power_usage, buffer_size,
954  node_power->in_prob[node_power->selected_input],
955  node_power->in_dens[node_power->selected_input], TRUE,
957  power_add_usage(power_usage, &sub_power_usage);
958  power_component_add_usage(&sub_power_usage,
960 
961  /* Wire Capacitance */
962  power_usage_wire(&sub_power_usage, C_wire,
964  power_add_usage(power_usage, &sub_power_usage);
965  power_component_add_usage(&sub_power_usage,
967 
968  /* Determine types of switches that this wire drives */
969  connectionbox_fanout = 0;
970  switchbox_fanout = 0;
971  for (switch_idx = 0; switch_idx < node->num_edges; switch_idx++) {
972  if (node->switches[switch_idx]
973  == routing_arch->wire_to_ipin_switch) {
974  connectionbox_fanout++;
975  } else if (node->switches[switch_idx]
976  == routing_arch->delayless_switch) {
977  /* Do nothing */
978  } else {
979  switchbox_fanout++;
980  }
981  }
982 
983  /* Buffer to next Switchbox */
984  if (switchbox_fanout) {
986  switchbox_fanout * g_power_commonly_used->NMOS_1X_C_d);
987  power_usage_buffer(&sub_power_usage, buffer_size,
988  1 - node_power->in_prob[node_power->selected_input],
989  node_power->in_dens[node_power->selected_input], FALSE,
991  power_add_usage(power_usage, &sub_power_usage);
992  power_component_add_usage(&sub_power_usage,
994  }
995 
996  /* Driver for ConnectionBox */
997  if (connectionbox_fanout) {
998 
1000  connectionbox_fanout
1002 
1003  power_usage_buffer(&sub_power_usage, buffer_size,
1004  node_power->in_dens[node_power->selected_input],
1005  1 - node_power->in_prob[node_power->selected_input],
1007  power_add_usage(power_usage, &sub_power_usage);
1008  power_component_add_usage(&sub_power_usage,
1010 
1013  }
1014  break;
1015  case INTRA_CLUSTER_EDGE:
1016  assert(0);
1017  break;
1018  default:
1020  "The global routing-resource graph contains an unknown node type.");
1021  break;
1022  }
1023  }
1024 }
1025 
1027  int port_idx;
1028  t_port * port_to_find;
1029  t_pb_graph_node * node = pin->parent_node;
1030  boolean found;
1031 
1032  pin->pin_power = (t_pb_graph_pin_power*) malloc(
1033  sizeof(t_pb_graph_pin_power));
1034  pin->pin_power->C_wire = 0.;
1035  pin->pin_power->buffer_size = 0.;
1036  pin->pin_power->scaled_by_pin = NULL;
1037 
1038  if (pin->port->port_power->scaled_by_port) {
1039 
1040  port_to_find = pin->port->port_power->scaled_by_port;
1041 
1042  /*pin->pin_power->scaled_by_pin =
1043  get_pb_graph_node_pin_from_model_port_pin(
1044  port_to_find->model_port,
1045  pin->port->port_power->scaled_by_port_pin_idx,
1046  pin->parent_node);*/
1047  /* Search input, output, clock ports */
1048 
1049  found = FALSE;
1050  for (port_idx = 0; port_idx < node->num_input_ports; port_idx++) {
1051  if (node->input_pins[port_idx][0].port == port_to_find) {
1052  pin->pin_power->scaled_by_pin =
1053  &node->input_pins[port_idx][pin->port->port_power->scaled_by_port_pin_idx];
1054  found = TRUE;
1055  break;
1056  }
1057  }
1058  if (!found) {
1059  for (port_idx = 0; port_idx < node->num_output_ports; port_idx++) {
1060  if (node->output_pins[port_idx][0].port == port_to_find) {
1061  pin->pin_power->scaled_by_pin =
1062  &node->output_pins[port_idx][pin->port->port_power->scaled_by_port_pin_idx];
1063  found = TRUE;
1064  break;
1065  }
1066  }
1067  }
1068  if (!found) {
1069  for (port_idx = 0; port_idx < node->num_clock_ports; port_idx++) {
1070  if (node->clock_pins[port_idx][0].port == port_to_find) {
1071  pin->pin_power->scaled_by_pin =
1072  &node->clock_pins[port_idx][pin->port->port_power->scaled_by_port_pin_idx];
1073  found = TRUE;
1074  break;
1075  }
1076  }
1077  }
1078  assert(found);
1079 
1080  assert(pin->pin_power->scaled_by_pin);
1081  }
1082 }
1083 
1085  int mode;
1086  int type;
1087  int pb;
1088  int port_idx;
1089  int pin_idx;
1090 
1091  for (port_idx = 0; port_idx < pb_node->num_input_ports; port_idx++) {
1092  for (pin_idx = 0; pin_idx < pb_node->num_input_pins[port_idx];
1093  pin_idx++) {
1095  &pb_node->input_pins[port_idx][pin_idx]);
1096  }
1097  }
1098 
1099  for (port_idx = 0; port_idx < pb_node->num_output_ports; port_idx++) {
1100  for (pin_idx = 0; pin_idx < pb_node->num_output_pins[port_idx];
1101  pin_idx++) {
1103  &pb_node->output_pins[port_idx][pin_idx]);
1104  }
1105  }
1106 
1107  for (port_idx = 0; port_idx < pb_node->num_clock_ports; port_idx++) {
1108  for (pin_idx = 0; pin_idx < pb_node->num_clock_pins[port_idx];
1109  pin_idx++) {
1111  &pb_node->clock_pins[port_idx][pin_idx]);
1112  }
1113  }
1114 
1115  for (mode = 0; mode < pb_node->pb_type->num_modes; mode++) {
1116  for (type = 0;
1117  type < pb_node->pb_type->modes[mode].num_pb_type_children;
1118  type++) {
1119  for (pb = 0;
1120  pb
1121  < pb_node->pb_type->modes[mode].pb_type_children[type].num_pb;
1122  pb++) {
1124  &pb_node->child_pb_graph_nodes[mode][type][pb]);
1125  }
1126  }
1127  }
1128 }
1129 
1131  int type_idx;
1132 
1133  for (type_idx = 0; type_idx < num_types; type_idx++) {
1134  if (type_descriptors[type_idx].pb_graph_head) {
1135  power_init_pb_pins_rec(type_descriptors[type_idx].pb_graph_head);
1136  }
1137  }
1138 }
1139 
1141  int net_idx;
1142  int rr_node_idx;
1143  int max_fanin;
1144  int max_IPIN_fanin;
1145  int max_seg_to_IPIN_fanout;
1146  int max_seg_to_seg_fanout;
1147  int max_seg_fanout;
1148 
1149  /* Copy probability/density values to new netlist */
1150  for (net_idx = 0; net_idx < num_nets; net_idx++) {
1151  if (!clb_net[net_idx].net_power) {
1152  clb_net[net_idx].net_power = new t_net_power;
1153  }
1154  clb_net[net_idx].net_power->probability =
1156  clb_net[net_idx].net_power->density =
1158  }
1159 
1160  /* Initialize RR Graph Structures */
1162  sizeof(t_rr_node_power));
1163  for (rr_node_idx = 0; rr_node_idx < num_rr_nodes; rr_node_idx++) {
1164  rr_node_power[rr_node_idx].driver_switch_type = OPEN;
1165 
1166  }
1167 
1168  /* Initialize Mux Architectures */
1169  max_fanin = 0;
1170  max_IPIN_fanin = 0;
1171  max_seg_to_seg_fanout = 0;
1172  max_seg_to_IPIN_fanout = 0;
1173  for (rr_node_idx = 0; rr_node_idx < num_rr_nodes; rr_node_idx++) {
1174  int switch_idx;
1175  int fanout_to_IPIN = 0;
1176  int fanout_to_seg = 0;
1177  t_rr_node * node = &rr_node[rr_node_idx];
1178  t_rr_node_power * node_power = &rr_node_power[rr_node_idx];
1179 
1180  switch (node->type) {
1181  case IPIN:
1182  max_IPIN_fanin = max(max_IPIN_fanin,
1183  static_cast<int>(node->fan_in));
1184  max_fanin = max(max_fanin, static_cast<int>(node->fan_in));
1185 
1186  node_power->in_dens = (float*) my_calloc(node->fan_in,
1187  sizeof(float));
1188  node_power->in_prob = (float*) my_calloc(node->fan_in,
1189  sizeof(float));
1190  break;
1191  case CHANX:
1192  case CHANY:
1193  for (switch_idx = 0; switch_idx < node->num_edges; switch_idx++) {
1194  if (node->switches[switch_idx]
1195  == routing_arch->wire_to_ipin_switch) {
1196  fanout_to_IPIN++;
1197  } else if (node->switches[switch_idx]
1198  != routing_arch->delayless_switch) {
1199  fanout_to_seg++;
1200  }
1201  }
1202  max_seg_to_IPIN_fanout = max(max_seg_to_IPIN_fanout,
1203  fanout_to_IPIN);
1204  max_seg_to_seg_fanout = max(max_seg_to_seg_fanout, fanout_to_seg);
1205  max_fanin = max(max_fanin, static_cast<int>(node->fan_in));
1206 
1207  node_power->in_dens = (float*) my_calloc(node->fan_in,
1208  sizeof(float));
1209  node_power->in_prob = (float*) my_calloc(node->fan_in,
1210  sizeof(float));
1211  break;
1212  default:
1213  /* Do nothing */
1214  break;
1215  }
1216  }
1218  g_power_commonly_used->max_IPIN_fanin = max_IPIN_fanin;
1219  g_power_commonly_used->max_seg_to_seg_fanout = max_seg_to_seg_fanout;
1220  g_power_commonly_used->max_seg_to_IPIN_fanout = max_seg_to_IPIN_fanout;
1221 
1222 #if (PRINT_SPICE_COMPARISON)
1225 #endif
1226 
1227  /* Populate driver switch type */
1228  for (rr_node_idx = 0; rr_node_idx < num_rr_nodes; rr_node_idx++) {
1229  t_rr_node * node = &rr_node[rr_node_idx];
1230  int edge_idx;
1231 
1232  for (edge_idx = 0; edge_idx < node->num_edges; edge_idx++) {
1233  if (node->edges[edge_idx] != OPEN) {
1234  if (rr_node_power[node->edges[edge_idx]].driver_switch_type
1235  == OPEN) {
1236  rr_node_power[node->edges[edge_idx]].driver_switch_type =
1237  node->switches[edge_idx];
1238  } else {
1239  assert(
1240  rr_node_power[node->edges[edge_idx]].driver_switch_type
1241  == node->switches[edge_idx]);
1242  }
1243  }
1244  }
1245  }
1246 
1247  /* Find Max Fanout of Routing Buffer */
1248  max_seg_fanout = 0;
1249  for (rr_node_idx = 0; rr_node_idx < num_rr_nodes; rr_node_idx++) {
1250  t_rr_node * node = &rr_node[rr_node_idx];
1251 
1252  switch (node->type) {
1253  case CHANX:
1254  case CHANY:
1255  if (node->num_edges > max_seg_fanout) {
1256  max_seg_fanout = node->num_edges;
1257  }
1258  break;
1259  default:
1260  /* Do nothing */
1261  break;
1262  }
1263  }
1264  g_power_commonly_used->max_seg_fanout = max_seg_fanout;
1265 }
1266 
1267 /**
1268  * Initialization for all power-related functions
1269  */
1270 boolean power_init(char * power_out_filepath,
1271  char * cmos_tech_behavior_filepath, t_arch * arch,
1272  t_det_routing_arch * routing_arch) {
1273  boolean error = FALSE;
1274 
1275  /* Set global power architecture & options */
1276  g_power_arch = arch->power;
1280 
1281  /* Set up Logs */
1284  sizeof(t_log));
1287 
1288  /* Initialize output file */
1289  if (!error) {
1290  g_power_output->out = NULL;
1291  g_power_output->out = my_fopen(power_out_filepath, "w", 0);
1292  if (!g_power_output->out) {
1293  error = TRUE;
1294  }
1295  }
1296 
1297  /* Load technology properties */
1298  power_tech_init(cmos_tech_behavior_filepath);
1299 
1300  /* Low-Level Initialization */
1302 
1303  /* Initialize sub-modules */
1305 
1306  /* Perform callibration */
1307  power_callibrate();
1308 
1309  /* Initialize routing information */
1310  power_routing_init(routing_arch);
1311 
1312 // Allocates power structures for each pb pin
1314 
1315  /* Size all components */
1316  power_sizing_init(arch);
1317 
1318  //power_print_spice_comparison();
1319 
1320  return error;
1321 }
1322 
1323 /**
1324  * Uninitialize power module
1325  */
1326 boolean power_uninit(void) {
1327  int mux_size;
1328  int log_idx;
1329  int rr_node_idx;
1330  int msg_idx;
1331  boolean error = FALSE;
1332 
1333  for (rr_node_idx = 0; rr_node_idx < num_rr_nodes; rr_node_idx++) {
1334  t_rr_node * node = &rr_node[rr_node_idx];
1335  t_rr_node_power * node_power = &rr_node_power[rr_node_idx];
1336 
1337  switch (node->type) {
1338  case CHANX:
1339  case CHANY:
1340  case IPIN:
1341  if (node->fan_in) {
1342  free(node_power->in_dens);
1343  free(node_power->in_prob);
1344  }
1345  break;
1346  default:
1347  /* Do nothing */
1348  break;
1349  }
1350  }
1351  free(rr_node_power);
1352 
1353  /* Free mux architectures */
1354  for (std::map<float, t_power_mux_info*>::iterator it =
1356  it != g_power_commonly_used->mux_info.end(); it++) {
1357  t_power_mux_info * mux_info = it->second;
1358  for (mux_size = 1; mux_size <= mux_info->mux_arch_max_size;
1359  mux_size++) {
1360  dealloc_mux_graph(mux_info->mux_arch[mux_size].mux_graph_head);
1361  }
1362  delete mux_info;
1363  }
1364  free(g_power_commonly_used);
1365 
1366  if (g_power_output->out) {
1367  fclose(g_power_output->out);
1368  }
1369 
1370  /* Free logs */
1371  for (log_idx = 0; log_idx < g_power_output->num_logs; log_idx++) {
1372  for (msg_idx = 0; msg_idx < g_power_output->logs[log_idx].num_messages;
1373  msg_idx++) {
1374  free(g_power_output->logs[log_idx].messages[msg_idx]);
1375  }
1376  free(g_power_output->logs[log_idx].messages);
1377  free(g_power_output->logs[log_idx].name);
1378  }
1379  free(g_power_output->logs);
1380  free(g_power_output);
1381 
1382  return error;
1383 }
1384 
1385 #if 0
1386 /**
1387  * Prints the power of all pb structures, in an xml format that matches the archicture file
1388  */
1389 static void power_print_pb_usage_recursive(FILE * fp, t_pb_type * type,
1390  int indent_level, float parent_power, float total_power) {
1391  int mode_idx;
1392  int mode_indent;
1393  int child_idx;
1394  int interc_idx;
1395  float pb_type_power;
1396 
1397  pb_type_power = type->pb_type_power->power_usage.dynamic
1399 
1400  print_tabs(fp, indent_level);
1401  fprintf(fp,
1402  "<pb_type name=\"%s\" P=\"%.4g\" P_parent=\"%.3g\" P_total=\"%.3g\" P_dyn=\"%.3g\" >\n",
1403  type->name, pb_type_power, pb_type_power / parent_power * 100,
1404  pb_type_power / total_power * 100,
1405  type->pb_type_power->power_usage.dynamic / pb_type_power);
1406 
1407  mode_indent = 0;
1408  if (type->num_modes > 1) {
1409  mode_indent = 1;
1410  }
1411 
1412  for (mode_idx = 0; mode_idx < type->num_modes; mode_idx++) {
1413  float mode_power;
1414  mode_power = type->modes[mode_idx].mode_power->power_usage.dynamic
1415  + type->modes[mode_idx].mode_power->power_usage.leakage;
1416 
1417  if (type->num_modes > 1) {
1418  print_tabs(fp, indent_level + mode_indent);
1419  fprintf(fp,
1420  "<mode name=\"%s\" P=\"%.4g\" P_parent=\"%.3g\" P_total=\"%.3g\" P_dyn=\"%.3g\">\n",
1421  type->modes[mode_idx].name, mode_power,
1422  mode_power / pb_type_power * 100,
1423  mode_power / total_power * 100,
1424  type->modes[mode_idx].mode_power->power_usage.dynamic
1425  / mode_power);
1426  }
1427 
1428  if (type->modes[mode_idx].num_interconnect) {
1429  /* Sum the interconnect power */
1430  t_power_usage interc_power_usage;
1431  float interc_total_power;
1432 
1433  power_zero_usage(&interc_power_usage);
1434  for (interc_idx = 0;
1435  interc_idx < type->modes[mode_idx].num_interconnect;
1436  interc_idx++) {
1437  power_add_usage(&interc_power_usage,
1438  &type->modes[mode_idx].interconnect[interc_idx].interconnect_power->power_usage);
1439  }
1440  interc_total_power = interc_power_usage.dynamic
1441  + interc_power_usage.leakage;
1442 
1443  /* All interconnect */
1444  print_tabs(fp, indent_level + mode_indent + 1);
1445  fprintf(fp,
1446  "<interconnect P=\"%.4g\" P_parent=\"%.3g\" P_total=\"%.3g\" P_dyn=\"%.3g\">\n",
1447  interc_total_power, interc_total_power / mode_power * 100,
1448  interc_total_power / total_power * 100,
1449  interc_power_usage.dynamic / interc_total_power);
1450  for (interc_idx = 0;
1451  interc_idx < type->modes[mode_idx].num_interconnect;
1452  interc_idx++) {
1453  float interc_power =
1454  type->modes[mode_idx].interconnect[interc_idx].interconnect_power->power_usage.dynamic
1455  + type->modes[mode_idx].interconnect[interc_idx].interconnect_power->power_usage.leakage;
1456  /* Each interconnect */
1457  print_tabs(fp, indent_level + mode_indent + 2);
1458  fprintf(fp,
1459  "<%s name=\"%s\" P=\"%.4g\" P_parent=\"%.3g\" P_total=\"%.3g\" P_dyn=\"%.3g\"/>\n",
1461  type->modes[mode_idx].interconnect[interc_idx].type),
1462  type->modes[mode_idx].interconnect[interc_idx].name,
1463  interc_power, interc_power / interc_total_power * 100,
1464  interc_power / total_power * 100,
1465  type->modes[mode_idx].interconnect[interc_idx].interconnect_power->power_usage.dynamic
1466  / interc_power);
1467  }
1468  print_tabs(fp, indent_level + mode_indent + 1);
1469  fprintf(fp, "</interconnect>\n");
1470  }
1471 
1472  for (child_idx = 0;
1473  child_idx < type->modes[mode_idx].num_pb_type_children;
1474  child_idx++) {
1475  power_print_pb_usage_recursive(fp,
1476  &type->modes[mode_idx].pb_type_children[child_idx],
1477  indent_level + mode_indent + 1,
1478  type->modes[mode_idx].mode_power->power_usage.dynamic
1479  + type->modes[mode_idx].mode_power->power_usage.leakage,
1480  total_power);
1481  }
1482 
1483  if (type->num_modes > 1) {
1484  print_tabs(fp, indent_level + mode_indent);
1485  fprintf(fp, "</mode>\n");
1486  }
1487  }
1488 
1489  print_tabs(fp, indent_level);
1490  fprintf(fp, "</pb_type>\n");
1491 }
1492 
1493 static void power_print_clb_detailed(FILE * fp) {
1494  int type_idx;
1495 
1496  float clb_power_total = power_component_get_usage_sum(
1498  for (type_idx = 0; type_idx < num_types; type_idx++) {
1499  if (!type_descriptors[type_idx].pb_type) {
1500  continue;
1501  }
1502 
1503  power_print_pb_usage_recursive(fp, type_descriptors[type_idx].pb_type,
1504  0, clb_power_total, clb_power_total);
1505  }
1506 }
1507 #endif
1508 
1509 /*
1510  static void power_print_stats(FILE * fp) {
1511  fprintf(fp, "Max Segment Fanout: %d\n",
1512  g_power_commonly_used->max_seg_fanout);
1513  fprintf(fp, "Max Segment->Segment Fanout: %d\n",
1514  g_power_commonly_used->max_seg_to_seg_fanout);
1515  fprintf(fp, "Max Segment->IPIN Fanout: %d\n",
1516  g_power_commonly_used->max_seg_to_IPIN_fanout);
1517  fprintf(fp, "Max IPIN fanin: %d\n", g_power_commonly_used->max_IPIN_fanin);
1518  fprintf(fp, "Average SB Buffer Size: %.1f\n",
1519  g_power_commonly_used->total_sb_buffer_size
1520  / (float) g_power_commonly_used->num_sb_buffers);
1521  fprintf(fp, "SB Buffer Transistors: %g\n",
1522  power_count_transistors_buffer(
1523  g_power_commonly_used->total_sb_buffer_size
1524  / (float) g_power_commonly_used->num_sb_buffers));
1525  fprintf(fp, "Average CB Buffer Size: %.1f\n",
1526  g_power_commonly_used->total_cb_buffer_size
1527  / (float) g_power_commonly_used->num_cb_buffers);
1528  fprintf(fp, "Tile length (um): %.2f\n",
1529  g_power_commonly_used->tile_length * CONVERT_UM_PER_M);
1530  fprintf(fp, "1X Inverter C_in: %g\n", g_power_commonly_used->INV_1X_C_in);
1531  fprintf(fp, "\n");
1532  }
1533  */
1534 
1536  e_power_estimation_method power_method) {
1537  switch (power_method) {
1539  return "Undefined";
1540  case POWER_METHOD_IGNORE:
1541  return "Ignore";
1543  return "Transistor Auto-Size";
1545  return "Transistor Specify-Size";
1547  return "Pin-Toggle";
1549  return "C-Internal";
1550  case POWER_METHOD_ABSOLUTE:
1551  return "Absolute";
1553  return "Sum of Children";
1554  default:
1555  return "Unkown";
1556  }
1557 }
1558 
1559 static void power_print_breakdown_pb_rec(FILE * fp, t_pb_type * pb_type,
1560  int indent) {
1561  int mode_idx;
1562  int child_idx;
1563  int i;
1564  char buf[51];
1565  int child_indent;
1566  int interc_idx;
1567  t_mode * mode;
1568  t_power_usage interc_usage;
1569  e_power_estimation_method est_method =
1570  pb_type->pb_type_power->estimation_method;
1572  t_pb_type_power * pb_power = pb_type->pb_type_power;
1573 
1574  for (i = 0; i < indent; i++) {
1575  buf[i] = ' ';
1576  }
1577  strncpy(buf + indent, pb_type->name, 50 - indent);
1578  buf[50] = '\0';
1579  buf[strlen((pb_type->name)) + indent] = '\0';
1581  pb_type->name, power_sum_usage(&pb_power->power_usage), total_power,
1582  power_perc_dynamic(&pb_power->power_usage),
1584  pb_type->pb_type_power->estimation_method));
1585 
1587  pb_type->pb_type_power->estimation_method)) {
1588  /* Local bufs and wires */
1589  power_print_breakdown_entry(fp, indent + 1,
1591  power_sum_usage(&pb_power->power_usage_bufs_wires), total_power,
1592  power_perc_dynamic(&pb_power->power_usage_bufs_wires), NULL);
1593  }
1594 
1595  if (power_method_is_recursive(est_method)) {
1596  if (pb_type->num_modes > 1) {
1597  child_indent = indent + 2;
1598  } else {
1599  child_indent = indent + 1;
1600  }
1601 
1602  for (mode_idx = 0; mode_idx < pb_type->num_modes; mode_idx++) {
1603  mode = &pb_type->modes[mode_idx];
1604 
1605  if (pb_type->num_modes > 1) {
1606  power_print_breakdown_entry(fp, indent + 1,
1609  total_power,
1611  NULL);
1612  }
1613 
1614  /* Interconnect Power */
1615  power_zero_usage(&interc_usage);
1616 
1617  /* Sum the interconnect */
1618  if (power_method_is_transistor_level(est_method)) {
1619  for (interc_idx = 0; interc_idx < mode->num_interconnect;
1620  interc_idx++) {
1621  power_add_usage(&interc_usage,
1622  &mode->interconnect[interc_idx].interconnect_power->power_usage);
1623  }
1624  if (mode->num_interconnect) {
1625  power_print_breakdown_entry(fp, child_indent,
1627  power_sum_usage(&interc_usage), total_power,
1628  power_perc_dynamic(&interc_usage), NULL);
1629  }
1630 
1631  /* Print Interconnect Breakdown */
1632  for (interc_idx = 0; interc_idx < mode->num_interconnect;
1633  interc_idx++) {
1634  t_interconnect * interc = &mode->interconnect[interc_idx];
1635  if (interc->type == DIRECT_INTERC) {
1636  // no power - skip
1637  } else {
1638  power_print_breakdown_entry(fp, child_indent + 1,
1641  &interc->interconnect_power->power_usage),
1642  total_power,
1644  &interc->interconnect_power->power_usage),
1645  NULL);
1646  }
1647  }
1648  }
1649 
1650  for (child_idx = 0;
1651  child_idx < pb_type->modes[mode_idx].num_pb_type_children;
1652  child_idx++) {
1654  &pb_type->modes[mode_idx].pb_type_children[child_idx],
1655  child_indent);
1656  }
1657  }
1658  }
1659 }
1660 
1661 static void power_print_summary(FILE * fp, t_vpr_setup vpr_setup) {
1662  char * arch;
1663  char * arch_new;
1664 
1665  /* Extract filename from full path */
1666  arch = vpr_setup.FileNameOpts.ArchFile;
1667 
1668  arch_new = strrchr(vpr_setup.FileNameOpts.ArchFile, '/');
1669  if (arch_new)
1670  arch = arch_new + 1;
1671 
1672  arch_new = strrchr(vpr_setup.FileNameOpts.ArchFile, '\\');
1673  if (arch_new)
1674  arch = arch_new + 1;
1675 
1676  fprintf(g_power_output->out, "Circuit: %s\n",
1677  vpr_setup.FileNameOpts.CircuitName);
1678  fprintf(g_power_output->out, "Architecture: %s\n", arch);
1679  fprintf(fp, "Technology (nm): %.0f\n",
1681  fprintf(fp, "Voltage: %.2f\n", g_power_tech->Vdd);
1682  fprintf(fp, "Temperature: %g\n", g_power_tech->temperature);
1683  fprintf(fp, "Critical Path: %g\n", g_solution_inf.T_crit);
1684  fprintf(fp, "Size of FPGA: %d x %d\n", nx, ny);
1685  fprintf(fp, "Channel Width: %d\n", g_solution_inf.channel_width);
1686  fprintf(fp, "\n");
1687 }
1688 
1689 /*
1690  * Top-level function for the power module.
1691  * Calculates the average power of the entire FPGA (watts),
1692  * and prints it to the output file
1693  * - run_time_s: (Return value) The total runtime in seconds (us accuracy)
1694  */
1695 e_power_ret_code power_total(float * run_time_s, t_vpr_setup vpr_setup,
1696  t_arch * arch, t_det_routing_arch * routing_arch) {
1697  t_power_usage total_power;
1698  t_power_usage sub_power_usage;
1699  clock_t t_start;
1700  clock_t t_end;
1701  t_power_usage clb_power_usage;
1702 
1703  t_start = clock();
1704 
1705  power_zero_usage(&total_power);
1706 
1707  if (routing_arch->directionality == BI_DIRECTIONAL) {
1709  "Cannot calculate routing power for bi-directional architectures");
1710  return POWER_RET_CODE_ERRORS;
1711  }
1712 
1713  /* Calculate Power */
1714  /* Routing */
1715  power_usage_routing(&sub_power_usage, routing_arch, arch->Segments);
1716  power_add_usage(&total_power, &sub_power_usage);
1718 
1719  /* Clock */
1720  power_usage_clock(&sub_power_usage, arch->clocks);
1721  power_add_usage(&total_power, &sub_power_usage);
1723 
1724  /* CLBs */
1725  power_usage_blocks(&clb_power_usage);
1726  power_add_usage(&total_power, &clb_power_usage);
1727  power_component_add_usage(&clb_power_usage, POWER_COMPONENT_PB);
1728 
1730 
1731  power_print_title(g_power_output->out, "Summary");
1732  power_print_summary(g_power_output->out, vpr_setup);
1733 
1734  /* Print Error & Warning Logs */
1737 
1738  //power_print_title(g_power_output->out, "Statistics");
1739  //power_print_stats(g_power_output->out);
1740 
1741  power_print_title(g_power_output->out, "Power Breakdown");
1743 
1744  power_print_title(g_power_output->out, "Power Breakdown by PB");
1746 
1747  //power_print_title(g_power_output->out, "Spice Comparison");
1748  //power_print_spice_comparison();
1749 
1750  t_end = clock();
1751 
1752  *run_time_s = (float) (t_end - t_start) / CLOCKS_PER_SEC;
1753 
1754  /* Return code */
1756  return POWER_RET_CODE_ERRORS;
1758  return POWER_RET_CODE_WARNINGS;
1759  } else {
1760  return POWER_RET_CODE_SUCCESS;
1761  }
1762 }
1763 
1764 /**
1765  * Prints the power usage for all components
1766  * - fp: File descripter to print out to
1767  */
1768 static void power_print_breakdown_summary(FILE * fp) {
1770  0., 0., 0., NULL);
1772  fprintf(fp, "\n");
1773 }
1774 
1775 static void power_print_breakdown_pb(FILE * fp) {
1776  fprintf(fp,
1777  "This sections provides a detailed breakdown of power usage by PB (physical\n"
1778  "block). For each PB, the power is listed, which is the sum power of all\n"
1779  "instances of the block. It also indicates its percentage of total power (entire\n"
1780  "FPGA), as well as the percentage of its power that is dynamic (vs. static). It\n"
1781  "also indicates the method used for power estimation.\n\n"
1782  "The data includes:\n"
1783  "\tModes:\t\tWhen a pb contains multiple modes, each mode is "
1784  "listed, with\n\t\t\t\tits power statistics.\n"
1785  "\tBufs/Wires:\tPower of all local "
1786  "buffers and local wire switching\n"
1787  "\t\t\t\t(transistor-level estimation only).\n"
1788  "\tInterc:\t\tPower of local interconnect multiplexers (transistor-\n"
1789  "\t\t\t\tlevel estimation only)\n\n"
1790  "Description of Estimation Methods:\n"
1791  "\tTransistor Auto-Size: Transistor-level power estimation. Local buffers and\n"
1792  "\t\twire lengths are automatically sized. This is the default estimation\n"
1793  "\t\tmethod.\n"
1794  "\tTransistor Specify-Size: Transistor-level power estimation. Local buffers\n"
1795  "\t\tand wire lengths are only inserted where specified by the user in the\n"
1796  "\t\tarchitecture file.\n"
1797  "\tPin-Toggle: Dynamic power is calculated using enery-per-toggle of the PB\n"
1798  "\t\tinput pins. Static power is absolute.\n"
1799  "\tC-Internal: Dynamic power is calculated using an internal equivalent\n"
1800  "\t\tcapacitance for PB type. Static power is absolute.\n"
1801  "\tAbsolute: Dynamic and static power are absolutes from the architecture file.\n"
1802  "\tSum of Children: Power of PB is only the sum of all child PBs; interconnect\n"
1803  "\t\tbetween the PB and its children is ignored.\n"
1804  "\tIgnore: Power of PB is ignored.\n\n\n");
1805 
1807  0., 0., 0., NULL);
1808 
1809  for (int type_idx = 0; type_idx < num_types; type_idx++) {
1810  if (type_descriptors[type_idx].pb_type) {
1812  type_descriptors[type_idx].pb_type, 0);
1813  }
1814  }
1815  fprintf(fp, "\n");
1816 }
1817 
1818 /**
1819  * Internal recurseive function, used by power_component_print_usage
1820  */
1821 static void power_print_breakdown_component(FILE * fp, char * name,
1822  e_power_component_type type, int indent_level) {
1823  power_print_breakdown_entry(fp, indent_level,
1829 
1830  switch (type) {
1831  case (POWER_COMPONENT_TOTAL):
1833  indent_level + 1);
1835  indent_level + 1);
1837  indent_level + 1);
1838  break;
1839  case (POWER_COMPONENT_ROUTING):
1840  power_print_breakdown_component(fp, "Switch Box",
1841  POWER_COMPONENT_ROUTE_SB, indent_level + 1);
1842  power_print_breakdown_component(fp, "Connection Box",
1843  POWER_COMPONENT_ROUTE_CB, indent_level + 1);
1844  power_print_breakdown_component(fp, "Global Wires",
1845  POWER_COMPONENT_ROUTE_GLB_WIRE, indent_level + 1);
1846  break;
1847  case (POWER_COMPONENT_CLOCK):
1848  /*
1849  power_print_breakdown_component(fp, "Clock Buffers",
1850  POWER_COMPONENT_CLOCK_BUFFER, indent_level + 1);
1851  power_print_breakdown_component(fp, "Clock Wires",
1852  POWER_COMPONENT_CLOCK_WIRE, indent_level + 1);
1853  */
1854  break;
1855  case (POWER_COMPONENT_PB):
1856  power_print_breakdown_component(fp, "Primitives",
1857  POWER_COMPONENT_PB_PRIMITIVES, indent_level + 1);
1858  power_print_breakdown_component(fp, "Interc Structures",
1859  POWER_COMPONENT_PB_INTERC_MUXES, indent_level + 1);
1860  power_print_breakdown_component(fp, "Buffers and Wires",
1861  POWER_COMPONENT_PB_BUFS_WIRE, indent_level + 1);
1862  power_print_breakdown_component(fp, "Other Estimation Methods",
1863  POWER_COMPONENT_PB_OTHER, indent_level + 1);
1864  break;
1865  default:
1866  break;
1867  }
1868 }
1869 
1870 static void power_print_breakdown_entry(FILE * fp, int indent,
1871  e_power_breakdown_entry_type type, char * name, float power,
1872  float total_power, float perc_dyn, char * method) {
1873  const int buf_size = 32;
1874  char buf[buf_size];
1875 
1876  switch (type) {
1878  fprintf(fp, "%-*s%-12s%-12s%-12s%-12s\n\n", buf_size, "Component",
1879  "Power (W)", "%-Total", "%-Dynamic", "Method");
1880  break;
1882  for (int i = 0; i < indent; i++)
1883  buf[i] = ' ';
1884  strcpy(buf + indent, "Mode:");
1885  strncpy(buf + indent + 5, name, buf_size - indent - 6);
1886  fprintf(fp, "%-*s%-12.4g%-12.4g%-12.4g\n", buf_size, buf, power,
1887  power / total_power, perc_dyn);
1888  break;
1892  for (int i = 0; i < indent; i++)
1893  buf[i] = ' ';
1894  strncpy(buf + indent, name, buf_size - indent - 1);
1895  buf[buf_size - 1] = '\0';
1896 
1897  fprintf(fp, "%-*s%-12.4g%-12.4g%-12.4g\n", buf_size, buf, power,
1898  power / total_power, perc_dyn);
1899  break;
1901  for (int i = 0; i < indent; i++)
1902  buf[i] = ' ';
1903  strncpy(buf + indent, name, buf_size - indent - 1);
1904  buf[buf_size - 1] = '\0';
1905 
1906  fprintf(fp, "%-*s%-12.4g%-12.4g%-12.4g%-12s\n", buf_size, buf, power,
1907  power / total_power, perc_dyn, method);
1908  break;
1909  default:
1910  break;
1911  }
1912 }
t_type_ptr type
Definition: vpr_types.h:522
void power_usage_wire(t_power_usage *power_usage, float capacitance, float density, float period)
static void power_usage_blocks(t_power_usage *power_usage)
Definition: power.c:592
#define CONVERT_NM_PER_M
Definition: power.c:50
short xhigh
Definition: vpr_types.h:891
static char * power_estimation_method_name(e_power_estimation_method power_method)
Definition: power.c:1535
struct s_net_power t_net_power
Definition: vpr_types.h:43
static void dealloc_mux_graph_rec(t_mux_node *node)
Definition: power.c:747
short num_edges
Definition: vpr_types.h:901
char * name
Definition: vpr_types.h:179
t_clock_network * clock_inf
t_interconnect * interconnect
t_pb_graph_pin ** clock_pins
t_power_tech * g_power_tech
Definition: power.c:67
enum e_pb_type_class class_type
t_power_arch * g_power_arch
Definition: power.c:68
FILE * out
Definition: power.h:200
int index
Definition: vpr_types.h:866
short cost_index
Definition: vpr_types.h:897
FILE * my_fopen(const char *fname, const char *flag, int prompt)
Definition: util.c:54
int * edges
Definition: vpr_types.h:903
t_port_power * port_power
t_power_arch * power
struct s_pb ** child_pbs
Definition: vpr_types.h:185
t_mux_arch * mux_arch
Definition: power.h:214
char * name
void power_callibrate(void)
float total_cb_buffer_size
Definition: power.h:262
void power_usage_mux_multilevel(t_power_usage *power_usage, t_mux_arch *mux_arch, float *in_prob, float *in_dens, int selected_input, boolean output_level_restored, float period)
struct s_pb_type * pb_type_children
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
float power_component_get_usage_sum(e_power_component_type component_idx)
t_rr_node * rr_node
Definition: globals.c:70
int net_num
Definition: vpr_types.h:917
e_power_estimation_method estimation_method
float clb_net_prob(int net_idx)
Definition: power_util.c:428
t_type_ptr EMPTY_TYPE
Definition: globals.c:41
int * clb_to_vpack_net_mapping
Definition: globals.c:33
short num_inputs
Definition: power.h:271
static void power_usage_routing(t_power_usage *power_usage, t_det_routing_arch *routing_arch, t_segment_inf *segment_inf)
Definition: power.c:762
t_rr_indexed_data * rr_indexed_data
Definition: globals.c:74
t_mode * modes
short delayless_switch
Definition: vpr_types.h:764
t_power_usage power_usage
static void power_print_breakdown_component(FILE *fp, char *name, e_power_component_type type, int indent_level)
Definition: power.c:1821
short ylow
Definition: vpr_types.h:892
float power_buffer_size_from_logical_effort(float C_load)
Definition: power_util.c:469
int num_interconnect
struct s_power_commonly_used t_power_commonly_used
Definition: power.h:62
boolean power_init(char *power_out_filepath, char *cmos_tech_behavior_filepath, t_arch *arch, t_det_routing_arch *routing_arch)
Definition: power.c:1270
float tech_size
Definition: power.h:134
t_power_commonly_used * g_power_commonly_used
Definition: power.c:66
void power_routing_init(t_det_routing_arch *routing_arch)
Definition: power.c:1140
float power_calc_node_switching(float capacitance, float density, float period)
void power_usage_local_interc_mux(t_power_usage *power_usage, t_pb *pb, t_interconnect_pins *interc_pins)
static void power_print_breakdown_pb(FILE *fp)
Definition: power.c:1775
void power_usage_ff(t_power_usage *power_usage, float size, float D_prob, float D_dens, float Q_prob, float Q_dens, float clk_prob, float clk_dens, float period)
float temperature
Definition: power.h:135
void * my_calloc(size_t nelem, size_t size)
Definition: util.c:132
t_pb_type_power * pb_type_power
static void power_print_breakdown_pb_rec(FILE *fp, t_pb_type *pb_type, int indent)
Definition: power.c:1559
int num_nets
Definition: globals.c:27
char * name
Definition: power.h:206
void power_sizing_init(t_arch *arch)
Definition: power_sizing.c:237
void power_lowlevel_init()
t_clock_arch * g_clock_arch
Definition: globals.c:97
e_power_breakdown_entry_type
Definition: power.c:54
struct s_linked_vptr * truth_table
Definition: vpr_types.h:227
char * alloc_SRAM_values_from_truth_table(int LUT_size, t_linked_vptr *truth_table)
Definition: power_util.c:273
char * blif_model
t_pb_graph_pin ** output_pins
static void power_print_summary(FILE *fp, t_vpr_setup vpr_setup)
Definition: power.c:1661
std::map< float, t_power_mux_info * > mux_info
Definition: power.h:245
t_log * logs
Definition: power.h:201
t_pb_graph_pin * scaled_by_pin
#define BUFSIZE
Definition: graphics.c:184
struct s_file_name_opts FileNameOpts
Definition: vpr_types.h:1034
char * interconnect_type_name(enum e_interconnect type)
Definition: power_util.c:436
short driver_switch_type
Definition: power.h:273
e_power_component_type
Definition: util.h:12
boolean power_uninit(void)
Definition: power.c:1326
int channel_width
Definition: power.h:84
boolean visited
Definition: power.h:268
t_power_output * g_power_output
Definition: power.c:65
t_solution_inf g_solution_inf
Definition: power.c:64
float * in_prob
Definition: power.h:270
int max_routing_mux_size
Definition: power.h:248
t_power_usage absolute_power_per_instance
t_mux_arch * power_get_mux_arch(int num_mux_inputs, float transistor_size)
Definition: power_util.c:490
int max_seg_to_IPIN_fanout
Definition: power.h:251
boolean power_method_is_transistor_level(e_power_estimation_method estimation_method)
Definition: power_util.c:576
static t_rr_node_power * rr_node_power
Definition: power.c:69
void power_components_init(void)
int max_seg_to_seg_fanout
Definition: power.h:252
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
struct s_trace * next
Definition: vpr_types.h:870
static void * my_malloc(int ibytes)
Definition: graphics.c:499
void power_alloc_and_init_pb_pin(t_pb_graph_pin *pin)
Definition: power.c:1026
t_clock_arch * clocks
int level
Definition: power.h:295
int num_logs
Definition: power.h:202
enum e_directionality directionality
Definition: vpr_types.h:758
#define max(a, b)
Definition: graphics.c:171
struct s_block * block
Definition: globals.c:31
static void power_usage_clock_single(t_power_usage *power_usage, t_clock_network *clock_inf)
Definition: power.c:666
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
char * CircuitName
Definition: vpr_types.h:577
int num_rr_nodes
Definition: globals.c:69
int nx
Definition: globals.c:46
void power_tech_init(char *cmos_tech_behavior_filepath)
struct s_pb_graph_node * parent_node
int logical_block
Definition: vpr_types.h:181
float * in_dens
Definition: power.h:269
struct s_trace ** trace_head
Definition: globals.c:64
void power_zero_usage(t_power_usage *power_usage)
Definition: power_util.c:44
struct s_switch_inf * switch_inf
Definition: globals.c:83
static void power_print_breakdown_summary(FILE *fp)
Definition: power.c:1768
enum e_interconnect type
boolean reverse_scaled
t_segment_inf * Segments
struct s_pb_graph_node *** child_pb_graph_nodes
int num_pb_type_children
int scaled_by_port_pin_idx
float total_sb_buffer_size
Definition: power.h:259
static void power_reset_tile_usage(void)
Definition: power.c:579
struct s_grid_tile ** grid
Definition: globals.c:59
int num_messages
Definition: power.h:208
float T_crit
Definition: power.h:83
static void power_reset_pb_type(t_pb_type *pb_type)
Definition: power.c:550
short fan_in
Definition: vpr_types.h:900
float pin_dens(t_pb *pb, t_pb_graph_pin *pin)
Definition: power_util.c:81
void power_component_add_usage(t_power_usage *power_usage, e_power_component_type component_idx)
int * blocks
Definition: vpr_types.h:525
float LUT_transistor_size
void power_usage_lut(t_power_usage *power_usage, int lut_size, float transistor_size, char *SRAM_values, float *input_prob, float *input_dens, float period)
struct s_pb_type * pb_type
short yhigh
Definition: vpr_types.h:893
void power_usage_local_pin_toggle(t_power_usage *power_usage, t_pb *pb, t_pb_graph_pin *pin)
Definition: power.c:204
float clb_net_density(int net_idx)
Definition: power_util.c:420
struct s_pb_type * pb_type
float energy_per_toggle
int num_types
Definition: globals.c:37
short * switches
Definition: vpr_types.h:904
float power_sum_usage(t_power_usage *power_usage)
Definition: power_util.c:59
static void power_usage_local_buffers_and_wires(t_power_usage *power_usage, t_pb *pb, t_pb_graph_node *pb_node)
Definition: power.c:248
float power_calc_buffer_size_from_Cout(float C_out)
static void power_usage_pb(t_power_usage *power_usage, t_pb *pb, t_pb_graph_node *pb_node)
Definition: power.c:293
static void power_usage_primitive(t_power_usage *power_usage, t_pb *pb, t_pb_graph_node *pb_graph_node)
Definition: power.c:123
float Vdd
Definition: power.h:132
short xlow
Definition: vpr_types.h:890
e_power_ret_code
Definition: power.h:42
Definition: slre.c:50
int num_inputs
Definition: power.h:292
t_pb * pb
Definition: vpr_types.h:567
void power_pb_pins_init()
Definition: power.c:1130
float power_buffer_size
float power_perc_dynamic(t_power_usage *power_usage)
Definition: power_util.c:63
boolean autosize_buffer
float density
Definition: vpr_types.h:490
static void power_print_breakdown_entry(FILE *fp, int indent, e_power_breakdown_entry_type type, char *name, float power, float total_power, float perc_dyn, char *method)
Definition: power.c:1870
struct s_type_descriptor * type_descriptors
Definition: globals.c:38
struct s_net * vpack_net
Definition: globals.c:19
short selected_input
Definition: power.h:272
e_power_buffer_type power_buffer_type
t_port * scaled_by_port
static void print_tabs(FILE *fpout, int num_tabs)
int mode
Definition: vpr_types.h:183
t_power_usage power_usage
t_mux_node * mux_graph_head
Definition: power.h:284
t_power_usage power_usage
void power_usage_buffer(t_power_usage *power_usage, float size, float in_prob, float in_dens, boolean level_restorer, float period)
t_power_components g_power_by_component
t_power_usage power_usage_bufs_wires
int ny
Definition: globals.c:47
char * my_strdup(const char *str)
Definition: util.c:101
t_mode_power * mode_power
float mux_transistor_size
Definition: power.h:205
void power_init_pb_pins_rec(t_pb_graph_node *pb_node)
Definition: power.c:1084
short wire_to_ipin_switch
Definition: vpr_types.h:765
static void dealloc_mux_graph(t_mux_node *node)
Definition: power.c:742
t_interconnect_power * interconnect_power
static void power_usage_clock(t_power_usage *power_usage, t_clock_arch *clock_arch)
Definition: power.c:627
void power_usage_local_pin_buffer_and_wire(t_power_usage *power_usage, t_pb *pb, t_pb_graph_pin *pin)
Definition: power.c:225
t_pb_graph_pin_power * pin_power
t_rr_type type
Definition: vpr_types.h:902
t_pb_graph_pin ** input_pins
struct s_logical_block * logical_block
Definition: globals.c:20
t_interconnect_pins ** interconnect_pins
t_mux_node * children
Definition: power.h:293
Definition: util.h:12
e_power_ret_code power_total(float *run_time_s, t_vpr_setup vpr_setup, t_arch *arch, t_det_routing_arch *routing_arch)
Definition: power.c:1695
void power_log_msg(e_power_log_type log_type, char *msg)
Definition: power_util.c:67
t_power_usage * components
char ** messages
Definition: power.h:207
void output_logs(FILE *fp, t_log *logs, int num_logs)
Definition: power_util.c:457
void power_usage_inverter(t_power_usage *power_usage, float in_dens, float in_prob, float size, float period)