VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
power_cmos_tech.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 relating to the cmos technology. It
20  * includes functions to read the transistor characteristics from the
21  * xml file into data structures, and functions to search within
22  * these data structures.
23  */
24 
25 /************************* INCLUDES *********************************/
26 #include <cstring>
27 using namespace std;
28 
29 #include <assert.h>
30 
31 #include "power_cmos_tech.h"
32 #include "power.h"
33 #include "power_util.h"
34 #include "ezxml.h"
35 #include "util.h"
36 #include "read_xml_util.h"
37 #include "PowerSpicedComponent.h"
38 #include "power_callibrate.h"
39 
40 /************************* GLOBALS **********************************/
44 
45 /************************* FUNCTION DECLARATIONS ********************/
46 
47 static void power_tech_load_xml_file(char * cmos_tech_behavior_filepath);
51 static int power_compare_transistor_size(const void * key_void,
52  const void * elem_void);
53 static int power_compare_voltage_pair(const void * key_void,
54  const void * elem_void);
55 static int power_compare_leakage_pair(const void * key_void,
56  const void * elem_void);
57 //static void power_tech_xml_load_sc(ezxml_t parent);
58 static int power_compare_buffer_strength(const void * key_void,
59  const void * elem_void);
60 static int power_compare_buffer_sc_levr(const void * key_void,
61  const void * elem_void);
62 static void power_tech_xml_load_components(ezxml_t parent);
63 static void power_tech_xml_load_component(ezxml_t parent,
64  PowerSpicedComponent ** component, char * name,
65  float (*usage_fn)(int num_inputs, float transistor_size));
66 /************************* FUNCTION DEFINITIONS *********************/
67 
68 void power_tech_init(char * cmos_tech_behavior_filepath) {
69  power_tech_load_xml_file(cmos_tech_behavior_filepath);
70 }
71 
72 /**
73  * Reads the transistor properties from the .xml file
74  */
75 void power_tech_load_xml_file(char * cmos_tech_behavior_filepath) {
76  ezxml_t cur, child, prev;
77  const char * prop;
78  char msg[BUFSIZE];
79 
80  if (!file_exists(cmos_tech_behavior_filepath)) {
81  /* .xml transistor characteristics is missing */
82  sprintf(msg,
83  "The CMOS technology behavior file ('%s') does not exist. No power information will be calculated.",
84  cmos_tech_behavior_filepath);
86 
90 
94 
95  g_power_tech->Vdd = 0.;
97  g_power_tech->PN_ratio = 1.;
98  return;
99  }
100  cur = ezxml_parse_file(cmos_tech_behavior_filepath);
101 
102  prop = FindProperty(cur, "file", TRUE);
103  ezxml_set_attr(cur, "file", NULL);
104 
105  prop = FindProperty(cur, "size", TRUE);
106  g_power_tech->tech_size = atof(prop);
107  ezxml_set_attr(cur, "size", NULL);
108 
109  child = FindElement(cur, "operating_point", TRUE);
110  g_power_tech->temperature = GetFloatProperty(child, "temperature", TRUE, 0);
111  g_power_tech->Vdd = GetFloatProperty(child, "Vdd", TRUE, 0);
112  FreeNode(child);
113 
114  child = FindElement(cur, "p_to_n", TRUE);
115  g_power_tech->PN_ratio = GetFloatProperty(child, "ratio", TRUE, 0);
116  FreeNode(child);
117 
118  /* Transistor Information */
119  child = FindFirstElement(cur, "transistor", TRUE);
121 
122  prev = child;
123  child = child->next;
124  FreeNode(prev);
125 
127  FreeNode(child);
128 
129  /* Multiplexer Voltage Information */
130  child = FindElement(cur, "multiplexers", TRUE);
132  FreeNode(child);
133 
134  /* Vds Leakage Information */
135  child = FindElement(cur, "nmos_leakages", TRUE);
137  FreeNode(child);
138 
139  /* Buffer SC Info */
140  /*
141  child = FindElement(cur, "buffer_sc", TRUE);
142  power_tech_xml_load_sc(child);
143  FreeNode(child);
144  */
145 
146  /* Components */
147  child = FindElement(cur, "components", TRUE);
149  FreeNode(child);
150 
151  FreeNode(cur);
152 }
153 
155  PowerSpicedComponent ** component, char * name,
156  float (*usage_fn)(int num_inputs, float transistor_size)) {
157  ezxml_t cur, child, gc, prev;
158 
159  *component = new PowerSpicedComponent(usage_fn);
160 
161  cur = FindElement(parent, name, TRUE);
162 
163  child = FindFirstElement(cur, "inputs", TRUE);
164  while (child) {
165  int num_inputs = GetIntProperty(child, "num_inputs", TRUE, 0);
166 
167  gc = FindFirstElement(child, "size", TRUE);
168  while (gc) {
169  float transistor_size = GetFloatProperty(gc, "transistor_size",
170  TRUE, 0.);
171  float power = GetFloatProperty(gc, "power", TRUE, 0.);
172  (*component)->add_data_point(num_inputs, transistor_size, power);
173 
174  prev = gc;
175  gc = gc->next;
176  FreeNode(prev);
177  }
178  prev = child;
179  child = child->next;
180  FreeNode(prev);
181  }
182  FreeNode(cur);
183 }
184 
186 
189  sizeof(PowerSpicedComponent*));
190 
194 
198 
202 
206 
210 
211 }
212 
213 /**
214  * Read short-circuit buffer information from the transistor .xml file.
215  * This contains values for buffers of various 1) # Stages 2) Stage strength 3) Input type & capacitance
216  */
217 #if 0
218 static void power_tech_xml_load_sc(ezxml_t parent) {
219  ezxml_t child, prev, gc, ggc;
220  int i, j, k;
221  int num_buffer_sizes;
222 
223  /* Information for buffers, based on # of stages in buffer */
224  num_buffer_sizes = CountChildren(parent, "stages", 1);
225  g_power_tech->max_buffer_size = num_buffer_sizes; /* buffer size starts at 1, not 0 */
228 
229  child = FindFirstElement(parent, "stages", TRUE);
230  i = 1;
231  while (child) {
233 
234  GetIntProperty(child, "num_stages", TRUE, 1);
235 
236  /* For the given # of stages, find the records for the strength of each stage */
237  size_inf->num_strengths = CountChildren(child, "strength", 1);
239  size_inf->num_strengths, sizeof(t_power_buffer_strength_inf));
240 
241  gc = FindFirstElement(child, "strength", TRUE);
242  j = 0;
243  while (gc) {
244  t_power_buffer_strength_inf * strength_inf =
245  &size_inf->strength_inf[j];
246 
247  /* Get the short circuit factor for a buffer with no level restorer at the input */
248  strength_inf->stage_gain = GetFloatProperty(gc, "gain", TRUE, 0.0);
249  strength_inf->sc_no_levr = GetFloatProperty(gc, "sc_nolevr", TRUE,
250  0.0);
251 
252  /* Get the short circuit factor for buffers with level restorers at the input */
253  strength_inf->num_levr_entries = CountChildren(gc, "input_cap", 1);
255  strength_inf->num_levr_entries,
257 
258  ggc = FindFirstElement(gc, "input_cap", TRUE);
259  k = 0;
260  while (ggc) {
261  t_power_buffer_sc_levr_inf * levr_inf =
262  &strength_inf->sc_levr_inf[k];
263 
264  /* Short circuit factor is depdent on size of mux that drives the buffer */
265  levr_inf->mux_size = GetIntProperty(ggc, "mux_size", TRUE, 0);
266  levr_inf->sc_levr = GetFloatProperty(ggc, "sc_levr", TRUE, 0.0);
267 
268  prev = ggc;
269  ggc = ggc->next;
270  FreeNode(prev);
271  k++;
272  }
273 
274  prev = gc;
275  gc = gc->next;
276  FreeNode(prev);
277  j++;
278  }
279 
280  prev = child;
281  child = child->next;
282  FreeNode(prev);
283  i++;
284  }
285 }
286 #endif
287 
288 /**
289  * Read NMOS subthreshold leakage currents from the .xml transistor characteristics
290  * This builds a table of (Vds,Ids) value pairs
291  * */
293  ezxml_t me, child, prev;
294  int num_nmos_sizes;
295  int num_leakage_pairs;
296  int i;
297  int nmos_idx;
298 
299  num_nmos_sizes = CountChildren(parent, "nmos", 1);
300  g_power_tech->num_nmos_leakage_info = num_nmos_sizes;
302  num_nmos_sizes, sizeof(t_power_nmos_leakage_inf));
303 
304  me = FindFirstElement(parent, "nmos", TRUE);
305  nmos_idx = 0;
306  while (me) {
307  t_power_nmos_leakage_inf * nmos_info =
308  &g_power_tech->nmos_leakage_info[nmos_idx];
309  nmos_info->nmos_size = GetFloatProperty(me, "size", TRUE, 0.);
310 
311  num_leakage_pairs = CountChildren(me, "nmos_leakage", 1);
312  nmos_info->num_leakage_pairs = num_leakage_pairs;
314  num_leakage_pairs, sizeof(t_power_nmos_leakage_pair));
315 
316  child = FindFirstElement(me, "nmos_leakage", TRUE);
317  i = 0;
318  while (child) {
319  nmos_info->leakage_pairs[i].v_ds = GetFloatProperty(child, "Vds",
320  TRUE, 0.0);
321  nmos_info->leakage_pairs[i].i_ds = GetFloatProperty(child, "Ids",
322  TRUE, 0.0);
323 
324  prev = child;
325  child = child->next;
326  FreeNode(prev);
327  i++;
328  }
329 
330  prev = me;
331  me = me->next;
332  FreeNode(prev);
333  nmos_idx++;
334  }
335 
336 }
337 
338 /**
339  * Read multiplexer information from the .xml transistor characteristics.
340  * This contains the estimates of mux output voltages, depending on 1) Mux Size 2) Mux Vin
341  * */
343  ezxml_t me, child, prev, gc;
344  int num_nmos_sizes;
345  int num_mux_sizes;
346  int i, j, nmos_idx;
347 
348  /* Process all nmos sizes */
349  num_nmos_sizes = CountChildren(parent, "nmos", 1);
350  g_power_tech->num_nmos_mux_info = num_nmos_sizes;
352  num_nmos_sizes, sizeof(t_power_nmos_mux_inf));
353 
354  me = FindFirstElement(parent, "nmos", TRUE);
355  nmos_idx = 0;
356  while (me) {
357  t_power_nmos_mux_inf * nmos_inf = &g_power_tech->nmos_mux_info[nmos_idx];
358  nmos_inf->nmos_size = GetFloatProperty(me, "size", TRUE, 0.0);
359 // ezxml_set_attr(me, "size", NULL);
360 
361  /* Process all multiplexer sizes */
362  num_mux_sizes = CountChildren(me, "multiplexer", 1);
363 
364  /* Add entries for 0 and 1, for convenience, although
365  * they will never be used
366  */
367  nmos_inf->max_mux_sl_size = 1 + num_mux_sizes;
369  nmos_inf->max_mux_sl_size + 1, sizeof(t_power_mux_volt_inf));
370 
371  child = FindFirstElement(me, "multiplexer", TRUE);
372  i = 1;
373  while (child) {
374  int num_voltages;
375 
376  assert(i == GetFloatProperty(child, "size", TRUE, 0));
377 
378  /* For each mux size, process all of the Vin levels */
379  num_voltages = CountChildren(child, "voltages", 1);
380 
381  nmos_inf->mux_voltage_inf[i].num_voltage_pairs = num_voltages;
382  nmos_inf->mux_voltage_inf[i].mux_voltage_pairs =
383  (t_power_mux_volt_pair*) my_calloc(num_voltages,
384  sizeof(t_power_mux_volt_pair));
385 
386  gc = FindFirstElement(child, "voltages", TRUE);
387  j = 0;
388  while (gc) {
389  /* For each mux size, and Vin level, get the min/max V_out */
390  nmos_inf->mux_voltage_inf[i].mux_voltage_pairs[j].v_in =
391  GetFloatProperty(gc, "in", TRUE, 0.0);
393  GetFloatProperty(gc, "out_min", TRUE, 0.0);
395  GetFloatProperty(gc, "out_max", TRUE, 0.0);
396 
397  prev = gc;
398  gc = gc->next;
399  FreeNode(prev);
400  j++;
401  }
402 
403  prev = child;
404  child = child->next;
405  FreeNode(prev);
406  i++;
407  }
408 
409  prev = me;
410  me = me->next;
411  FreeNode(prev);
412  nmos_idx++;
413  }
414 
415 }
416 
417 /**
418  * Read the transistor information from the .xml transistor characteristics.
419  * For each transistor size, it extracts the:
420  * - transistor node capacitances
421  * - subthreshold leakage
422  * - gate leakage
423  */
425  t_transistor_inf * trans_inf;
426  const char * prop;
427  ezxml_t child, prev, grandchild;
428  int i;
429 
430  /* Get transistor type: NMOS or PMOS */
431  prop = FindProperty(parent, "type", TRUE);
432  trans_inf = NULL;
433  if (strcmp(prop, "nmos") == 0) {
434  trans_inf = &g_power_tech->NMOS_inf;
435  } else if (strcmp(prop, "pmos") == 0) {
436  trans_inf = &g_power_tech->PMOS_inf;
437  } else {
438  assert(0);
439  }
440  ezxml_set_attr(parent, "type", NULL);
441 
442  /* Get long transistor information (W=1,L=2) */
444  sizeof(t_transistor_size_inf));
445 
446  child = FindElement(parent, "long_size", TRUE);
447  assert(GetIntProperty(child, "L", TRUE, 0) == 2);
448  trans_inf->long_trans_inf->size = GetFloatProperty(child, "W", TRUE, 0);
449 
450  grandchild = FindElement(child, "leakage_current", TRUE);
452  grandchild, "subthreshold", TRUE, 0);
453  FreeNode(grandchild);
454 
455  grandchild = FindElement(child, "capacitance", TRUE);
456  trans_inf->long_trans_inf->C_g = GetFloatProperty(grandchild, "C_g", TRUE,
457  0);
458  trans_inf->long_trans_inf->C_d = GetFloatProperty(grandchild, "C_d", TRUE,
459  0);
460  trans_inf->long_trans_inf->C_s = GetFloatProperty(grandchild, "C_s", TRUE,
461  0);
462  FreeNode(grandchild);
463 
464  /* Process all transistor sizes */
465  trans_inf->num_size_entries = CountChildren(parent, "size", 1);
466  trans_inf->size_inf = (t_transistor_size_inf*) my_calloc(
467  trans_inf->num_size_entries, sizeof(t_transistor_size_inf));
468  FreeNode(child);
469 
470  child = FindFirstElement(parent, "size", TRUE);
471  i = 0;
472  while (child) {
473  assert(GetIntProperty(child, "L", TRUE, 0) == 1);
474 
475  trans_inf->size_inf[i].size = GetFloatProperty(child, "W", TRUE, 0);
476 
477  /* Get leakage currents */
478  grandchild = FindElement(child, "leakage_current", TRUE);
480  grandchild, "subthreshold", TRUE, 0);
481  trans_inf->size_inf[i].leakage_gate = GetFloatProperty(grandchild,
482  "gate", TRUE, 0);
483  FreeNode(grandchild);
484 
485  /* Get node capacitances */
486  grandchild = FindElement(child, "capacitance", TRUE);
487  trans_inf->size_inf[i].C_g = GetFloatProperty(grandchild, "C_g", TRUE,
488  0);
489  trans_inf->size_inf[i].C_s = GetFloatProperty(grandchild, "C_s", TRUE,
490  0);
491  trans_inf->size_inf[i].C_d = GetFloatProperty(grandchild, "C_d", TRUE,
492  0);
493  FreeNode(grandchild);
494 
495  prev = child;
496  child = child->next;
497  FreeNode(prev);
498  i++;
499  }
500 }
501 
502 /**
503  * This function searches for a transistor by size
504  * - lower: (Return value) The lower-bound matching transistor
505  * - upper: (Return value) The upper-bound matching transistor
506  * - type: The transistor type to search for
507  * - size: The transistor size to search for (size = W/L)
508  */
510  t_transistor_size_inf ** upper, e_tx_type type, float size) {
511  char msg[1024];
513  t_transistor_size_inf * found;
514  t_transistor_inf * trans_info;
515  float min_size, max_size;
516  boolean error = FALSE;
517 
518  key.size = size;
519 
520  /* Find the appropriate global transistor records */
521  trans_info = NULL;
522  if (type == NMOS) {
523  trans_info = &g_power_tech->NMOS_inf;
524  } else if (type == PMOS) {
525  trans_info = &g_power_tech->PMOS_inf;
526  } else {
527  assert(0);
528  }
529 
530  /* No transistor data exists */
531  if (trans_info->size_inf == NULL) {
533  "No transistor information exists. Cannot determine transistor properties.");
534  error = TRUE;
535  return error;
536  }
537 
538  /* Make note of the transistor record we are searching in, and the bounds */
539  g_transistor_last_searched = trans_info;
540  min_size = trans_info->size_inf[0].size;
541  max_size = trans_info->size_inf[trans_info->num_size_entries - 1].size;
542 
543  found = (t_transistor_size_inf*) bsearch(&key, trans_info->size_inf,
544  trans_info->num_size_entries, sizeof(t_transistor_size_inf),
546  assert(found);
547 
548  if (size < min_size) {
549  /* Too small */
550  assert(found == &trans_info->size_inf[0]);
551  sprintf(msg,
552  "Using %s transistor of size '%f', which is smaller than the smallest modeled transistor (%f) in the technology behavior file.",
553  transistor_type_name(type), size, min_size);
555  *lower = NULL;
556  *upper = found;
557  } else if (size > max_size) {
558  /* Too large */
559  assert(
560  found
561  == &trans_info->size_inf[trans_info->num_size_entries
562  - 1]);
563  sprintf(msg,
564  "Using %s transistor of size '%f', which is larger than the largest modeled transistor (%f) in the technology behavior file.",
565  transistor_type_name(type), size, max_size);
567  *lower = found;
568  *upper = NULL;
569  } else {
570  *lower = found;
571  *upper = found + 1;
572  }
573 
574  return error;
575 }
576 
577 /**
578  * This function searches for the Ids leakage current, based on a given Vds.
579  * This function is used for minimum-sized NMOS transistors (used in muxs).
580  * - lower: (Return value) The lower-bound matching V/I pair
581  * - upper: (Return value) The upper-bound matching V/I pair
582  * - v_ds: The drain/source voltage to search for
583  */
587  float v_ds) {
590 
591  key.v_ds = v_ds;
592 
593  g_power_searching_nmos_leakage_info = nmos_leakage_info;
594 
595  found = (t_power_nmos_leakage_pair*) bsearch(&key,
596  nmos_leakage_info->leakage_pairs,
597  nmos_leakage_info->num_leakage_pairs,
599  assert(found);
600 
601  if (found
602  == &nmos_leakage_info->leakage_pairs[nmos_leakage_info->num_leakage_pairs
603  - 1]) {
604  /* The results equal to the max voltage (Vdd) */
605  *lower = found;
606  *upper = NULL;
607  } else {
608  *lower = found;
609  *upper = found + 1;
610  }
611 }
612 
613 /**
614  * This function searches for the information for a given buffer strength.
615  * - lower: (Return value) The lower-bound matching record
616  * - upper: (Return value) The upper-bound matching record
617  * - stage_gain: The buffer strength to search for
618  */
621  t_power_buffer_size_inf * size_inf, float stage_gain) {
624 
625  float min_size;
626  float max_size;
627 
628  min_size = size_inf->strength_inf[0].stage_gain;
629  max_size = size_inf->strength_inf[size_inf->num_strengths - 1].stage_gain;
630 
631  assert(stage_gain >= min_size && stage_gain <= max_size);
632 
633  key.stage_gain = stage_gain;
634 
635  found = (t_power_buffer_strength_inf*) bsearch(&key, size_inf->strength_inf,
636  size_inf->num_strengths, sizeof(t_power_buffer_strength_inf),
638 
639  if (stage_gain == max_size) {
640  *lower = found;
641  *upper = NULL;
642  } else {
643  *lower = found;
644  *upper = found + 1;
645  }
646 }
647 
648 /**
649  * This function searches for short-circuit current information for a level-restoring buffer,
650  * based on the size of the multiplexer driving the input
651  * - lower: (Return value) The lower-bound matching record
652  * - upper: (Return value) The upper-bound matching record
653  * - buffer_strength: The set of records to search withing, which are for a specific buffer size/strength
654  * - input_mux_size: The input mux size to search for
655  */
658  t_power_buffer_strength_inf * buffer_strength, int input_mux_size) {
661  char msg[1024];
662  int max_size;
663 
664  assert(input_mux_size >= 1);
665 
666  key.mux_size = input_mux_size;
667 
668  g_buffer_strength_last_searched = buffer_strength;
669  found = (t_power_buffer_sc_levr_inf*) bsearch(&key,
670  buffer_strength->sc_levr_inf, buffer_strength->num_levr_entries,
672 
673  max_size = buffer_strength->sc_levr_inf[buffer_strength->num_levr_entries
674  - 1].mux_size;
675  if (input_mux_size > max_size) {
676  /* Input mux too large */
677  assert(
678  found
679  == &buffer_strength->sc_levr_inf[buffer_strength->num_levr_entries
680  - 1]);
681  sprintf(msg,
682  "Using buffer driven by mux of size '%d', which is larger than the largest modeled size (%d) in the technology behavior file.",
683  input_mux_size, max_size);
685  *lower = found;
686  *upper = NULL;
687  } else {
688  *lower = found;
689  *upper = found + 1;
690  }
691 }
692 
693 /**
694  * Comparison function, used by power_find_nmos_leakage
695  */
696 static int power_compare_leakage_pair(const void * key_void,
697  const void * elem_void) {
698  const t_power_nmos_leakage_pair * key =
699  (const t_power_nmos_leakage_pair*) key_void;
700  const t_power_nmos_leakage_pair * elem =
701  (const t_power_nmos_leakage_pair*) elem_void;
702  const t_power_nmos_leakage_pair * next =
703  (const t_power_nmos_leakage_pair*) elem + 1;
704 
705  /* Compare against last? */
706  if (elem
708  - 1]) {
709  if (key->v_ds >= elem->v_ds) {
710  return 0;
711  } else {
712  return -1;
713  }
714  }
715 
716  /* Check for exact match to Vdd (upper end) */
717  if (key->v_ds == elem->v_ds) {
718  return 0;
719  } else if (key->v_ds < elem->v_ds) {
720  return -1;
721  } else if (key->v_ds > next->v_ds) {
722  return 1;
723  } else {
724  return 0;
725  }
726 }
727 
728 /**
729  * This function searches for multiplexer output voltage information, based on input voltage
730  * - lower: (Return value) The lower-bound matching record
731  * - upper: (Return value) The upper-bound matching record
732  * - volt_inf: The set of records to search within, which are for a specific mux size
733  * - v_in: The input voltage to search for
734  */
736  t_power_mux_volt_pair ** upper, t_power_mux_volt_inf * volt_inf,
737  float v_in) {
739  t_power_mux_volt_pair * found;
740 
741  key.v_in = v_in;
742 
743  g_mux_volt_last_searched = volt_inf;
744  found = (t_power_mux_volt_pair*) bsearch(&key, volt_inf->mux_voltage_pairs,
745  volt_inf->num_voltage_pairs, sizeof(t_power_mux_volt_pair),
747  assert(found);
748 
749  if (found
750  == &volt_inf->mux_voltage_pairs[volt_inf->num_voltage_pairs - 1]) {
751  *lower = found;
752  *upper = NULL;
753  } else {
754  *lower = found;
755  *upper = found + 1;
756  }
757 }
758 
759 /**
760  * Comparison function, used by power_find_buffer_sc_levr
761  */
762 static int power_compare_buffer_sc_levr(const void * key_void,
763  const void * elem_void) {
764  const t_power_buffer_sc_levr_inf * key =
765  (const t_power_buffer_sc_levr_inf*) key_void;
766  const t_power_buffer_sc_levr_inf * elem =
767  (const t_power_buffer_sc_levr_inf*) elem_void;
768  const t_power_buffer_sc_levr_inf * next;
769 
770  /* Compare against last? */
771  if (elem
773  - 1]) {
774  if (key->mux_size >= elem->mux_size) {
775  return 0;
776  } else {
777  return -1;
778  }
779  }
780 
781  /* Compare against first? */
782  if (elem == &g_buffer_strength_last_searched->sc_levr_inf[0]) {
783  if (key->mux_size < elem->mux_size) {
784  return 0;
785  }
786  }
787 
788  /* Check if the key is between elem and the next element */
789  next = elem + 1;
790  if (key->mux_size > next->mux_size) {
791  return 1;
792  } else if (key->mux_size < elem->mux_size) {
793  return -1;
794  } else {
795  return 0;
796  }
797 }
798 
799 /**
800  * Comparison function, used by power_find_buffer_strength_inf
801  */
802 static int power_compare_buffer_strength(const void * key_void,
803  const void * elem_void) {
804  const t_power_buffer_strength_inf * key =
805  (const t_power_buffer_strength_inf*) key_void;
806  const t_power_buffer_strength_inf * elem =
807  (const t_power_buffer_strength_inf*) elem_void;
808  const t_power_buffer_strength_inf * next =
809  (const t_power_buffer_strength_inf*) elem + 1;
810 
811  /* Check for exact match */
812  if (key->stage_gain == elem->stage_gain) {
813  return 0;
814  } else if (key->stage_gain < elem->stage_gain) {
815  return -1;
816  } else if (key->stage_gain > next->stage_gain) {
817  return 1;
818  } else {
819  return 0;
820  }
821 }
822 
823 /**
824  * Comparison function, used by power_find_transistor_info
825  */
826 static int power_compare_transistor_size(const void * key_void,
827  const void * elem_void) {
828  const t_transistor_size_inf * key = (const t_transistor_size_inf*) key_void;
829  const t_transistor_size_inf * elem =
830  (const t_transistor_size_inf*) elem_void;
831  const t_transistor_size_inf * next;
832 
833  /* Check if we are comparing against the last element */
834  if (elem
836  - 1]) {
837  /* Match if the desired value is larger than the largest item in the list */
838  if (key->size >= elem->size) {
839  return 0;
840  } else {
841  return -1;
842  }
843  }
844 
845  /* Check if we are comparing against the first element */
846  if (elem == &g_transistor_last_searched->size_inf[0]) {
847  /* Match the smallest if it is smaller than the smallest */
848  if (key->size < elem->size) {
849  return 0;
850  }
851  }
852 
853  /* Check if the key is between elem and the next element */
854  next = elem + 1;
855  if (key->size > next->size) {
856  return 1;
857  } else if (key->size < elem->size) {
858  return -1;
859  } else {
860  return 0;
861  }
862 
863 }
864 
865 /**
866  * Comparison function, used by power_find_mux_volt_inf
867  */
868 static int power_compare_voltage_pair(const void * key_void,
869  const void * elem_void) {
870  const t_power_mux_volt_pair * key = (const t_power_mux_volt_pair *) key_void;
871  const t_power_mux_volt_pair * elem =
872  (const t_power_mux_volt_pair *) elem_void;
873  const t_power_mux_volt_pair * next = (const t_power_mux_volt_pair *) elem
874  + 1;
875 
876  /* Check if we are comparing against the last element */
877  if (elem
879  - 1]) {
880  /* Match if the desired value is larger than the largest item in the list */
881  if (key->v_in >= elem->v_in) {
882  return 0;
883  } else {
884  return -1;
885  }
886  }
887 
888  /* Check for exact match to Vdd (upper end) */
889  if (key->v_in == elem->v_in) {
890  return 0;
891  } else if (key->v_in < elem->v_in) {
892  return -1;
893  } else if (key->v_in > next->v_in) {
894  return 1;
895  } else {
896  return 0;
897  }
898 }
899 
t_power_tech * g_power_tech
Definition: power.c:67
static int power_compare_buffer_strength(const void *key_void, const void *elem_void)
Definition: ezxml.h:44
float power_usage_mux_for_callibration(int num_inputs, float transistor_size)
Definition: power.h:89
t_transistor_size_inf * size_inf
Definition: power.h:113
PowerSpicedComponent ** component_callibration
Definition: power.h:237
static t_transistor_inf * g_transistor_last_searched
t_transistor_inf PMOS_inf
Definition: power.h:138
t_power_mux_volt_inf * mux_voltage_inf
Definition: power.h:120
float tech_size
Definition: power.h:134
t_power_commonly_used * g_power_commonly_used
Definition: power.c:66
static int power_compare_buffer_sc_levr(const void *key_void, const void *elem_void)
t_power_buffer_sc_levr_inf * sc_levr_inf
Definition: power.h:181
t_power_nmos_leakage_pair * leakage_pairs
Definition: power.h:126
static int power_compare_transistor_size(const void *key_void, const void *elem_void)
static t_power_mux_volt_inf * g_mux_volt_last_searched
float temperature
Definition: power.h:135
void * my_calloc(size_t nelem, size_t size)
Definition: util.c:132
t_power_nmos_mux_inf * nmos_mux_info
Definition: power.h:142
static void power_tech_xml_load_components(ezxml_t parent)
float PN_ratio
Definition: power.h:131
static void process_tech_xml_load_transistor_info(ezxml_t parent)
t_power_nmos_leakage_inf * g_power_searching_nmos_leakage_info
static int power_compare_leakage_pair(const void *key_void, const void *elem_void)
float power_usage_ff_for_callibration(int num_inputs, float transistor_size)
static void power_tech_xml_load_nmos_st_leakages(ezxml_t parent)
#define BUFSIZE
Definition: graphics.c:184
static void power_tech_xml_load_component(ezxml_t parent, PowerSpicedComponent **component, char *name, float(*usage_fn)(int num_inputs, float transistor_size))
t_power_buffer_strength_inf * strength_inf
Definition: power.h:156
Definition: util.h:12
static t_power_buffer_strength_inf * g_buffer_strength_last_searched
float power_usage_buf_for_callibration(int num_inputs, float transistor_size)
ezxml_t next
Definition: ezxml.h:49
ezxml_t ezxml_set_attr(ezxml_t xml, char *name, char *value)
Definition: ezxml.c:1165
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)
static void * my_malloc(int ibytes)
Definition: graphics.c:499
ezxml_t FindElement(INP ezxml_t Parent, INP const char *Name, INP boolean Required)
Definition: read_xml_util.c:11
static int power_compare_voltage_pair(const void *key_void, const void *elem_void)
float power_usage_lut_for_callibration(int num_inputs, float transistor_size)
static void power_tech_load_xml_file(char *cmos_tech_behavior_filepath)
void power_tech_init(char *cmos_tech_behavior_filepath)
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 FreeNode(INOUTP ezxml_t Node)
Definition: read_xml_util.c:73
int num_nmos_leakage_info
Definition: power.h:145
ezxml_t FindFirstElement(INP ezxml_t Parent, INP const char *Name, INP boolean Required)
Definition: read_xml_util.c:38
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
int GetIntProperty(INP ezxml_t Parent, INP char *Name, INP boolean Required, INP int default_value)
float GetFloatProperty(INP ezxml_t Parent, INP char *Name, INP boolean Required, INP float default_value)
float Vdd
Definition: power.h:132
boolean file_exists(const char *filename)
Definition: util.c:760
float leakage_subthreshold
Definition: power.h:97
ezxml_t ezxml_parse_file(const char *file)
Definition: ezxml.c:846
int num_size_entries
Definition: power.h:112
int CountChildren(INP ezxml_t Node, INP const char *Name, INP int min_count)
int max_buffer_size
Definition: power.h:149
t_transistor_inf NMOS_inf
Definition: power.h:137
t_power_buffer_size_inf * buffer_size_inf
Definition: power.h:150
char * transistor_type_name(e_tx_type type)
Definition: power_util.c:71
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
static GC gc
Definition: graphics.c:387
boolean power_find_transistor_info(t_transistor_size_inf **lower, t_transistor_size_inf **upper, e_tx_type type, float size)
const char * FindProperty(INP ezxml_t Parent, INP const char *Name, INP boolean)
static void power_tech_xml_load_multiplexer_info(ezxml_t parent)
Definition: util.h:12
void power_log_msg(e_power_log_type log_type, char *msg)
Definition: power_util.c:67
e_tx_type
Definition: power.h:88
float power_usage_buf_levr_for_callibration(int num_inputs, float transistor_size)
t_power_mux_volt_pair * mux_voltage_pairs
Definition: power.h:162