VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
power_lowlevel.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 functions that calculate the power of low-level
20  * components (inverters, simple multiplexers, etc)
21  */
22 
23 /************************* INCLUDES *********************************/
24 #include <assert.h>
25 
26 #include "power_lowlevel.h"
27 #include "power_util.h"
28 #include "power_cmos_tech.h"
29 #include "globals.h"
30 
31 /************************* FUNCTION DELCARATIONS ********************/
32 static float power_calc_node_switching_v(float capacitance, float density,
33  float period, float voltage);
34 static void power_calc_transistor_capacitance(float *C_d, float *C_s,
35  float *C_g, e_tx_type transistor_type, float size);
36 static float power_calc_leakage_st(e_tx_type transistor_type, float size);
37 static float power_calc_leakage_st_pass_transistor(float size, float v_ds);
38 static float power_calc_leakage_gate(e_tx_type transistor_type, float size);
39 /*static float power_calc_buffer_sc_levr(
40  t_power_buffer_strength_inf * buffer_strength, int input_mux_size);*/
41 
42 /************************* FUNCTION DEFINITIONS *********************/
43 
44 /**
45  * Initializer function for this module, called by power_init
46  */
48  float C_d, C_s, C_g;
49 
50  power_calc_transistor_capacitance(&C_d, &C_s, &C_g, NMOS, 1.0);
54 
55  power_calc_transistor_capacitance(&C_d, &C_s, &C_g, PMOS,
60 
62  1.0);
64  1.0 * g_power_tech->PN_ratio);
65 
72 
73  power_calc_transistor_capacitance(&C_d, &C_s, &C_g, NMOS, 2.0);
74  g_power_commonly_used->INV_2X_C = C_g + C_d;
75  power_calc_transistor_capacitance(&C_d, &C_s, &C_g, PMOS,
76  2.0 * g_power_tech->PN_ratio);
77  g_power_commonly_used->INV_2X_C += C_g + C_d;
78 
79 }
80 
81 /**
82  * Calculates the switching power of a node
83  * - capacitance: The capacitance of the nodoe
84  * - density: The transition density of the node
85  */
86 float power_calc_node_switching(float capacitance, float density,
87  float period) {
88  return 0.5 * g_power_tech->Vdd * g_power_tech->Vdd * capacitance * density
89  / period;
90 }
91 
92 /**
93  * Calculates the switching power of a node, with non-Vdd voltage
94  * - capacitance: The capacitance of the nodoe
95  * - density: The transition density of the node
96  * - voltage: The voltage when the node is charged
97  */
98 static float power_calc_node_switching_v(float capacitance, float density,
99  float period, float voltage) {
100  return 0.5 * voltage * g_power_tech->Vdd * capacitance * density / period;
101 }
102 
103 /**
104  * Calculates the power of an inverter
105  * - power_usage: (Return value) The power usage of the inverter
106  * - in_dens: The transition density of the input
107  * - in_prob: The signal probability of the input
108  * - size: The inverter size, relative to a min-size inverter
109  */
110 void power_usage_inverter(t_power_usage * power_usage, float in_dens,
111  float in_prob, float size, float period) {
112  float C_drain, C_gate, C_source;
113  float C_inv;
114 
115  float PMOS_size = g_power_tech->PN_ratio * size;
116  float NMOS_size = size;
117 
118  power_usage->dynamic = 0.;
119  power_usage->leakage = 0.;
120 
121  C_inv = 0.;
122 
123  power_calc_transistor_capacitance(&C_drain, &C_source, &C_gate, NMOS,
124  NMOS_size);
125  C_inv += C_gate + C_drain;
126 
127  power_calc_transistor_capacitance(&C_drain, &C_source, &C_gate, PMOS,
128  PMOS_size);
129  C_inv += C_gate + C_drain;
130 
131  power_usage->dynamic = power_calc_node_switching(C_inv, in_dens, period);
132 
133  power_usage->leakage = in_prob * power_calc_leakage_st(PMOS, PMOS_size)
134  + (1 - in_prob) * power_calc_leakage_st(NMOS, NMOS_size);
135 
136  power_usage->leakage += in_prob * power_calc_leakage_gate(NMOS, NMOS_size)
137  + (1 - in_prob) * power_calc_leakage_gate(PMOS, PMOS_size);
138 }
139 
140 /**
141  * Calculates the power of an inverter, with irregular P/N ratio
142  * - power_usage: (Return value) The power usage of the inverter
143  * - dy_power_input: (Return value) The dynamic power of the input node
144  * - in_dens: The transition density of the input
145  * - in_prob: The signal probability of the input
146  * - PMOS_size: (W/L) of the PMOS
147  * - NMOS_size: (W/L) of the NMOS
148  */
150  float * dyn_power_input, float in_density, float in_probability,
151  float PMOS_size, float NMOS_size, float period) {
152  float C_drain, C_gate, C_source;
153  float C_inv;
154  float C_in;
155 
156  power_usage->dynamic = 0.;
157  power_usage->leakage = 0.;
158 
159  C_inv = 0.;
160  C_in = 0.;
161 
162  power_calc_transistor_capacitance(&C_drain, &C_source, &C_gate, NMOS,
163  NMOS_size);
164  C_inv += C_gate + C_drain;
165  C_in += C_gate;
166 
167  power_calc_transistor_capacitance(&C_drain, &C_source, &C_gate, PMOS,
168  PMOS_size);
169  C_inv += C_gate + C_drain;
170  C_in += C_gate;
171 
172  power_usage->dynamic = power_calc_node_switching(C_inv, in_density, period);
173  *dyn_power_input = power_calc_node_switching(C_in, in_density, period);
174 
175  power_usage->leakage = in_probability
176  * power_calc_leakage_st(PMOS, PMOS_size)
177  + (1 - in_probability) * power_calc_leakage_st(NMOS, NMOS_size);
178 }
179 
180 /**
181  * Calculates the power of an inverter, also returning dynamic power of the input
182  * - power_usage: (Return value) The power usage of the inverter
183  * - input_dynamic_power: (Return value) The dynamic power of the input node
184  * - in_dens: The transition density of the input
185  * - in_prob: The signal probability of the input
186  * - size: The inverter size, relative to a min-size inverter
187  */
188 #if 0
189 void power_calc_inverter_with_input(t_power_usage * power_usage,
190  float * input_dynamic_power, float in_density, float in_prob,
191  float size) {
192  float C_drain, C_gate, C_source;
193  float C_inv;
194  float C_in;
195 
196  float PMOS_size = g_power_tech->PN_ratio * size;
197  float NMOS_size = size;
198 
199  power_usage->dynamic = 0.;
200  power_usage->leakage = 0.;
201 
202  C_inv = 0.;
203  C_in = 0.;
204 
205  power_calc_transistor_capacitance(&C_drain, &C_source, &C_gate, NMOS,
206  NMOS_size);
207  C_inv += C_gate + C_drain;
208  C_in += C_gate;
209 
210  power_calc_transistor_capacitance(&C_drain, &C_source, &C_gate, PMOS,
211  PMOS_size);
212  C_inv += C_gate + C_drain;
213  C_in += C_gate;
214 
215  power_usage->dynamic = power_calc_node_switching(C_inv, in_density);
216  *input_dynamic_power = power_calc_node_switching(C_in, in_density);
217 
218  power_usage->leakage = in_prob * power_calc_leakage_st(PMOS, PMOS_size)
219  + (1 - in_prob) * power_calc_leakage_st(NMOS, NMOS_size);
220 
221  power_usage->leakage += in_prob * power_calc_leakage_gate(NMOS, NMOS_size)
222  + (1 - in_prob) * power_calc_leakage_gate(PMOS, PMOS_size);
223 }
224 #endif
225 
226 /**
227  * Calculate the capacitance for a transistor
228  * - C_d: (Return value) Drain capacitance
229  * - C_s: (Return value) Source capacitance
230  * - C_g: (Return value) Gate capacitance
231  * - transistor_type: NMOS or PMOS
232  * - size: (W/L) size of the transistor
233  */
234 static void power_calc_transistor_capacitance(float *C_d, float *C_s,
235  float *C_g, e_tx_type transistor_type, float size) {
236  t_transistor_size_inf * tx_info_lower;
237  t_transistor_size_inf * tx_info_upper;
238  boolean error;
239 
240  /* Initialize to 0 */
241  *C_d = 0.;
242  *C_s = 0.;
243  *C_g = 0.;
244 
245  error = power_find_transistor_info(&tx_info_lower, &tx_info_upper,
246  transistor_type, size);
247  if (error) {
248  return;
249  }
250 
251  if (tx_info_lower == NULL) {
252  /* No lower bound */
253  *C_d = tx_info_upper->C_d;
254  *C_s = tx_info_upper->C_s;
255  *C_g = tx_info_upper->C_g;
256  } else if (tx_info_upper == NULL) {
257  /* No upper bound */
258  *C_d = tx_info_lower->C_d;
259  *C_s = tx_info_lower->C_s;
260  *C_g = tx_info_lower->C_g;
261  } else {
262  /* Linear approximation between sizes */
263  float percent_upper = (size - tx_info_lower->size)
264  / (tx_info_upper->size - tx_info_lower->size);
265  *C_d = (1 - percent_upper) * tx_info_lower->C_d
266  + percent_upper * tx_info_upper->C_d;
267  *C_s = (1 - percent_upper) * tx_info_lower->C_s
268  + percent_upper * tx_info_upper->C_s;
269  *C_g = (1 - percent_upper) * tx_info_lower->C_g
270  + percent_upper * tx_info_upper->C_g;
271  }
272 
273  return;
274 }
275 
276 /**
277  * Returns the subthreshold leakage power of a transistor,
278  * for V_ds = V_dd
279  * - transistor_type: NMOS or PMOS
280  * - size: (W/L) of transistor
281  */
282 static float power_calc_leakage_st(e_tx_type transistor_type, float size) {
283  t_transistor_size_inf * tx_info_lower;
284  t_transistor_size_inf * tx_info_upper;
285  boolean error;
286  float current;
287 
288  error = power_find_transistor_info(&tx_info_lower, &tx_info_upper,
289  transistor_type, size);
290  if (error) {
291  return 0;
292  }
293 
294  if (tx_info_lower == NULL) {
295  /* No lower bound */
296  current = tx_info_upper->leakage_subthreshold;
297 
298  } else if (tx_info_upper == NULL) {
299  /* No upper bound */
300  current = tx_info_lower->leakage_subthreshold;
301  } else {
302  /* Linear approximation between sizes */
303  float percent_upper = (size - tx_info_lower->size)
304  / (tx_info_upper->size - tx_info_lower->size);
305  current = (1 - percent_upper) * tx_info_lower->leakage_subthreshold
306  + percent_upper * tx_info_upper->leakage_subthreshold;
307  }
308 
309  return current * g_power_tech->Vdd;
310 }
311 
312 /**
313  * Returns the gate gate leakage power of a transistor
314  * - transistor_type: NMOS or PMOS
315  * - size: (W/L) of transistor
316  */
317 static float power_calc_leakage_gate(e_tx_type transistor_type, float size) {
318  t_transistor_size_inf * tx_info_lower;
319  t_transistor_size_inf * tx_info_upper;
320  boolean error;
321  float current;
322 
323  error = power_find_transistor_info(&tx_info_lower, &tx_info_upper,
324  transistor_type, size);
325  if (error) {
326  return 0;
327  }
328 
329  if (tx_info_lower == NULL) {
330  /* No lower bound */
331  current = tx_info_upper->leakage_gate;
332 
333  } else if (tx_info_upper == NULL) {
334  /* No upper bound */
335  current = tx_info_lower->leakage_gate;
336  } else {
337  /* Linear approximation between sizes */
338  float percent_upper = (size - tx_info_lower->size)
339  / (tx_info_upper->size - tx_info_lower->size);
340  current = (1 - percent_upper) * tx_info_lower->leakage_gate
341  + percent_upper * tx_info_upper->leakage_gate;
342  }
343 
344  return current * g_power_tech->Vdd;
345 }
346 
347 /**
348  * Returns the subthreshold leakage power of a pass-transistor,
349  * assumed to be a minimum-sized NMOS
350  * - size: (W/L) size of transistor (Must be 1.0)
351  * - v_ds: Drain-source voltage
352  */
353 static float power_calc_leakage_st_pass_transistor(float size, float v_ds) {
354  t_power_nmos_leakage_inf * nmos_low = NULL;
355  t_power_nmos_leakage_inf * nmos_high = NULL;
356 
359  float i_ds;
360  float power_low;
361  float power_high;
362  bool over_range = false;
363 
364  assert(size >= 1.0);
365 
366  // Check if nmos size is beyond range
367  if (size
369  - 1].nmos_size) {
370  nmos_low =
372  - 1];
373  over_range = true;
374  } else {
375  for (int i = 1; i < g_power_tech->num_nmos_leakage_info; i++) {
376  if (size < g_power_tech->nmos_leakage_info[i].nmos_size) {
377  nmos_low = &g_power_tech->nmos_leakage_info[i - 1];
378  nmos_high = &g_power_tech->nmos_leakage_info[i];
379  break;
380  }
381  }
382  }
383 
384  if (size
386  - 1].nmos_size) {
388  "The architectures uses multiplexers with \
389  transistors sizes larger than what is defined in the <nmos_leakages> \
390  section of the technology file.");
391  }
392 
393  power_find_nmos_leakage(nmos_low, &lower, &upper, v_ds);
394  if (lower->v_ds == v_ds || !upper) {
395  i_ds = lower->i_ds;
396  } else {
397  float perc_upper = (v_ds - lower->v_ds) / (upper->v_ds - lower->v_ds);
398  i_ds = (1 - perc_upper) * lower->i_ds + perc_upper * upper->i_ds;
399  }
400  power_low = i_ds * g_power_tech->Vdd;
401 
402  if (!over_range) {
403  power_find_nmos_leakage(nmos_high, &lower, &upper, v_ds);
404  if (lower->v_ds == v_ds || !upper) {
405  i_ds = lower->i_ds;
406  } else {
407  float perc_upper = (v_ds - lower->v_ds)
408  / (upper->v_ds - lower->v_ds);
409  i_ds = (1 - perc_upper) * lower->i_ds + perc_upper * upper->i_ds;
410  }
411  power_high = i_ds * g_power_tech->Vdd;
412  }
413 
414  if (over_range) {
415  return power_low;
416  } else {
417  float perc_upper = (size - nmos_low->nmos_size)
418  / (nmos_high->nmos_size - nmos_low->nmos_size);
419  return power_high * perc_upper + power_low * (1 - perc_upper);
420  }
421 }
422 
423 /**
424  * Calculates the power of a wire
425  * - power_usage: (Return value) Power usage of the wire
426  * - capacitance: Capacitance of the wire (F)
427  * - density: Transition density of the wire
428  */
429 void power_usage_wire(t_power_usage * power_usage, float capacitance,
430  float density, float period) {
431  power_usage->leakage = 0.;
432  power_usage->dynamic = power_calc_node_switching(capacitance, density,
433  period);
434 }
435 
436 /**
437  * Calculates the power of a 2-input multiplexer, comprised of transmission gates
438  * - power_usage: (Return value) Power usage of the mux
439  * - in_dens: Array of input transition densities
440  * - in_prob: Array of input signal probabilities
441  * - sel_desn: Transition density of select line
442  * - sel_prob: Signal probability of select line
443  * - out_dens: Transition density of the output
444  */
445 void power_usage_MUX2_transmission(t_power_usage * power_usage, float size,
446  float * in_dens, float * in_prob, float sel_dens, float out_dens,
447  float period) {
448 
449  power_zero_usage(power_usage);
450 
451  float leakage_n, leakage_p;
452  leakage_n = power_calc_leakage_st(NMOS, size);
453  leakage_p = power_calc_leakage_st(PMOS, size * g_power_tech->PN_ratio);
454 
455  float C_g_n, C_d_n, C_s_n;
456  power_calc_transistor_capacitance(&C_d_n, &C_s_n, &C_g_n, NMOS, size);
457 
458  float C_g_p, C_d_p, C_s_p;
459  power_calc_transistor_capacitance(&C_d_p, &C_s_p, &C_g_p, PMOS,
460  size * g_power_tech->PN_ratio);
461 
462  /* A transmission gate leaks if the selected input != other input */
463  power_usage->leakage += (in_prob[0] * (1 - in_prob[1])
464  + (1 - in_prob[0]) * in_prob[1]) * (leakage_n + leakage_p);
465 
466  /* Gate switching */
467  power_usage->dynamic += 2
468  * power_calc_node_switching(C_g_n + C_g_p, sel_dens, period);
469 
470  /* Input switching */
471  power_usage->dynamic += power_calc_node_switching(C_d_n + C_s_p, in_dens[0],
472  period);
473  power_usage->dynamic += power_calc_node_switching(C_d_n + C_s_p, in_dens[1],
474  period);
475 
476  /* Output switching */
477  power_usage->dynamic += power_calc_node_switching(2 * (C_s_n + C_d_p),
478  out_dens, period);
479 }
480 
481 /**
482  * Calucates the power of a static, single-level multiplexer
483  * - power_usage: (Return value) power usage of the mux
484  * - out_prob: (Return value) Signal probability of the output
485  * - out_dens: (Return value) Transition density of the output
486  * - num_inputs: Number of inputs of the mux
487  * - selected_idx: The input index that is selected by the select lines
488  * - in_prob: Array of input signal probabilities
489  * - in_dens: Array of input tranistion densities
490  * - v_in: Array of input max voltages
491  * - transistor_size: Size of the NMOS transistors (must be 1.0)
492  * - v_out_restored: Whether the output will be level restored to Vdd
493  */
495  float * out_prob, float * out_dens, float * v_out, int num_inputs,
496  int selected_idx, float * in_prob, float * in_dens, float * v_in,
497  float transistor_size, boolean v_out_restored, float period) {
498  int input_idx;
499  float v_in_selected;
500  float in_prob_avg;
501 
502  power_zero_usage(power_usage);
503 
504  assert(transistor_size >= 1.0);
505 
506  if (selected_idx < num_inputs) {
507  *out_prob = in_prob[selected_idx];
508  *out_dens = in_dens[selected_idx];
509  v_in_selected = v_in[selected_idx];
510 
511  } else {
512  /* In this case, the multiplexer is not symetrical. The
513  * other branch of the mux has more inputs than this one,
514  * and the selected input index is not a valid index for
515  * this portion of the mux. If the mux was actually built
516  * this way, there would likely be a weak pull-up to ensure
517  * that the node does not float.
518  */
519  *out_prob = 1.0;
520  *out_dens = 0.0;
521 
522  v_in_selected = 0.;
523  for (input_idx = 0; input_idx < num_inputs; input_idx++) {
524  v_in_selected += v_in[input_idx];
525  }
526  v_in_selected /= num_inputs;
527  }
528 
529  in_prob_avg = 0.;
530 
531  float C_d, C_g, C_s;
532  power_calc_transistor_capacitance(&C_d, &C_s, &C_g, NMOS, transistor_size);
533 
534  for (input_idx = 0; input_idx < num_inputs; input_idx++) {
535  /* Dynamic Power at Inputs */
536  power_usage->dynamic += power_calc_node_switching_v(C_d,
537  in_dens[input_idx], period, v_in[input_idx]);
538 
539  if (input_idx != selected_idx) {
540  in_prob_avg += in_prob[input_idx];
541  }
542  }
543  in_prob_avg /= (num_inputs - 1);
544 
545  if (v_out_restored) {
546  *v_out = g_power_tech->Vdd;
547  } else {
548  *v_out = power_calc_mux_v_out(num_inputs, transistor_size,
549  v_in_selected, in_prob_avg);
550  }
551 
552  for (input_idx = 0; input_idx < num_inputs; input_idx++) {
553  /* Leakage */
554  /* The selected input will never leak */
555  if (input_idx == selected_idx) {
556  continue;
557  }
558 
559  /* Output is high and this input is low */
560  power_usage->leakage += (*out_prob) * (1 - in_prob[input_idx])
561  * power_calc_leakage_st_pass_transistor(transistor_size,
562  *v_out);
563 
564  /* Output is low and this input is high */
565  power_usage->leakage += (1 - *out_prob) * in_prob[input_idx]
566  * power_calc_leakage_st_pass_transistor(transistor_size,
567  v_in[input_idx]);
568  }
569 
570  /* Dynamic Power at Output */
571  power_usage->dynamic += power_calc_node_switching_v(C_s * num_inputs,
572  *out_dens, period, *v_out);
573 
574 }
575 
576 /**
577  * This function calcualtes the output voltage of a single-level multiplexer
578  * - num_inputs: Number of inputs of the multiplexer
579  * - transistor_size: The size of the NMOS transistors (must be 1.0)
580  * - v_in: The input voltage of the selcted input
581  * - in_prob_avg: The average signal probabilities of the non-selected inputs
582  */
583 float power_calc_mux_v_out(int num_inputs, float transistor_size, float v_in,
584  float in_prob_avg) {
585  t_power_mux_volt_inf * mux_volt_inf_low;
586  t_power_mux_volt_inf * mux_volt_inf_high;
587  t_power_mux_volt_pair * lower;
588  t_power_mux_volt_pair * upper;
589  float v_out_min, v_out_max;
590  float v_out_low;
591  float v_out_high;
592  bool over_range = false;
593 
594  assert(transistor_size >= 1.0);
595 
596  t_power_nmos_mux_inf * mux_nmos_inf_lower = NULL;
597  t_power_nmos_mux_inf * mux_nmos_inf_upper = NULL;
598 
599 // Check if nmos size is beyond range
600  if (transistor_size
602  mux_nmos_inf_lower =
604  over_range = true;
605  } else {
606  for (int i = 1; i < g_power_tech->num_nmos_mux_info; i++) {
607  if (transistor_size < g_power_tech->nmos_mux_info[i].nmos_size) {
608  mux_nmos_inf_lower = &g_power_tech->nmos_mux_info[i - 1];
609  mux_nmos_inf_upper = &g_power_tech->nmos_mux_info[i];
610  break;
611  }
612  }
613  }
614 
615  if (transistor_size
618  "The architectures uses multiplexers with \
619  transistors sizes larger than what is defined in the <multiplexers> \
620  section of the technology file.");
621  }
622 
623  if (num_inputs > mux_nmos_inf_lower->max_mux_sl_size
624  || (!over_range && num_inputs > mux_nmos_inf_upper->max_mux_sl_size)) {
626  "The circuit contains a single-level mux larger than \
627  what is defined in the <multiplexers> section of the \
628  technology file.");
629  }
630 
631  mux_volt_inf_low = &mux_nmos_inf_lower->mux_voltage_inf[num_inputs];
632 
633  power_find_mux_volt_inf(&lower, &upper, mux_volt_inf_low, v_in);
634  if (lower->v_in == v_in || !upper) {
635  v_out_min = lower->v_out_min;
636  v_out_max = lower->v_out_max;
637  } else {
638  float perc_upper = (v_in - lower->v_in) / (upper->v_in - lower->v_in);
639  v_out_min = (1 - perc_upper) * lower->v_out_min
640  + perc_upper * upper->v_out_min;
641  v_out_max = (1 - perc_upper) * lower->v_out_max
642  + perc_upper * upper->v_out_max;
643  }
644  v_out_low = in_prob_avg * v_out_max + (1 - in_prob_avg) * v_out_min;
645 
646  if (!over_range) {
647  mux_volt_inf_high = &mux_nmos_inf_upper->mux_voltage_inf[num_inputs];
648  power_find_mux_volt_inf(&lower, &upper, mux_volt_inf_high, v_in);
649  if (lower->v_in == v_in || !upper) {
650  v_out_min = lower->v_out_min;
651  v_out_max = lower->v_out_max;
652  } else {
653  float perc_upper = (v_in - lower->v_in)
654  / (upper->v_in - lower->v_in);
655  v_out_min = (1 - perc_upper) * lower->v_out_min
656  + perc_upper * upper->v_out_min;
657  v_out_max = (1 - perc_upper) * lower->v_out_max
658  + perc_upper * upper->v_out_max;
659  }
660  v_out_high = in_prob_avg * v_out_max + (1 - in_prob_avg) * v_out_min;
661  }
662 
663  if (over_range) {
664  return v_out_low;
665  } else {
666  float perc_upper =
667  (transistor_size - mux_nmos_inf_lower->nmos_size)
668  / (mux_nmos_inf_upper->nmos_size
669  - mux_nmos_inf_lower->nmos_size);
670  return v_out_high * perc_upper + (1 - perc_upper) * v_out_low;
671  }
672 }
673 
674 /** This function calculates the power of a single-level multiplexer, where the
675  * select lines are dynamic
676  * - power_usage: (Return value) The power usage of the mux
677  * - num_inputs: Number of multiplexer inputs (must be 2)
678  * - out_density: The transition density of the output
679  * - out_prob: The signal probability of the output
680  * - v_out: The output max voltage
681  * - in_prob: Array of input signal probabilities
682  * - in_dens: Array of input tranistion densities
683  * - v_in: Array of input voltages
684  * - sel_dens: Transition density of the select line
685  * - sel_prob: Signal probability of the select line
686  * - tranisistor_size: NMOS transistor sizes (must be 1.0)
687  */
689  int num_inputs, float out_density, float v_out, float * in_prob,
690  float * in_dens, float * v_in, float sel_dens, float sel_prob,
691  float transistor_size, float period) {
692 
693  assert(num_inputs == 2);
694 
695  power_zero_usage(power_usage);
696 
697  /* Leakage occurs when input1 != input2.
698  * If the selected input is low, the other transistor leaks input->output
699  * If the selected input is high, the other transistor leaks output->input*/
700 
701  /* 1st selected, 1st Low, 2nd High - Leakage from 2nd in->out */
702  power_usage->leakage += (1 - sel_prob) * (1 - in_prob[0]) * in_prob[1]
703  * power_calc_leakage_st_pass_transistor(transistor_size, v_in[1]);
704 
705  /* 1st selected, 1st High, 2nd Low - Leakage from 2nd out->in */
706  /* 2nd selected, 1st Low, 2nd High - Leakage from 1st out->in */
707  power_usage->leakage += ((1 - sel_prob) * in_prob[0] * (1 - in_prob[1])
708  + sel_prob * (1 - in_prob[0]) * in_prob[1])
709  * power_calc_leakage_st_pass_transistor(transistor_size, v_out);
710 
711  /* 2nd selected, 1st High, 2nd Low - Leakage from 1st in->out */
712  power_usage->leakage += sel_prob * in_prob[0] * (1 - in_prob[1])
713  * power_calc_leakage_st_pass_transistor(transistor_size, v_in[0]);
714 
715  /* Gate switching */
716  float C_d, C_s, C_g;
717  power_calc_transistor_capacitance(&C_d, &C_s, &C_g, NMOS, transistor_size);
718  power_usage->dynamic += 2
719  * power_calc_node_switching(C_g, sel_dens, period);
720 
721  /* Input switching */
722  power_usage->dynamic += power_calc_node_switching_v(C_d, in_dens[0], period,
723  v_in[0]);
724  power_usage->dynamic += power_calc_node_switching_v(C_d, in_dens[1], period,
725  v_in[1]);
726 
727  /* Output switching */
728  power_usage->dynamic += power_calc_node_switching_v(2 * C_s, out_density,
729  period, v_out);
730 }
731 
732 /**
733  * This function calculates the power of a level restorer, which is a biased
734  * inverter with a pull-up PMOS transistor in feedback.
735  * - power_usage: (Return value) Power usage of the level restorer
736  * - dyn_power_in: (Return value) Dynamic power at the input
737  * - in_density: Transition density of the input
738  * - in_prob: Signal probability of the input
739  */
741  float * dyn_power_in, float in_dens, float in_prob, float period) {
742  t_power_usage sub_power_usage;
743  float C;
744  float C_in;
745  float input_dyn_power = 0.;
746 
747  power_zero_usage(power_usage);
748 
749  /* Inverter */
750  power_usage_inverter_irregular(&sub_power_usage, &input_dyn_power, in_dens,
751  in_prob, 1.0, 2.0, period);
752  power_add_usage(power_usage, &sub_power_usage);
753 
754  /* Pull-up PMOS */
755  if (g_power_tech->PMOS_inf.long_trans_inf == NULL) {
757  "No long transistor information exists. Cannot determine transistor properties.");
758  return;
759  }
763 
764  input_dyn_power += power_calc_node_switching(C_in, in_dens, period);
765  power_usage->dynamic += power_calc_node_switching(C, in_dens, period);
766  power_usage->leakage += (1 - in_prob)
768 
769  *dyn_power_in = input_dyn_power;
770 }
771 
772 /**
773  * This function calculates the short-circuit factor for a buffer. This factor
774  * represents the short-circuit power of a buffer, as a factor of switching power.
775  * - stages: Number of stages of the buffer
776  * - gain: The gain at each stage
777  * - level_restorer: Whether this buffer must level-restore the input to Vdd
778  * - input_mux_size: For level-restoring buffers, what is the size of the mux driving it
779  */
780 // Not used anymore
781 #if 0
782 float power_calc_buffer_sc(int stages, float gain, boolean level_restorer,
783  int input_mux_size) {
784 
785  t_power_buffer_size_inf * size_inf;
786  t_power_buffer_strength_inf * strength_lower;
787  t_power_buffer_strength_inf * strength_upper;
788  float sc;
789 
790  /* Find information for given buffer size */
791  size_inf = &g_power_tech->buffer_size_inf[stages];
792 
793  /* Find information for a given size/strength */
794  power_find_buffer_strength_inf(&strength_lower, &strength_upper, size_inf,
795  gain);
796 
797  if (!level_restorer) {
798  if (strength_upper == NULL) {
799  sc = strength_lower->sc_no_levr;
800  } else {
801  float percent_upper = (gain - strength_lower->stage_gain)
802  / (strength_upper->stage_gain - strength_lower->stage_gain);
803  sc = (1 - percent_upper) * strength_lower->sc_no_levr
804  + percent_upper * strength_upper->sc_no_levr;
805  }
806  } else {
807  /* Level Restored - Short Circuit depends on input mux size */
808 
809  if (strength_upper == NULL) {
810  sc = power_calc_buffer_sc_levr(strength_lower, input_mux_size);
811  } else {
812  float sc_buf_low;
813  float sc_buf_high;
814 
815  sc_buf_low = power_calc_buffer_sc_levr(strength_lower,
816  input_mux_size);
817  sc_buf_high = power_calc_buffer_sc_levr(strength_upper,
818  input_mux_size);
819 
820  float percent_upper = (gain - strength_lower->stage_gain)
821  / (strength_upper->stage_gain - strength_lower->stage_gain);
822  sc = (1 - percent_upper) * sc_buf_low + percent_upper * sc_buf_high;
823  }
824  }
825  return sc;
826 }
827 
828 /**
829  * This function calculates the short-circuit factor for a level-restoring buffer,
830  * used by power_calc_buffer_sc
831  * - buffer_strength: The buffer information, for a given size/strength
832  * - input_mux_size: The size of the mux driving this buffer
833  */
834 static float power_calc_buffer_sc_levr(
835  t_power_buffer_strength_inf * buffer_strength, int input_mux_size) {
836  t_power_buffer_sc_levr_inf * mux_lower;
837  t_power_buffer_sc_levr_inf * mux_upper;
838 
839  power_find_buffer_sc_levr(&mux_lower, &mux_upper, buffer_strength,
840  input_mux_size);
841  if (mux_upper == NULL) {
842  return mux_lower->sc_levr;
843  } else {
844  float percent_upper = (input_mux_size - mux_lower->mux_size)
845  / (mux_upper->mux_size - mux_lower->mux_size);
846  return (1 - percent_upper) * mux_lower->sc_levr
847  + percent_upper * mux_upper->sc_levr;
848  }
849 }
850 #endif
851 
853  int i;
854  float C_found;
855 
856  t_transistor_inf * nmos_info = &g_power_tech->NMOS_inf;
857  t_transistor_inf * pmos_info = &g_power_tech->PMOS_inf;
858 
859  assert(nmos_info->num_size_entries == pmos_info->num_size_entries);
860 
861  for (i = 0; i < nmos_info->num_size_entries; i++) {
862  C_found = nmos_info->size_inf[i].C_d + pmos_info->size_inf[i].C_d;
863 
864  /* Not likely, since floating point */
865  if (C_out == C_found) {
866  return nmos_info->size_inf[i].size;
867  }
868 
869  /* Gone past */
870  if (C_found > C_out) {
871  if (i == 0) {
873  "Attempted to search for a transistor with a capacitance smaller than the smallest in the technology file.\n");
874  return nmos_info->size_inf[i].size;
875  } else {
876  float C_prev = nmos_info->size_inf[i - 1].C_d
877  + pmos_info->size_inf[i - 1].C_d;
878  float percent_upper = (C_out - C_prev) / (C_found - C_prev);
879  return percent_upper * nmos_info->size_inf[i].size
880  + (1 - percent_upper) * nmos_info->size_inf[i - 1].size;
881  }
882  }
883 
884  /* Reached the End */
885  if (i == nmos_info->num_size_entries - 1) {
887  "Attempted to search for a transistor with a capacitance greater than the largest in the technology file.\n");
888  return nmos_info->size_inf[i].size;
889  }
890  }
891 
892  return 0;
893 }
void power_usage_wire(t_power_usage *power_usage, float capacitance, float density, float period)
float PMOS_1X_st_leakage
Definition: power.h:242
t_power_tech * g_power_tech
Definition: power.c:67
static float power_calc_leakage_gate(e_tx_type transistor_type, float size)
Definition: power.h:89
t_transistor_size_inf * size_inf
Definition: power.h:113
void power_usage_mux_singlelevel_static(t_power_usage *power_usage, float *out_prob, float *out_dens, float *v_out, int num_inputs, int selected_idx, float *in_prob, float *in_dens, float *v_in, float transistor_size, boolean v_out_restored, float period)
t_transistor_inf PMOS_inf
Definition: power.h:138
void power_usage_level_restorer(t_power_usage *power_usage, float *dyn_power_in, float in_dens, float in_prob, float period)
t_power_mux_volt_inf * mux_voltage_inf
Definition: power.h:120
t_power_commonly_used * g_power_commonly_used
Definition: power.c:66
float power_calc_node_switching(float capacitance, float density, float period)
float NMOS_1X_st_leakage
Definition: power.h:240
t_power_nmos_mux_inf * nmos_mux_info
Definition: power.h:142
float PN_ratio
Definition: power.h:131
void power_lowlevel_init()
void power_find_buffer_sc_levr(t_power_buffer_sc_levr_inf **lower, t_power_buffer_sc_levr_inf **upper, t_power_buffer_strength_inf *buffer_strength, int input_mux_size)
void power_add_usage(t_power_usage *dest, const t_power_usage *src)
Definition: power_util.c:49
void power_usage_inverter_irregular(t_power_usage *power_usage, float *dyn_power_input, float in_density, float in_probability, float PMOS_size, float NMOS_size, float period)
static float power_calc_leakage_st(e_tx_type transistor_type, float size)
void power_find_nmos_leakage(t_power_nmos_leakage_inf *nmos_leakage_info, t_power_nmos_leakage_pair **lower, t_power_nmos_leakage_pair **upper, float v_ds)
void power_zero_usage(t_power_usage *power_usage)
Definition: power_util.c:44
static void power_calc_transistor_capacitance(float *C_d, float *C_s, float *C_g, e_tx_type transistor_type, float size)
void power_usage_MUX2_transmission(t_power_usage *power_usage, float size, float *in_dens, float *in_prob, float sel_dens, float out_dens, float period)
int num_nmos_leakage_info
Definition: power.h:145
static float power_calc_leakage_st_pass_transistor(float size, float v_ds)
static float power_calc_node_switching_v(float capacitance, float density, float period, float voltage)
Definition: power.h:89
int num_nmos_mux_info
Definition: power.h:141
void power_find_mux_volt_inf(t_power_mux_volt_pair **lower, t_power_mux_volt_pair **upper, t_power_mux_volt_inf *volt_inf, float v_in)
t_power_nmos_leakage_inf * nmos_leakage_info
Definition: power.h:146
void power_usage_mux_singlelevel_dynamic(t_power_usage *power_usage, int num_inputs, float out_density, float v_out, float *in_prob, float *in_dens, float *v_in, float sel_dens, float sel_prob, float transistor_size, float period)
float power_calc_buffer_size_from_Cout(float C_out)
float Vdd
Definition: power.h:132
float leakage_subthreshold
Definition: power.h:97
int num_size_entries
Definition: power.h:112
t_transistor_inf NMOS_inf
Definition: power.h:137
t_power_buffer_size_inf * buffer_size_inf
Definition: power.h:150
float power_calc_mux_v_out(int num_inputs, float transistor_size, float v_in, float in_prob_avg)
void power_find_buffer_strength_inf(t_power_buffer_strength_inf **lower, t_power_buffer_strength_inf **upper, t_power_buffer_size_inf *size_inf, float stage_gain)
t_transistor_size_inf * long_trans_inf
Definition: power.h:114
boolean power_find_transistor_info(t_transistor_size_inf **lower, t_transistor_size_inf **upper, e_tx_type type, float size)
void power_log_msg(e_power_log_type log_type, char *msg)
Definition: power_util.c:67
e_tx_type
Definition: power.h:88
void power_usage_inverter(t_power_usage *power_usage, float in_dens, float in_prob, float size, float period)