basic_circuit.cc revision 10152
111183Serfan.azarkhish@unibo.it/*****************************************************************************
211183Serfan.azarkhish@unibo.it *                                McPAT/CACTI
311183Serfan.azarkhish@unibo.it *                      SOFTWARE LICENSE AGREEMENT
411183Serfan.azarkhish@unibo.it *            Copyright 2012 Hewlett-Packard Development Company, L.P.
511183Serfan.azarkhish@unibo.it *                          All Rights Reserved
611183Serfan.azarkhish@unibo.it *
711183Serfan.azarkhish@unibo.it * Redistribution and use in source and binary forms, with or without
811183Serfan.azarkhish@unibo.it * modification, are permitted provided that the following conditions are
911183Serfan.azarkhish@unibo.it * met: redistributions of source code must retain the above copyright
1011183Serfan.azarkhish@unibo.it * notice, this list of conditions and the following disclaimer;
1111183Serfan.azarkhish@unibo.it * redistributions in binary form must reproduce the above copyright
1211183Serfan.azarkhish@unibo.it * notice, this list of conditions and the following disclaimer in the
1311183Serfan.azarkhish@unibo.it * documentation and/or other materials provided with the distribution;
1411183Serfan.azarkhish@unibo.it * neither the name of the copyright holders nor the names of its
1511183Serfan.azarkhish@unibo.it * contributors may be used to endorse or promote products derived from
1611183Serfan.azarkhish@unibo.it * this software without specific prior written permission.
1711183Serfan.azarkhish@unibo.it
1811183Serfan.azarkhish@unibo.it * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1911183Serfan.azarkhish@unibo.it * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2011183Serfan.azarkhish@unibo.it * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2111183Serfan.azarkhish@unibo.it * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2211183Serfan.azarkhish@unibo.it * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2311183Serfan.azarkhish@unibo.it * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2411183Serfan.azarkhish@unibo.it * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2511183Serfan.azarkhish@unibo.it * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2611183Serfan.azarkhish@unibo.it * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2711183Serfan.azarkhish@unibo.it * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2811183Serfan.azarkhish@unibo.it * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.”
2911183Serfan.azarkhish@unibo.it *
3011183Serfan.azarkhish@unibo.it ***************************************************************************/
3111183Serfan.azarkhish@unibo.it
3211183Serfan.azarkhish@unibo.it
3311183Serfan.azarkhish@unibo.it
3411183Serfan.azarkhish@unibo.it
3511183Serfan.azarkhish@unibo.it#include <cassert>
3611183Serfan.azarkhish@unibo.it#include <cmath>
3711183Serfan.azarkhish@unibo.it#include <iostream>
3811183Serfan.azarkhish@unibo.it
3911183Serfan.azarkhish@unibo.it#include "basic_circuit.h"
4011551Sabdul.mutaal@gmail.com#include "parameter.h"
4111183Serfan.azarkhish@unibo.it
4211183Serfan.azarkhish@unibo.ituint32_t _log2(uint64_t num)
4311183Serfan.azarkhish@unibo.it{
4411183Serfan.azarkhish@unibo.it  uint32_t log2 = 0;
4511183Serfan.azarkhish@unibo.it
4611183Serfan.azarkhish@unibo.it  if (num == 0)
4711183Serfan.azarkhish@unibo.it  {
4811183Serfan.azarkhish@unibo.it    std::cerr << "log0?" << std::endl;
4911183Serfan.azarkhish@unibo.it    exit(1);
5011183Serfan.azarkhish@unibo.it  }
5111183Serfan.azarkhish@unibo.it
5211551Sabdul.mutaal@gmail.com  while (num > 1)
5311551Sabdul.mutaal@gmail.com  {
5411551Sabdul.mutaal@gmail.com    num = (num >> 1);
5511551Sabdul.mutaal@gmail.com    log2++;
5611183Serfan.azarkhish@unibo.it  }
5711183Serfan.azarkhish@unibo.it
5811183Serfan.azarkhish@unibo.it  return log2;
5911183Serfan.azarkhish@unibo.it}
6011183Serfan.azarkhish@unibo.it
6111837Swendy.elsasser@arm.com
6211183Serfan.azarkhish@unibo.itbool is_pow2(int64_t val)
6311183Serfan.azarkhish@unibo.it{
6411183Serfan.azarkhish@unibo.it  if (val <= 0)
6511183Serfan.azarkhish@unibo.it  {
6611183Serfan.azarkhish@unibo.it    return false;
6711183Serfan.azarkhish@unibo.it  }
6811551Sabdul.mutaal@gmail.com  else if (val == 1)
6911183Serfan.azarkhish@unibo.it  {
7011551Sabdul.mutaal@gmail.com    return true;
7111551Sabdul.mutaal@gmail.com  }
7211551Sabdul.mutaal@gmail.com  else
7311551Sabdul.mutaal@gmail.com  {
7411551Sabdul.mutaal@gmail.com    return (_log2(val) != _log2(val-1));
7511183Serfan.azarkhish@unibo.it  }
7611551Sabdul.mutaal@gmail.com}
7711183Serfan.azarkhish@unibo.it
7811551Sabdul.mutaal@gmail.com
7911551Sabdul.mutaal@gmail.comint powers (int base, int n)
8011551Sabdul.mutaal@gmail.com{
8111183Serfan.azarkhish@unibo.it  int i, p;
8211183Serfan.azarkhish@unibo.it
8311183Serfan.azarkhish@unibo.it  p = 1;
8411551Sabdul.mutaal@gmail.com  for (i = 1; i <= n; ++i)
8511551Sabdul.mutaal@gmail.com    p *= base;
8611551Sabdul.mutaal@gmail.com  return p;
8711551Sabdul.mutaal@gmail.com}
8811551Sabdul.mutaal@gmail.com
8911551Sabdul.mutaal@gmail.com/*----------------------------------------------------------------------*/
9011551Sabdul.mutaal@gmail.com
9111551Sabdul.mutaal@gmail.comdouble logtwo (double x)
9211551Sabdul.mutaal@gmail.com{
9311551Sabdul.mutaal@gmail.com  assert(x > 0);
9411551Sabdul.mutaal@gmail.com  return ((double) (log (x) / log (2.0)));
9511551Sabdul.mutaal@gmail.com}
9611551Sabdul.mutaal@gmail.com
9711551Sabdul.mutaal@gmail.com/*----------------------------------------------------------------------*/
9811551Sabdul.mutaal@gmail.com
9911551Sabdul.mutaal@gmail.com
10011551Sabdul.mutaal@gmail.comdouble gate_C(
10111551Sabdul.mutaal@gmail.com    double width,
10211551Sabdul.mutaal@gmail.com    double wirelength,
10311551Sabdul.mutaal@gmail.com    bool   _is_dram,
10411551Sabdul.mutaal@gmail.com    bool   _is_cell,
10511551Sabdul.mutaal@gmail.com    bool   _is_wl_tr)
10611551Sabdul.mutaal@gmail.com{
10711551Sabdul.mutaal@gmail.com  const TechnologyParameter::DeviceType * dt;
10811551Sabdul.mutaal@gmail.com
10911551Sabdul.mutaal@gmail.com  if (_is_dram && _is_cell)
11011551Sabdul.mutaal@gmail.com  {
11111551Sabdul.mutaal@gmail.com    dt = &g_tp.dram_acc;   //DRAM cell access transistor
11211551Sabdul.mutaal@gmail.com  }
11311551Sabdul.mutaal@gmail.com  else if (_is_dram && _is_wl_tr)
11411551Sabdul.mutaal@gmail.com  {
11511551Sabdul.mutaal@gmail.com    dt = &g_tp.dram_wl;    //DRAM wordline transistor
11611551Sabdul.mutaal@gmail.com  }
11711551Sabdul.mutaal@gmail.com  else if (!_is_dram && _is_cell)
11811551Sabdul.mutaal@gmail.com  {
11911551Sabdul.mutaal@gmail.com    dt = &g_tp.sram_cell;  // SRAM cell access transistor
12011551Sabdul.mutaal@gmail.com  }
12111551Sabdul.mutaal@gmail.com  else
12211551Sabdul.mutaal@gmail.com  {
12311551Sabdul.mutaal@gmail.com    dt = &g_tp.peri_global;
12411183Serfan.azarkhish@unibo.it  }
12512340Szulian@eit.uni-kl.de
12611183Serfan.azarkhish@unibo.it  return (dt->C_g_ideal + dt->C_overlap + 3*dt->C_fringe)*width + dt->l_phy*Cpolywire;
12711183Serfan.azarkhish@unibo.it}
12811183Serfan.azarkhish@unibo.it
12912340Szulian@eit.uni-kl.de
13011183Serfan.azarkhish@unibo.it// returns gate capacitance in Farads
13112340Szulian@eit.uni-kl.de// actually this function is the same as gate_C() now
13212340Szulian@eit.uni-kl.dedouble gate_C_pass(
13312340Szulian@eit.uni-kl.de    double width,       // gate width in um (length is Lphy_periph_global)
13411183Serfan.azarkhish@unibo.it    double wirelength,  // poly wire length going to gate in lambda
13512340Szulian@eit.uni-kl.de    bool   _is_dram,
13612340Szulian@eit.uni-kl.de    bool   _is_cell,
13711183Serfan.azarkhish@unibo.it    bool   _is_wl_tr)
13811183Serfan.azarkhish@unibo.it{
13911183Serfan.azarkhish@unibo.it  // v5.0
14011183Serfan.azarkhish@unibo.it  const TechnologyParameter::DeviceType * dt;
14111183Serfan.azarkhish@unibo.it
14212340Szulian@eit.uni-kl.de  if ((_is_dram) && (_is_cell))
14312340Szulian@eit.uni-kl.de  {
14411183Serfan.azarkhish@unibo.it    dt = &g_tp.dram_acc;   //DRAM cell access transistor
14511183Serfan.azarkhish@unibo.it  }
14612340Szulian@eit.uni-kl.de  else if ((_is_dram) && (_is_wl_tr))
14712340Szulian@eit.uni-kl.de  {
14811183Serfan.azarkhish@unibo.it    dt = &g_tp.dram_wl;    //DRAM wordline transistor
14911183Serfan.azarkhish@unibo.it  }
15011183Serfan.azarkhish@unibo.it  else if ((!_is_dram) && _is_cell)
15112340Szulian@eit.uni-kl.de  {
15212340Szulian@eit.uni-kl.de    dt = &g_tp.sram_cell;  // SRAM cell access transistor
15311183Serfan.azarkhish@unibo.it  }
15411183Serfan.azarkhish@unibo.it  else
15511183Serfan.azarkhish@unibo.it  {
15612340Szulian@eit.uni-kl.de    dt = &g_tp.peri_global;
15712340Szulian@eit.uni-kl.de  }
15811183Serfan.azarkhish@unibo.it
15911551Sabdul.mutaal@gmail.com  return (dt->C_g_ideal + dt->C_overlap + 3*dt->C_fringe)*width + dt->l_phy*Cpolywire;
16012340Szulian@eit.uni-kl.de}
16112340Szulian@eit.uni-kl.de
16211551Sabdul.mutaal@gmail.com
16312340Szulian@eit.uni-kl.de
16411551Sabdul.mutaal@gmail.comdouble drain_C_(
16512340Szulian@eit.uni-kl.de    double width,
16612340Szulian@eit.uni-kl.de    int nchannel,
16711183Serfan.azarkhish@unibo.it    int stack,
16811183Serfan.azarkhish@unibo.it    int next_arg_thresh_folding_width_or_height_cell,
16911183Serfan.azarkhish@unibo.it    double fold_dimension,
17012340Szulian@eit.uni-kl.de    bool _is_dram,
17112340Szulian@eit.uni-kl.de    bool _is_cell,
17212340Szulian@eit.uni-kl.de    bool _is_wl_tr)
17311183Serfan.azarkhish@unibo.it{
17411183Serfan.azarkhish@unibo.it  double w_folded_tr;
17511183Serfan.azarkhish@unibo.it  const  TechnologyParameter::DeviceType * dt;
17612340Szulian@eit.uni-kl.de
17712340Szulian@eit.uni-kl.de  if ((_is_dram) && (_is_cell))
17812340Szulian@eit.uni-kl.de  {
17911183Serfan.azarkhish@unibo.it    dt = &g_tp.dram_acc;   // DRAM cell access transistor
18011183Serfan.azarkhish@unibo.it  }
18111183Serfan.azarkhish@unibo.it  else if ((_is_dram) && (_is_wl_tr))
18212340Szulian@eit.uni-kl.de  {
18312340Szulian@eit.uni-kl.de    dt = &g_tp.dram_wl;    // DRAM wordline transistor
18411183Serfan.azarkhish@unibo.it  }
18511551Sabdul.mutaal@gmail.com  else if ((!_is_dram) && _is_cell)
18612340Szulian@eit.uni-kl.de  {
18712340Szulian@eit.uni-kl.de    dt = &g_tp.sram_cell;  // SRAM cell access transistor
18811183Serfan.azarkhish@unibo.it  }
18911551Sabdul.mutaal@gmail.com  else
19011551Sabdul.mutaal@gmail.com  {
19111551Sabdul.mutaal@gmail.com    dt = &g_tp.peri_global;
19211551Sabdul.mutaal@gmail.com  }
19312340Szulian@eit.uni-kl.de
19412340Szulian@eit.uni-kl.de  double c_junc_area = dt->C_junc;
19512340Szulian@eit.uni-kl.de  double c_junc_sidewall = dt->C_junc_sidewall;
19611551Sabdul.mutaal@gmail.com  double c_fringe    = 2*dt->C_fringe;
19711551Sabdul.mutaal@gmail.com  double c_overlap   = 2*dt->C_overlap;
19811551Sabdul.mutaal@gmail.com  double drain_C_metal_connecting_folded_tr = 0;
19911551Sabdul.mutaal@gmail.com
20012340Szulian@eit.uni-kl.de  // determine the width of the transistor after folding (if it is getting folded)
20112340Szulian@eit.uni-kl.de  if (next_arg_thresh_folding_width_or_height_cell == 0)
20212340Szulian@eit.uni-kl.de  { // interpret fold_dimension as the the folding width threshold
20311551Sabdul.mutaal@gmail.com    // i.e. the value of transistor width above which the transistor gets folded
20411551Sabdul.mutaal@gmail.com    w_folded_tr = fold_dimension;
20511551Sabdul.mutaal@gmail.com  }
20612340Szulian@eit.uni-kl.de  else
20712340Szulian@eit.uni-kl.de  { // interpret fold_dimension as the height of the cell that this transistor is part of.
20812340Szulian@eit.uni-kl.de    double h_tr_region  = fold_dimension - 2 * g_tp.HPOWERRAIL;
20911551Sabdul.mutaal@gmail.com    // TODO : w_folded_tr must come from Component::compute_gate_area()
21011183Serfan.azarkhish@unibo.it    double ratio_p_to_n = 2.0 / (2.0 + 1.0);
21112340Szulian@eit.uni-kl.de    if (nchannel)
21212340Szulian@eit.uni-kl.de    {
21311183Serfan.azarkhish@unibo.it      w_folded_tr = (1 - ratio_p_to_n) * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS);
21411183Serfan.azarkhish@unibo.it    }
21512340Szulian@eit.uni-kl.de    else
21612340Szulian@eit.uni-kl.de    {
21711183Serfan.azarkhish@unibo.it      w_folded_tr = ratio_p_to_n * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS);
21811551Sabdul.mutaal@gmail.com    }
21912340Szulian@eit.uni-kl.de  }
22012340Szulian@eit.uni-kl.de  int num_folded_tr = (int) (ceil(width / w_folded_tr));
22112340Szulian@eit.uni-kl.de
22211183Serfan.azarkhish@unibo.it  if (num_folded_tr < 2)
22312340Szulian@eit.uni-kl.de  {
22412340Szulian@eit.uni-kl.de    w_folded_tr = width;
22512340Szulian@eit.uni-kl.de  }
22612340Szulian@eit.uni-kl.de
22712340Szulian@eit.uni-kl.de  double total_drain_w = (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) +  // only for drain
22812340Szulian@eit.uni-kl.de                         (stack - 1) * g_tp.spacing_poly_to_poly;
22911183Serfan.azarkhish@unibo.it  double drain_h_for_sidewall = w_folded_tr;
23012340Szulian@eit.uni-kl.de  double total_drain_height_for_cap_wrt_gate = w_folded_tr + 2 * w_folded_tr * (stack - 1);
23112340Szulian@eit.uni-kl.de  if (num_folded_tr > 1)
23211183Serfan.azarkhish@unibo.it  {
23311183Serfan.azarkhish@unibo.it    total_drain_w += (num_folded_tr - 2) * (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) +
23412340Szulian@eit.uni-kl.de                     (num_folded_tr - 1) * ((stack - 1) * g_tp.spacing_poly_to_poly);
23512340Szulian@eit.uni-kl.de
23611183Serfan.azarkhish@unibo.it    if (num_folded_tr%2 == 0)
23711551Sabdul.mutaal@gmail.com    {
23812340Szulian@eit.uni-kl.de      drain_h_for_sidewall = 0;
23912340Szulian@eit.uni-kl.de    }
24011183Serfan.azarkhish@unibo.it    total_drain_height_for_cap_wrt_gate *= num_folded_tr;
24112340Szulian@eit.uni-kl.de    drain_C_metal_connecting_folded_tr   = g_tp.wire_local.C_per_um * total_drain_w;
24212340Szulian@eit.uni-kl.de  }
24312340Szulian@eit.uni-kl.de
24411183Serfan.azarkhish@unibo.it  double drain_C_area     = c_junc_area * total_drain_w * w_folded_tr;
24512340Szulian@eit.uni-kl.de  double drain_C_sidewall = c_junc_sidewall * (drain_h_for_sidewall + 2 * total_drain_w);
24611551Sabdul.mutaal@gmail.com  double drain_C_wrt_gate = (c_fringe + c_overlap) * total_drain_height_for_cap_wrt_gate;
24712340Szulian@eit.uni-kl.de
24812340Szulian@eit.uni-kl.de  return (drain_C_area + drain_C_sidewall + drain_C_wrt_gate + drain_C_metal_connecting_folded_tr);
24912340Szulian@eit.uni-kl.de}
25011551Sabdul.mutaal@gmail.com
25111551Sabdul.mutaal@gmail.com
25211551Sabdul.mutaal@gmail.comdouble tr_R_on(
25312340Szulian@eit.uni-kl.de    double width,
25412340Szulian@eit.uni-kl.de    int nchannel,
25512340Szulian@eit.uni-kl.de    int stack,
25611551Sabdul.mutaal@gmail.com    bool _is_dram,
25711551Sabdul.mutaal@gmail.com    bool _is_cell,
25811551Sabdul.mutaal@gmail.com    bool _is_wl_tr)
25912340Szulian@eit.uni-kl.de{
26012340Szulian@eit.uni-kl.de  const TechnologyParameter::DeviceType * dt;
26112340Szulian@eit.uni-kl.de
26212340Szulian@eit.uni-kl.de  if ((_is_dram) && (_is_cell))
26312340Szulian@eit.uni-kl.de  {
26412340Szulian@eit.uni-kl.de    dt = &g_tp.dram_acc;   //DRAM cell access transistor
26512340Szulian@eit.uni-kl.de  }
26612340Szulian@eit.uni-kl.de  else if ((_is_dram) && (_is_wl_tr))
26712340Szulian@eit.uni-kl.de  {
26812340Szulian@eit.uni-kl.de    dt = &g_tp.dram_wl;    //DRAM wordline transistor
26912340Szulian@eit.uni-kl.de  }
27012340Szulian@eit.uni-kl.de  else if ((!_is_dram) && _is_cell)
27112340Szulian@eit.uni-kl.de  {
27212340Szulian@eit.uni-kl.de    dt = &g_tp.sram_cell;  // SRAM cell access transistor
27312340Szulian@eit.uni-kl.de  }
27412340Szulian@eit.uni-kl.de  else
27512340Szulian@eit.uni-kl.de  {
27612340Szulian@eit.uni-kl.de    dt = &g_tp.peri_global;
27712340Szulian@eit.uni-kl.de  }
27812340Szulian@eit.uni-kl.de
27912340Szulian@eit.uni-kl.de  double restrans = (nchannel) ? dt->R_nch_on : dt->R_pch_on;
28012340Szulian@eit.uni-kl.de  return (stack * restrans / width);
28112340Szulian@eit.uni-kl.de}
28212340Szulian@eit.uni-kl.de
28312340Szulian@eit.uni-kl.de
28412340Szulian@eit.uni-kl.de/* This routine operates in reverse: given a resistance, it finds
28512340Szulian@eit.uni-kl.de * the transistor width that would have this R.  It is used in the
28612340Szulian@eit.uni-kl.de * data wordline to estimate the wordline driver size. */
28712340Szulian@eit.uni-kl.de
28811551Sabdul.mutaal@gmail.com// returns width in um
28911551Sabdul.mutaal@gmail.comdouble R_to_w(
29012340Szulian@eit.uni-kl.de    double res,
29112340Szulian@eit.uni-kl.de    int   nchannel,
29211551Sabdul.mutaal@gmail.com    bool _is_dram,
29312340Szulian@eit.uni-kl.de    bool _is_cell,
29412340Szulian@eit.uni-kl.de    bool _is_wl_tr)
29511183Serfan.azarkhish@unibo.it{
29612340Szulian@eit.uni-kl.de  const TechnologyParameter::DeviceType * dt;
29712340Szulian@eit.uni-kl.de
29812340Szulian@eit.uni-kl.de  if ((_is_dram) && (_is_cell))
29912340Szulian@eit.uni-kl.de  {
30012340Szulian@eit.uni-kl.de    dt = &g_tp.dram_acc;   //DRAM cell access transistor
30112340Szulian@eit.uni-kl.de  }
30212340Szulian@eit.uni-kl.de  else if ((_is_dram) && (_is_wl_tr))
30312340Szulian@eit.uni-kl.de  {
30412340Szulian@eit.uni-kl.de    dt = &g_tp.dram_wl;    //DRAM wordline transistor
30512340Szulian@eit.uni-kl.de  }
30612340Szulian@eit.uni-kl.de  else if ((!_is_dram) && (_is_cell))
30712340Szulian@eit.uni-kl.de  {
30812340Szulian@eit.uni-kl.de    dt = &g_tp.sram_cell;  // SRAM cell access transistor
30912340Szulian@eit.uni-kl.de  }
31011183Serfan.azarkhish@unibo.it  else
31112340Szulian@eit.uni-kl.de  {
31212340Szulian@eit.uni-kl.de    dt = &g_tp.peri_global;
31312340Szulian@eit.uni-kl.de  }
31412340Szulian@eit.uni-kl.de
31512340Szulian@eit.uni-kl.de  double restrans = (nchannel) ? dt->R_nch_on : dt->R_pch_on;
31612340Szulian@eit.uni-kl.de  return (restrans / res);
31712340Szulian@eit.uni-kl.de}
31812340Szulian@eit.uni-kl.de
31912340Szulian@eit.uni-kl.de
32012340Szulian@eit.uni-kl.dedouble pmos_to_nmos_sz_ratio(
32112340Szulian@eit.uni-kl.de    bool _is_dram,
32212340Szulian@eit.uni-kl.de    bool _is_wl_tr)
32312340Szulian@eit.uni-kl.de{
32412340Szulian@eit.uni-kl.de  double p_to_n_sizing_ratio;
32512340Szulian@eit.uni-kl.de  if ((_is_dram) && (_is_wl_tr))
32612340Szulian@eit.uni-kl.de  { //DRAM wordline transistor
32712340Szulian@eit.uni-kl.de    p_to_n_sizing_ratio = g_tp.dram_wl.n_to_p_eff_curr_drv_ratio;
32812340Szulian@eit.uni-kl.de  }
32912340Szulian@eit.uni-kl.de  else
33012340Szulian@eit.uni-kl.de  { //DRAM or SRAM all other transistors
33112340Szulian@eit.uni-kl.de    p_to_n_sizing_ratio = g_tp.peri_global.n_to_p_eff_curr_drv_ratio;
33212340Szulian@eit.uni-kl.de  }
33312340Szulian@eit.uni-kl.de  return p_to_n_sizing_ratio;
33412340Szulian@eit.uni-kl.de}
33512340Szulian@eit.uni-kl.de
33612340Szulian@eit.uni-kl.de
33712340Szulian@eit.uni-kl.de// "Timing Models for MOS Circuits" by Mark Horowitz, 1984
33812340Szulian@eit.uni-kl.dedouble horowitz(
33912340Szulian@eit.uni-kl.de    double inputramptime, // input rise time
34012340Szulian@eit.uni-kl.de    double tf,            // time constant of gate
34112340Szulian@eit.uni-kl.de    double vs1,           // threshold voltage
34211183Serfan.azarkhish@unibo.it    double vs2,           // threshold voltage
34311551Sabdul.mutaal@gmail.com    int    rise)          // whether input rises or fall
34412340Szulian@eit.uni-kl.de{
34512340Szulian@eit.uni-kl.de  if (inputramptime == 0 && vs1 == vs2)
34612340Szulian@eit.uni-kl.de  {
34711183Serfan.azarkhish@unibo.it    return tf * (vs1 < 1 ? -log(vs1) : log(vs1));
34811551Sabdul.mutaal@gmail.com  }
34912340Szulian@eit.uni-kl.de  double a, b, td;
35012340Szulian@eit.uni-kl.de
35112340Szulian@eit.uni-kl.de  a = inputramptime / tf;
35212340Szulian@eit.uni-kl.de  if (rise == RISE)
35312340Szulian@eit.uni-kl.de  {
35411183Serfan.azarkhish@unibo.it    b = 0.5;
35511551Sabdul.mutaal@gmail.com    td = tf * sqrt(log(vs1)*log(vs1) + 2*a*b*(1.0 - vs1)) + tf*(log(vs1) - log(vs2));
35611551Sabdul.mutaal@gmail.com  }
35712340Szulian@eit.uni-kl.de  else
35812340Szulian@eit.uni-kl.de  {
35912340Szulian@eit.uni-kl.de    b = 0.4;
36012340Szulian@eit.uni-kl.de    td = tf * sqrt(log(1.0 - vs1)*log(1.0 - vs1) + 2*a*b*(vs1)) + tf*(log(1.0 - vs1) - log(1.0 - vs2));
36112340Szulian@eit.uni-kl.de  }
36212340Szulian@eit.uni-kl.de  return (td);
36312340Szulian@eit.uni-kl.de}
36411551Sabdul.mutaal@gmail.com
36512340Szulian@eit.uni-kl.dedouble cmos_Ileak(
36612340Szulian@eit.uni-kl.de    double nWidth,
36712340Szulian@eit.uni-kl.de    double pWidth,
36812340Szulian@eit.uni-kl.de    bool _is_dram,
36912340Szulian@eit.uni-kl.de    bool _is_cell,
37012340Szulian@eit.uni-kl.de    bool _is_wl_tr)
37112340Szulian@eit.uni-kl.de{
37212340Szulian@eit.uni-kl.de  TechnologyParameter::DeviceType * dt;
37312340Szulian@eit.uni-kl.de
37412340Szulian@eit.uni-kl.de  if ((!_is_dram)&&(_is_cell))
37512340Szulian@eit.uni-kl.de  { //SRAM cell access transistor
37611183Serfan.azarkhish@unibo.it    dt = &(g_tp.sram_cell);
37712340Szulian@eit.uni-kl.de  }
37812340Szulian@eit.uni-kl.de  else if ((_is_dram)&&(_is_wl_tr))
37912340Szulian@eit.uni-kl.de  { //DRAM wordline transistor
38012340Szulian@eit.uni-kl.de    dt = &(g_tp.dram_wl);
38111183Serfan.azarkhish@unibo.it  }
38211551Sabdul.mutaal@gmail.com  else
38311551Sabdul.mutaal@gmail.com  { //DRAM or SRAM all other transistors
38411551Sabdul.mutaal@gmail.com    dt = &(g_tp.peri_global);
38512340Szulian@eit.uni-kl.de  }
38612340Szulian@eit.uni-kl.de  return nWidth*dt->I_off_n + pWidth*dt->I_off_p;
38711551Sabdul.mutaal@gmail.com}
38812340Szulian@eit.uni-kl.de
38912340Szulian@eit.uni-kl.de
39011551Sabdul.mutaal@gmail.comdouble simplified_nmos_leakage(
39112340Szulian@eit.uni-kl.de    double nwidth,
39212340Szulian@eit.uni-kl.de    bool _is_dram,
39312340Szulian@eit.uni-kl.de    bool _is_cell,
39412340Szulian@eit.uni-kl.de    bool _is_wl_tr)
39512340Szulian@eit.uni-kl.de{
39611551Sabdul.mutaal@gmail.com  TechnologyParameter::DeviceType * dt;
39712340Szulian@eit.uni-kl.de
39812340Szulian@eit.uni-kl.de  if ((!_is_dram)&&(_is_cell))
39912340Szulian@eit.uni-kl.de  { //SRAM cell access transistor
40011551Sabdul.mutaal@gmail.com    dt = &(g_tp.sram_cell);
40111551Sabdul.mutaal@gmail.com  }
40212340Szulian@eit.uni-kl.de  else if ((_is_dram)&&(_is_wl_tr))
40312340Szulian@eit.uni-kl.de  { //DRAM wordline transistor
40412340Szulian@eit.uni-kl.de    dt = &(g_tp.dram_wl);
40512340Szulian@eit.uni-kl.de  }
40612340Szulian@eit.uni-kl.de  else
40712340Szulian@eit.uni-kl.de  { //DRAM or SRAM all other transistors
40811551Sabdul.mutaal@gmail.com    dt = &(g_tp.peri_global);
40912340Szulian@eit.uni-kl.de  }
41012340Szulian@eit.uni-kl.de  return nwidth * dt->I_off_n;
41112340Szulian@eit.uni-kl.de}
41212340Szulian@eit.uni-kl.de
41312340Szulian@eit.uni-kl.deint factorial(int n, int m)
41411551Sabdul.mutaal@gmail.com{
41511551Sabdul.mutaal@gmail.com        int fa = m, i;
41612340Szulian@eit.uni-kl.de        for (i=m+1; i<=n; i++)
41712340Szulian@eit.uni-kl.de                fa *=i;
41811551Sabdul.mutaal@gmail.com        return fa;
41911551Sabdul.mutaal@gmail.com}
42011551Sabdul.mutaal@gmail.com
42111183Serfan.azarkhish@unibo.itint combination(int n, int m)
42211551Sabdul.mutaal@gmail.com{
42311551Sabdul.mutaal@gmail.com  int ret;
42411551Sabdul.mutaal@gmail.com  ret = factorial(n, m+1) / factorial(n - m);
42511551Sabdul.mutaal@gmail.com  return ret;
42612340Szulian@eit.uni-kl.de}
42711551Sabdul.mutaal@gmail.com
42811551Sabdul.mutaal@gmail.comdouble simplified_pmos_leakage(
42911551Sabdul.mutaal@gmail.com    double pwidth,
43012340Szulian@eit.uni-kl.de    bool _is_dram,
43112340Szulian@eit.uni-kl.de    bool _is_cell,
43212340Szulian@eit.uni-kl.de    bool _is_wl_tr)
43311551Sabdul.mutaal@gmail.com{
43411551Sabdul.mutaal@gmail.com  TechnologyParameter::DeviceType * dt;
43511551Sabdul.mutaal@gmail.com
43611551Sabdul.mutaal@gmail.com  if ((!_is_dram)&&(_is_cell))
43711551Sabdul.mutaal@gmail.com  { //SRAM cell access transistor
43811551Sabdul.mutaal@gmail.com    dt = &(g_tp.sram_cell);
43911551Sabdul.mutaal@gmail.com  }
44011551Sabdul.mutaal@gmail.com  else if ((_is_dram)&&(_is_wl_tr))
44111551Sabdul.mutaal@gmail.com  { //DRAM wordline transistor
44211551Sabdul.mutaal@gmail.com    dt = &(g_tp.dram_wl);
44311551Sabdul.mutaal@gmail.com  }
44411551Sabdul.mutaal@gmail.com  else
44511551Sabdul.mutaal@gmail.com  { //DRAM or SRAM all other transistors
44611551Sabdul.mutaal@gmail.com    dt = &(g_tp.peri_global);
44711551Sabdul.mutaal@gmail.com  }
44811551Sabdul.mutaal@gmail.com  return pwidth * dt->I_off_p;
44911551Sabdul.mutaal@gmail.com}
45012340Szulian@eit.uni-kl.de
45112340Szulian@eit.uni-kl.dedouble cmos_Ig_n(
45211551Sabdul.mutaal@gmail.com    double nWidth,
45311551Sabdul.mutaal@gmail.com    bool _is_dram,
45411551Sabdul.mutaal@gmail.com    bool _is_cell,
45511551Sabdul.mutaal@gmail.com    bool _is_wl_tr)
45611551Sabdul.mutaal@gmail.com{
45711551Sabdul.mutaal@gmail.com  TechnologyParameter::DeviceType * dt;
45811551Sabdul.mutaal@gmail.com
45911551Sabdul.mutaal@gmail.com  if ((!_is_dram)&&(_is_cell))
46011551Sabdul.mutaal@gmail.com  { //SRAM cell access transistor
46111551Sabdul.mutaal@gmail.com    dt = &(g_tp.sram_cell);
46211551Sabdul.mutaal@gmail.com  }
46311551Sabdul.mutaal@gmail.com  else if ((_is_dram)&&(_is_wl_tr))
46412340Szulian@eit.uni-kl.de  { //DRAM wordline transistor
46511551Sabdul.mutaal@gmail.com    dt = &(g_tp.dram_wl);
46611551Sabdul.mutaal@gmail.com  }
46711551Sabdul.mutaal@gmail.com  else
46811551Sabdul.mutaal@gmail.com  { //DRAM or SRAM all other transistors
46911551Sabdul.mutaal@gmail.com    dt = &(g_tp.peri_global);
47011551Sabdul.mutaal@gmail.com  }
47111551Sabdul.mutaal@gmail.com  return nWidth*dt->I_g_on_n;
47211551Sabdul.mutaal@gmail.com}
47311551Sabdul.mutaal@gmail.com
47411551Sabdul.mutaal@gmail.comdouble cmos_Ig_p(
47511551Sabdul.mutaal@gmail.com    double pWidth,
47611551Sabdul.mutaal@gmail.com    bool _is_dram,
47711551Sabdul.mutaal@gmail.com    bool _is_cell,
47811551Sabdul.mutaal@gmail.com    bool _is_wl_tr)
47911551Sabdul.mutaal@gmail.com{
48011551Sabdul.mutaal@gmail.com  TechnologyParameter::DeviceType * dt;
48111551Sabdul.mutaal@gmail.com
48211551Sabdul.mutaal@gmail.com  if ((!_is_dram)&&(_is_cell))
48311551Sabdul.mutaal@gmail.com  { //SRAM cell access transistor
48411551Sabdul.mutaal@gmail.com    dt = &(g_tp.sram_cell);
48511551Sabdul.mutaal@gmail.com  }
48611551Sabdul.mutaal@gmail.com  else if ((_is_dram)&&(_is_wl_tr))
48711551Sabdul.mutaal@gmail.com  { //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//
814//	cout <<t1<<"t1\n"<<t2<<"t2\n"<<t3<<"t3\n"<<t4<<"t4\n"<<fanout<<endl;
815//
816//
817//	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);
818//	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);
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}
830