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. 510234Syasuko.eckert@amd.com * Copyright (c) 2010-2013 Advanced Micro Devices, Inc. 610152Satgutier@umich.edu * All Rights Reserved 710152Satgutier@umich.edu * 810152Satgutier@umich.edu * Redistribution and use in source and binary forms, with or without 910152Satgutier@umich.edu * modification, are permitted provided that the following conditions are 1010152Satgutier@umich.edu * met: redistributions of source code must retain the above copyright 1110152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer; 1210152Satgutier@umich.edu * redistributions in binary form must reproduce the above copyright 1310152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer in the 1410152Satgutier@umich.edu * documentation and/or other materials provided with the distribution; 1510152Satgutier@umich.edu * neither the name of the copyright holders nor the names of its 1610152Satgutier@umich.edu * contributors may be used to endorse or promote products derived from 1710152Satgutier@umich.edu * this software without specific prior written permission. 1810152Satgutier@umich.edu 1910152Satgutier@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2010152Satgutier@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2110152Satgutier@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2210152Satgutier@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2310152Satgutier@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2410152Satgutier@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2510152Satgutier@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2610152Satgutier@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2710152Satgutier@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2810152Satgutier@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2910234Syasuko.eckert@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3010152Satgutier@umich.edu * 3110152Satgutier@umich.edu ***************************************************************************/ 3210152Satgutier@umich.edu 3310152Satgutier@umich.edu 3410152Satgutier@umich.edu 3510152Satgutier@umich.edu 3610152Satgutier@umich.edu#include <cassert> 3710152Satgutier@umich.edu#include <cmath> 3810152Satgutier@umich.edu#include <iostream> 3910152Satgutier@umich.edu 4010152Satgutier@umich.edu#include "basic_circuit.h" 4110152Satgutier@umich.edu#include "parameter.h" 4210152Satgutier@umich.edu 4310234Syasuko.eckert@amd.comuint32_t _log2(uint64_t num) { 4410234Syasuko.eckert@amd.com uint32_t log2 = 0; 4510152Satgutier@umich.edu 4610234Syasuko.eckert@amd.com if (num == 0) { 4710234Syasuko.eckert@amd.com std::cerr << "log0?" << std::endl; 4810234Syasuko.eckert@amd.com exit(1); 4910234Syasuko.eckert@amd.com } 5010152Satgutier@umich.edu 5110234Syasuko.eckert@amd.com while (num > 1) { 5210234Syasuko.eckert@amd.com num = (num >> 1); 5310234Syasuko.eckert@amd.com log2++; 5410234Syasuko.eckert@amd.com } 5510152Satgutier@umich.edu 5610234Syasuko.eckert@amd.com return log2; 5710152Satgutier@umich.edu} 5810152Satgutier@umich.edu 5910152Satgutier@umich.edu 6010234Syasuko.eckert@amd.combool is_pow2(int64_t val) { 6110234Syasuko.eckert@amd.com if (val <= 0) { 6210234Syasuko.eckert@amd.com return false; 6310234Syasuko.eckert@amd.com } else if (val == 1) { 6410234Syasuko.eckert@amd.com return true; 6510234Syasuko.eckert@amd.com } else { 6610234Syasuko.eckert@amd.com return (_log2(val) != _log2(val - 1)); 6710234Syasuko.eckert@amd.com } 6810152Satgutier@umich.edu} 6910152Satgutier@umich.edu 7010152Satgutier@umich.edu 7110234Syasuko.eckert@amd.comint powers (int base, int n) { 7210234Syasuko.eckert@amd.com int i, p; 7310152Satgutier@umich.edu 7410234Syasuko.eckert@amd.com p = 1; 7510234Syasuko.eckert@amd.com for (i = 1; i <= n; ++i) 7610234Syasuko.eckert@amd.com p *= base; 7710234Syasuko.eckert@amd.com return p; 7810152Satgutier@umich.edu} 7910152Satgutier@umich.edu 8010152Satgutier@umich.edu/*----------------------------------------------------------------------*/ 8110152Satgutier@umich.edu 8210234Syasuko.eckert@amd.comdouble logtwo (double x) { 8310234Syasuko.eckert@amd.com assert(x > 0); 8410234Syasuko.eckert@amd.com return ((double) (log (x) / log (2.0))); 8510152Satgutier@umich.edu} 8610152Satgutier@umich.edu 8710152Satgutier@umich.edu/*----------------------------------------------------------------------*/ 8810152Satgutier@umich.edu 8910152Satgutier@umich.edu 9010152Satgutier@umich.edudouble gate_C( 9110152Satgutier@umich.edu double width, 9210152Satgutier@umich.edu double wirelength, 9310152Satgutier@umich.edu bool _is_dram, 9410152Satgutier@umich.edu bool _is_cell, 9510234Syasuko.eckert@amd.com bool _is_wl_tr) { 9610234Syasuko.eckert@amd.com const TechnologyParameter::DeviceType * dt; 9710152Satgutier@umich.edu 9810234Syasuko.eckert@amd.com if (_is_dram && _is_cell) { 9910234Syasuko.eckert@amd.com dt = &g_tp.dram_acc; //DRAM cell access transistor 10010234Syasuko.eckert@amd.com } else if (_is_dram && _is_wl_tr) { 10110234Syasuko.eckert@amd.com dt = &g_tp.dram_wl; //DRAM wordline transistor 10210234Syasuko.eckert@amd.com } else if (!_is_dram && _is_cell) { 10310234Syasuko.eckert@amd.com dt = &g_tp.sram_cell; // SRAM cell access transistor 10410234Syasuko.eckert@amd.com } else { 10510234Syasuko.eckert@amd.com dt = &g_tp.peri_global; 10610234Syasuko.eckert@amd.com } 10710152Satgutier@umich.edu 10810234Syasuko.eckert@amd.com return (dt->C_g_ideal + dt->C_overlap + 3*dt->C_fringe)*width + dt->l_phy*Cpolywire; 10910152Satgutier@umich.edu} 11010152Satgutier@umich.edu 11110152Satgutier@umich.edu 11210152Satgutier@umich.edu// returns gate capacitance in Farads 11310152Satgutier@umich.edu// actually this function is the same as gate_C() now 11410152Satgutier@umich.edudouble gate_C_pass( 11510152Satgutier@umich.edu double width, // gate width in um (length is Lphy_periph_global) 11610152Satgutier@umich.edu double wirelength, // poly wire length going to gate in lambda 11710152Satgutier@umich.edu bool _is_dram, 11810152Satgutier@umich.edu bool _is_cell, 11910234Syasuko.eckert@amd.com bool _is_wl_tr) { 12010234Syasuko.eckert@amd.com // v5.0 12110234Syasuko.eckert@amd.com const TechnologyParameter::DeviceType * dt; 12210152Satgutier@umich.edu 12310234Syasuko.eckert@amd.com if ((_is_dram) && (_is_cell)) { 12410234Syasuko.eckert@amd.com dt = &g_tp.dram_acc; //DRAM cell access transistor 12510234Syasuko.eckert@amd.com } else if ((_is_dram) && (_is_wl_tr)) { 12610234Syasuko.eckert@amd.com dt = &g_tp.dram_wl; //DRAM wordline transistor 12710234Syasuko.eckert@amd.com } else if ((!_is_dram) && _is_cell) { 12810234Syasuko.eckert@amd.com dt = &g_tp.sram_cell; // SRAM cell access transistor 12910234Syasuko.eckert@amd.com } else { 13010234Syasuko.eckert@amd.com dt = &g_tp.peri_global; 13110234Syasuko.eckert@amd.com } 13210152Satgutier@umich.edu 13310234Syasuko.eckert@amd.com return (dt->C_g_ideal + dt->C_overlap + 3*dt->C_fringe)*width + dt->l_phy*Cpolywire; 13410152Satgutier@umich.edu} 13510152Satgutier@umich.edu 13610152Satgutier@umich.edu 13710152Satgutier@umich.edu 13810152Satgutier@umich.edudouble drain_C_( 13910152Satgutier@umich.edu double width, 14010152Satgutier@umich.edu int nchannel, 14110152Satgutier@umich.edu int stack, 14210152Satgutier@umich.edu int next_arg_thresh_folding_width_or_height_cell, 14310152Satgutier@umich.edu double fold_dimension, 14410152Satgutier@umich.edu bool _is_dram, 14510152Satgutier@umich.edu bool _is_cell, 14610234Syasuko.eckert@amd.com bool _is_wl_tr) { 14710234Syasuko.eckert@amd.com double w_folded_tr; 14810234Syasuko.eckert@amd.com const TechnologyParameter::DeviceType * dt; 14910152Satgutier@umich.edu 15010234Syasuko.eckert@amd.com if ((_is_dram) && (_is_cell)) { 15110234Syasuko.eckert@amd.com dt = &g_tp.dram_acc; // DRAM cell access transistor 15210234Syasuko.eckert@amd.com } else if ((_is_dram) && (_is_wl_tr)) { 15310234Syasuko.eckert@amd.com dt = &g_tp.dram_wl; // DRAM wordline transistor 15410234Syasuko.eckert@amd.com } else if ((!_is_dram) && _is_cell) { 15510234Syasuko.eckert@amd.com dt = &g_tp.sram_cell; // SRAM cell access transistor 15610234Syasuko.eckert@amd.com } else { 15710234Syasuko.eckert@amd.com dt = &g_tp.peri_global; 15810234Syasuko.eckert@amd.com } 15910152Satgutier@umich.edu 16010234Syasuko.eckert@amd.com double c_junc_area = dt->C_junc; 16110234Syasuko.eckert@amd.com double c_junc_sidewall = dt->C_junc_sidewall; 16210234Syasuko.eckert@amd.com double c_fringe = 2 * dt->C_fringe; 16310234Syasuko.eckert@amd.com double c_overlap = 2 * dt->C_overlap; 16410234Syasuko.eckert@amd.com double drain_C_metal_connecting_folded_tr = 0; 16510152Satgutier@umich.edu 16610234Syasuko.eckert@amd.com // determine the width of the transistor after folding (if it is getting folded) 16710234Syasuko.eckert@amd.com if (next_arg_thresh_folding_width_or_height_cell == 0) { 16810234Syasuko.eckert@amd.com // interpret fold_dimension as the the folding width threshold 16910234Syasuko.eckert@amd.com // i.e. the value of transistor width above which the transistor gets folded 17010234Syasuko.eckert@amd.com w_folded_tr = fold_dimension; 17110234Syasuko.eckert@amd.com } else { // interpret fold_dimension as the height of the cell that this transistor is part of. 17210234Syasuko.eckert@amd.com double h_tr_region = fold_dimension - 2 * g_tp.HPOWERRAIL; 17310234Syasuko.eckert@amd.com // TODO : w_folded_tr must come from Component::compute_gate_area() 17410234Syasuko.eckert@amd.com double ratio_p_to_n = 2.0 / (2.0 + 1.0); 17510234Syasuko.eckert@amd.com if (nchannel) { 17610234Syasuko.eckert@amd.com w_folded_tr = (1 - ratio_p_to_n) * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS); 17710234Syasuko.eckert@amd.com } else { 17810234Syasuko.eckert@amd.com w_folded_tr = ratio_p_to_n * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS); 17910234Syasuko.eckert@amd.com } 18010152Satgutier@umich.edu } 18110234Syasuko.eckert@amd.com int num_folded_tr = (int) (ceil(width / w_folded_tr)); 18210234Syasuko.eckert@amd.com 18310234Syasuko.eckert@amd.com if (num_folded_tr < 2) { 18410234Syasuko.eckert@amd.com w_folded_tr = width; 18510152Satgutier@umich.edu } 18610152Satgutier@umich.edu 18710234Syasuko.eckert@amd.com double total_drain_w = (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) + // only for drain 18810234Syasuko.eckert@amd.com (stack - 1) * g_tp.spacing_poly_to_poly; 18910234Syasuko.eckert@amd.com double drain_h_for_sidewall = w_folded_tr; 19010234Syasuko.eckert@amd.com double total_drain_height_for_cap_wrt_gate = w_folded_tr + 2 * w_folded_tr * (stack - 1); 19110234Syasuko.eckert@amd.com if (num_folded_tr > 1) { 19210234Syasuko.eckert@amd.com total_drain_w += (num_folded_tr - 2) * (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) + 19310234Syasuko.eckert@amd.com (num_folded_tr - 1) * ((stack - 1) * g_tp.spacing_poly_to_poly); 19410152Satgutier@umich.edu 19510234Syasuko.eckert@amd.com if (num_folded_tr % 2 == 0) { 19610234Syasuko.eckert@amd.com drain_h_for_sidewall = 0; 19710234Syasuko.eckert@amd.com } 19810234Syasuko.eckert@amd.com total_drain_height_for_cap_wrt_gate *= num_folded_tr; 19910234Syasuko.eckert@amd.com drain_C_metal_connecting_folded_tr = g_tp.wire_local.C_per_um * total_drain_w; 20010234Syasuko.eckert@amd.com } 20110152Satgutier@umich.edu 20210234Syasuko.eckert@amd.com double drain_C_area = c_junc_area * total_drain_w * w_folded_tr; 20310234Syasuko.eckert@amd.com double drain_C_sidewall = c_junc_sidewall * (drain_h_for_sidewall + 2 * total_drain_w); 20410234Syasuko.eckert@amd.com double drain_C_wrt_gate = (c_fringe + c_overlap) * total_drain_height_for_cap_wrt_gate; 20510152Satgutier@umich.edu 20610234Syasuko.eckert@amd.com return (drain_C_area + drain_C_sidewall + drain_C_wrt_gate + drain_C_metal_connecting_folded_tr); 20710152Satgutier@umich.edu} 20810152Satgutier@umich.edu 20910152Satgutier@umich.edu 21010152Satgutier@umich.edudouble tr_R_on( 21110152Satgutier@umich.edu double width, 21210152Satgutier@umich.edu int nchannel, 21310152Satgutier@umich.edu int stack, 21410152Satgutier@umich.edu bool _is_dram, 21510152Satgutier@umich.edu bool _is_cell, 21610234Syasuko.eckert@amd.com bool _is_wl_tr) { 21710234Syasuko.eckert@amd.com const TechnologyParameter::DeviceType * dt; 21810152Satgutier@umich.edu 21910234Syasuko.eckert@amd.com if ((_is_dram) && (_is_cell)) { 22010234Syasuko.eckert@amd.com dt = &g_tp.dram_acc; //DRAM cell access transistor 22110234Syasuko.eckert@amd.com } else if ((_is_dram) && (_is_wl_tr)) { 22210234Syasuko.eckert@amd.com dt = &g_tp.dram_wl; //DRAM wordline transistor 22310234Syasuko.eckert@amd.com } else if ((!_is_dram) && _is_cell) { 22410234Syasuko.eckert@amd.com dt = &g_tp.sram_cell; // SRAM cell access transistor 22510234Syasuko.eckert@amd.com } else { 22610234Syasuko.eckert@amd.com dt = &g_tp.peri_global; 22710234Syasuko.eckert@amd.com } 22810152Satgutier@umich.edu 22910234Syasuko.eckert@amd.com double restrans = (nchannel) ? dt->R_nch_on : dt->R_pch_on; 23010234Syasuko.eckert@amd.com return (stack * restrans / width); 23110152Satgutier@umich.edu} 23210152Satgutier@umich.edu 23310152Satgutier@umich.edu 23410152Satgutier@umich.edu/* This routine operates in reverse: given a resistance, it finds 23510152Satgutier@umich.edu * the transistor width that would have this R. It is used in the 23610152Satgutier@umich.edu * data wordline to estimate the wordline driver size. */ 23710152Satgutier@umich.edu 23810152Satgutier@umich.edu// returns width in um 23910152Satgutier@umich.edudouble R_to_w( 24010152Satgutier@umich.edu double res, 24110152Satgutier@umich.edu int nchannel, 24210152Satgutier@umich.edu bool _is_dram, 24310152Satgutier@umich.edu bool _is_cell, 24410234Syasuko.eckert@amd.com bool _is_wl_tr) { 24510234Syasuko.eckert@amd.com const TechnologyParameter::DeviceType * dt; 24610152Satgutier@umich.edu 24710234Syasuko.eckert@amd.com if ((_is_dram) && (_is_cell)) { 24810234Syasuko.eckert@amd.com dt = &g_tp.dram_acc; //DRAM cell access transistor 24910234Syasuko.eckert@amd.com } else if ((_is_dram) && (_is_wl_tr)) { 25010234Syasuko.eckert@amd.com dt = &g_tp.dram_wl; //DRAM wordline transistor 25110234Syasuko.eckert@amd.com } else if ((!_is_dram) && (_is_cell)) { 25210234Syasuko.eckert@amd.com dt = &g_tp.sram_cell; // SRAM cell access transistor 25310234Syasuko.eckert@amd.com } else { 25410234Syasuko.eckert@amd.com dt = &g_tp.peri_global; 25510234Syasuko.eckert@amd.com } 25610152Satgutier@umich.edu 25710234Syasuko.eckert@amd.com double restrans = (nchannel) ? dt->R_nch_on : dt->R_pch_on; 25810234Syasuko.eckert@amd.com return (restrans / res); 25910152Satgutier@umich.edu} 26010152Satgutier@umich.edu 26110152Satgutier@umich.edu 26210152Satgutier@umich.edudouble pmos_to_nmos_sz_ratio( 26310152Satgutier@umich.edu bool _is_dram, 26410234Syasuko.eckert@amd.com bool _is_wl_tr) { 26510234Syasuko.eckert@amd.com double p_to_n_sizing_ratio; 26610234Syasuko.eckert@amd.com if ((_is_dram) && (_is_wl_tr)) { //DRAM wordline transistor 26710234Syasuko.eckert@amd.com p_to_n_sizing_ratio = g_tp.dram_wl.n_to_p_eff_curr_drv_ratio; 26810234Syasuko.eckert@amd.com } else { //DRAM or SRAM all other transistors 26910234Syasuko.eckert@amd.com p_to_n_sizing_ratio = g_tp.peri_global.n_to_p_eff_curr_drv_ratio; 27010234Syasuko.eckert@amd.com } 27110234Syasuko.eckert@amd.com return p_to_n_sizing_ratio; 27210152Satgutier@umich.edu} 27310152Satgutier@umich.edu 27410152Satgutier@umich.edu 27510152Satgutier@umich.edu// "Timing Models for MOS Circuits" by Mark Horowitz, 1984 27610152Satgutier@umich.edudouble horowitz( 27710152Satgutier@umich.edu double inputramptime, // input rise time 27810152Satgutier@umich.edu double tf, // time constant of gate 27910152Satgutier@umich.edu double vs1, // threshold voltage 28010152Satgutier@umich.edu double vs2, // threshold voltage 28110234Syasuko.eckert@amd.com int rise) { // whether input rises or fall 28210234Syasuko.eckert@amd.com if (inputramptime == 0 && vs1 == vs2) { 28310234Syasuko.eckert@amd.com return tf * (vs1 < 1 ? -log(vs1) : log(vs1)); 28410234Syasuko.eckert@amd.com } 28510234Syasuko.eckert@amd.com double a, b, td; 28610152Satgutier@umich.edu 28710234Syasuko.eckert@amd.com a = inputramptime / tf; 28810234Syasuko.eckert@amd.com if (rise == RISE) { 28910234Syasuko.eckert@amd.com b = 0.5; 29010234Syasuko.eckert@amd.com td = tf * sqrt(log(vs1) * log(vs1) + 2 * a * b * (1.0 - vs1)) + 29110234Syasuko.eckert@amd.com tf * (log(vs1) - log(vs2)); 29210234Syasuko.eckert@amd.com } else { 29310234Syasuko.eckert@amd.com b = 0.4; 29410234Syasuko.eckert@amd.com td = tf * sqrt(log(1.0 - vs1) * log(1.0 - vs1) + 2 * a * b * (vs1)) + 29510234Syasuko.eckert@amd.com tf * (log(1.0 - vs1) - log(1.0 - vs2)); 29610234Syasuko.eckert@amd.com } 29710234Syasuko.eckert@amd.com return (td); 29810152Satgutier@umich.edu} 29910152Satgutier@umich.edu 30010152Satgutier@umich.edudouble cmos_Ileak( 30110152Satgutier@umich.edu double nWidth, 30210152Satgutier@umich.edu double pWidth, 30310152Satgutier@umich.edu bool _is_dram, 30410152Satgutier@umich.edu bool _is_cell, 30510234Syasuko.eckert@amd.com bool _is_wl_tr) { 30610234Syasuko.eckert@amd.com TechnologyParameter::DeviceType * dt; 30710152Satgutier@umich.edu 30810234Syasuko.eckert@amd.com if ((!_is_dram) && (_is_cell)) { //SRAM cell access transistor 30910234Syasuko.eckert@amd.com dt = &(g_tp.sram_cell); 31010234Syasuko.eckert@amd.com } else if ((_is_dram) && (_is_wl_tr)) { //DRAM wordline transistor 31110234Syasuko.eckert@amd.com dt = &(g_tp.dram_wl); 31210234Syasuko.eckert@amd.com } else { //DRAM or SRAM all other transistors 31310234Syasuko.eckert@amd.com dt = &(g_tp.peri_global); 31410234Syasuko.eckert@amd.com } 31510234Syasuko.eckert@amd.com return nWidth*dt->I_off_n + pWidth*dt->I_off_p; 31610152Satgutier@umich.edu} 31710152Satgutier@umich.edu 31810152Satgutier@umich.edu 31910152Satgutier@umich.edudouble simplified_nmos_leakage( 32010152Satgutier@umich.edu double nwidth, 32110152Satgutier@umich.edu bool _is_dram, 32210152Satgutier@umich.edu bool _is_cell, 32310234Syasuko.eckert@amd.com bool _is_wl_tr) { 32410234Syasuko.eckert@amd.com TechnologyParameter::DeviceType * dt; 32510152Satgutier@umich.edu 32610234Syasuko.eckert@amd.com if ((!_is_dram) && (_is_cell)) { //SRAM cell access transistor 32710234Syasuko.eckert@amd.com dt = &(g_tp.sram_cell); 32810234Syasuko.eckert@amd.com } else if ((_is_dram) && (_is_wl_tr)) { //DRAM wordline transistor 32910234Syasuko.eckert@amd.com dt = &(g_tp.dram_wl); 33010234Syasuko.eckert@amd.com } else { //DRAM or SRAM all other transistors 33110234Syasuko.eckert@amd.com dt = &(g_tp.peri_global); 33210234Syasuko.eckert@amd.com } 33310234Syasuko.eckert@amd.com return nwidth * dt->I_off_n; 33410152Satgutier@umich.edu} 33510152Satgutier@umich.edu 33610234Syasuko.eckert@amd.comint factorial(int n, int m) { 33710234Syasuko.eckert@amd.com int fa = m, i; 33810234Syasuko.eckert@amd.com for (i = m + 1; i <= n; i++) 33910234Syasuko.eckert@amd.com fa *= i; 34010234Syasuko.eckert@amd.com return fa; 34110152Satgutier@umich.edu} 34210152Satgutier@umich.edu 34310234Syasuko.eckert@amd.comint combination(int n, int m) { 34410234Syasuko.eckert@amd.com int ret; 34510234Syasuko.eckert@amd.com ret = factorial(n, m + 1) / factorial(n - m); 34610234Syasuko.eckert@amd.com return ret; 34710152Satgutier@umich.edu} 34810152Satgutier@umich.edu 34910152Satgutier@umich.edudouble simplified_pmos_leakage( 35010152Satgutier@umich.edu double pwidth, 35110152Satgutier@umich.edu bool _is_dram, 35210152Satgutier@umich.edu bool _is_cell, 35310234Syasuko.eckert@amd.com bool _is_wl_tr) { 35410234Syasuko.eckert@amd.com TechnologyParameter::DeviceType * dt; 35510152Satgutier@umich.edu 35610234Syasuko.eckert@amd.com if ((!_is_dram) && (_is_cell)) { //SRAM cell access transistor 35710234Syasuko.eckert@amd.com dt = &(g_tp.sram_cell); 35810234Syasuko.eckert@amd.com } else if ((_is_dram) && (_is_wl_tr)) { //DRAM wordline transistor 35910234Syasuko.eckert@amd.com dt = &(g_tp.dram_wl); 36010234Syasuko.eckert@amd.com } else { //DRAM or SRAM all other transistors 36110234Syasuko.eckert@amd.com dt = &(g_tp.peri_global); 36210234Syasuko.eckert@amd.com } 36310234Syasuko.eckert@amd.com return pwidth * dt->I_off_p; 36410152Satgutier@umich.edu} 36510152Satgutier@umich.edu 36610152Satgutier@umich.edudouble cmos_Ig_n( 36710152Satgutier@umich.edu double nWidth, 36810152Satgutier@umich.edu bool _is_dram, 36910152Satgutier@umich.edu bool _is_cell, 37010234Syasuko.eckert@amd.com bool _is_wl_tr) { 37110234Syasuko.eckert@amd.com TechnologyParameter::DeviceType * dt; 37210152Satgutier@umich.edu 37310234Syasuko.eckert@amd.com if ((!_is_dram) && (_is_cell)) { //SRAM cell access transistor 37410234Syasuko.eckert@amd.com dt = &(g_tp.sram_cell); 37510234Syasuko.eckert@amd.com } else if ((_is_dram) && (_is_wl_tr)) { //DRAM wordline transistor 37610234Syasuko.eckert@amd.com dt = &(g_tp.dram_wl); 37710234Syasuko.eckert@amd.com } else { //DRAM or SRAM all other transistors 37810234Syasuko.eckert@amd.com dt = &(g_tp.peri_global); 37910234Syasuko.eckert@amd.com } 38010234Syasuko.eckert@amd.com return nWidth*dt->I_g_on_n; 38110152Satgutier@umich.edu} 38210152Satgutier@umich.edu 38310152Satgutier@umich.edudouble cmos_Ig_p( 38410152Satgutier@umich.edu double pWidth, 38510152Satgutier@umich.edu bool _is_dram, 38610152Satgutier@umich.edu bool _is_cell, 38710234Syasuko.eckert@amd.com bool _is_wl_tr) { 38810234Syasuko.eckert@amd.com TechnologyParameter::DeviceType * dt; 38910152Satgutier@umich.edu 39010234Syasuko.eckert@amd.com if ((!_is_dram) && (_is_cell)) { //SRAM cell access transistor 39110234Syasuko.eckert@amd.com dt = &(g_tp.sram_cell); 39210234Syasuko.eckert@amd.com } else if ((_is_dram) && (_is_wl_tr)) { //DRAM wordline transistor 39310234Syasuko.eckert@amd.com dt = &(g_tp.dram_wl); 39410234Syasuko.eckert@amd.com } else { //DRAM or SRAM all other transistors 39510234Syasuko.eckert@amd.com dt = &(g_tp.peri_global); 39610234Syasuko.eckert@amd.com } 39710234Syasuko.eckert@amd.com return pWidth*dt->I_g_on_p; 39810152Satgutier@umich.edu} 39910152Satgutier@umich.edu 40010152Satgutier@umich.edudouble cmos_Isub_leakage( 40110152Satgutier@umich.edu double nWidth, 40210152Satgutier@umich.edu double pWidth, 40310152Satgutier@umich.edu int fanin, 40410152Satgutier@umich.edu enum Gate_type g_type, 40510152Satgutier@umich.edu bool _is_dram, 40610152Satgutier@umich.edu bool _is_cell, 40710152Satgutier@umich.edu bool _is_wl_tr, 40810234Syasuko.eckert@amd.com enum Half_net_topology topo) { 40910234Syasuko.eckert@amd.com assert (fanin >= 1); 41010234Syasuko.eckert@amd.com double nmos_leak = simplified_nmos_leakage(nWidth, _is_dram, _is_cell, _is_wl_tr); 41110234Syasuko.eckert@amd.com double pmos_leak = simplified_pmos_leakage(pWidth, _is_dram, _is_cell, _is_wl_tr); 41210234Syasuko.eckert@amd.com double Isub = 0; 41310152Satgutier@umich.edu int num_states; 41410152Satgutier@umich.edu int num_off_tx; 41510152Satgutier@umich.edu 41610152Satgutier@umich.edu num_states = int(pow(2.0, fanin)); 41710152Satgutier@umich.edu 41810234Syasuko.eckert@amd.com switch (g_type) { 41910152Satgutier@umich.edu case nmos: 42010234Syasuko.eckert@amd.com if (fanin == 1) { 42110234Syasuko.eckert@amd.com Isub = nmos_leak / num_states; 42210234Syasuko.eckert@amd.com } else { 42310234Syasuko.eckert@amd.com if (topo == parallel) { 42410234Syasuko.eckert@amd.com //only when all tx are off, leakage power is non-zero. 42510234Syasuko.eckert@amd.com //The possibility of this state is 1/num_states 42610234Syasuko.eckert@amd.com Isub = nmos_leak * fanin / num_states; 42710234Syasuko.eckert@amd.com } else { 42810234Syasuko.eckert@amd.com for (num_off_tx = 1; num_off_tx <= fanin; num_off_tx++) { 42910234Syasuko.eckert@amd.com //when num_off_tx ==0 there is no leakage power 43010234Syasuko.eckert@amd.com Isub += nmos_leak * pow(UNI_LEAK_STACK_FACTOR, 43110234Syasuko.eckert@amd.com (num_off_tx - 1)) * 43210234Syasuko.eckert@amd.com combination(fanin, num_off_tx); 43310152Satgutier@umich.edu } 43410234Syasuko.eckert@amd.com Isub /= num_states; 43510234Syasuko.eckert@amd.com } 43610152Satgutier@umich.edu 43710152Satgutier@umich.edu } 43810152Satgutier@umich.edu break; 43910152Satgutier@umich.edu case pmos: 44010234Syasuko.eckert@amd.com if (fanin == 1) { 44110234Syasuko.eckert@amd.com Isub = pmos_leak / num_states; 44210234Syasuko.eckert@amd.com } else { 44310234Syasuko.eckert@amd.com if (topo == parallel) { 44410234Syasuko.eckert@amd.com //only when all tx are off, leakage power is non-zero. 44510234Syasuko.eckert@amd.com //The possibility of this state is 1/num_states 44610234Syasuko.eckert@amd.com Isub = pmos_leak * fanin / num_states; 44710234Syasuko.eckert@amd.com } else { 44810234Syasuko.eckert@amd.com for (num_off_tx = 1; num_off_tx <= fanin; num_off_tx++) { 44910234Syasuko.eckert@amd.com //when num_off_tx ==0 there is no leakage power 45010234Syasuko.eckert@amd.com Isub += pmos_leak * pow(UNI_LEAK_STACK_FACTOR, 45110234Syasuko.eckert@amd.com (num_off_tx - 1)) * 45210234Syasuko.eckert@amd.com combination(fanin, num_off_tx); 45310152Satgutier@umich.edu } 45410234Syasuko.eckert@amd.com Isub /= num_states; 45510234Syasuko.eckert@amd.com } 45610152Satgutier@umich.edu 45710152Satgutier@umich.edu } 45810152Satgutier@umich.edu break; 45910152Satgutier@umich.edu case inv: 46010234Syasuko.eckert@amd.com Isub = (nmos_leak + pmos_leak) / 2; 46110152Satgutier@umich.edu break; 46210152Satgutier@umich.edu case nand: 46310234Syasuko.eckert@amd.com Isub += fanin * pmos_leak;//the pullup network 46410234Syasuko.eckert@amd.com for (num_off_tx = 1; num_off_tx <= fanin; num_off_tx++) { 46510234Syasuko.eckert@amd.com // the pulldown network 46610234Syasuko.eckert@amd.com Isub += nmos_leak * pow(UNI_LEAK_STACK_FACTOR, 46710234Syasuko.eckert@amd.com (num_off_tx - 1)) * 46810234Syasuko.eckert@amd.com combination(fanin, num_off_tx); 46910152Satgutier@umich.edu } 47010234Syasuko.eckert@amd.com Isub /= num_states; 47110152Satgutier@umich.edu break; 47210152Satgutier@umich.edu case nor: 47310234Syasuko.eckert@amd.com for (num_off_tx = 1; num_off_tx <= fanin; num_off_tx++) { 47410234Syasuko.eckert@amd.com // the pullup network 47510234Syasuko.eckert@amd.com Isub += pmos_leak * pow(UNI_LEAK_STACK_FACTOR, 47610234Syasuko.eckert@amd.com (num_off_tx - 1)) * 47710234Syasuko.eckert@amd.com combination(fanin, num_off_tx); 47810152Satgutier@umich.edu } 47910234Syasuko.eckert@amd.com Isub += fanin * nmos_leak;//the pulldown network 48010234Syasuko.eckert@amd.com Isub /= num_states; 48110152Satgutier@umich.edu break; 48210152Satgutier@umich.edu case tri: 48310234Syasuko.eckert@amd.com Isub += (nmos_leak + pmos_leak) / 2;//enabled 48410234Syasuko.eckert@amd.com //disabled upper bound of leakage power 48510234Syasuko.eckert@amd.com Isub += nmos_leak * UNI_LEAK_STACK_FACTOR; 48610234Syasuko.eckert@amd.com Isub /= 2; 48710152Satgutier@umich.edu break; 48810152Satgutier@umich.edu case tg: 48910234Syasuko.eckert@amd.com Isub = (nmos_leak + pmos_leak) / 2; 49010152Satgutier@umich.edu break; 49110152Satgutier@umich.edu default: 49210152Satgutier@umich.edu assert(0); 49310152Satgutier@umich.edu break; 49410234Syasuko.eckert@amd.com } 49510152Satgutier@umich.edu 49610152Satgutier@umich.edu return Isub; 49710152Satgutier@umich.edu} 49810152Satgutier@umich.edu 49910152Satgutier@umich.edu 50010152Satgutier@umich.edudouble cmos_Ig_leakage( 50110152Satgutier@umich.edu double nWidth, 50210152Satgutier@umich.edu double pWidth, 50310152Satgutier@umich.edu int fanin, 50410152Satgutier@umich.edu enum Gate_type g_type, 50510152Satgutier@umich.edu bool _is_dram, 50610152Satgutier@umich.edu bool _is_cell, 50710152Satgutier@umich.edu bool _is_wl_tr, 50810234Syasuko.eckert@amd.com enum Half_net_topology topo) { 50910234Syasuko.eckert@amd.com assert (fanin >= 1); 51010234Syasuko.eckert@amd.com double nmos_leak = cmos_Ig_n(nWidth, _is_dram, _is_cell, _is_wl_tr); 51110234Syasuko.eckert@amd.com double pmos_leak = cmos_Ig_p(pWidth, _is_dram, _is_cell, _is_wl_tr); 51210234Syasuko.eckert@amd.com double Ig_on = 0; 51310234Syasuko.eckert@amd.com int num_states; 51410234Syasuko.eckert@amd.com int num_on_tx; 51510152Satgutier@umich.edu 51610234Syasuko.eckert@amd.com num_states = int(pow(2.0, fanin)); 51710152Satgutier@umich.edu 51810234Syasuko.eckert@amd.com switch (g_type) { 51910234Syasuko.eckert@amd.com case nmos: 52010234Syasuko.eckert@amd.com if (fanin == 1) { 52110234Syasuko.eckert@amd.com Ig_on = nmos_leak / num_states; 52210234Syasuko.eckert@amd.com } else { 52310234Syasuko.eckert@amd.com if (topo == parallel) { 52410234Syasuko.eckert@amd.com for (num_on_tx = 1; num_on_tx <= fanin; num_on_tx++) { 52510234Syasuko.eckert@amd.com Ig_on += nmos_leak * combination(fanin, num_on_tx) * 52610234Syasuko.eckert@amd.com num_on_tx; 52710152Satgutier@umich.edu } 52810234Syasuko.eckert@amd.com } else { 52910234Syasuko.eckert@amd.com //pull down network when all TXs are on. 53010234Syasuko.eckert@amd.com Ig_on += nmos_leak * fanin; 53110234Syasuko.eckert@amd.com //num_on_tx is the number of on tx 53210234Syasuko.eckert@amd.com for (num_on_tx = 1; num_on_tx < fanin; num_on_tx++) { 53310234Syasuko.eckert@amd.com //when num_on_tx=[1,n-1] 53410234Syasuko.eckert@amd.com //TODO: this is a approximation now, a precise computation 53510234Syasuko.eckert@amd.com //will be very complicated. 53610234Syasuko.eckert@amd.com Ig_on += nmos_leak * combination(fanin, num_on_tx) * 53710234Syasuko.eckert@amd.com num_on_tx / 2; 53810152Satgutier@umich.edu } 53910234Syasuko.eckert@amd.com Ig_on /= num_states; 54010234Syasuko.eckert@amd.com } 54110234Syasuko.eckert@amd.com } 54210234Syasuko.eckert@amd.com break; 54310234Syasuko.eckert@amd.com case pmos: 54410234Syasuko.eckert@amd.com if (fanin == 1) { 54510234Syasuko.eckert@amd.com Ig_on = pmos_leak / num_states; 54610234Syasuko.eckert@amd.com } else { 54710234Syasuko.eckert@amd.com if (topo == parallel) { 54810234Syasuko.eckert@amd.com for (num_on_tx = 1; num_on_tx <= fanin; num_on_tx++) { 54910234Syasuko.eckert@amd.com Ig_on += pmos_leak * combination(fanin, num_on_tx) * 55010234Syasuko.eckert@amd.com num_on_tx; 55110152Satgutier@umich.edu } 55210234Syasuko.eckert@amd.com } else { 55310234Syasuko.eckert@amd.com //pull down network when all TXs are on. 55410234Syasuko.eckert@amd.com Ig_on += pmos_leak * fanin; 55510234Syasuko.eckert@amd.com //num_on_tx is the number of on tx 55610234Syasuko.eckert@amd.com for (num_on_tx = 1; num_on_tx < fanin; num_on_tx++) { 55710234Syasuko.eckert@amd.com //when num_on_tx=[1,n-1] 55810234Syasuko.eckert@amd.com //TODO: this is a approximation now, a precise computation 55910234Syasuko.eckert@amd.com //will be very complicated. 56010234Syasuko.eckert@amd.com Ig_on += pmos_leak * combination(fanin, num_on_tx) * 56110234Syasuko.eckert@amd.com num_on_tx / 2; 56210152Satgutier@umich.edu } 56310234Syasuko.eckert@amd.com Ig_on /= num_states; 56410234Syasuko.eckert@amd.com } 56510234Syasuko.eckert@amd.com } 56610234Syasuko.eckert@amd.com break; 56710152Satgutier@umich.edu 56810234Syasuko.eckert@amd.com case inv: 56910234Syasuko.eckert@amd.com Ig_on = (nmos_leak + pmos_leak) / 2; 57010234Syasuko.eckert@amd.com break; 57110234Syasuko.eckert@amd.com case nand: 57210234Syasuko.eckert@amd.com //pull up network 57310234Syasuko.eckert@amd.com //when num_on_tx=[1,n] 57410234Syasuko.eckert@amd.com for (num_on_tx = 1; num_on_tx <= fanin; num_on_tx++) { 57510234Syasuko.eckert@amd.com Ig_on += pmos_leak * combination(fanin, num_on_tx) * num_on_tx; 57610234Syasuko.eckert@amd.com } 57710152Satgutier@umich.edu 57810234Syasuko.eckert@amd.com //pull down network 57910234Syasuko.eckert@amd.com Ig_on += nmos_leak * fanin;//pull down network when all TXs are on. 58010234Syasuko.eckert@amd.com //num_on_tx is the number of on tx 58110234Syasuko.eckert@amd.com for (num_on_tx = 1; num_on_tx < fanin; num_on_tx++) { 58210234Syasuko.eckert@amd.com //when num_on_tx=[1,n-1] 58310234Syasuko.eckert@amd.com //TODO: this is a approximation now, a precise computation will be 58410234Syasuko.eckert@amd.com //very complicated. 58510234Syasuko.eckert@amd.com Ig_on += nmos_leak * combination(fanin, num_on_tx) * num_on_tx / 2; 58610234Syasuko.eckert@amd.com } 58710234Syasuko.eckert@amd.com Ig_on /= num_states; 58810234Syasuko.eckert@amd.com break; 58910234Syasuko.eckert@amd.com case nor: 59010234Syasuko.eckert@amd.com // num_on_tx is the number of on tx in pull up network 59110234Syasuko.eckert@amd.com Ig_on += pmos_leak * fanin;//pull up network when all TXs are on. 59210234Syasuko.eckert@amd.com for (num_on_tx = 1; num_on_tx < fanin; num_on_tx++) { 59310234Syasuko.eckert@amd.com Ig_on += pmos_leak * combination(fanin, num_on_tx) * num_on_tx / 2; 59410152Satgutier@umich.edu 59510234Syasuko.eckert@amd.com } 59610234Syasuko.eckert@amd.com //pull down network 59710234Syasuko.eckert@amd.com for (num_on_tx = 1; num_on_tx <= fanin; num_on_tx++) { 59810234Syasuko.eckert@amd.com //when num_on_tx=[1,n] 59910234Syasuko.eckert@amd.com Ig_on += nmos_leak * combination(fanin, num_on_tx) * num_on_tx; 60010234Syasuko.eckert@amd.com } 60110234Syasuko.eckert@amd.com Ig_on /= num_states; 60210234Syasuko.eckert@amd.com break; 60310234Syasuko.eckert@amd.com case tri: 60410234Syasuko.eckert@amd.com Ig_on += (2 * nmos_leak + 2 * pmos_leak) / 2;//enabled 60510234Syasuko.eckert@amd.com //disabled upper bound of leakage power 60610234Syasuko.eckert@amd.com Ig_on += (nmos_leak + pmos_leak) / 2; 60710234Syasuko.eckert@amd.com Ig_on /= 2; 60810234Syasuko.eckert@amd.com break; 60910234Syasuko.eckert@amd.com case tg: 61010234Syasuko.eckert@amd.com Ig_on = (nmos_leak + pmos_leak) / 2; 61110234Syasuko.eckert@amd.com break; 61210234Syasuko.eckert@amd.com default: 61310234Syasuko.eckert@amd.com assert(0); 61410234Syasuko.eckert@amd.com break; 61510234Syasuko.eckert@amd.com } 61610152Satgutier@umich.edu 61710234Syasuko.eckert@amd.com return Ig_on; 61810152Satgutier@umich.edu} 61910152Satgutier@umich.edu 62010152Satgutier@umich.edudouble shortcircuit_simple( 62110152Satgutier@umich.edu double vt, 62210152Satgutier@umich.edu double velocity_index, 62310152Satgutier@umich.edu double c_in, 62410152Satgutier@umich.edu double c_out, 62510152Satgutier@umich.edu double w_nmos, 62610152Satgutier@umich.edu double w_pmos, 62710152Satgutier@umich.edu double i_on_n, 62810152Satgutier@umich.edu double i_on_p, 62910152Satgutier@umich.edu double i_on_n_in, 63010152Satgutier@umich.edu double i_on_p_in, 63110234Syasuko.eckert@amd.com double vdd) { 63210152Satgutier@umich.edu 63310234Syasuko.eckert@amd.com 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 63410234Syasuko.eckert@amd.com double fo_n, fo_p, fanout, beta_ratio, vt_to_vdd_ratio; 63510152Satgutier@umich.edu 63610234Syasuko.eckert@amd.com fo_n = i_on_n / i_on_n_in; 63710234Syasuko.eckert@amd.com fo_p = i_on_p / i_on_p_in; 63810234Syasuko.eckert@amd.com fanout = c_out / c_in; 63910234Syasuko.eckert@amd.com beta_ratio = i_on_p / i_on_n; 64010234Syasuko.eckert@amd.com vt_to_vdd_ratio = vt / vdd; 64110152Satgutier@umich.edu 64210234Syasuko.eckert@amd.com //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; 64310234Syasuko.eckert@amd.com p_short_circuit_discharge_low = 64410234Syasuko.eckert@amd.com 10 / 3 * (pow(((vdd - vt) - vt_to_vdd_ratio), 3.0) / 64510234Syasuko.eckert@amd.com pow(velocity_index, 2.0) / pow(2.0, 3 * vt_to_vdd_ratio * 64610234Syasuko.eckert@amd.com vt_to_vdd_ratio)) * c_in * 64710234Syasuko.eckert@amd.com vdd * vdd * fo_p * fo_p / fanout / beta_ratio; 64810234Syasuko.eckert@amd.com p_short_circuit_charge_low = 64910234Syasuko.eckert@amd.com 10 / 3 * (pow(((vdd - vt) - vt_to_vdd_ratio), 3.0) / 65010234Syasuko.eckert@amd.com pow(velocity_index, 2.0) / pow(2.0, 3 * vt_to_vdd_ratio * 65110234Syasuko.eckert@amd.com vt_to_vdd_ratio)) * c_in * 65210234Syasuko.eckert@amd.com vdd * vdd * fo_n * fo_n / fanout * beta_ratio; 65310152Satgutier@umich.edu// double t1, t2, t3, t4, t5; 65410152Satgutier@umich.edu// t1=pow(((vdd-vt)-vt_to_vdd_ratio),3); 65510152Satgutier@umich.edu// t2=pow(velocity_index,2.0); 65610152Satgutier@umich.edu// t3=pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio); 65710152Satgutier@umich.edu// t4=t1/t2/t3; 65810152Satgutier@umich.edu// cout <<t1<<"t1\n"<<t2<<"t2\n"<<t3<<"t3\n"<<t4<<"t4\n"<<fanout<<endl; 65910152Satgutier@umich.edu 66010234Syasuko.eckert@amd.com p_short_circuit_discharge_high = 66110234Syasuko.eckert@amd.com pow(((vdd - vt) - vt_to_vdd_ratio), 1.5) * c_in * vdd * vdd * 66210234Syasuko.eckert@amd.com fo_p / 10 / pow(2, 3 * vt_to_vdd_ratio + 2 * velocity_index); 66310234Syasuko.eckert@amd.com p_short_circuit_charge_high = pow(((vdd - vt) - vt_to_vdd_ratio), 1.5) * 66410234Syasuko.eckert@amd.com c_in * vdd * vdd * fo_n / 10 / pow(2, 3 * vt_to_vdd_ratio + 2 * 66510234Syasuko.eckert@amd.com velocity_index); 66610152Satgutier@umich.edu 66710152Satgutier@umich.edu// t1=pow(((vdd-vt)-vt_to_vdd_ratio),1.5); 66810152Satgutier@umich.edu// t2=pow(2, 3*vt_to_vdd_ratio+2*velocity_index); 66910152Satgutier@umich.edu// t3=t1/t2; 67010152Satgutier@umich.edu// cout <<t1<<"t1\n"<<t2<<"t2\n"<<t3<<"t3\n"<<t4<<"t4\n"<<fanout<<endl; 67110152Satgutier@umich.edu// p_short_circuit_discharge = 1.0/(1.0/p_short_circuit_discharge_low + 1.0/p_short_circuit_discharge_high); 67210152Satgutier@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. 67310152Satgutier@umich.edu 67410234Syasuko.eckert@amd.com p_short_circuit_discharge = p_short_circuit_discharge_low; 67510234Syasuko.eckert@amd.com p_short_circuit_charge = p_short_circuit_charge_low; 67610234Syasuko.eckert@amd.com p_short_circuit = (p_short_circuit_discharge + p_short_circuit_charge) / 2; 67710152Satgutier@umich.edu 67810234Syasuko.eckert@amd.com return (p_short_circuit); 67910152Satgutier@umich.edu} 68010152Satgutier@umich.edu 68110152Satgutier@umich.edudouble shortcircuit( 68210152Satgutier@umich.edu double vt, 68310152Satgutier@umich.edu double velocity_index, 68410152Satgutier@umich.edu double c_in, 68510152Satgutier@umich.edu double c_out, 68610152Satgutier@umich.edu double w_nmos, 68710152Satgutier@umich.edu double w_pmos, 68810152Satgutier@umich.edu double i_on_n, 68910152Satgutier@umich.edu double i_on_p, 69010152Satgutier@umich.edu double i_on_n_in, 69110152Satgutier@umich.edu double i_on_p_in, 69210234Syasuko.eckert@amd.com double vdd) { 69310152Satgutier@umich.edu 69410234Syasuko.eckert@amd.com //this is actually energy 69510234Syasuko.eckert@amd.com double p_short_circuit = 0, p_short_circuit_discharge; 69610234Syasuko.eckert@amd.com double fo_n, fo_p, fanout, beta_ratio, vt_to_vdd_ratio; 69710234Syasuko.eckert@amd.com double f_alpha, k_v, e, g_v_alpha, h_v_alpha; 69810152Satgutier@umich.edu 69910234Syasuko.eckert@amd.com fo_n = i_on_n / i_on_n_in; 70010234Syasuko.eckert@amd.com fo_p = i_on_p / i_on_p_in; 70110234Syasuko.eckert@amd.com fanout = 1; 70210234Syasuko.eckert@amd.com beta_ratio = i_on_p / i_on_n; 70310234Syasuko.eckert@amd.com vt_to_vdd_ratio = vt / vdd; 70410234Syasuko.eckert@amd.com e = 2.71828; 70510234Syasuko.eckert@amd.com f_alpha = 1 / (velocity_index + 2) - velocity_index / 70610234Syasuko.eckert@amd.com (2 * (velocity_index + 3)) + velocity_index / (velocity_index + 4) * 70710234Syasuko.eckert@amd.com (velocity_index / 2 - 1); 70810234Syasuko.eckert@amd.com k_v = 0.9 / 0.8 + (vdd - vt) / 0.8 * log(10 * (vdd - vt) / e); 70910234Syasuko.eckert@amd.com g_v_alpha = (velocity_index + 1) * 71010234Syasuko.eckert@amd.com pow((1 - velocity_index), velocity_index) * 71110234Syasuko.eckert@amd.com pow((1 - velocity_index), velocity_index / 2) / f_alpha / 71210234Syasuko.eckert@amd.com pow((1 - velocity_index - velocity_index), 71310234Syasuko.eckert@amd.com (velocity_index / 2 + velocity_index + 2)); 71410234Syasuko.eckert@amd.com h_v_alpha = pow(2, velocity_index) * (velocity_index + 1) * 71510234Syasuko.eckert@amd.com pow((1 - velocity_index), velocity_index) / 71610234Syasuko.eckert@amd.com pow((1 - velocity_index - velocity_index), (velocity_index + 1)); 71710152Satgutier@umich.edu 71810234Syasuko.eckert@amd.com //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; 71910152Satgutier@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; 72010152Satgutier@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; 72110152Satgutier@umich.edu// double t1, t2, t3, t4, t5; 72210152Satgutier@umich.edu// t1=pow(((vdd-vt)-vt_to_vdd_ratio),3); 72310152Satgutier@umich.edu// t2=pow(velocity_index,2.0); 72410152Satgutier@umich.edu// t3=pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio); 72510152Satgutier@umich.edu// t4=t1/t2/t3; 72610152Satgutier@umich.edu// 72710152Satgutier@umich.edu// cout <<t1<<"t1\n"<<t2<<"t2\n"<<t3<<"t3\n"<<t4<<"t4\n"<<fanout<<endl; 72810152Satgutier@umich.edu// 72910152Satgutier@umich.edu// 73010152Satgutier@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); 73110152Satgutier@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); 73210152Satgutier@umich.edu// 73310152Satgutier@umich.edu// p_short_circuit_discharge = 1.0/(1.0/p_short_circuit_discharge_low + 1.0/p_short_circuit_discharge_high); 73410152Satgutier@umich.edu// p_short_circuit_charge = 1/(1/p_short_circuit_charge_low + 1/p_short_circuit_charge_high); 73510152Satgutier@umich.edu// 73610152Satgutier@umich.edu// p_short_circuit = (p_short_circuit_discharge + p_short_circuit_charge)/2; 73710152Satgutier@umich.edu// 73810152Satgutier@umich.edu// p_short_circuit = p_short_circuit_discharge; 73910152Satgutier@umich.edu 74010234Syasuko.eckert@amd.com p_short_circuit_discharge = k_v * vdd * vdd * c_in * fo_p * fo_p / 74110234Syasuko.eckert@amd.com ((vdd - vt) * g_v_alpha * fanout * beta_ratio / 2 / k_v + h_v_alpha * 74210234Syasuko.eckert@amd.com fo_p); 74310234Syasuko.eckert@amd.com return (p_short_circuit); 74410152Satgutier@umich.edu} 745