Deleted Added
sdiff udiff text old ( 10152:52c552138ba1 ) new ( 10234:5cb711fa6176 )
full compact
1/*****************************************************************************
2 * McPAT/CACTI
3 * SOFTWARE LICENSE AGREEMENT
4 * Copyright 2012 Hewlett-Packard Development Company, L.P.
5 * All Rights Reserved
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met: redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer;
11 * redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the

--- 7 unchanged lines hidden (view full) ---

20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 ***************************************************************************/
31
32
33
34
35#include <cassert>
36#include <cmath>
37#include <iostream>
38
39#include "basic_circuit.h"
40#include "parameter.h"
41
42uint32_t _log2(uint64_t num)
43{
44 uint32_t log2 = 0;
45
46 if (num == 0)
47 {
48 std::cerr << "log0?" << std::endl;
49 exit(1);
50 }
51
52 while (num > 1)
53 {
54 num = (num >> 1);
55 log2++;
56 }
57
58 return log2;
59}
60
61
62bool is_pow2(int64_t val)
63{
64 if (val <= 0)
65 {
66 return false;
67 }
68 else if (val == 1)
69 {
70 return true;
71 }
72 else
73 {
74 return (_log2(val) != _log2(val-1));
75 }
76}
77
78
79int powers (int base, int n)
80{
81 int i, p;
82
83 p = 1;
84 for (i = 1; i <= n; ++i)
85 p *= base;
86 return p;
87}
88
89/*----------------------------------------------------------------------*/
90
91double logtwo (double x)
92{
93 assert(x > 0);
94 return ((double) (log (x) / log (2.0)));
95}
96
97/*----------------------------------------------------------------------*/
98
99
100double gate_C(
101 double width,
102 double wirelength,
103 bool _is_dram,
104 bool _is_cell,
105 bool _is_wl_tr)
106{
107 const TechnologyParameter::DeviceType * dt;
108
109 if (_is_dram && _is_cell)
110 {
111 dt = &g_tp.dram_acc; //DRAM cell access transistor
112 }
113 else if (_is_dram && _is_wl_tr)
114 {
115 dt = &g_tp.dram_wl; //DRAM wordline transistor
116 }
117 else if (!_is_dram && _is_cell)
118 {
119 dt = &g_tp.sram_cell; // SRAM cell access transistor
120 }
121 else
122 {
123 dt = &g_tp.peri_global;
124 }
125
126 return (dt->C_g_ideal + dt->C_overlap + 3*dt->C_fringe)*width + dt->l_phy*Cpolywire;
127}
128
129
130// returns gate capacitance in Farads
131// actually this function is the same as gate_C() now
132double gate_C_pass(
133 double width, // gate width in um (length is Lphy_periph_global)
134 double wirelength, // poly wire length going to gate in lambda
135 bool _is_dram,
136 bool _is_cell,
137 bool _is_wl_tr)
138{
139 // v5.0
140 const TechnologyParameter::DeviceType * dt;
141
142 if ((_is_dram) && (_is_cell))
143 {
144 dt = &g_tp.dram_acc; //DRAM cell access transistor
145 }
146 else if ((_is_dram) && (_is_wl_tr))
147 {
148 dt = &g_tp.dram_wl; //DRAM wordline transistor
149 }
150 else if ((!_is_dram) && _is_cell)
151 {
152 dt = &g_tp.sram_cell; // SRAM cell access transistor
153 }
154 else
155 {
156 dt = &g_tp.peri_global;
157 }
158
159 return (dt->C_g_ideal + dt->C_overlap + 3*dt->C_fringe)*width + dt->l_phy*Cpolywire;
160}
161
162
163
164double drain_C_(
165 double width,
166 int nchannel,
167 int stack,
168 int next_arg_thresh_folding_width_or_height_cell,
169 double fold_dimension,
170 bool _is_dram,
171 bool _is_cell,
172 bool _is_wl_tr)
173{
174 double w_folded_tr;
175 const TechnologyParameter::DeviceType * dt;
176
177 if ((_is_dram) && (_is_cell))
178 {
179 dt = &g_tp.dram_acc; // DRAM cell access transistor
180 }
181 else if ((_is_dram) && (_is_wl_tr))
182 {
183 dt = &g_tp.dram_wl; // DRAM wordline transistor
184 }
185 else if ((!_is_dram) && _is_cell)
186 {
187 dt = &g_tp.sram_cell; // SRAM cell access transistor
188 }
189 else
190 {
191 dt = &g_tp.peri_global;
192 }
193
194 double c_junc_area = dt->C_junc;
195 double c_junc_sidewall = dt->C_junc_sidewall;
196 double c_fringe = 2*dt->C_fringe;
197 double c_overlap = 2*dt->C_overlap;
198 double drain_C_metal_connecting_folded_tr = 0;
199
200 // determine the width of the transistor after folding (if it is getting folded)
201 if (next_arg_thresh_folding_width_or_height_cell == 0)
202 { // interpret fold_dimension as the the folding width threshold
203 // i.e. the value of transistor width above which the transistor gets folded
204 w_folded_tr = fold_dimension;
205 }
206 else
207 { // interpret fold_dimension as the height of the cell that this transistor is part of.
208 double h_tr_region = fold_dimension - 2 * g_tp.HPOWERRAIL;
209 // TODO : w_folded_tr must come from Component::compute_gate_area()
210 double ratio_p_to_n = 2.0 / (2.0 + 1.0);
211 if (nchannel)
212 {
213 w_folded_tr = (1 - ratio_p_to_n) * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS);
214 }
215 else
216 {
217 w_folded_tr = ratio_p_to_n * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS);
218 }
219 }
220 int num_folded_tr = (int) (ceil(width / w_folded_tr));
221
222 if (num_folded_tr < 2)
223 {
224 w_folded_tr = width;
225 }
226
227 double total_drain_w = (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) + // only for drain
228 (stack - 1) * g_tp.spacing_poly_to_poly;
229 double drain_h_for_sidewall = w_folded_tr;
230 double total_drain_height_for_cap_wrt_gate = w_folded_tr + 2 * w_folded_tr * (stack - 1);
231 if (num_folded_tr > 1)
232 {
233 total_drain_w += (num_folded_tr - 2) * (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) +
234 (num_folded_tr - 1) * ((stack - 1) * g_tp.spacing_poly_to_poly);
235
236 if (num_folded_tr%2 == 0)
237 {
238 drain_h_for_sidewall = 0;
239 }
240 total_drain_height_for_cap_wrt_gate *= num_folded_tr;
241 drain_C_metal_connecting_folded_tr = g_tp.wire_local.C_per_um * total_drain_w;
242 }
243
244 double drain_C_area = c_junc_area * total_drain_w * w_folded_tr;
245 double drain_C_sidewall = c_junc_sidewall * (drain_h_for_sidewall + 2 * total_drain_w);
246 double drain_C_wrt_gate = (c_fringe + c_overlap) * total_drain_height_for_cap_wrt_gate;
247
248 return (drain_C_area + drain_C_sidewall + drain_C_wrt_gate + drain_C_metal_connecting_folded_tr);
249}
250
251
252double tr_R_on(
253 double width,
254 int nchannel,
255 int stack,
256 bool _is_dram,
257 bool _is_cell,
258 bool _is_wl_tr)
259{
260 const TechnologyParameter::DeviceType * dt;
261
262 if ((_is_dram) && (_is_cell))
263 {
264 dt = &g_tp.dram_acc; //DRAM cell access transistor
265 }
266 else if ((_is_dram) && (_is_wl_tr))
267 {
268 dt = &g_tp.dram_wl; //DRAM wordline transistor
269 }
270 else if ((!_is_dram) && _is_cell)
271 {
272 dt = &g_tp.sram_cell; // SRAM cell access transistor
273 }
274 else
275 {
276 dt = &g_tp.peri_global;
277 }
278
279 double restrans = (nchannel) ? dt->R_nch_on : dt->R_pch_on;
280 return (stack * restrans / width);
281}
282
283
284/* This routine operates in reverse: given a resistance, it finds
285 * the transistor width that would have this R. It is used in the
286 * data wordline to estimate the wordline driver size. */
287
288// returns width in um
289double R_to_w(
290 double res,
291 int nchannel,
292 bool _is_dram,
293 bool _is_cell,
294 bool _is_wl_tr)
295{
296 const TechnologyParameter::DeviceType * dt;
297
298 if ((_is_dram) && (_is_cell))
299 {
300 dt = &g_tp.dram_acc; //DRAM cell access transistor
301 }
302 else if ((_is_dram) && (_is_wl_tr))
303 {
304 dt = &g_tp.dram_wl; //DRAM wordline transistor
305 }
306 else if ((!_is_dram) && (_is_cell))
307 {
308 dt = &g_tp.sram_cell; // SRAM cell access transistor
309 }
310 else
311 {
312 dt = &g_tp.peri_global;
313 }
314
315 double restrans = (nchannel) ? dt->R_nch_on : dt->R_pch_on;
316 return (restrans / res);
317}
318
319
320double pmos_to_nmos_sz_ratio(
321 bool _is_dram,
322 bool _is_wl_tr)
323{
324 double p_to_n_sizing_ratio;
325 if ((_is_dram) && (_is_wl_tr))
326 { //DRAM wordline transistor
327 p_to_n_sizing_ratio = g_tp.dram_wl.n_to_p_eff_curr_drv_ratio;
328 }
329 else
330 { //DRAM or SRAM all other transistors
331 p_to_n_sizing_ratio = g_tp.peri_global.n_to_p_eff_curr_drv_ratio;
332 }
333 return p_to_n_sizing_ratio;
334}
335
336
337// "Timing Models for MOS Circuits" by Mark Horowitz, 1984
338double horowitz(
339 double inputramptime, // input rise time
340 double tf, // time constant of gate
341 double vs1, // threshold voltage
342 double vs2, // threshold voltage
343 int rise) // whether input rises or fall
344{
345 if (inputramptime == 0 && vs1 == vs2)
346 {
347 return tf * (vs1 < 1 ? -log(vs1) : log(vs1));
348 }
349 double a, b, td;
350
351 a = inputramptime / tf;
352 if (rise == RISE)
353 {
354 b = 0.5;
355 td = tf * sqrt(log(vs1)*log(vs1) + 2*a*b*(1.0 - vs1)) + tf*(log(vs1) - log(vs2));
356 }
357 else
358 {
359 b = 0.4;
360 td = tf * sqrt(log(1.0 - vs1)*log(1.0 - vs1) + 2*a*b*(vs1)) + tf*(log(1.0 - vs1) - log(1.0 - vs2));
361 }
362 return (td);
363}
364
365double cmos_Ileak(
366 double nWidth,
367 double pWidth,
368 bool _is_dram,
369 bool _is_cell,
370 bool _is_wl_tr)
371{
372 TechnologyParameter::DeviceType * dt;
373
374 if ((!_is_dram)&&(_is_cell))
375 { //SRAM cell access transistor
376 dt = &(g_tp.sram_cell);
377 }
378 else if ((_is_dram)&&(_is_wl_tr))
379 { //DRAM wordline transistor
380 dt = &(g_tp.dram_wl);
381 }
382 else
383 { //DRAM or SRAM all other transistors
384 dt = &(g_tp.peri_global);
385 }
386 return nWidth*dt->I_off_n + pWidth*dt->I_off_p;
387}
388
389
390double simplified_nmos_leakage(
391 double nwidth,
392 bool _is_dram,
393 bool _is_cell,
394 bool _is_wl_tr)
395{
396 TechnologyParameter::DeviceType * dt;
397
398 if ((!_is_dram)&&(_is_cell))
399 { //SRAM cell access transistor
400 dt = &(g_tp.sram_cell);
401 }
402 else if ((_is_dram)&&(_is_wl_tr))
403 { //DRAM wordline transistor
404 dt = &(g_tp.dram_wl);
405 }
406 else
407 { //DRAM or SRAM all other transistors
408 dt = &(g_tp.peri_global);
409 }
410 return nwidth * dt->I_off_n;
411}
412
413int factorial(int n, int m)
414{
415 int fa = m, i;
416 for (i=m+1; i<=n; i++)
417 fa *=i;
418 return fa;
419}
420
421int combination(int n, int m)
422{
423 int ret;
424 ret = factorial(n, m+1) / factorial(n - m);
425 return ret;
426}
427
428double simplified_pmos_leakage(
429 double pwidth,
430 bool _is_dram,
431 bool _is_cell,
432 bool _is_wl_tr)
433{
434 TechnologyParameter::DeviceType * dt;
435
436 if ((!_is_dram)&&(_is_cell))
437 { //SRAM cell access transistor
438 dt = &(g_tp.sram_cell);
439 }
440 else if ((_is_dram)&&(_is_wl_tr))
441 { //DRAM wordline transistor
442 dt = &(g_tp.dram_wl);
443 }
444 else
445 { //DRAM or SRAM all other transistors
446 dt = &(g_tp.peri_global);
447 }
448 return pwidth * dt->I_off_p;
449}
450
451double cmos_Ig_n(
452 double nWidth,
453 bool _is_dram,
454 bool _is_cell,
455 bool _is_wl_tr)
456{
457 TechnologyParameter::DeviceType * dt;
458
459 if ((!_is_dram)&&(_is_cell))
460 { //SRAM cell access transistor
461 dt = &(g_tp.sram_cell);
462 }
463 else if ((_is_dram)&&(_is_wl_tr))
464 { //DRAM wordline transistor
465 dt = &(g_tp.dram_wl);
466 }
467 else
468 { //DRAM or SRAM all other transistors
469 dt = &(g_tp.peri_global);
470 }
471 return nWidth*dt->I_g_on_n;
472}
473
474double cmos_Ig_p(
475 double pWidth,
476 bool _is_dram,
477 bool _is_cell,
478 bool _is_wl_tr)
479{
480 TechnologyParameter::DeviceType * dt;
481
482 if ((!_is_dram)&&(_is_cell))
483 { //SRAM cell access transistor
484 dt = &(g_tp.sram_cell);
485 }
486 else if ((_is_dram)&&(_is_wl_tr))
487 { //DRAM wordline transistor
488 dt = &(g_tp.dram_wl);
489 }
490 else
491 { //DRAM or SRAM all other transistors
492 dt = &(g_tp.peri_global);
493 }
494 return pWidth*dt->I_g_on_p;
495}
496
497double cmos_Isub_leakage(
498 double nWidth,
499 double pWidth,
500 int fanin,
501 enum Gate_type g_type,
502 bool _is_dram,
503 bool _is_cell,
504 bool _is_wl_tr,
505 enum Half_net_topology topo)
506{
507 assert (fanin>=1);
508 double nmos_leak = simplified_nmos_leakage(nWidth, _is_dram, _is_cell, _is_wl_tr);
509 double pmos_leak = simplified_pmos_leakage(pWidth, _is_dram, _is_cell, _is_wl_tr);
510 double Isub=0;
511 int num_states;
512 int num_off_tx;
513
514 num_states = int(pow(2.0, fanin));
515
516 switch (g_type)
517 {
518 case nmos:
519 if (fanin==1)
520 {
521 Isub = nmos_leak/num_states;
522 }
523 else
524 {
525 if (topo==parallel)
526 {
527 Isub=nmos_leak*fanin/num_states; //only when all tx are off, leakage power is non-zero. The possibility of this state is 1/num_states
528 }
529 else
530 {
531 for (num_off_tx=1; num_off_tx<=fanin; num_off_tx++) //when num_off_tx ==0 there is no leakage power
532 {
533 //Isub += nmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*(factorial(fanin)/(factorial(fanin, num_off_tx)*factorial(num_off_tx)));
534 Isub += nmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*combination(fanin, num_off_tx);
535 }
536 Isub /=num_states;
537 }
538
539 }
540 break;
541 case pmos:
542 if (fanin==1)
543 {
544 Isub = pmos_leak/num_states;
545 }
546 else
547 {
548 if (topo==parallel)
549 {
550 Isub=pmos_leak*fanin/num_states; //only when all tx are off, leakage power is non-zero. The possibility of this state is 1/num_states
551 }
552 else
553 {
554 for (num_off_tx=1; num_off_tx<=fanin; num_off_tx++) //when num_off_tx ==0 there is no leakage power
555 {
556 //Isub += pmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*(factorial(fanin)/(factorial(fanin, num_off_tx)*factorial(num_off_tx)));
557 Isub += pmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*combination(fanin, num_off_tx);
558 }
559 Isub /=num_states;
560 }
561
562 }
563 break;
564 case inv:
565 Isub = (nmos_leak + pmos_leak)/2;
566 break;
567 case nand:
568 Isub += fanin*pmos_leak;//the pullup network
569 for (num_off_tx=1; num_off_tx<=fanin; num_off_tx++) // the pulldown network
570 {
571 //Isub += nmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*(factorial(fanin)/(factorial(fanin, num_off_tx)*factorial(num_off_tx)));
572 Isub += nmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*combination(fanin, num_off_tx);
573 }
574 Isub /=num_states;
575 break;
576 case nor:
577 for (num_off_tx=1; num_off_tx<=fanin; num_off_tx++) // the pullup network
578 {
579 //Isub += pmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*(factorial(fanin)/(factorial(fanin, num_off_tx)*factorial(num_off_tx)));
580 Isub += pmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*combination(fanin, num_off_tx);
581 }
582 Isub += fanin*nmos_leak;//the pulldown network
583 Isub /=num_states;
584 break;
585 case tri:
586 Isub += (nmos_leak + pmos_leak)/2;//enabled
587 Isub += nmos_leak*UNI_LEAK_STACK_FACTOR; //disabled upper bound of leakage power
588 Isub /=2;
589 break;
590 case tg:
591 Isub = (nmos_leak + pmos_leak)/2;
592 break;
593 default:
594 assert(0);
595 break;
596 }
597
598 return Isub;
599}
600
601
602double cmos_Ig_leakage(
603 double nWidth,
604 double pWidth,
605 int fanin,
606 enum Gate_type g_type,
607 bool _is_dram,
608 bool _is_cell,
609 bool _is_wl_tr,
610 enum Half_net_topology topo)
611{
612 assert (fanin>=1);
613 double nmos_leak = cmos_Ig_n(nWidth, _is_dram, _is_cell, _is_wl_tr);
614 double pmos_leak = cmos_Ig_p(pWidth, _is_dram, _is_cell, _is_wl_tr);
615 double Ig_on=0;
616 int num_states;
617 int num_on_tx;
618
619 num_states = int(pow(2.0, fanin));
620
621 switch (g_type)
622 {
623 case nmos:
624 if (fanin==1)
625 {
626 Ig_on = nmos_leak/num_states;
627 }
628 else
629 {
630 if (topo==parallel)
631 {
632 for (num_on_tx=1; num_on_tx<=fanin; num_on_tx++)
633 {
634 Ig_on += nmos_leak*combination(fanin, num_on_tx)*num_on_tx;
635 }
636 }
637 else
638 {
639 Ig_on += nmos_leak * fanin;//pull down network when all TXs are on.
640 //num_on_tx is the number of on tx
641 for (num_on_tx=1; num_on_tx<fanin; num_on_tx++)//when num_on_tx=[1,n-1]
642 {
643 Ig_on += nmos_leak*combination(fanin, num_on_tx)*num_on_tx/2;//TODO: this is a approximation now, a precise computation will be very complicated.
644 }
645 Ig_on /=num_states;
646 }
647 }
648 break;
649 case pmos:
650 if (fanin==1)
651 {
652 Ig_on = pmos_leak/num_states;
653 }
654 else
655 {
656 if (topo==parallel)
657 {
658 for (num_on_tx=1; num_on_tx<=fanin; num_on_tx++)
659 {
660 Ig_on += pmos_leak*combination(fanin, num_on_tx)*num_on_tx;
661 }
662 }
663 else
664 {
665 Ig_on += pmos_leak * fanin;//pull down network when all TXs are on.
666 //num_on_tx is the number of on tx
667 for (num_on_tx=1; num_on_tx<fanin; num_on_tx++)//when num_on_tx=[1,n-1]
668 {
669 Ig_on += pmos_leak*combination(fanin, num_on_tx)*num_on_tx/2;//TODO: this is a approximation now, a precise computation will be very complicated.
670 }
671 Ig_on /=num_states;
672 }
673 }
674 break;
675
676 case inv:
677 Ig_on = (nmos_leak + pmos_leak)/2;
678 break;
679 case nand:
680 //pull up network
681 for (num_on_tx=1; num_on_tx<=fanin; num_on_tx++)//when num_on_tx=[1,n]
682 {
683 Ig_on += pmos_leak*combination(fanin, num_on_tx)*num_on_tx;
684 }
685
686 //pull down network
687 Ig_on += nmos_leak * fanin;//pull down network when all TXs are on.
688 //num_on_tx is the number of on tx
689 for (num_on_tx=1; num_on_tx<fanin; num_on_tx++)//when num_on_tx=[1,n-1]
690 {
691 Ig_on += nmos_leak*combination(fanin, num_on_tx)*num_on_tx/2;//TODO: this is a approximation now, a precise computation will be very complicated.
692 }
693 Ig_on /=num_states;
694 break;
695 case nor:
696 // num_on_tx is the number of on tx in pull up network
697 Ig_on += pmos_leak * fanin;//pull up network when all TXs are on.
698 for (num_on_tx=1; num_on_tx<fanin; num_on_tx++)
699 {
700 Ig_on += pmos_leak*combination(fanin, num_on_tx)*num_on_tx/2;
701
702 }
703 //pull down network
704 for (num_on_tx=1; num_on_tx<=fanin; num_on_tx++)//when num_on_tx=[1,n]
705 {
706 Ig_on += nmos_leak*combination(fanin, num_on_tx)*num_on_tx;
707 }
708 Ig_on /=num_states;
709 break;
710 case tri:
711 Ig_on += (2*nmos_leak + 2*pmos_leak)/2;//enabled
712 Ig_on += (nmos_leak + pmos_leak)/2; //disabled upper bound of leakage power
713 Ig_on /=2;
714 break;
715 case tg:
716 Ig_on = (nmos_leak + pmos_leak)/2;
717 break;
718 default:
719 assert(0);
720 break;
721 }
722
723 return Ig_on;
724}
725
726double shortcircuit_simple(
727 double vt,
728 double velocity_index,
729 double c_in,
730 double c_out,
731 double w_nmos,
732 double w_pmos,
733 double i_on_n,
734 double i_on_p,
735 double i_on_n_in,
736 double i_on_p_in,
737 double vdd)
738{
739
740 double p_short_circuit, p_short_circuit_discharge, p_short_circuit_charge, p_short_circuit_discharge_low, p_short_circuit_discharge_high, p_short_circuit_charge_low, p_short_circuit_charge_high; //this is actually energy
741 double fo_n, fo_p, fanout, beta_ratio, vt_to_vdd_ratio;
742
743 fo_n = i_on_n/i_on_n_in;
744 fo_p = i_on_p/i_on_p_in;
745 fanout = c_out/c_in;
746 beta_ratio = i_on_p/i_on_n;
747 vt_to_vdd_ratio = vt/vdd;
748
749 //p_short_circuit_discharge_low = 10/3*(pow(0.5-vt_to_vdd_ratio,3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_p*fo_p/fanout/beta_ratio;
750 p_short_circuit_discharge_low = 10/3*(pow(((vdd-vt)-vt_to_vdd_ratio),3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_p*fo_p/fanout/beta_ratio;
751 p_short_circuit_charge_low = 10/3*(pow(((vdd-vt)-vt_to_vdd_ratio),3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_n*fo_n/fanout*beta_ratio;
752// double t1, t2, t3, t4, t5;
753// t1=pow(((vdd-vt)-vt_to_vdd_ratio),3);
754// t2=pow(velocity_index,2.0);
755// t3=pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio);
756// t4=t1/t2/t3;
757// cout <<t1<<"t1\n"<<t2<<"t2\n"<<t3<<"t3\n"<<t4<<"t4\n"<<fanout<<endl;
758
759 p_short_circuit_discharge_high = pow(((vdd-vt)-vt_to_vdd_ratio),1.5)*c_in*vdd*vdd*fo_p/10/pow(2, 3*vt_to_vdd_ratio+2*velocity_index);
760 p_short_circuit_charge_high = pow(((vdd-vt)-vt_to_vdd_ratio),1.5)*c_in*vdd*vdd*fo_n/10/pow(2, 3*vt_to_vdd_ratio+2*velocity_index);
761
762// t1=pow(((vdd-vt)-vt_to_vdd_ratio),1.5);
763// t2=pow(2, 3*vt_to_vdd_ratio+2*velocity_index);
764// t3=t1/t2;
765// cout <<t1<<"t1\n"<<t2<<"t2\n"<<t3<<"t3\n"<<t4<<"t4\n"<<fanout<<endl;
766// p_short_circuit_discharge = 1.0/(1.0/p_short_circuit_discharge_low + 1.0/p_short_circuit_discharge_high);
767// p_short_circuit_charge = 1/(1/p_short_circuit_charge_low + 1/p_short_circuit_charge_high); //harmmoic mean cannot be applied simple formulas.
768
769 p_short_circuit_discharge = p_short_circuit_discharge_low;
770 p_short_circuit_charge = p_short_circuit_charge_low;
771 p_short_circuit = (p_short_circuit_discharge + p_short_circuit_charge)/2;
772
773 return (p_short_circuit);
774}
775
776double shortcircuit(
777 double vt,
778 double velocity_index,
779 double c_in,
780 double c_out,
781 double w_nmos,
782 double w_pmos,
783 double i_on_n,
784 double i_on_p,
785 double i_on_n_in,
786 double i_on_p_in,
787 double vdd)
788{
789
790 double p_short_circuit=0, p_short_circuit_discharge;//, p_short_circuit_charge, p_short_circuit_discharge_low, p_short_circuit_discharge_high, p_short_circuit_charge_low, p_short_circuit_charge_high; //this is actually energy
791 double fo_n, fo_p, fanout, beta_ratio, vt_to_vdd_ratio;
792 double f_alpha, k_v, e, g_v_alpha, h_v_alpha;
793
794 fo_n = i_on_n/i_on_n_in;
795 fo_p = i_on_p/i_on_p_in;
796 fanout = 1;
797 beta_ratio = i_on_p/i_on_n;
798 vt_to_vdd_ratio = vt/vdd;
799 e = 2.71828;
800 f_alpha = 1/(velocity_index+2) -velocity_index/(2*(velocity_index+3)) +velocity_index/(velocity_index+4)*(velocity_index/2-1);
801 k_v = 0.9/0.8+(vdd-vt)/0.8*log(10*(vdd-vt)/e);
802 g_v_alpha = (velocity_index + 1)*pow((1-velocity_index),velocity_index)*pow((1-velocity_index),velocity_index/2)/f_alpha/pow((1-velocity_index-velocity_index),(velocity_index/2+velocity_index+2));
803 h_v_alpha = pow(2, velocity_index)*(velocity_index+1)*pow((1-velocity_index),velocity_index)/pow((1-velocity_index-velocity_index),(velocity_index+1));
804
805 //p_short_circuit_discharge_low = 10/3*(pow(0.5-vt_to_vdd_ratio,3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_p*fo_p/fanout/beta_ratio;
806// p_short_circuit_discharge_low = 10/3*(pow(((vdd-vt)-vt_to_vdd_ratio),3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_p*fo_p/fanout/beta_ratio;
807// p_short_circuit_charge_low = 10/3*(pow(((vdd-vt)-vt_to_vdd_ratio),3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_n*fo_n/fanout*beta_ratio;
808// double t1, t2, t3, t4, t5;
809// t1=pow(((vdd-vt)-vt_to_vdd_ratio),3);
810// t2=pow(velocity_index,2.0);
811// t3=pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio);
812// t4=t1/t2/t3;
813//

--- 5 unchanged lines hidden (view full) ---

819//
820// p_short_circuit_discharge = 1.0/(1.0/p_short_circuit_discharge_low + 1.0/p_short_circuit_discharge_high);
821// p_short_circuit_charge = 1/(1/p_short_circuit_charge_low + 1/p_short_circuit_charge_high);
822//
823// p_short_circuit = (p_short_circuit_discharge + p_short_circuit_charge)/2;
824//
825// p_short_circuit = p_short_circuit_discharge;
826
827 p_short_circuit_discharge = k_v*vdd*vdd*c_in*fo_p*fo_p/((vdd-vt)*g_v_alpha*fanout*beta_ratio/2/k_v + h_v_alpha*fo_p);
828 return (p_short_circuit);
829}