basic_circuit.cc revision 10152
110152Satgutier@umich.edu/*****************************************************************************
210152Satgutier@umich.edu *                                McPAT/CACTI
310152Satgutier@umich.edu *                      SOFTWARE LICENSE AGREEMENT
410152Satgutier@umich.edu *            Copyright 2012 Hewlett-Packard Development Company, L.P.
510152Satgutier@umich.edu *                          All Rights Reserved
610152Satgutier@umich.edu *
710152Satgutier@umich.edu * Redistribution and use in source and binary forms, with or without
810152Satgutier@umich.edu * modification, are permitted provided that the following conditions are
910152Satgutier@umich.edu * met: redistributions of source code must retain the above copyright
1010152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer;
1110152Satgutier@umich.edu * redistributions in binary form must reproduce the above copyright
1210152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer in the
1310152Satgutier@umich.edu * documentation and/or other materials provided with the distribution;
1410152Satgutier@umich.edu * neither the name of the copyright holders nor the names of its
1510152Satgutier@umich.edu * contributors may be used to endorse or promote products derived from
1610152Satgutier@umich.edu * this software without specific prior written permission.
1710152Satgutier@umich.edu
1810152Satgutier@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1910152Satgutier@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2010152Satgutier@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2110152Satgutier@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2210152Satgutier@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2310152Satgutier@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2410152Satgutier@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2510152Satgutier@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2610152Satgutier@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2710152Satgutier@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2810152Satgutier@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.”
2910152Satgutier@umich.edu *
3010152Satgutier@umich.edu ***************************************************************************/
3110152Satgutier@umich.edu
3210152Satgutier@umich.edu
3310152Satgutier@umich.edu
3410152Satgutier@umich.edu
3510152Satgutier@umich.edu#include <cassert>
3610152Satgutier@umich.edu#include <cmath>
3710152Satgutier@umich.edu#include <iostream>
3810152Satgutier@umich.edu
3910152Satgutier@umich.edu#include "basic_circuit.h"
4010152Satgutier@umich.edu#include "parameter.h"
4110152Satgutier@umich.edu
4210152Satgutier@umich.eduuint32_t _log2(uint64_t num)
4310152Satgutier@umich.edu{
4410152Satgutier@umich.edu  uint32_t log2 = 0;
4510152Satgutier@umich.edu
4610152Satgutier@umich.edu  if (num == 0)
4710152Satgutier@umich.edu  {
4810152Satgutier@umich.edu    std::cerr << "log0?" << std::endl;
4910152Satgutier@umich.edu    exit(1);
5010152Satgutier@umich.edu  }
5110152Satgutier@umich.edu
5210152Satgutier@umich.edu  while (num > 1)
5310152Satgutier@umich.edu  {
5410152Satgutier@umich.edu    num = (num >> 1);
5510152Satgutier@umich.edu    log2++;
5610152Satgutier@umich.edu  }
5710152Satgutier@umich.edu
5810152Satgutier@umich.edu  return log2;
5910152Satgutier@umich.edu}
6010152Satgutier@umich.edu
6110152Satgutier@umich.edu
6210152Satgutier@umich.edubool is_pow2(int64_t val)
6310152Satgutier@umich.edu{
6410152Satgutier@umich.edu  if (val <= 0)
6510152Satgutier@umich.edu  {
6610152Satgutier@umich.edu    return false;
6710152Satgutier@umich.edu  }
6810152Satgutier@umich.edu  else if (val == 1)
6910152Satgutier@umich.edu  {
7010152Satgutier@umich.edu    return true;
7110152Satgutier@umich.edu  }
7210152Satgutier@umich.edu  else
7310152Satgutier@umich.edu  {
7410152Satgutier@umich.edu    return (_log2(val) != _log2(val-1));
7510152Satgutier@umich.edu  }
7610152Satgutier@umich.edu}
7710152Satgutier@umich.edu
7810152Satgutier@umich.edu
7910152Satgutier@umich.eduint powers (int base, int n)
8010152Satgutier@umich.edu{
8110152Satgutier@umich.edu  int i, p;
8210152Satgutier@umich.edu
8310152Satgutier@umich.edu  p = 1;
8410152Satgutier@umich.edu  for (i = 1; i <= n; ++i)
8510152Satgutier@umich.edu    p *= base;
8610152Satgutier@umich.edu  return p;
8710152Satgutier@umich.edu}
8810152Satgutier@umich.edu
8910152Satgutier@umich.edu/*----------------------------------------------------------------------*/
9010152Satgutier@umich.edu
9110152Satgutier@umich.edudouble logtwo (double x)
9210152Satgutier@umich.edu{
9310152Satgutier@umich.edu  assert(x > 0);
9410152Satgutier@umich.edu  return ((double) (log (x) / log (2.0)));
9510152Satgutier@umich.edu}
9610152Satgutier@umich.edu
9710152Satgutier@umich.edu/*----------------------------------------------------------------------*/
9810152Satgutier@umich.edu
9910152Satgutier@umich.edu
10010152Satgutier@umich.edudouble gate_C(
10110152Satgutier@umich.edu    double width,
10210152Satgutier@umich.edu    double wirelength,
10310152Satgutier@umich.edu    bool   _is_dram,
10410152Satgutier@umich.edu    bool   _is_cell,
10510152Satgutier@umich.edu    bool   _is_wl_tr)
10610152Satgutier@umich.edu{
10710152Satgutier@umich.edu  const TechnologyParameter::DeviceType * dt;
10810152Satgutier@umich.edu
10910152Satgutier@umich.edu  if (_is_dram && _is_cell)
11010152Satgutier@umich.edu  {
11110152Satgutier@umich.edu    dt = &g_tp.dram_acc;   //DRAM cell access transistor
11210152Satgutier@umich.edu  }
11310152Satgutier@umich.edu  else if (_is_dram && _is_wl_tr)
11410152Satgutier@umich.edu  {
11510152Satgutier@umich.edu    dt = &g_tp.dram_wl;    //DRAM wordline transistor
11610152Satgutier@umich.edu  }
11710152Satgutier@umich.edu  else if (!_is_dram && _is_cell)
11810152Satgutier@umich.edu  {
11910152Satgutier@umich.edu    dt = &g_tp.sram_cell;  // SRAM cell access transistor
12010152Satgutier@umich.edu  }
12110152Satgutier@umich.edu  else
12210152Satgutier@umich.edu  {
12310152Satgutier@umich.edu    dt = &g_tp.peri_global;
12410152Satgutier@umich.edu  }
12510152Satgutier@umich.edu
12610152Satgutier@umich.edu  return (dt->C_g_ideal + dt->C_overlap + 3*dt->C_fringe)*width + dt->l_phy*Cpolywire;
12710152Satgutier@umich.edu}
12810152Satgutier@umich.edu
12910152Satgutier@umich.edu
13010152Satgutier@umich.edu// returns gate capacitance in Farads
13110152Satgutier@umich.edu// actually this function is the same as gate_C() now
13210152Satgutier@umich.edudouble gate_C_pass(
13310152Satgutier@umich.edu    double width,       // gate width in um (length is Lphy_periph_global)
13410152Satgutier@umich.edu    double wirelength,  // poly wire length going to gate in lambda
13510152Satgutier@umich.edu    bool   _is_dram,
13610152Satgutier@umich.edu    bool   _is_cell,
13710152Satgutier@umich.edu    bool   _is_wl_tr)
13810152Satgutier@umich.edu{
13910152Satgutier@umich.edu  // v5.0
14010152Satgutier@umich.edu  const TechnologyParameter::DeviceType * dt;
14110152Satgutier@umich.edu
14210152Satgutier@umich.edu  if ((_is_dram) && (_is_cell))
14310152Satgutier@umich.edu  {
14410152Satgutier@umich.edu    dt = &g_tp.dram_acc;   //DRAM cell access transistor
14510152Satgutier@umich.edu  }
14610152Satgutier@umich.edu  else if ((_is_dram) && (_is_wl_tr))
14710152Satgutier@umich.edu  {
14810152Satgutier@umich.edu    dt = &g_tp.dram_wl;    //DRAM wordline transistor
14910152Satgutier@umich.edu  }
15010152Satgutier@umich.edu  else if ((!_is_dram) && _is_cell)
15110152Satgutier@umich.edu  {
15210152Satgutier@umich.edu    dt = &g_tp.sram_cell;  // SRAM cell access transistor
15310152Satgutier@umich.edu  }
15410152Satgutier@umich.edu  else
15510152Satgutier@umich.edu  {
15610152Satgutier@umich.edu    dt = &g_tp.peri_global;
15710152Satgutier@umich.edu  }
15810152Satgutier@umich.edu
15910152Satgutier@umich.edu  return (dt->C_g_ideal + dt->C_overlap + 3*dt->C_fringe)*width + dt->l_phy*Cpolywire;
16010152Satgutier@umich.edu}
16110152Satgutier@umich.edu
16210152Satgutier@umich.edu
16310152Satgutier@umich.edu
16410152Satgutier@umich.edudouble drain_C_(
16510152Satgutier@umich.edu    double width,
16610152Satgutier@umich.edu    int nchannel,
16710152Satgutier@umich.edu    int stack,
16810152Satgutier@umich.edu    int next_arg_thresh_folding_width_or_height_cell,
16910152Satgutier@umich.edu    double fold_dimension,
17010152Satgutier@umich.edu    bool _is_dram,
17110152Satgutier@umich.edu    bool _is_cell,
17210152Satgutier@umich.edu    bool _is_wl_tr)
17310152Satgutier@umich.edu{
17410152Satgutier@umich.edu  double w_folded_tr;
17510152Satgutier@umich.edu  const  TechnologyParameter::DeviceType * dt;
17610152Satgutier@umich.edu
17710152Satgutier@umich.edu  if ((_is_dram) && (_is_cell))
17810152Satgutier@umich.edu  {
17910152Satgutier@umich.edu    dt = &g_tp.dram_acc;   // DRAM cell access transistor
18010152Satgutier@umich.edu  }
18110152Satgutier@umich.edu  else if ((_is_dram) && (_is_wl_tr))
18210152Satgutier@umich.edu  {
18310152Satgutier@umich.edu    dt = &g_tp.dram_wl;    // DRAM wordline transistor
18410152Satgutier@umich.edu  }
18510152Satgutier@umich.edu  else if ((!_is_dram) && _is_cell)
18610152Satgutier@umich.edu  {
18710152Satgutier@umich.edu    dt = &g_tp.sram_cell;  // SRAM cell access transistor
18810152Satgutier@umich.edu  }
18910152Satgutier@umich.edu  else
19010152Satgutier@umich.edu  {
19110152Satgutier@umich.edu    dt = &g_tp.peri_global;
19210152Satgutier@umich.edu  }
19310152Satgutier@umich.edu
19410152Satgutier@umich.edu  double c_junc_area = dt->C_junc;
19510152Satgutier@umich.edu  double c_junc_sidewall = dt->C_junc_sidewall;
19610152Satgutier@umich.edu  double c_fringe    = 2*dt->C_fringe;
19710152Satgutier@umich.edu  double c_overlap   = 2*dt->C_overlap;
19810152Satgutier@umich.edu  double drain_C_metal_connecting_folded_tr = 0;
19910152Satgutier@umich.edu
20010152Satgutier@umich.edu  // determine the width of the transistor after folding (if it is getting folded)
20110152Satgutier@umich.edu  if (next_arg_thresh_folding_width_or_height_cell == 0)
20210152Satgutier@umich.edu  { // interpret fold_dimension as the the folding width threshold
20310152Satgutier@umich.edu    // i.e. the value of transistor width above which the transistor gets folded
20410152Satgutier@umich.edu    w_folded_tr = fold_dimension;
20510152Satgutier@umich.edu  }
20610152Satgutier@umich.edu  else
20710152Satgutier@umich.edu  { // interpret fold_dimension as the height of the cell that this transistor is part of.
20810152Satgutier@umich.edu    double h_tr_region  = fold_dimension - 2 * g_tp.HPOWERRAIL;
20910152Satgutier@umich.edu    // TODO : w_folded_tr must come from Component::compute_gate_area()
21010152Satgutier@umich.edu    double ratio_p_to_n = 2.0 / (2.0 + 1.0);
21110152Satgutier@umich.edu    if (nchannel)
21210152Satgutier@umich.edu    {
21310152Satgutier@umich.edu      w_folded_tr = (1 - ratio_p_to_n) * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS);
21410152Satgutier@umich.edu    }
21510152Satgutier@umich.edu    else
21610152Satgutier@umich.edu    {
21710152Satgutier@umich.edu      w_folded_tr = ratio_p_to_n * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS);
21810152Satgutier@umich.edu    }
21910152Satgutier@umich.edu  }
22010152Satgutier@umich.edu  int num_folded_tr = (int) (ceil(width / w_folded_tr));
22110152Satgutier@umich.edu
22210152Satgutier@umich.edu  if (num_folded_tr < 2)
22310152Satgutier@umich.edu  {
22410152Satgutier@umich.edu    w_folded_tr = width;
22510152Satgutier@umich.edu  }
22610152Satgutier@umich.edu
22710152Satgutier@umich.edu  double total_drain_w = (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) +  // only for drain
22810152Satgutier@umich.edu                         (stack - 1) * g_tp.spacing_poly_to_poly;
22910152Satgutier@umich.edu  double drain_h_for_sidewall = w_folded_tr;
23010152Satgutier@umich.edu  double total_drain_height_for_cap_wrt_gate = w_folded_tr + 2 * w_folded_tr * (stack - 1);
23110152Satgutier@umich.edu  if (num_folded_tr > 1)
23210152Satgutier@umich.edu  {
23310152Satgutier@umich.edu    total_drain_w += (num_folded_tr - 2) * (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) +
23410152Satgutier@umich.edu                     (num_folded_tr - 1) * ((stack - 1) * g_tp.spacing_poly_to_poly);
23510152Satgutier@umich.edu
23610152Satgutier@umich.edu    if (num_folded_tr%2 == 0)
23710152Satgutier@umich.edu    {
23810152Satgutier@umich.edu      drain_h_for_sidewall = 0;
23910152Satgutier@umich.edu    }
24010152Satgutier@umich.edu    total_drain_height_for_cap_wrt_gate *= num_folded_tr;
24110152Satgutier@umich.edu    drain_C_metal_connecting_folded_tr   = g_tp.wire_local.C_per_um * total_drain_w;
24210152Satgutier@umich.edu  }
24310152Satgutier@umich.edu
24410152Satgutier@umich.edu  double drain_C_area     = c_junc_area * total_drain_w * w_folded_tr;
24510152Satgutier@umich.edu  double drain_C_sidewall = c_junc_sidewall * (drain_h_for_sidewall + 2 * total_drain_w);
24610152Satgutier@umich.edu  double drain_C_wrt_gate = (c_fringe + c_overlap) * total_drain_height_for_cap_wrt_gate;
24710152Satgutier@umich.edu
24810152Satgutier@umich.edu  return (drain_C_area + drain_C_sidewall + drain_C_wrt_gate + drain_C_metal_connecting_folded_tr);
24910152Satgutier@umich.edu}
25010152Satgutier@umich.edu
25110152Satgutier@umich.edu
25210152Satgutier@umich.edudouble tr_R_on(
25310152Satgutier@umich.edu    double width,
25410152Satgutier@umich.edu    int nchannel,
25510152Satgutier@umich.edu    int stack,
25610152Satgutier@umich.edu    bool _is_dram,
25710152Satgutier@umich.edu    bool _is_cell,
25810152Satgutier@umich.edu    bool _is_wl_tr)
25910152Satgutier@umich.edu{
26010152Satgutier@umich.edu  const TechnologyParameter::DeviceType * dt;
26110152Satgutier@umich.edu
26210152Satgutier@umich.edu  if ((_is_dram) && (_is_cell))
26310152Satgutier@umich.edu  {
26410152Satgutier@umich.edu    dt = &g_tp.dram_acc;   //DRAM cell access transistor
26510152Satgutier@umich.edu  }
26610152Satgutier@umich.edu  else if ((_is_dram) && (_is_wl_tr))
26710152Satgutier@umich.edu  {
26810152Satgutier@umich.edu    dt = &g_tp.dram_wl;    //DRAM wordline transistor
26910152Satgutier@umich.edu  }
27010152Satgutier@umich.edu  else if ((!_is_dram) && _is_cell)
27110152Satgutier@umich.edu  {
27210152Satgutier@umich.edu    dt = &g_tp.sram_cell;  // SRAM cell access transistor
27310152Satgutier@umich.edu  }
27410152Satgutier@umich.edu  else
27510152Satgutier@umich.edu  {
27610152Satgutier@umich.edu    dt = &g_tp.peri_global;
27710152Satgutier@umich.edu  }
27810152Satgutier@umich.edu
27910152Satgutier@umich.edu  double restrans = (nchannel) ? dt->R_nch_on : dt->R_pch_on;
28010152Satgutier@umich.edu  return (stack * restrans / width);
28110152Satgutier@umich.edu}
28210152Satgutier@umich.edu
28310152Satgutier@umich.edu
28410152Satgutier@umich.edu/* This routine operates in reverse: given a resistance, it finds
28510152Satgutier@umich.edu * the transistor width that would have this R.  It is used in the
28610152Satgutier@umich.edu * data wordline to estimate the wordline driver size. */
28710152Satgutier@umich.edu
28810152Satgutier@umich.edu// returns width in um
28910152Satgutier@umich.edudouble R_to_w(
29010152Satgutier@umich.edu    double res,
29110152Satgutier@umich.edu    int   nchannel,
29210152Satgutier@umich.edu    bool _is_dram,
29310152Satgutier@umich.edu    bool _is_cell,
29410152Satgutier@umich.edu    bool _is_wl_tr)
29510152Satgutier@umich.edu{
29610152Satgutier@umich.edu  const TechnologyParameter::DeviceType * dt;
29710152Satgutier@umich.edu
29810152Satgutier@umich.edu  if ((_is_dram) && (_is_cell))
29910152Satgutier@umich.edu  {
30010152Satgutier@umich.edu    dt = &g_tp.dram_acc;   //DRAM cell access transistor
30110152Satgutier@umich.edu  }
30210152Satgutier@umich.edu  else if ((_is_dram) && (_is_wl_tr))
30310152Satgutier@umich.edu  {
30410152Satgutier@umich.edu    dt = &g_tp.dram_wl;    //DRAM wordline transistor
30510152Satgutier@umich.edu  }
30610152Satgutier@umich.edu  else if ((!_is_dram) && (_is_cell))
30710152Satgutier@umich.edu  {
30810152Satgutier@umich.edu    dt = &g_tp.sram_cell;  // SRAM cell access transistor
30910152Satgutier@umich.edu  }
31010152Satgutier@umich.edu  else
31110152Satgutier@umich.edu  {
31210152Satgutier@umich.edu    dt = &g_tp.peri_global;
31310152Satgutier@umich.edu  }
31410152Satgutier@umich.edu
31510152Satgutier@umich.edu  double restrans = (nchannel) ? dt->R_nch_on : dt->R_pch_on;
31610152Satgutier@umich.edu  return (restrans / res);
31710152Satgutier@umich.edu}
31810152Satgutier@umich.edu
31910152Satgutier@umich.edu
32010152Satgutier@umich.edudouble pmos_to_nmos_sz_ratio(
32110152Satgutier@umich.edu    bool _is_dram,
32210152Satgutier@umich.edu    bool _is_wl_tr)
32310152Satgutier@umich.edu{
32410152Satgutier@umich.edu  double p_to_n_sizing_ratio;
32510152Satgutier@umich.edu  if ((_is_dram) && (_is_wl_tr))
32610152Satgutier@umich.edu  { //DRAM wordline transistor
32710152Satgutier@umich.edu    p_to_n_sizing_ratio = g_tp.dram_wl.n_to_p_eff_curr_drv_ratio;
32810152Satgutier@umich.edu  }
32910152Satgutier@umich.edu  else
33010152Satgutier@umich.edu  { //DRAM or SRAM all other transistors
33110152Satgutier@umich.edu    p_to_n_sizing_ratio = g_tp.peri_global.n_to_p_eff_curr_drv_ratio;
33210152Satgutier@umich.edu  }
33310152Satgutier@umich.edu  return p_to_n_sizing_ratio;
33410152Satgutier@umich.edu}
33510152Satgutier@umich.edu
33610152Satgutier@umich.edu
33710152Satgutier@umich.edu// "Timing Models for MOS Circuits" by Mark Horowitz, 1984
33810152Satgutier@umich.edudouble horowitz(
33910152Satgutier@umich.edu    double inputramptime, // input rise time
34010152Satgutier@umich.edu    double tf,            // time constant of gate
34110152Satgutier@umich.edu    double vs1,           // threshold voltage
34210152Satgutier@umich.edu    double vs2,           // threshold voltage
34310152Satgutier@umich.edu    int    rise)          // whether input rises or fall
34410152Satgutier@umich.edu{
34510152Satgutier@umich.edu  if (inputramptime == 0 && vs1 == vs2)
34610152Satgutier@umich.edu  {
34710152Satgutier@umich.edu    return tf * (vs1 < 1 ? -log(vs1) : log(vs1));
34810152Satgutier@umich.edu  }
34910152Satgutier@umich.edu  double a, b, td;
35010152Satgutier@umich.edu
35110152Satgutier@umich.edu  a = inputramptime / tf;
35210152Satgutier@umich.edu  if (rise == RISE)
35310152Satgutier@umich.edu  {
35410152Satgutier@umich.edu    b = 0.5;
35510152Satgutier@umich.edu    td = tf * sqrt(log(vs1)*log(vs1) + 2*a*b*(1.0 - vs1)) + tf*(log(vs1) - log(vs2));
35610152Satgutier@umich.edu  }
35710152Satgutier@umich.edu  else
35810152Satgutier@umich.edu  {
35910152Satgutier@umich.edu    b = 0.4;
36010152Satgutier@umich.edu    td = tf * sqrt(log(1.0 - vs1)*log(1.0 - vs1) + 2*a*b*(vs1)) + tf*(log(1.0 - vs1) - log(1.0 - vs2));
36110152Satgutier@umich.edu  }
36210152Satgutier@umich.edu  return (td);
36310152Satgutier@umich.edu}
36410152Satgutier@umich.edu
36510152Satgutier@umich.edudouble cmos_Ileak(
36610152Satgutier@umich.edu    double nWidth,
36710152Satgutier@umich.edu    double pWidth,
36810152Satgutier@umich.edu    bool _is_dram,
36910152Satgutier@umich.edu    bool _is_cell,
37010152Satgutier@umich.edu    bool _is_wl_tr)
37110152Satgutier@umich.edu{
37210152Satgutier@umich.edu  TechnologyParameter::DeviceType * dt;
37310152Satgutier@umich.edu
37410152Satgutier@umich.edu  if ((!_is_dram)&&(_is_cell))
37510152Satgutier@umich.edu  { //SRAM cell access transistor
37610152Satgutier@umich.edu    dt = &(g_tp.sram_cell);
37710152Satgutier@umich.edu  }
37810152Satgutier@umich.edu  else if ((_is_dram)&&(_is_wl_tr))
37910152Satgutier@umich.edu  { //DRAM wordline transistor
38010152Satgutier@umich.edu    dt = &(g_tp.dram_wl);
38110152Satgutier@umich.edu  }
38210152Satgutier@umich.edu  else
38310152Satgutier@umich.edu  { //DRAM or SRAM all other transistors
38410152Satgutier@umich.edu    dt = &(g_tp.peri_global);
38510152Satgutier@umich.edu  }
38610152Satgutier@umich.edu  return nWidth*dt->I_off_n + pWidth*dt->I_off_p;
38710152Satgutier@umich.edu}
38810152Satgutier@umich.edu
38910152Satgutier@umich.edu
39010152Satgutier@umich.edudouble simplified_nmos_leakage(
39110152Satgutier@umich.edu    double nwidth,
39210152Satgutier@umich.edu    bool _is_dram,
39310152Satgutier@umich.edu    bool _is_cell,
39410152Satgutier@umich.edu    bool _is_wl_tr)
39510152Satgutier@umich.edu{
39610152Satgutier@umich.edu  TechnologyParameter::DeviceType * dt;
39710152Satgutier@umich.edu
39810152Satgutier@umich.edu  if ((!_is_dram)&&(_is_cell))
39910152Satgutier@umich.edu  { //SRAM cell access transistor
40010152Satgutier@umich.edu    dt = &(g_tp.sram_cell);
40110152Satgutier@umich.edu  }
40210152Satgutier@umich.edu  else if ((_is_dram)&&(_is_wl_tr))
40310152Satgutier@umich.edu  { //DRAM wordline transistor
40410152Satgutier@umich.edu    dt = &(g_tp.dram_wl);
40510152Satgutier@umich.edu  }
40610152Satgutier@umich.edu  else
40710152Satgutier@umich.edu  { //DRAM or SRAM all other transistors
40810152Satgutier@umich.edu    dt = &(g_tp.peri_global);
40910152Satgutier@umich.edu  }
41010152Satgutier@umich.edu  return nwidth * dt->I_off_n;
41110152Satgutier@umich.edu}
41210152Satgutier@umich.edu
41310152Satgutier@umich.eduint factorial(int n, int m)
41410152Satgutier@umich.edu{
41510152Satgutier@umich.edu        int fa = m, i;
41610152Satgutier@umich.edu        for (i=m+1; i<=n; i++)
41710152Satgutier@umich.edu                fa *=i;
41810152Satgutier@umich.edu        return fa;
41910152Satgutier@umich.edu}
42010152Satgutier@umich.edu
42110152Satgutier@umich.eduint combination(int n, int m)
42210152Satgutier@umich.edu{
42310152Satgutier@umich.edu  int ret;
42410152Satgutier@umich.edu  ret = factorial(n, m+1) / factorial(n - m);
42510152Satgutier@umich.edu  return ret;
42610152Satgutier@umich.edu}
42710152Satgutier@umich.edu
42810152Satgutier@umich.edudouble simplified_pmos_leakage(
42910152Satgutier@umich.edu    double pwidth,
43010152Satgutier@umich.edu    bool _is_dram,
43110152Satgutier@umich.edu    bool _is_cell,
43210152Satgutier@umich.edu    bool _is_wl_tr)
43310152Satgutier@umich.edu{
43410152Satgutier@umich.edu  TechnologyParameter::DeviceType * dt;
43510152Satgutier@umich.edu
43610152Satgutier@umich.edu  if ((!_is_dram)&&(_is_cell))
43710152Satgutier@umich.edu  { //SRAM cell access transistor
43810152Satgutier@umich.edu    dt = &(g_tp.sram_cell);
43910152Satgutier@umich.edu  }
44010152Satgutier@umich.edu  else if ((_is_dram)&&(_is_wl_tr))
44110152Satgutier@umich.edu  { //DRAM wordline transistor
44210152Satgutier@umich.edu    dt = &(g_tp.dram_wl);
44310152Satgutier@umich.edu  }
44410152Satgutier@umich.edu  else
44510152Satgutier@umich.edu  { //DRAM or SRAM all other transistors
44610152Satgutier@umich.edu    dt = &(g_tp.peri_global);
44710152Satgutier@umich.edu  }
44810152Satgutier@umich.edu  return pwidth * dt->I_off_p;
44910152Satgutier@umich.edu}
45010152Satgutier@umich.edu
45110152Satgutier@umich.edudouble cmos_Ig_n(
45210152Satgutier@umich.edu    double nWidth,
45310152Satgutier@umich.edu    bool _is_dram,
45410152Satgutier@umich.edu    bool _is_cell,
45510152Satgutier@umich.edu    bool _is_wl_tr)
45610152Satgutier@umich.edu{
45710152Satgutier@umich.edu  TechnologyParameter::DeviceType * dt;
45810152Satgutier@umich.edu
45910152Satgutier@umich.edu  if ((!_is_dram)&&(_is_cell))
46010152Satgutier@umich.edu  { //SRAM cell access transistor
46110152Satgutier@umich.edu    dt = &(g_tp.sram_cell);
46210152Satgutier@umich.edu  }
46310152Satgutier@umich.edu  else if ((_is_dram)&&(_is_wl_tr))
46410152Satgutier@umich.edu  { //DRAM wordline transistor
46510152Satgutier@umich.edu    dt = &(g_tp.dram_wl);
46610152Satgutier@umich.edu  }
46710152Satgutier@umich.edu  else
46810152Satgutier@umich.edu  { //DRAM or SRAM all other transistors
46910152Satgutier@umich.edu    dt = &(g_tp.peri_global);
47010152Satgutier@umich.edu  }
47110152Satgutier@umich.edu  return nWidth*dt->I_g_on_n;
47210152Satgutier@umich.edu}
47310152Satgutier@umich.edu
47410152Satgutier@umich.edudouble cmos_Ig_p(
47510152Satgutier@umich.edu    double pWidth,
47610152Satgutier@umich.edu    bool _is_dram,
47710152Satgutier@umich.edu    bool _is_cell,
47810152Satgutier@umich.edu    bool _is_wl_tr)
47910152Satgutier@umich.edu{
48010152Satgutier@umich.edu  TechnologyParameter::DeviceType * dt;
48110152Satgutier@umich.edu
48210152Satgutier@umich.edu  if ((!_is_dram)&&(_is_cell))
48310152Satgutier@umich.edu  { //SRAM cell access transistor
48410152Satgutier@umich.edu    dt = &(g_tp.sram_cell);
48510152Satgutier@umich.edu  }
48610152Satgutier@umich.edu  else if ((_is_dram)&&(_is_wl_tr))
48710152Satgutier@umich.edu  { //DRAM wordline transistor
48810152Satgutier@umich.edu    dt = &(g_tp.dram_wl);
48910152Satgutier@umich.edu  }
49010152Satgutier@umich.edu  else
49110152Satgutier@umich.edu  { //DRAM or SRAM all other transistors
49210152Satgutier@umich.edu    dt = &(g_tp.peri_global);
49310152Satgutier@umich.edu  }
49410152Satgutier@umich.edu  return pWidth*dt->I_g_on_p;
49510152Satgutier@umich.edu}
49610152Satgutier@umich.edu
49710152Satgutier@umich.edudouble cmos_Isub_leakage(
49810152Satgutier@umich.edu    double nWidth,
49910152Satgutier@umich.edu    double pWidth,
50010152Satgutier@umich.edu    int    fanin,
50110152Satgutier@umich.edu    enum Gate_type g_type,
50210152Satgutier@umich.edu    bool _is_dram,
50310152Satgutier@umich.edu    bool _is_cell,
50410152Satgutier@umich.edu    bool _is_wl_tr,
50510152Satgutier@umich.edu    enum Half_net_topology topo)
50610152Satgutier@umich.edu{
50710152Satgutier@umich.edu        assert (fanin>=1);
50810152Satgutier@umich.edu        double nmos_leak = simplified_nmos_leakage(nWidth, _is_dram, _is_cell, _is_wl_tr);
50910152Satgutier@umich.edu        double pmos_leak = simplified_pmos_leakage(pWidth, _is_dram, _is_cell, _is_wl_tr);
51010152Satgutier@umich.edu    double Isub=0;
51110152Satgutier@umich.edu    int    num_states;
51210152Satgutier@umich.edu    int    num_off_tx;
51310152Satgutier@umich.edu
51410152Satgutier@umich.edu    num_states = int(pow(2.0, fanin));
51510152Satgutier@umich.edu
51610152Satgutier@umich.edu    switch (g_type)
51710152Satgutier@umich.edu    {
51810152Satgutier@umich.edu    case nmos:
51910152Satgutier@umich.edu        if (fanin==1)
52010152Satgutier@umich.edu        {
52110152Satgutier@umich.edu                Isub = nmos_leak/num_states;
52210152Satgutier@umich.edu        }
52310152Satgutier@umich.edu        else
52410152Satgutier@umich.edu        {
52510152Satgutier@umich.edu                if (topo==parallel)
52610152Satgutier@umich.edu                {
52710152Satgutier@umich.edu                        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
52810152Satgutier@umich.edu                }
52910152Satgutier@umich.edu                else
53010152Satgutier@umich.edu                {
53110152Satgutier@umich.edu                        for (num_off_tx=1; num_off_tx<=fanin; num_off_tx++) //when num_off_tx ==0 there is no leakage power
53210152Satgutier@umich.edu                        {
53310152Satgutier@umich.edu                                //Isub += nmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*(factorial(fanin)/(factorial(fanin, num_off_tx)*factorial(num_off_tx)));
53410152Satgutier@umich.edu                                Isub += nmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*combination(fanin, num_off_tx);
53510152Satgutier@umich.edu                        }
53610152Satgutier@umich.edu                        Isub /=num_states;
53710152Satgutier@umich.edu                }
53810152Satgutier@umich.edu
53910152Satgutier@umich.edu        }
54010152Satgutier@umich.edu        break;
54110152Satgutier@umich.edu    case pmos:
54210152Satgutier@umich.edu        if (fanin==1)
54310152Satgutier@umich.edu        {
54410152Satgutier@umich.edu                Isub = pmos_leak/num_states;
54510152Satgutier@umich.edu        }
54610152Satgutier@umich.edu        else
54710152Satgutier@umich.edu        {
54810152Satgutier@umich.edu                if (topo==parallel)
54910152Satgutier@umich.edu                {
55010152Satgutier@umich.edu                        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
55110152Satgutier@umich.edu                }
55210152Satgutier@umich.edu                else
55310152Satgutier@umich.edu                {
55410152Satgutier@umich.edu                        for (num_off_tx=1; num_off_tx<=fanin; num_off_tx++) //when num_off_tx ==0 there is no leakage power
55510152Satgutier@umich.edu                        {
55610152Satgutier@umich.edu                                //Isub += pmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*(factorial(fanin)/(factorial(fanin, num_off_tx)*factorial(num_off_tx)));
55710152Satgutier@umich.edu                                Isub += pmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*combination(fanin, num_off_tx);
55810152Satgutier@umich.edu                        }
55910152Satgutier@umich.edu                        Isub /=num_states;
56010152Satgutier@umich.edu                }
56110152Satgutier@umich.edu
56210152Satgutier@umich.edu        }
56310152Satgutier@umich.edu        break;
56410152Satgutier@umich.edu    case inv:
56510152Satgutier@umich.edu        Isub = (nmos_leak + pmos_leak)/2;
56610152Satgutier@umich.edu        break;
56710152Satgutier@umich.edu    case nand:
56810152Satgutier@umich.edu        Isub += fanin*pmos_leak;//the pullup network
56910152Satgutier@umich.edu        for (num_off_tx=1; num_off_tx<=fanin; num_off_tx++) // the pulldown network
57010152Satgutier@umich.edu        {
57110152Satgutier@umich.edu                //Isub += nmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*(factorial(fanin)/(factorial(fanin, num_off_tx)*factorial(num_off_tx)));
57210152Satgutier@umich.edu            Isub += nmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*combination(fanin, num_off_tx);
57310152Satgutier@umich.edu        }
57410152Satgutier@umich.edu        Isub /=num_states;
57510152Satgutier@umich.edu        break;
57610152Satgutier@umich.edu    case nor:
57710152Satgutier@umich.edu        for (num_off_tx=1; num_off_tx<=fanin; num_off_tx++) // the pullup network
57810152Satgutier@umich.edu        {
57910152Satgutier@umich.edu                //Isub += pmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*(factorial(fanin)/(factorial(fanin, num_off_tx)*factorial(num_off_tx)));
58010152Satgutier@umich.edu                Isub += pmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*combination(fanin, num_off_tx);
58110152Satgutier@umich.edu        }
58210152Satgutier@umich.edu        Isub += fanin*nmos_leak;//the pulldown network
58310152Satgutier@umich.edu        Isub /=num_states;
58410152Satgutier@umich.edu        break;
58510152Satgutier@umich.edu    case tri:
58610152Satgutier@umich.edu        Isub += (nmos_leak + pmos_leak)/2;//enabled
58710152Satgutier@umich.edu        Isub += nmos_leak*UNI_LEAK_STACK_FACTOR; //disabled upper bound of leakage power
58810152Satgutier@umich.edu        Isub /=2;
58910152Satgutier@umich.edu        break;
59010152Satgutier@umich.edu    case tg:
59110152Satgutier@umich.edu        Isub = (nmos_leak + pmos_leak)/2;
59210152Satgutier@umich.edu        break;
59310152Satgutier@umich.edu    default:
59410152Satgutier@umich.edu        assert(0);
59510152Satgutier@umich.edu        break;
59610152Satgutier@umich.edu          }
59710152Satgutier@umich.edu
59810152Satgutier@umich.edu    return Isub;
59910152Satgutier@umich.edu}
60010152Satgutier@umich.edu
60110152Satgutier@umich.edu
60210152Satgutier@umich.edudouble cmos_Ig_leakage(
60310152Satgutier@umich.edu    double nWidth,
60410152Satgutier@umich.edu    double pWidth,
60510152Satgutier@umich.edu    int    fanin,
60610152Satgutier@umich.edu    enum Gate_type g_type,
60710152Satgutier@umich.edu    bool _is_dram,
60810152Satgutier@umich.edu    bool _is_cell,
60910152Satgutier@umich.edu    bool _is_wl_tr,
61010152Satgutier@umich.edu    enum Half_net_topology topo)
61110152Satgutier@umich.edu{
61210152Satgutier@umich.edu        assert (fanin>=1);
61310152Satgutier@umich.edu                double nmos_leak = cmos_Ig_n(nWidth, _is_dram, _is_cell, _is_wl_tr);
61410152Satgutier@umich.edu                double pmos_leak = cmos_Ig_p(pWidth, _is_dram, _is_cell, _is_wl_tr);
61510152Satgutier@umich.edu            double Ig_on=0;
61610152Satgutier@umich.edu            int    num_states;
61710152Satgutier@umich.edu            int    num_on_tx;
61810152Satgutier@umich.edu
61910152Satgutier@umich.edu            num_states = int(pow(2.0, fanin));
62010152Satgutier@umich.edu
62110152Satgutier@umich.edu            switch (g_type)
62210152Satgutier@umich.edu            {
62310152Satgutier@umich.edu            case nmos:
62410152Satgutier@umich.edu                if (fanin==1)
62510152Satgutier@umich.edu                {
62610152Satgutier@umich.edu                        Ig_on = nmos_leak/num_states;
62710152Satgutier@umich.edu                }
62810152Satgutier@umich.edu                else
62910152Satgutier@umich.edu                {
63010152Satgutier@umich.edu                        if (topo==parallel)
63110152Satgutier@umich.edu                        {
63210152Satgutier@umich.edu                        for (num_on_tx=1; num_on_tx<=fanin; num_on_tx++)
63310152Satgutier@umich.edu                        {
63410152Satgutier@umich.edu                                Ig_on += nmos_leak*combination(fanin, num_on_tx)*num_on_tx;
63510152Satgutier@umich.edu                        }
63610152Satgutier@umich.edu                        }
63710152Satgutier@umich.edu                        else
63810152Satgutier@umich.edu                        {
63910152Satgutier@umich.edu                                Ig_on += nmos_leak * fanin;//pull down network when all TXs are on.
64010152Satgutier@umich.edu                            //num_on_tx is the number of on tx
64110152Satgutier@umich.edu                                for (num_on_tx=1; num_on_tx<fanin; num_on_tx++)//when num_on_tx=[1,n-1]
64210152Satgutier@umich.edu                                {
64310152Satgutier@umich.edu                                        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.
64410152Satgutier@umich.edu                                }
64510152Satgutier@umich.edu                                Ig_on /=num_states;
64610152Satgutier@umich.edu                        }
64710152Satgutier@umich.edu                }
64810152Satgutier@umich.edu                break;
64910152Satgutier@umich.edu            case pmos:
65010152Satgutier@umich.edu                if (fanin==1)
65110152Satgutier@umich.edu                {
65210152Satgutier@umich.edu                        Ig_on = pmos_leak/num_states;
65310152Satgutier@umich.edu                }
65410152Satgutier@umich.edu                else
65510152Satgutier@umich.edu                {
65610152Satgutier@umich.edu                        if (topo==parallel)
65710152Satgutier@umich.edu                    {
65810152Satgutier@umich.edu                  for (num_on_tx=1; num_on_tx<=fanin; num_on_tx++)
65910152Satgutier@umich.edu                  {
66010152Satgutier@umich.edu                          Ig_on += pmos_leak*combination(fanin, num_on_tx)*num_on_tx;
66110152Satgutier@umich.edu                  }
66210152Satgutier@umich.edu                    }
66310152Satgutier@umich.edu                    else
66410152Satgutier@umich.edu                    {
66510152Satgutier@umich.edu                          Ig_on += pmos_leak * fanin;//pull down network when all TXs are on.
66610152Satgutier@umich.edu                      //num_on_tx is the number of on tx
66710152Satgutier@umich.edu                          for (num_on_tx=1; num_on_tx<fanin; num_on_tx++)//when num_on_tx=[1,n-1]
66810152Satgutier@umich.edu                          {
66910152Satgutier@umich.edu                                  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.
67010152Satgutier@umich.edu                          }
67110152Satgutier@umich.edu                          Ig_on /=num_states;
67210152Satgutier@umich.edu                    }
67310152Satgutier@umich.edu                }
67410152Satgutier@umich.edu                break;
67510152Satgutier@umich.edu
67610152Satgutier@umich.edu            case inv:
67710152Satgutier@umich.edu                Ig_on = (nmos_leak + pmos_leak)/2;
67810152Satgutier@umich.edu                break;
67910152Satgutier@umich.edu            case nand:
68010152Satgutier@umich.edu                //pull up network
68110152Satgutier@umich.edu                for (num_on_tx=1; num_on_tx<=fanin; num_on_tx++)//when num_on_tx=[1,n]
68210152Satgutier@umich.edu                {
68310152Satgutier@umich.edu                        Ig_on += pmos_leak*combination(fanin, num_on_tx)*num_on_tx;
68410152Satgutier@umich.edu                }
68510152Satgutier@umich.edu
68610152Satgutier@umich.edu                //pull down network
68710152Satgutier@umich.edu                Ig_on += nmos_leak * fanin;//pull down network when all TXs are on.
68810152Satgutier@umich.edu                //num_on_tx is the number of on tx
68910152Satgutier@umich.edu                for (num_on_tx=1; num_on_tx<fanin; num_on_tx++)//when num_on_tx=[1,n-1]
69010152Satgutier@umich.edu                {
69110152Satgutier@umich.edu                        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.
69210152Satgutier@umich.edu                }
69310152Satgutier@umich.edu                Ig_on /=num_states;
69410152Satgutier@umich.edu                break;
69510152Satgutier@umich.edu            case nor:
69610152Satgutier@umich.edu                // num_on_tx is the number of on tx in pull up network
69710152Satgutier@umich.edu                Ig_on += pmos_leak * fanin;//pull up network when all TXs are on.
69810152Satgutier@umich.edu                for (num_on_tx=1; num_on_tx<fanin; num_on_tx++)
69910152Satgutier@umich.edu                {
70010152Satgutier@umich.edu                        Ig_on += pmos_leak*combination(fanin, num_on_tx)*num_on_tx/2;
70110152Satgutier@umich.edu
70210152Satgutier@umich.edu                }
70310152Satgutier@umich.edu                //pull down network
70410152Satgutier@umich.edu                for (num_on_tx=1; num_on_tx<=fanin; num_on_tx++)//when num_on_tx=[1,n]
70510152Satgutier@umich.edu                {
70610152Satgutier@umich.edu                        Ig_on += nmos_leak*combination(fanin, num_on_tx)*num_on_tx;
70710152Satgutier@umich.edu                }
70810152Satgutier@umich.edu                Ig_on /=num_states;
70910152Satgutier@umich.edu                break;
71010152Satgutier@umich.edu            case tri:
71110152Satgutier@umich.edu                Ig_on += (2*nmos_leak + 2*pmos_leak)/2;//enabled
71210152Satgutier@umich.edu                Ig_on += (nmos_leak + pmos_leak)/2; //disabled upper bound of leakage power
71310152Satgutier@umich.edu                Ig_on /=2;
71410152Satgutier@umich.edu                break;
71510152Satgutier@umich.edu            case tg:
71610152Satgutier@umich.edu                Ig_on = (nmos_leak + pmos_leak)/2;
71710152Satgutier@umich.edu                break;
71810152Satgutier@umich.edu            default:
71910152Satgutier@umich.edu                assert(0);
72010152Satgutier@umich.edu                break;
72110152Satgutier@umich.edu                  }
72210152Satgutier@umich.edu
72310152Satgutier@umich.edu            return Ig_on;
72410152Satgutier@umich.edu}
72510152Satgutier@umich.edu
72610152Satgutier@umich.edudouble shortcircuit_simple(
72710152Satgutier@umich.edu    double vt,
72810152Satgutier@umich.edu    double velocity_index,
72910152Satgutier@umich.edu    double c_in,
73010152Satgutier@umich.edu    double c_out,
73110152Satgutier@umich.edu    double w_nmos,
73210152Satgutier@umich.edu    double w_pmos,
73310152Satgutier@umich.edu    double i_on_n,
73410152Satgutier@umich.edu    double i_on_p,
73510152Satgutier@umich.edu    double i_on_n_in,
73610152Satgutier@umich.edu    double i_on_p_in,
73710152Satgutier@umich.edu    double vdd)
73810152Satgutier@umich.edu{
73910152Satgutier@umich.edu
74010152Satgutier@umich.edu        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
74110152Satgutier@umich.edu        double fo_n, fo_p, fanout, beta_ratio, vt_to_vdd_ratio;
74210152Satgutier@umich.edu
74310152Satgutier@umich.edu        fo_n	= i_on_n/i_on_n_in;
74410152Satgutier@umich.edu        fo_p	= i_on_p/i_on_p_in;
74510152Satgutier@umich.edu        fanout	= c_out/c_in;
74610152Satgutier@umich.edu        beta_ratio = i_on_p/i_on_n;
74710152Satgutier@umich.edu        vt_to_vdd_ratio = vt/vdd;
74810152Satgutier@umich.edu
74910152Satgutier@umich.edu        //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;
75010152Satgutier@umich.edu        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;
75110152Satgutier@umich.edu        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;
75210152Satgutier@umich.edu//	double t1, t2, t3, t4, t5;
75310152Satgutier@umich.edu//	t1=pow(((vdd-vt)-vt_to_vdd_ratio),3);
75410152Satgutier@umich.edu//	t2=pow(velocity_index,2.0);
75510152Satgutier@umich.edu//	t3=pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio);
75610152Satgutier@umich.edu//	t4=t1/t2/t3;
75710152Satgutier@umich.edu//	cout <<t1<<"t1\n"<<t2<<"t2\n"<<t3<<"t3\n"<<t4<<"t4\n"<<fanout<<endl;
75810152Satgutier@umich.edu
75910152Satgutier@umich.edu        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);
76010152Satgutier@umich.edu        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);
76110152Satgutier@umich.edu
76210152Satgutier@umich.edu//	t1=pow(((vdd-vt)-vt_to_vdd_ratio),1.5);
76310152Satgutier@umich.edu//	t2=pow(2, 3*vt_to_vdd_ratio+2*velocity_index);
76410152Satgutier@umich.edu//	t3=t1/t2;
76510152Satgutier@umich.edu//	cout <<t1<<"t1\n"<<t2<<"t2\n"<<t3<<"t3\n"<<t4<<"t4\n"<<fanout<<endl;
76610152Satgutier@umich.edu//	p_short_circuit_discharge = 1.0/(1.0/p_short_circuit_discharge_low + 1.0/p_short_circuit_discharge_high);
76710152Satgutier@umich.edu//	p_short_circuit_charge = 1/(1/p_short_circuit_charge_low + 1/p_short_circuit_charge_high); //harmmoic mean cannot be applied simple formulas.
76810152Satgutier@umich.edu
76910152Satgutier@umich.edu        p_short_circuit_discharge = p_short_circuit_discharge_low;
77010152Satgutier@umich.edu        p_short_circuit_charge = p_short_circuit_charge_low;
77110152Satgutier@umich.edu        p_short_circuit = (p_short_circuit_discharge + p_short_circuit_charge)/2;
77210152Satgutier@umich.edu
77310152Satgutier@umich.edu  return (p_short_circuit);
77410152Satgutier@umich.edu}
77510152Satgutier@umich.edu
77610152Satgutier@umich.edudouble shortcircuit(
77710152Satgutier@umich.edu    double vt,
77810152Satgutier@umich.edu    double velocity_index,
77910152Satgutier@umich.edu    double c_in,
78010152Satgutier@umich.edu    double c_out,
78110152Satgutier@umich.edu    double w_nmos,
78210152Satgutier@umich.edu    double w_pmos,
78310152Satgutier@umich.edu    double i_on_n,
78410152Satgutier@umich.edu    double i_on_p,
78510152Satgutier@umich.edu    double i_on_n_in,
78610152Satgutier@umich.edu    double i_on_p_in,
78710152Satgutier@umich.edu    double vdd)
78810152Satgutier@umich.edu{
78910152Satgutier@umich.edu
79010152Satgutier@umich.edu        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
79110152Satgutier@umich.edu        double fo_n, fo_p, fanout, beta_ratio, vt_to_vdd_ratio;
79210152Satgutier@umich.edu        double f_alpha, k_v, e, g_v_alpha, h_v_alpha;
79310152Satgutier@umich.edu
79410152Satgutier@umich.edu        fo_n		= i_on_n/i_on_n_in;
79510152Satgutier@umich.edu        fo_p		= i_on_p/i_on_p_in;
79610152Satgutier@umich.edu        fanout		= 1;
79710152Satgutier@umich.edu        beta_ratio 	= i_on_p/i_on_n;
79810152Satgutier@umich.edu        vt_to_vdd_ratio = vt/vdd;
79910152Satgutier@umich.edu        e 			= 	2.71828;
80010152Satgutier@umich.edu        f_alpha		=	1/(velocity_index+2) -velocity_index/(2*(velocity_index+3)) +velocity_index/(velocity_index+4)*(velocity_index/2-1);
80110152Satgutier@umich.edu        k_v			=	0.9/0.8+(vdd-vt)/0.8*log(10*(vdd-vt)/e);
80210152Satgutier@umich.edu        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));
80310152Satgutier@umich.edu        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));
80410152Satgutier@umich.edu
80510152Satgutier@umich.edu        //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;
80610152Satgutier@umich.edu//	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;
80710152Satgutier@umich.edu//	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;
80810152Satgutier@umich.edu//	double t1, t2, t3, t4, t5;
80910152Satgutier@umich.edu//	t1=pow(((vdd-vt)-vt_to_vdd_ratio),3);
81010152Satgutier@umich.edu//	t2=pow(velocity_index,2.0);
81110152Satgutier@umich.edu//	t3=pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio);
81210152Satgutier@umich.edu//	t4=t1/t2/t3;
81310152Satgutier@umich.edu//
81410152Satgutier@umich.edu//	cout <<t1<<"t1\n"<<t2<<"t2\n"<<t3<<"t3\n"<<t4<<"t4\n"<<fanout<<endl;
81510152Satgutier@umich.edu//
81610152Satgutier@umich.edu//
81710152Satgutier@umich.edu//	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);
81810152Satgutier@umich.edu//	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);
81910152Satgutier@umich.edu//
82010152Satgutier@umich.edu//	p_short_circuit_discharge = 1.0/(1.0/p_short_circuit_discharge_low + 1.0/p_short_circuit_discharge_high);
82110152Satgutier@umich.edu//	p_short_circuit_charge = 1/(1/p_short_circuit_charge_low + 1/p_short_circuit_charge_high);
82210152Satgutier@umich.edu//
82310152Satgutier@umich.edu//	p_short_circuit = (p_short_circuit_discharge + p_short_circuit_charge)/2;
82410152Satgutier@umich.edu//
82510152Satgutier@umich.edu//	p_short_circuit = p_short_circuit_discharge;
82610152Satgutier@umich.edu
82710152Satgutier@umich.edu        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);
82810152Satgutier@umich.edu  return (p_short_circuit);
82910152Satgutier@umich.edu}
830