decoder.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#include <cassert> 3510152Satgutier@umich.edu#include <cmath> 3610152Satgutier@umich.edu#include <iostream> 3710152Satgutier@umich.edu 3810152Satgutier@umich.edu#include "area.h" 3910152Satgutier@umich.edu#include "decoder.h" 4010152Satgutier@umich.edu#include "parameter.h" 4110152Satgutier@umich.edu 4210152Satgutier@umich.eduusing namespace std; 4310152Satgutier@umich.edu 4410152Satgutier@umich.edu 4510152Satgutier@umich.eduDecoder::Decoder( 4610152Satgutier@umich.edu int _num_dec_signals, 4710152Satgutier@umich.edu bool flag_way_select, 4810152Satgutier@umich.edu double _C_ld_dec_out, 4910152Satgutier@umich.edu double _R_wire_dec_out, 5010152Satgutier@umich.edu bool fully_assoc_, 5110152Satgutier@umich.edu bool is_dram_, 5210152Satgutier@umich.edu bool is_wl_tr_, 5310152Satgutier@umich.edu const Area & cell_) 5410152Satgutier@umich.edu:exist(false), 5510152Satgutier@umich.edu C_ld_dec_out(_C_ld_dec_out), 5610152Satgutier@umich.edu R_wire_dec_out(_R_wire_dec_out), 5710152Satgutier@umich.edu num_gates(0), num_gates_min(2), 5810152Satgutier@umich.edu delay(0), 5910152Satgutier@umich.edu //power(), 6010152Satgutier@umich.edu fully_assoc(fully_assoc_), is_dram(is_dram_), 6110152Satgutier@umich.edu is_wl_tr(is_wl_tr_), cell(cell_) 6210152Satgutier@umich.edu{ 6310152Satgutier@umich.edu 6410152Satgutier@umich.edu for (int i = 0; i < MAX_NUMBER_GATES_STAGE; i++) 6510152Satgutier@umich.edu { 6610152Satgutier@umich.edu w_dec_n[i] = 0; 6710152Satgutier@umich.edu w_dec_p[i] = 0; 6810152Satgutier@umich.edu } 6910152Satgutier@umich.edu 7010152Satgutier@umich.edu /* 7110152Satgutier@umich.edu * _num_dec_signals is the number of decoded signal as output 7210152Satgutier@umich.edu * num_addr_bits_dec is the number of signal to be decoded 7310152Satgutier@umich.edu * as the decoders input. 7410152Satgutier@umich.edu */ 7510152Satgutier@umich.edu int num_addr_bits_dec = _log2(_num_dec_signals); 7610152Satgutier@umich.edu 7710152Satgutier@umich.edu if (num_addr_bits_dec < 4) 7810152Satgutier@umich.edu { 7910152Satgutier@umich.edu if (flag_way_select) 8010152Satgutier@umich.edu { 8110152Satgutier@umich.edu exist = true; 8210152Satgutier@umich.edu num_in_signals = 2; 8310152Satgutier@umich.edu } 8410152Satgutier@umich.edu else 8510152Satgutier@umich.edu { 8610152Satgutier@umich.edu num_in_signals = 0; 8710152Satgutier@umich.edu } 8810152Satgutier@umich.edu } 8910152Satgutier@umich.edu else 9010152Satgutier@umich.edu { 9110152Satgutier@umich.edu exist = true; 9210152Satgutier@umich.edu 9310152Satgutier@umich.edu if (flag_way_select) 9410152Satgutier@umich.edu { 9510152Satgutier@umich.edu num_in_signals = 3; 9610152Satgutier@umich.edu } 9710152Satgutier@umich.edu else 9810152Satgutier@umich.edu { 9910152Satgutier@umich.edu num_in_signals = 2; 10010152Satgutier@umich.edu } 10110152Satgutier@umich.edu } 10210152Satgutier@umich.edu 10310152Satgutier@umich.edu assert(cell.h>0); 10410152Satgutier@umich.edu assert(cell.w>0); 10510152Satgutier@umich.edu // the height of a row-decoder-driver cell is fixed to be 4 * cell.h; 10610152Satgutier@umich.edu //area.h = 4 * cell.h; 10710152Satgutier@umich.edu area.h = g_tp.h_dec * cell.h; 10810152Satgutier@umich.edu 10910152Satgutier@umich.edu compute_widths(); 11010152Satgutier@umich.edu compute_area(); 11110152Satgutier@umich.edu} 11210152Satgutier@umich.edu 11310152Satgutier@umich.edu 11410152Satgutier@umich.edu 11510152Satgutier@umich.eduvoid Decoder::compute_widths() 11610152Satgutier@umich.edu{ 11710152Satgutier@umich.edu double F; 11810152Satgutier@umich.edu double p_to_n_sz_ratio = pmos_to_nmos_sz_ratio(is_dram, is_wl_tr); 11910152Satgutier@umich.edu double gnand2 = (2 + p_to_n_sz_ratio) / (1 + p_to_n_sz_ratio); 12010152Satgutier@umich.edu double gnand3 = (3 + p_to_n_sz_ratio) / (1 + p_to_n_sz_ratio); 12110152Satgutier@umich.edu 12210152Satgutier@umich.edu if (exist) 12310152Satgutier@umich.edu { 12410152Satgutier@umich.edu if (num_in_signals == 2 || fully_assoc) 12510152Satgutier@umich.edu { 12610152Satgutier@umich.edu w_dec_n[0] = 2 * g_tp.min_w_nmos_; 12710152Satgutier@umich.edu w_dec_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 12810152Satgutier@umich.edu F = gnand2; 12910152Satgutier@umich.edu } 13010152Satgutier@umich.edu else 13110152Satgutier@umich.edu { 13210152Satgutier@umich.edu w_dec_n[0] = 3 * g_tp.min_w_nmos_; 13310152Satgutier@umich.edu w_dec_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 13410152Satgutier@umich.edu F = gnand3; 13510152Satgutier@umich.edu } 13610152Satgutier@umich.edu 13710152Satgutier@umich.edu F *= C_ld_dec_out / (gate_C(w_dec_n[0], 0, is_dram, false, is_wl_tr) + 13810152Satgutier@umich.edu gate_C(w_dec_p[0], 0, is_dram, false, is_wl_tr)); 13910152Satgutier@umich.edu num_gates = logical_effort( 14010152Satgutier@umich.edu num_gates_min, 14110152Satgutier@umich.edu num_in_signals == 2 ? gnand2 : gnand3, 14210152Satgutier@umich.edu F, 14310152Satgutier@umich.edu w_dec_n, 14410152Satgutier@umich.edu w_dec_p, 14510152Satgutier@umich.edu C_ld_dec_out, 14610152Satgutier@umich.edu p_to_n_sz_ratio, 14710152Satgutier@umich.edu is_dram, 14810152Satgutier@umich.edu is_wl_tr, 14910152Satgutier@umich.edu g_tp.max_w_nmos_dec); 15010152Satgutier@umich.edu } 15110152Satgutier@umich.edu} 15210152Satgutier@umich.edu 15310152Satgutier@umich.edu 15410152Satgutier@umich.edu 15510152Satgutier@umich.eduvoid Decoder::compute_area() 15610152Satgutier@umich.edu{ 15710152Satgutier@umich.edu double cumulative_area = 0; 15810152Satgutier@umich.edu double cumulative_curr = 0; // cumulative leakage current 15910152Satgutier@umich.edu double cumulative_curr_Ig = 0; // cumulative leakage current 16010152Satgutier@umich.edu 16110152Satgutier@umich.edu if (exist) 16210152Satgutier@umich.edu { // First check if this decoder exists 16310152Satgutier@umich.edu if (num_in_signals == 2) 16410152Satgutier@umich.edu { 16510152Satgutier@umich.edu cumulative_area = compute_gate_area(NAND, 2, w_dec_p[0], w_dec_n[0], area.h); 16610152Satgutier@umich.edu cumulative_curr = cmos_Isub_leakage(w_dec_n[0], w_dec_p[0], 2, nand,is_dram); 16710152Satgutier@umich.edu cumulative_curr_Ig = cmos_Ig_leakage(w_dec_n[0], w_dec_p[0], 2, nand,is_dram); 16810152Satgutier@umich.edu } 16910152Satgutier@umich.edu else if (num_in_signals == 3) 17010152Satgutier@umich.edu { 17110152Satgutier@umich.edu cumulative_area = compute_gate_area(NAND, 3, w_dec_p[0], w_dec_n[0], area.h); 17210152Satgutier@umich.edu cumulative_curr = cmos_Isub_leakage(w_dec_n[0], w_dec_p[0], 3, nand, is_dram);; 17310152Satgutier@umich.edu cumulative_curr_Ig = cmos_Ig_leakage(w_dec_n[0], w_dec_p[0], 3, nand, is_dram); 17410152Satgutier@umich.edu } 17510152Satgutier@umich.edu 17610152Satgutier@umich.edu for (int i = 1; i < num_gates; i++) 17710152Satgutier@umich.edu { 17810152Satgutier@umich.edu cumulative_area += compute_gate_area(INV, 1, w_dec_p[i], w_dec_n[i], area.h); 17910152Satgutier@umich.edu cumulative_curr += cmos_Isub_leakage(w_dec_n[i], w_dec_p[i], 1, inv, is_dram); 18010152Satgutier@umich.edu cumulative_curr_Ig = cmos_Ig_leakage(w_dec_n[i], w_dec_p[i], 1, inv, is_dram); 18110152Satgutier@umich.edu } 18210152Satgutier@umich.edu power.readOp.leakage = cumulative_curr * g_tp.peri_global.Vdd; 18310152Satgutier@umich.edu power.readOp.gate_leakage = cumulative_curr_Ig * g_tp.peri_global.Vdd; 18410152Satgutier@umich.edu 18510152Satgutier@umich.edu area.w = (cumulative_area / area.h); 18610152Satgutier@umich.edu } 18710152Satgutier@umich.edu} 18810152Satgutier@umich.edu 18910152Satgutier@umich.edu 19010152Satgutier@umich.edu 19110152Satgutier@umich.edudouble Decoder::compute_delays(double inrisetime) 19210152Satgutier@umich.edu{ 19310152Satgutier@umich.edu if (exist) 19410152Satgutier@umich.edu { 19510152Satgutier@umich.edu double ret_val = 0; // outrisetime 19610152Satgutier@umich.edu int i; 19710152Satgutier@umich.edu double rd, tf, this_delay, c_load, c_intrinsic, Vpp; 19810152Satgutier@umich.edu double Vdd = g_tp.peri_global.Vdd; 19910152Satgutier@umich.edu 20010152Satgutier@umich.edu if ((is_wl_tr) && (is_dram)) 20110152Satgutier@umich.edu { 20210152Satgutier@umich.edu Vpp = g_tp.vpp; 20310152Satgutier@umich.edu } 20410152Satgutier@umich.edu else if (is_wl_tr) 20510152Satgutier@umich.edu { 20610152Satgutier@umich.edu Vpp = g_tp.sram_cell.Vdd; 20710152Satgutier@umich.edu } 20810152Satgutier@umich.edu else 20910152Satgutier@umich.edu { 21010152Satgutier@umich.edu Vpp = g_tp.peri_global.Vdd; 21110152Satgutier@umich.edu } 21210152Satgutier@umich.edu 21310152Satgutier@umich.edu // first check whether a decoder is required at all 21410152Satgutier@umich.edu rd = tr_R_on(w_dec_n[0], NCH, num_in_signals, is_dram, false, is_wl_tr); 21510152Satgutier@umich.edu c_load = gate_C(w_dec_n[1] + w_dec_p[1], 0.0, is_dram, false, is_wl_tr); 21610152Satgutier@umich.edu c_intrinsic = drain_C_(w_dec_p[0], PCH, 1, 1, area.h, is_dram, false, is_wl_tr) * num_in_signals + 21710152Satgutier@umich.edu drain_C_(w_dec_n[0], NCH, num_in_signals, 1, area.h, is_dram, false, is_wl_tr); 21810152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load); 21910152Satgutier@umich.edu this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE); 22010152Satgutier@umich.edu delay += this_delay; 22110152Satgutier@umich.edu inrisetime = this_delay / (1.0 - 0.5); 22210152Satgutier@umich.edu power.readOp.dynamic += (c_load + c_intrinsic) * Vdd * Vdd; 22310152Satgutier@umich.edu 22410152Satgutier@umich.edu for (i = 1; i < num_gates - 1; ++i) 22510152Satgutier@umich.edu { 22610152Satgutier@umich.edu rd = tr_R_on(w_dec_n[i], NCH, 1, is_dram, false, is_wl_tr); 22710152Satgutier@umich.edu c_load = gate_C(w_dec_p[i+1] + w_dec_n[i+1], 0.0, is_dram, false, is_wl_tr); 22810152Satgutier@umich.edu c_intrinsic = drain_C_(w_dec_p[i], PCH, 1, 1, area.h, is_dram, false, is_wl_tr) + 22910152Satgutier@umich.edu drain_C_(w_dec_n[i], NCH, 1, 1, area.h, is_dram, false, is_wl_tr); 23010152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load); 23110152Satgutier@umich.edu this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE); 23210152Satgutier@umich.edu delay += this_delay; 23310152Satgutier@umich.edu inrisetime = this_delay / (1.0 - 0.5); 23410152Satgutier@umich.edu power.readOp.dynamic += (c_load + c_intrinsic) * Vdd * Vdd; 23510152Satgutier@umich.edu } 23610152Satgutier@umich.edu 23710152Satgutier@umich.edu // add delay of final inverter that drives the wordline 23810152Satgutier@umich.edu i = num_gates - 1; 23910152Satgutier@umich.edu c_load = C_ld_dec_out; 24010152Satgutier@umich.edu rd = tr_R_on(w_dec_n[i], NCH, 1, is_dram, false, is_wl_tr); 24110152Satgutier@umich.edu c_intrinsic = drain_C_(w_dec_p[i], PCH, 1, 1, area.h, is_dram, false, is_wl_tr) + 24210152Satgutier@umich.edu drain_C_(w_dec_n[i], NCH, 1, 1, area.h, is_dram, false, is_wl_tr); 24310152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load) + R_wire_dec_out * c_load / 2; 24410152Satgutier@umich.edu this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE); 24510152Satgutier@umich.edu delay += this_delay; 24610152Satgutier@umich.edu ret_val = this_delay / (1.0 - 0.5); 24710152Satgutier@umich.edu power.readOp.dynamic += c_load * Vpp * Vpp + c_intrinsic * Vdd * Vdd; 24810152Satgutier@umich.edu 24910152Satgutier@umich.edu return ret_val; 25010152Satgutier@umich.edu } 25110152Satgutier@umich.edu else 25210152Satgutier@umich.edu { 25310152Satgutier@umich.edu return 0.0; 25410152Satgutier@umich.edu } 25510152Satgutier@umich.edu} 25610152Satgutier@umich.edu 25710152Satgutier@umich.eduvoid Decoder::leakage_feedback(double temperature) 25810152Satgutier@umich.edu{ 25910152Satgutier@umich.edu double cumulative_curr = 0; // cumulative leakage current 26010152Satgutier@umich.edu double cumulative_curr_Ig = 0; // cumulative leakage current 26110152Satgutier@umich.edu 26210152Satgutier@umich.edu if (exist) 26310152Satgutier@umich.edu { // First check if this decoder exists 26410152Satgutier@umich.edu if (num_in_signals == 2) 26510152Satgutier@umich.edu { 26610152Satgutier@umich.edu cumulative_curr = cmos_Isub_leakage(w_dec_n[0], w_dec_p[0], 2, nand,is_dram); 26710152Satgutier@umich.edu cumulative_curr_Ig = cmos_Ig_leakage(w_dec_n[0], w_dec_p[0], 2, nand,is_dram); 26810152Satgutier@umich.edu } 26910152Satgutier@umich.edu else if (num_in_signals == 3) 27010152Satgutier@umich.edu { 27110152Satgutier@umich.edu cumulative_curr = cmos_Isub_leakage(w_dec_n[0], w_dec_p[0], 3, nand, is_dram);; 27210152Satgutier@umich.edu cumulative_curr_Ig = cmos_Ig_leakage(w_dec_n[0], w_dec_p[0], 3, nand, is_dram); 27310152Satgutier@umich.edu } 27410152Satgutier@umich.edu 27510152Satgutier@umich.edu for (int i = 1; i < num_gates; i++) 27610152Satgutier@umich.edu { 27710152Satgutier@umich.edu cumulative_curr += cmos_Isub_leakage(w_dec_n[i], w_dec_p[i], 1, inv, is_dram); 27810152Satgutier@umich.edu cumulative_curr_Ig = cmos_Ig_leakage(w_dec_n[i], w_dec_p[i], 1, inv, is_dram); 27910152Satgutier@umich.edu } 28010152Satgutier@umich.edu 28110152Satgutier@umich.edu power.readOp.leakage = cumulative_curr * g_tp.peri_global.Vdd; 28210152Satgutier@umich.edu power.readOp.gate_leakage = cumulative_curr_Ig * g_tp.peri_global.Vdd; 28310152Satgutier@umich.edu } 28410152Satgutier@umich.edu} 28510152Satgutier@umich.edu 28610152Satgutier@umich.eduPredecBlk::PredecBlk( 28710152Satgutier@umich.edu int num_dec_signals, 28810152Satgutier@umich.edu Decoder * dec_, 28910152Satgutier@umich.edu double C_wire_predec_blk_out, 29010152Satgutier@umich.edu double R_wire_predec_blk_out_, 29110152Satgutier@umich.edu int num_dec_per_predec, 29210152Satgutier@umich.edu bool is_dram, 29310152Satgutier@umich.edu bool is_blk1) 29410152Satgutier@umich.edu :dec(dec_), 29510152Satgutier@umich.edu exist(false), 29610152Satgutier@umich.edu number_input_addr_bits(0), 29710152Satgutier@umich.edu C_ld_predec_blk_out(0), 29810152Satgutier@umich.edu R_wire_predec_blk_out(0), 29910152Satgutier@umich.edu branch_effort_nand2_gate_output(1), 30010152Satgutier@umich.edu branch_effort_nand3_gate_output(1), 30110152Satgutier@umich.edu flag_two_unique_paths(false), 30210152Satgutier@umich.edu flag_L2_gate(0), 30310152Satgutier@umich.edu number_inputs_L1_gate(0), 30410152Satgutier@umich.edu number_gates_L1_nand2_path(0), 30510152Satgutier@umich.edu number_gates_L1_nand3_path(0), 30610152Satgutier@umich.edu number_gates_L2(0), 30710152Satgutier@umich.edu min_number_gates_L1(2), 30810152Satgutier@umich.edu min_number_gates_L2(2), 30910152Satgutier@umich.edu num_L1_active_nand2_path(0), 31010152Satgutier@umich.edu num_L1_active_nand3_path(0), 31110152Satgutier@umich.edu delay_nand2_path(0), 31210152Satgutier@umich.edu delay_nand3_path(0), 31310152Satgutier@umich.edu power_nand2_path(), 31410152Satgutier@umich.edu power_nand3_path(), 31510152Satgutier@umich.edu power_L2(), 31610152Satgutier@umich.edu is_dram_(is_dram) 31710152Satgutier@umich.edu{ 31810152Satgutier@umich.edu int branch_effort_predec_out; 31910152Satgutier@umich.edu double C_ld_dec_gate; 32010152Satgutier@umich.edu int num_addr_bits_dec = _log2(num_dec_signals); 32110152Satgutier@umich.edu int blk1_num_input_addr_bits = (num_addr_bits_dec + 1) / 2; 32210152Satgutier@umich.edu int blk2_num_input_addr_bits = num_addr_bits_dec - blk1_num_input_addr_bits; 32310152Satgutier@umich.edu 32410152Satgutier@umich.edu w_L1_nand2_n[0] = 0; 32510152Satgutier@umich.edu w_L1_nand2_p[0] = 0; 32610152Satgutier@umich.edu w_L1_nand3_n[0] = 0; 32710152Satgutier@umich.edu w_L1_nand3_p[0] = 0; 32810152Satgutier@umich.edu 32910152Satgutier@umich.edu if (is_blk1 == true) 33010152Satgutier@umich.edu { 33110152Satgutier@umich.edu if (num_addr_bits_dec <= 0) 33210152Satgutier@umich.edu { 33310152Satgutier@umich.edu return; 33410152Satgutier@umich.edu } 33510152Satgutier@umich.edu else if (num_addr_bits_dec < 4) 33610152Satgutier@umich.edu { 33710152Satgutier@umich.edu // Just one predecoder block is required with NAND2 gates. No decoder required. 33810152Satgutier@umich.edu // The first level of predecoding directly drives the decoder output load 33910152Satgutier@umich.edu exist = true; 34010152Satgutier@umich.edu number_input_addr_bits = num_addr_bits_dec; 34110152Satgutier@umich.edu R_wire_predec_blk_out = dec->R_wire_dec_out; 34210152Satgutier@umich.edu C_ld_predec_blk_out = dec->C_ld_dec_out; 34310152Satgutier@umich.edu } 34410152Satgutier@umich.edu else 34510152Satgutier@umich.edu { 34610152Satgutier@umich.edu exist = true; 34710152Satgutier@umich.edu number_input_addr_bits = blk1_num_input_addr_bits; 34810152Satgutier@umich.edu branch_effort_predec_out = (1 << blk2_num_input_addr_bits); 34910152Satgutier@umich.edu C_ld_dec_gate = num_dec_per_predec * gate_C(dec->w_dec_n[0] + dec->w_dec_p[0], 0, is_dram_, false, false); 35010152Satgutier@umich.edu R_wire_predec_blk_out = R_wire_predec_blk_out_; 35110152Satgutier@umich.edu C_ld_predec_blk_out = branch_effort_predec_out * C_ld_dec_gate + C_wire_predec_blk_out; 35210152Satgutier@umich.edu } 35310152Satgutier@umich.edu } 35410152Satgutier@umich.edu else 35510152Satgutier@umich.edu { 35610152Satgutier@umich.edu if (num_addr_bits_dec >= 4) 35710152Satgutier@umich.edu { 35810152Satgutier@umich.edu exist = true; 35910152Satgutier@umich.edu number_input_addr_bits = blk2_num_input_addr_bits; 36010152Satgutier@umich.edu branch_effort_predec_out = (1 << blk1_num_input_addr_bits); 36110152Satgutier@umich.edu C_ld_dec_gate = num_dec_per_predec * gate_C(dec->w_dec_n[0] + dec->w_dec_p[0], 0, is_dram_, false, false); 36210152Satgutier@umich.edu R_wire_predec_blk_out = R_wire_predec_blk_out_; 36310152Satgutier@umich.edu C_ld_predec_blk_out = branch_effort_predec_out * C_ld_dec_gate + C_wire_predec_blk_out; 36410152Satgutier@umich.edu } 36510152Satgutier@umich.edu } 36610152Satgutier@umich.edu 36710152Satgutier@umich.edu compute_widths(); 36810152Satgutier@umich.edu compute_area(); 36910152Satgutier@umich.edu} 37010152Satgutier@umich.edu 37110152Satgutier@umich.edu 37210152Satgutier@umich.edu 37310152Satgutier@umich.eduvoid PredecBlk::compute_widths() 37410152Satgutier@umich.edu{ 37510152Satgutier@umich.edu double F, c_load_nand3_path, c_load_nand2_path; 37610152Satgutier@umich.edu double p_to_n_sz_ratio = pmos_to_nmos_sz_ratio(is_dram_); 37710152Satgutier@umich.edu double gnand2 = (2 + p_to_n_sz_ratio) / (1 + p_to_n_sz_ratio); 37810152Satgutier@umich.edu double gnand3 = (3 + p_to_n_sz_ratio) / (1 + p_to_n_sz_ratio); 37910152Satgutier@umich.edu 38010152Satgutier@umich.edu if (exist == false) return; 38110152Satgutier@umich.edu 38210152Satgutier@umich.edu 38310152Satgutier@umich.edu switch (number_input_addr_bits) 38410152Satgutier@umich.edu { 38510152Satgutier@umich.edu case 1: 38610152Satgutier@umich.edu flag_two_unique_paths = false; 38710152Satgutier@umich.edu number_inputs_L1_gate = 2; 38810152Satgutier@umich.edu flag_L2_gate = 0; 38910152Satgutier@umich.edu break; 39010152Satgutier@umich.edu case 2: 39110152Satgutier@umich.edu flag_two_unique_paths = false; 39210152Satgutier@umich.edu number_inputs_L1_gate = 2; 39310152Satgutier@umich.edu flag_L2_gate = 0; 39410152Satgutier@umich.edu break; 39510152Satgutier@umich.edu case 3: 39610152Satgutier@umich.edu flag_two_unique_paths = false; 39710152Satgutier@umich.edu number_inputs_L1_gate = 3; 39810152Satgutier@umich.edu flag_L2_gate = 0; 39910152Satgutier@umich.edu break; 40010152Satgutier@umich.edu case 4: 40110152Satgutier@umich.edu flag_two_unique_paths = false; 40210152Satgutier@umich.edu number_inputs_L1_gate = 2; 40310152Satgutier@umich.edu flag_L2_gate = 2; 40410152Satgutier@umich.edu branch_effort_nand2_gate_output = 4; 40510152Satgutier@umich.edu break; 40610152Satgutier@umich.edu case 5: 40710152Satgutier@umich.edu flag_two_unique_paths = true; 40810152Satgutier@umich.edu flag_L2_gate = 2; 40910152Satgutier@umich.edu branch_effort_nand2_gate_output = 8; 41010152Satgutier@umich.edu branch_effort_nand3_gate_output = 4; 41110152Satgutier@umich.edu break; 41210152Satgutier@umich.edu case 6: 41310152Satgutier@umich.edu flag_two_unique_paths = false; 41410152Satgutier@umich.edu number_inputs_L1_gate = 3; 41510152Satgutier@umich.edu flag_L2_gate = 2; 41610152Satgutier@umich.edu branch_effort_nand3_gate_output = 8; 41710152Satgutier@umich.edu break; 41810152Satgutier@umich.edu case 7: 41910152Satgutier@umich.edu flag_two_unique_paths = true; 42010152Satgutier@umich.edu flag_L2_gate = 3; 42110152Satgutier@umich.edu branch_effort_nand2_gate_output = 32; 42210152Satgutier@umich.edu branch_effort_nand3_gate_output = 16; 42310152Satgutier@umich.edu break; 42410152Satgutier@umich.edu case 8: 42510152Satgutier@umich.edu flag_two_unique_paths = true; 42610152Satgutier@umich.edu flag_L2_gate = 3; 42710152Satgutier@umich.edu branch_effort_nand2_gate_output = 64; 42810152Satgutier@umich.edu branch_effort_nand3_gate_output = 32; 42910152Satgutier@umich.edu break; 43010152Satgutier@umich.edu case 9: 43110152Satgutier@umich.edu flag_two_unique_paths = false; 43210152Satgutier@umich.edu number_inputs_L1_gate = 3; 43310152Satgutier@umich.edu flag_L2_gate = 3; 43410152Satgutier@umich.edu branch_effort_nand3_gate_output = 64; 43510152Satgutier@umich.edu break; 43610152Satgutier@umich.edu default: 43710152Satgutier@umich.edu assert(0); 43810152Satgutier@umich.edu break; 43910152Satgutier@umich.edu } 44010152Satgutier@umich.edu 44110152Satgutier@umich.edu // find the number of gates and sizing in second level of predecoder (if there is a second level) 44210152Satgutier@umich.edu if (flag_L2_gate) 44310152Satgutier@umich.edu { 44410152Satgutier@umich.edu if (flag_L2_gate == 2) 44510152Satgutier@umich.edu { // 2nd level is a NAND2 gate 44610152Satgutier@umich.edu w_L2_n[0] = 2 * g_tp.min_w_nmos_; 44710152Satgutier@umich.edu F = gnand2; 44810152Satgutier@umich.edu } 44910152Satgutier@umich.edu else 45010152Satgutier@umich.edu { // 2nd level is a NAND3 gate 45110152Satgutier@umich.edu w_L2_n[0] = 3 * g_tp.min_w_nmos_; 45210152Satgutier@umich.edu F = gnand3; 45310152Satgutier@umich.edu } 45410152Satgutier@umich.edu w_L2_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 45510152Satgutier@umich.edu F *= C_ld_predec_blk_out / (gate_C(w_L2_n[0], 0, is_dram_) + gate_C(w_L2_p[0], 0, is_dram_)); 45610152Satgutier@umich.edu number_gates_L2 = logical_effort( 45710152Satgutier@umich.edu min_number_gates_L2, 45810152Satgutier@umich.edu flag_L2_gate == 2 ? gnand2 : gnand3, 45910152Satgutier@umich.edu F, 46010152Satgutier@umich.edu w_L2_n, 46110152Satgutier@umich.edu w_L2_p, 46210152Satgutier@umich.edu C_ld_predec_blk_out, 46310152Satgutier@umich.edu p_to_n_sz_ratio, 46410152Satgutier@umich.edu is_dram_, false, 46510152Satgutier@umich.edu g_tp.max_w_nmos_); 46610152Satgutier@umich.edu 46710152Satgutier@umich.edu // Now find the number of gates and widths in first level of predecoder 46810152Satgutier@umich.edu if ((flag_two_unique_paths)||(number_inputs_L1_gate == 2)) 46910152Satgutier@umich.edu { // Whenever flag_two_unique_paths is true, it means first level of decoder employs 47010152Satgutier@umich.edu // both NAND2 and NAND3 gates. Or when number_inputs_L1_gate is 2, it means 47110152Satgutier@umich.edu // a NAND2 gate is used in the first level of the predecoder 47210152Satgutier@umich.edu c_load_nand2_path = branch_effort_nand2_gate_output * 47310152Satgutier@umich.edu (gate_C(w_L2_n[0], 0, is_dram_) + 47410152Satgutier@umich.edu gate_C(w_L2_p[0], 0, is_dram_)); 47510152Satgutier@umich.edu w_L1_nand2_n[0] = 2 * g_tp.min_w_nmos_; 47610152Satgutier@umich.edu w_L1_nand2_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 47710152Satgutier@umich.edu F = gnand2 * c_load_nand2_path / 47810152Satgutier@umich.edu (gate_C(w_L1_nand2_n[0], 0, is_dram_) + 47910152Satgutier@umich.edu gate_C(w_L1_nand2_p[0], 0, is_dram_)); 48010152Satgutier@umich.edu number_gates_L1_nand2_path = logical_effort( 48110152Satgutier@umich.edu min_number_gates_L1, 48210152Satgutier@umich.edu gnand2, 48310152Satgutier@umich.edu F, 48410152Satgutier@umich.edu w_L1_nand2_n, 48510152Satgutier@umich.edu w_L1_nand2_p, 48610152Satgutier@umich.edu c_load_nand2_path, 48710152Satgutier@umich.edu p_to_n_sz_ratio, 48810152Satgutier@umich.edu is_dram_, false, 48910152Satgutier@umich.edu g_tp.max_w_nmos_); 49010152Satgutier@umich.edu } 49110152Satgutier@umich.edu 49210152Satgutier@umich.edu //Now find widths of gates along path in which first gate is a NAND3 49310152Satgutier@umich.edu if ((flag_two_unique_paths)||(number_inputs_L1_gate == 3)) 49410152Satgutier@umich.edu { // Whenever flag_two_unique_paths is TRUE, it means first level of decoder employs 49510152Satgutier@umich.edu // both NAND2 and NAND3 gates. Or when number_inputs_L1_gate is 3, it means 49610152Satgutier@umich.edu // a NAND3 gate is used in the first level of the predecoder 49710152Satgutier@umich.edu c_load_nand3_path = branch_effort_nand3_gate_output * 49810152Satgutier@umich.edu (gate_C(w_L2_n[0], 0, is_dram_) + 49910152Satgutier@umich.edu gate_C(w_L2_p[0], 0, is_dram_)); 50010152Satgutier@umich.edu w_L1_nand3_n[0] = 3 * g_tp.min_w_nmos_; 50110152Satgutier@umich.edu w_L1_nand3_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 50210152Satgutier@umich.edu F = gnand3 * c_load_nand3_path / 50310152Satgutier@umich.edu (gate_C(w_L1_nand3_n[0], 0, is_dram_) + 50410152Satgutier@umich.edu gate_C(w_L1_nand3_p[0], 0, is_dram_)); 50510152Satgutier@umich.edu number_gates_L1_nand3_path = logical_effort( 50610152Satgutier@umich.edu min_number_gates_L1, 50710152Satgutier@umich.edu gnand3, 50810152Satgutier@umich.edu F, 50910152Satgutier@umich.edu w_L1_nand3_n, 51010152Satgutier@umich.edu w_L1_nand3_p, 51110152Satgutier@umich.edu c_load_nand3_path, 51210152Satgutier@umich.edu p_to_n_sz_ratio, 51310152Satgutier@umich.edu is_dram_, false, 51410152Satgutier@umich.edu g_tp.max_w_nmos_); 51510152Satgutier@umich.edu } 51610152Satgutier@umich.edu } 51710152Satgutier@umich.edu else 51810152Satgutier@umich.edu { // find number of gates and widths in first level of predecoder block when there is no second level 51910152Satgutier@umich.edu if (number_inputs_L1_gate == 2) 52010152Satgutier@umich.edu { 52110152Satgutier@umich.edu w_L1_nand2_n[0] = 2 * g_tp.min_w_nmos_; 52210152Satgutier@umich.edu w_L1_nand2_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 52310152Satgutier@umich.edu F = gnand2*C_ld_predec_blk_out / 52410152Satgutier@umich.edu (gate_C(w_L1_nand2_n[0], 0, is_dram_) + 52510152Satgutier@umich.edu gate_C(w_L1_nand2_p[0], 0, is_dram_)); 52610152Satgutier@umich.edu number_gates_L1_nand2_path = logical_effort( 52710152Satgutier@umich.edu min_number_gates_L1, 52810152Satgutier@umich.edu gnand2, 52910152Satgutier@umich.edu F, 53010152Satgutier@umich.edu w_L1_nand2_n, 53110152Satgutier@umich.edu w_L1_nand2_p, 53210152Satgutier@umich.edu C_ld_predec_blk_out, 53310152Satgutier@umich.edu p_to_n_sz_ratio, 53410152Satgutier@umich.edu is_dram_, false, 53510152Satgutier@umich.edu g_tp.max_w_nmos_); 53610152Satgutier@umich.edu } 53710152Satgutier@umich.edu else if (number_inputs_L1_gate == 3) 53810152Satgutier@umich.edu { 53910152Satgutier@umich.edu w_L1_nand3_n[0] = 3 * g_tp.min_w_nmos_; 54010152Satgutier@umich.edu w_L1_nand3_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 54110152Satgutier@umich.edu F = gnand3*C_ld_predec_blk_out / 54210152Satgutier@umich.edu (gate_C(w_L1_nand3_n[0], 0, is_dram_) + 54310152Satgutier@umich.edu gate_C(w_L1_nand3_p[0], 0, is_dram_)); 54410152Satgutier@umich.edu number_gates_L1_nand3_path = logical_effort( 54510152Satgutier@umich.edu min_number_gates_L1, 54610152Satgutier@umich.edu gnand3, 54710152Satgutier@umich.edu F, 54810152Satgutier@umich.edu w_L1_nand3_n, 54910152Satgutier@umich.edu w_L1_nand3_p, 55010152Satgutier@umich.edu C_ld_predec_blk_out, 55110152Satgutier@umich.edu p_to_n_sz_ratio, 55210152Satgutier@umich.edu is_dram_, false, 55310152Satgutier@umich.edu g_tp.max_w_nmos_); 55410152Satgutier@umich.edu } 55510152Satgutier@umich.edu } 55610152Satgutier@umich.edu} 55710152Satgutier@umich.edu 55810152Satgutier@umich.edu 55910152Satgutier@umich.edu 56010152Satgutier@umich.eduvoid PredecBlk::compute_area() 56110152Satgutier@umich.edu{ 56210152Satgutier@umich.edu if (exist) 56310152Satgutier@umich.edu { // First check whether a predecoder block is needed 56410152Satgutier@umich.edu int num_L1_nand2 = 0; 56510152Satgutier@umich.edu int num_L1_nand3 = 0; 56610152Satgutier@umich.edu int num_L2 = 0; 56710152Satgutier@umich.edu double tot_area_L1_nand3 =0; 56810152Satgutier@umich.edu double leak_L1_nand3 =0; 56910152Satgutier@umich.edu double gate_leak_L1_nand3 =0; 57010152Satgutier@umich.edu 57110152Satgutier@umich.edu double tot_area_L1_nand2 = compute_gate_area(NAND, 2, w_L1_nand2_p[0], w_L1_nand2_n[0], g_tp.cell_h_def); 57210152Satgutier@umich.edu double leak_L1_nand2 = cmos_Isub_leakage(w_L1_nand2_n[0], w_L1_nand2_p[0], 2, nand, is_dram_); 57310152Satgutier@umich.edu double gate_leak_L1_nand2 = cmos_Ig_leakage(w_L1_nand2_n[0], w_L1_nand2_p[0], 2, nand, is_dram_); 57410152Satgutier@umich.edu if (number_inputs_L1_gate != 3) { 57510152Satgutier@umich.edu tot_area_L1_nand3 = 0; 57610152Satgutier@umich.edu leak_L1_nand3 = 0; 57710152Satgutier@umich.edu gate_leak_L1_nand3 =0; 57810152Satgutier@umich.edu } 57910152Satgutier@umich.edu else { 58010152Satgutier@umich.edu tot_area_L1_nand3 = compute_gate_area(NAND, 3, w_L1_nand3_p[0], w_L1_nand3_n[0], g_tp.cell_h_def); 58110152Satgutier@umich.edu leak_L1_nand3 = cmos_Isub_leakage(w_L1_nand3_n[0], w_L1_nand3_p[0], 3, nand); 58210152Satgutier@umich.edu gate_leak_L1_nand3 = cmos_Ig_leakage(w_L1_nand3_n[0], w_L1_nand3_p[0], 3, nand); 58310152Satgutier@umich.edu } 58410152Satgutier@umich.edu 58510152Satgutier@umich.edu switch (number_input_addr_bits) 58610152Satgutier@umich.edu { 58710152Satgutier@umich.edu case 1: //2 NAND2 gates 58810152Satgutier@umich.edu num_L1_nand2 = 2; 58910152Satgutier@umich.edu num_L2 = 0; 59010152Satgutier@umich.edu num_L1_active_nand2_path =1; 59110152Satgutier@umich.edu num_L1_active_nand3_path =0; 59210152Satgutier@umich.edu break; 59310152Satgutier@umich.edu case 2: //4 NAND2 gates 59410152Satgutier@umich.edu num_L1_nand2 = 4; 59510152Satgutier@umich.edu num_L2 = 0; 59610152Satgutier@umich.edu num_L1_active_nand2_path =1; 59710152Satgutier@umich.edu num_L1_active_nand3_path =0; 59810152Satgutier@umich.edu break; 59910152Satgutier@umich.edu case 3: //8 NAND3 gates 60010152Satgutier@umich.edu num_L1_nand3 = 8; 60110152Satgutier@umich.edu num_L2 = 0; 60210152Satgutier@umich.edu num_L1_active_nand2_path =0; 60310152Satgutier@umich.edu num_L1_active_nand3_path =1; 60410152Satgutier@umich.edu break; 60510152Satgutier@umich.edu case 4: //4 + 4 NAND2 gates 60610152Satgutier@umich.edu num_L1_nand2 = 8; 60710152Satgutier@umich.edu num_L2 = 16; 60810152Satgutier@umich.edu num_L1_active_nand2_path =2; 60910152Satgutier@umich.edu num_L1_active_nand3_path =0; 61010152Satgutier@umich.edu break; 61110152Satgutier@umich.edu case 5: //4 NAND2 gates, 8 NAND3 gates 61210152Satgutier@umich.edu num_L1_nand2 = 4; 61310152Satgutier@umich.edu num_L1_nand3 = 8; 61410152Satgutier@umich.edu num_L2 = 32; 61510152Satgutier@umich.edu num_L1_active_nand2_path =1; 61610152Satgutier@umich.edu num_L1_active_nand3_path =1; 61710152Satgutier@umich.edu break; 61810152Satgutier@umich.edu case 6: //8 + 8 NAND3 gates 61910152Satgutier@umich.edu num_L1_nand3 = 16; 62010152Satgutier@umich.edu num_L2 = 64; 62110152Satgutier@umich.edu num_L1_active_nand2_path =0; 62210152Satgutier@umich.edu num_L1_active_nand3_path =2; 62310152Satgutier@umich.edu break; 62410152Satgutier@umich.edu case 7: //4 + 4 NAND2 gates, 8 NAND3 gates 62510152Satgutier@umich.edu num_L1_nand2 = 8; 62610152Satgutier@umich.edu num_L1_nand3 = 8; 62710152Satgutier@umich.edu num_L2 = 128; 62810152Satgutier@umich.edu num_L1_active_nand2_path =2; 62910152Satgutier@umich.edu num_L1_active_nand3_path =1; 63010152Satgutier@umich.edu break; 63110152Satgutier@umich.edu case 8: //4 NAND2 gates, 8 + 8 NAND3 gates 63210152Satgutier@umich.edu num_L1_nand2 = 4; 63310152Satgutier@umich.edu num_L1_nand3 = 16; 63410152Satgutier@umich.edu num_L2 = 256; 63510152Satgutier@umich.edu num_L1_active_nand2_path =2; 63610152Satgutier@umich.edu num_L1_active_nand3_path =2; 63710152Satgutier@umich.edu break; 63810152Satgutier@umich.edu case 9: //8 + 8 + 8 NAND3 gates 63910152Satgutier@umich.edu num_L1_nand3 = 24; 64010152Satgutier@umich.edu num_L2 = 512; 64110152Satgutier@umich.edu num_L1_active_nand2_path =0; 64210152Satgutier@umich.edu num_L1_active_nand3_path =3; 64310152Satgutier@umich.edu break; 64410152Satgutier@umich.edu default: 64510152Satgutier@umich.edu break; 64610152Satgutier@umich.edu } 64710152Satgutier@umich.edu 64810152Satgutier@umich.edu for (int i = 1; i < number_gates_L1_nand2_path; ++i) 64910152Satgutier@umich.edu { 65010152Satgutier@umich.edu tot_area_L1_nand2 += compute_gate_area(INV, 1, w_L1_nand2_p[i], w_L1_nand2_n[i], g_tp.cell_h_def); 65110152Satgutier@umich.edu leak_L1_nand2 += cmos_Isub_leakage(w_L1_nand2_n[i], w_L1_nand2_p[i], 2, nand, is_dram_); 65210152Satgutier@umich.edu gate_leak_L1_nand2 += cmos_Ig_leakage(w_L1_nand2_n[i], w_L1_nand2_p[i], 2, nand, is_dram_); 65310152Satgutier@umich.edu } 65410152Satgutier@umich.edu tot_area_L1_nand2 *= num_L1_nand2; 65510152Satgutier@umich.edu leak_L1_nand2 *= num_L1_nand2; 65610152Satgutier@umich.edu gate_leak_L1_nand2 *= num_L1_nand2; 65710152Satgutier@umich.edu 65810152Satgutier@umich.edu for (int i = 1; i < number_gates_L1_nand3_path; ++i) 65910152Satgutier@umich.edu { 66010152Satgutier@umich.edu tot_area_L1_nand3 += compute_gate_area(INV, 1, w_L1_nand3_p[i], w_L1_nand3_n[i], g_tp.cell_h_def); 66110152Satgutier@umich.edu leak_L1_nand3 += cmos_Isub_leakage(w_L1_nand3_n[i], w_L1_nand3_p[i], 3, nand, is_dram_); 66210152Satgutier@umich.edu gate_leak_L1_nand3 += cmos_Ig_leakage(w_L1_nand3_n[i], w_L1_nand3_p[i], 3, nand, is_dram_); 66310152Satgutier@umich.edu } 66410152Satgutier@umich.edu tot_area_L1_nand3 *= num_L1_nand3; 66510152Satgutier@umich.edu leak_L1_nand3 *= num_L1_nand3; 66610152Satgutier@umich.edu gate_leak_L1_nand3 *= num_L1_nand3; 66710152Satgutier@umich.edu 66810152Satgutier@umich.edu double cumulative_area_L1 = tot_area_L1_nand2 + tot_area_L1_nand3; 66910152Satgutier@umich.edu double cumulative_area_L2 = 0.0; 67010152Satgutier@umich.edu double leakage_L2 = 0.0; 67110152Satgutier@umich.edu double gate_leakage_L2 = 0.0; 67210152Satgutier@umich.edu 67310152Satgutier@umich.edu if (flag_L2_gate == 2) 67410152Satgutier@umich.edu { 67510152Satgutier@umich.edu cumulative_area_L2 = compute_gate_area(NAND, 2, w_L2_p[0], w_L2_n[0], g_tp.cell_h_def); 67610152Satgutier@umich.edu leakage_L2 = cmos_Isub_leakage(w_L2_n[0], w_L2_p[0], 2, nand, is_dram_); 67710152Satgutier@umich.edu gate_leakage_L2 = cmos_Ig_leakage(w_L2_n[0], w_L2_p[0], 2, nand, is_dram_); 67810152Satgutier@umich.edu } 67910152Satgutier@umich.edu else if (flag_L2_gate == 3) 68010152Satgutier@umich.edu { 68110152Satgutier@umich.edu cumulative_area_L2 = compute_gate_area(NAND, 3, w_L2_p[0], w_L2_n[0], g_tp.cell_h_def); 68210152Satgutier@umich.edu leakage_L2 = cmos_Isub_leakage(w_L2_n[0], w_L2_p[0], 3, nand, is_dram_); 68310152Satgutier@umich.edu gate_leakage_L2 = cmos_Ig_leakage(w_L2_n[0], w_L2_p[0], 3, nand, is_dram_); 68410152Satgutier@umich.edu } 68510152Satgutier@umich.edu 68610152Satgutier@umich.edu for (int i = 1; i < number_gates_L2; ++i) 68710152Satgutier@umich.edu { 68810152Satgutier@umich.edu cumulative_area_L2 += compute_gate_area(INV, 1, w_L2_p[i], w_L2_n[i], g_tp.cell_h_def); 68910152Satgutier@umich.edu leakage_L2 += cmos_Isub_leakage(w_L2_n[i], w_L2_p[i], 2, inv, is_dram_); 69010152Satgutier@umich.edu gate_leakage_L2 += cmos_Ig_leakage(w_L2_n[i], w_L2_p[i], 2, inv, is_dram_); 69110152Satgutier@umich.edu } 69210152Satgutier@umich.edu cumulative_area_L2 *= num_L2; 69310152Satgutier@umich.edu leakage_L2 *= num_L2; 69410152Satgutier@umich.edu gate_leakage_L2 *= num_L2; 69510152Satgutier@umich.edu 69610152Satgutier@umich.edu power_nand2_path.readOp.leakage = leak_L1_nand2 * g_tp.peri_global.Vdd; 69710152Satgutier@umich.edu power_nand3_path.readOp.leakage = leak_L1_nand3 * g_tp.peri_global.Vdd; 69810152Satgutier@umich.edu power_L2.readOp.leakage = leakage_L2 * g_tp.peri_global.Vdd; 69910152Satgutier@umich.edu area.set_area(cumulative_area_L1 + cumulative_area_L2); 70010152Satgutier@umich.edu power_nand2_path.readOp.gate_leakage = gate_leak_L1_nand2 * g_tp.peri_global.Vdd; 70110152Satgutier@umich.edu power_nand3_path.readOp.gate_leakage = gate_leak_L1_nand3 * g_tp.peri_global.Vdd; 70210152Satgutier@umich.edu power_L2.readOp.gate_leakage = gate_leakage_L2 * g_tp.peri_global.Vdd; 70310152Satgutier@umich.edu } 70410152Satgutier@umich.edu} 70510152Satgutier@umich.edu 70610152Satgutier@umich.edu 70710152Satgutier@umich.edu 70810152Satgutier@umich.edupair<double, double> PredecBlk::compute_delays( 70910152Satgutier@umich.edu pair<double, double> inrisetime) // <nand2, nand3> 71010152Satgutier@umich.edu{ 71110152Satgutier@umich.edu pair<double, double> ret_val; 71210152Satgutier@umich.edu ret_val.first = 0; // outrisetime_nand2_path 71310152Satgutier@umich.edu ret_val.second = 0; // outrisetime_nand3_path 71410152Satgutier@umich.edu 71510152Satgutier@umich.edu double inrisetime_nand2_path = inrisetime.first; 71610152Satgutier@umich.edu double inrisetime_nand3_path = inrisetime.second; 71710152Satgutier@umich.edu int i; 71810152Satgutier@umich.edu double rd, c_load, c_intrinsic, tf, this_delay; 71910152Satgutier@umich.edu double Vdd = g_tp.peri_global.Vdd; 72010152Satgutier@umich.edu 72110152Satgutier@umich.edu // TODO: following delay calculation part can be greatly simplified. 72210152Satgutier@umich.edu // first check whether a predecoder block is required 72310152Satgutier@umich.edu if (exist) 72410152Satgutier@umich.edu { 72510152Satgutier@umich.edu //Find delay in first level of predecoder block 72610152Satgutier@umich.edu //First find delay in path 72710152Satgutier@umich.edu if ((flag_two_unique_paths) || (number_inputs_L1_gate == 2)) 72810152Satgutier@umich.edu { 72910152Satgutier@umich.edu //First gate is a NAND2 gate 73010152Satgutier@umich.edu rd = tr_R_on(w_L1_nand2_n[0], NCH, 2, is_dram_); 73110152Satgutier@umich.edu c_load = gate_C(w_L1_nand2_n[1] + w_L1_nand2_p[1], 0.0, is_dram_); 73210152Satgutier@umich.edu c_intrinsic = 2 * drain_C_(w_L1_nand2_p[0], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 73310152Satgutier@umich.edu drain_C_(w_L1_nand2_n[0], NCH, 2, 1, g_tp.cell_h_def, is_dram_); 73410152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load); 73510152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 73610152Satgutier@umich.edu delay_nand2_path += this_delay; 73710152Satgutier@umich.edu inrisetime_nand2_path = this_delay / (1.0 - 0.5); 73810152Satgutier@umich.edu power_nand2_path.readOp.dynamic += (c_load + c_intrinsic) * Vdd * Vdd; 73910152Satgutier@umich.edu 74010152Satgutier@umich.edu //Add delays of all but the last inverter in the chain 74110152Satgutier@umich.edu for (i = 1; i < number_gates_L1_nand2_path - 1; ++i) 74210152Satgutier@umich.edu { 74310152Satgutier@umich.edu rd = tr_R_on(w_L1_nand2_n[i], NCH, 1, is_dram_); 74410152Satgutier@umich.edu c_load = gate_C(w_L1_nand2_n[i+1] + w_L1_nand2_p[i+1], 0.0, is_dram_); 74510152Satgutier@umich.edu c_intrinsic = drain_C_(w_L1_nand2_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 74610152Satgutier@umich.edu drain_C_(w_L1_nand2_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 74710152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load); 74810152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 74910152Satgutier@umich.edu delay_nand2_path += this_delay; 75010152Satgutier@umich.edu inrisetime_nand2_path = this_delay / (1.0 - 0.5); 75110152Satgutier@umich.edu power_nand2_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 75210152Satgutier@umich.edu } 75310152Satgutier@umich.edu 75410152Satgutier@umich.edu //Add delay of the last inverter 75510152Satgutier@umich.edu i = number_gates_L1_nand2_path - 1; 75610152Satgutier@umich.edu rd = tr_R_on(w_L1_nand2_n[i], NCH, 1, is_dram_); 75710152Satgutier@umich.edu if (flag_L2_gate) 75810152Satgutier@umich.edu { 75910152Satgutier@umich.edu c_load = branch_effort_nand2_gate_output*(gate_C(w_L2_n[0], 0, is_dram_) + gate_C(w_L2_p[0], 0, is_dram_)); 76010152Satgutier@umich.edu c_intrinsic = drain_C_(w_L1_nand2_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 76110152Satgutier@umich.edu drain_C_(w_L1_nand2_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 76210152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load); 76310152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 76410152Satgutier@umich.edu delay_nand2_path += this_delay; 76510152Satgutier@umich.edu inrisetime_nand2_path = this_delay / (1.0 - 0.5); 76610152Satgutier@umich.edu power_nand2_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 76710152Satgutier@umich.edu } 76810152Satgutier@umich.edu else 76910152Satgutier@umich.edu { //First level directly drives decoder output load 77010152Satgutier@umich.edu c_load = C_ld_predec_blk_out; 77110152Satgutier@umich.edu c_intrinsic = drain_C_(w_L1_nand2_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 77210152Satgutier@umich.edu drain_C_(w_L1_nand2_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 77310152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load) + R_wire_predec_blk_out * c_load / 2; 77410152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 77510152Satgutier@umich.edu delay_nand2_path += this_delay; 77610152Satgutier@umich.edu ret_val.first = this_delay / (1.0 - 0.5); 77710152Satgutier@umich.edu power_nand2_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 77810152Satgutier@umich.edu } 77910152Satgutier@umich.edu } 78010152Satgutier@umich.edu 78110152Satgutier@umich.edu if ((flag_two_unique_paths) || (number_inputs_L1_gate == 3)) 78210152Satgutier@umich.edu { //Check if the number of gates in the first level is more than 1. 78310152Satgutier@umich.edu //First gate is a NAND3 gate 78410152Satgutier@umich.edu rd = tr_R_on(w_L1_nand3_n[0], NCH, 3, is_dram_); 78510152Satgutier@umich.edu c_load = gate_C(w_L1_nand3_n[1] + w_L1_nand3_p[1], 0.0, is_dram_); 78610152Satgutier@umich.edu c_intrinsic = 3 * drain_C_(w_L1_nand3_p[0], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 78710152Satgutier@umich.edu drain_C_(w_L1_nand3_n[0], NCH, 3, 1, g_tp.cell_h_def, is_dram_); 78810152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load); 78910152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 79010152Satgutier@umich.edu delay_nand3_path += this_delay; 79110152Satgutier@umich.edu inrisetime_nand3_path = this_delay / (1.0 - 0.5); 79210152Satgutier@umich.edu power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 79310152Satgutier@umich.edu 79410152Satgutier@umich.edu //Add delays of all but the last inverter in the chain 79510152Satgutier@umich.edu for (i = 1; i < number_gates_L1_nand3_path - 1; ++i) 79610152Satgutier@umich.edu { 79710152Satgutier@umich.edu rd = tr_R_on(w_L1_nand3_n[i], NCH, 1, is_dram_); 79810152Satgutier@umich.edu c_load = gate_C(w_L1_nand3_n[i+1] + w_L1_nand3_p[i+1], 0.0, is_dram_); 79910152Satgutier@umich.edu c_intrinsic = drain_C_(w_L1_nand3_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 80010152Satgutier@umich.edu drain_C_(w_L1_nand3_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 80110152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load); 80210152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 80310152Satgutier@umich.edu delay_nand3_path += this_delay; 80410152Satgutier@umich.edu inrisetime_nand3_path = this_delay / (1.0 - 0.5); 80510152Satgutier@umich.edu power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 80610152Satgutier@umich.edu } 80710152Satgutier@umich.edu 80810152Satgutier@umich.edu //Add delay of the last inverter 80910152Satgutier@umich.edu i = number_gates_L1_nand3_path - 1; 81010152Satgutier@umich.edu rd = tr_R_on(w_L1_nand3_n[i], NCH, 1, is_dram_); 81110152Satgutier@umich.edu if (flag_L2_gate) 81210152Satgutier@umich.edu { 81310152Satgutier@umich.edu c_load = branch_effort_nand3_gate_output*(gate_C(w_L2_n[0], 0, is_dram_) + gate_C(w_L2_p[0], 0, is_dram_)); 81410152Satgutier@umich.edu c_intrinsic = drain_C_(w_L1_nand3_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 81510152Satgutier@umich.edu drain_C_(w_L1_nand3_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 81610152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load); 81710152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 81810152Satgutier@umich.edu delay_nand3_path += this_delay; 81910152Satgutier@umich.edu inrisetime_nand3_path = this_delay / (1.0 - 0.5); 82010152Satgutier@umich.edu power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 82110152Satgutier@umich.edu } 82210152Satgutier@umich.edu else 82310152Satgutier@umich.edu { //First level directly drives decoder output load 82410152Satgutier@umich.edu c_load = C_ld_predec_blk_out; 82510152Satgutier@umich.edu c_intrinsic = drain_C_(w_L1_nand3_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 82610152Satgutier@umich.edu drain_C_(w_L1_nand3_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 82710152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load) + R_wire_predec_blk_out * c_load / 2; 82810152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 82910152Satgutier@umich.edu delay_nand3_path += this_delay; 83010152Satgutier@umich.edu ret_val.second = this_delay / (1.0 - 0.5); 83110152Satgutier@umich.edu power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 83210152Satgutier@umich.edu } 83310152Satgutier@umich.edu } 83410152Satgutier@umich.edu 83510152Satgutier@umich.edu // Find delay through second level 83610152Satgutier@umich.edu if (flag_L2_gate) 83710152Satgutier@umich.edu { 83810152Satgutier@umich.edu if (flag_L2_gate == 2) 83910152Satgutier@umich.edu { 84010152Satgutier@umich.edu rd = tr_R_on(w_L2_n[0], NCH, 2, is_dram_); 84110152Satgutier@umich.edu c_load = gate_C(w_L2_n[1] + w_L2_p[1], 0.0, is_dram_); 84210152Satgutier@umich.edu c_intrinsic = 2 * drain_C_(w_L2_p[0], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 84310152Satgutier@umich.edu drain_C_(w_L2_n[0], NCH, 2, 1, g_tp.cell_h_def, is_dram_); 84410152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load); 84510152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 84610152Satgutier@umich.edu delay_nand2_path += this_delay; 84710152Satgutier@umich.edu inrisetime_nand2_path = this_delay / (1.0 - 0.5); 84810152Satgutier@umich.edu power_L2.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 84910152Satgutier@umich.edu } 85010152Satgutier@umich.edu else 85110152Satgutier@umich.edu { // flag_L2_gate = 3 85210152Satgutier@umich.edu rd = tr_R_on(w_L2_n[0], NCH, 3, is_dram_); 85310152Satgutier@umich.edu c_load = gate_C(w_L2_n[1] + w_L2_p[1], 0.0, is_dram_); 85410152Satgutier@umich.edu c_intrinsic = 3 * drain_C_(w_L2_p[0], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 85510152Satgutier@umich.edu drain_C_(w_L2_n[0], NCH, 3, 1, g_tp.cell_h_def, is_dram_); 85610152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load); 85710152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 85810152Satgutier@umich.edu delay_nand3_path += this_delay; 85910152Satgutier@umich.edu inrisetime_nand3_path = this_delay / (1.0 - 0.5); 86010152Satgutier@umich.edu power_L2.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 86110152Satgutier@umich.edu } 86210152Satgutier@umich.edu 86310152Satgutier@umich.edu for (i = 1; i < number_gates_L2 - 1; ++i) 86410152Satgutier@umich.edu { 86510152Satgutier@umich.edu rd = tr_R_on(w_L2_n[i], NCH, 1, is_dram_); 86610152Satgutier@umich.edu c_load = gate_C(w_L2_n[i+1] + w_L2_p[i+1], 0.0, is_dram_); 86710152Satgutier@umich.edu c_intrinsic = drain_C_(w_L2_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 86810152Satgutier@umich.edu drain_C_(w_L2_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 86910152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load); 87010152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 87110152Satgutier@umich.edu delay_nand2_path += this_delay; 87210152Satgutier@umich.edu inrisetime_nand2_path = this_delay / (1.0 - 0.5); 87310152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 87410152Satgutier@umich.edu delay_nand3_path += this_delay; 87510152Satgutier@umich.edu inrisetime_nand3_path = this_delay / (1.0 - 0.5); 87610152Satgutier@umich.edu power_L2.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 87710152Satgutier@umich.edu } 87810152Satgutier@umich.edu 87910152Satgutier@umich.edu //Add delay of final inverter that drives the wordline decoders 88010152Satgutier@umich.edu i = number_gates_L2 - 1; 88110152Satgutier@umich.edu c_load = C_ld_predec_blk_out; 88210152Satgutier@umich.edu rd = tr_R_on(w_L2_n[i], NCH, 1, is_dram_); 88310152Satgutier@umich.edu c_intrinsic = drain_C_(w_L2_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 88410152Satgutier@umich.edu drain_C_(w_L2_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 88510152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load) + R_wire_predec_blk_out * c_load / 2; 88610152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 88710152Satgutier@umich.edu delay_nand2_path += this_delay; 88810152Satgutier@umich.edu ret_val.first = this_delay / (1.0 - 0.5); 88910152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 89010152Satgutier@umich.edu delay_nand3_path += this_delay; 89110152Satgutier@umich.edu ret_val.second = this_delay / (1.0 - 0.5); 89210152Satgutier@umich.edu power_L2.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 89310152Satgutier@umich.edu } 89410152Satgutier@umich.edu } 89510152Satgutier@umich.edu 89610152Satgutier@umich.edu delay = (ret_val.first > ret_val.second) ? ret_val.first : ret_val.second; 89710152Satgutier@umich.edu return ret_val; 89810152Satgutier@umich.edu} 89910152Satgutier@umich.edu 90010152Satgutier@umich.eduvoid PredecBlk::leakage_feedback(double temperature) 90110152Satgutier@umich.edu{ 90210152Satgutier@umich.edu if (exist) 90310152Satgutier@umich.edu { // First check whether a predecoder block is needed 90410152Satgutier@umich.edu int num_L1_nand2 = 0; 90510152Satgutier@umich.edu int num_L1_nand3 = 0; 90610152Satgutier@umich.edu int num_L2 = 0; 90710152Satgutier@umich.edu double leak_L1_nand3 =0; 90810152Satgutier@umich.edu double gate_leak_L1_nand3 =0; 90910152Satgutier@umich.edu 91010152Satgutier@umich.edu double leak_L1_nand2 = cmos_Isub_leakage(w_L1_nand2_n[0], w_L1_nand2_p[0], 2, nand, is_dram_); 91110152Satgutier@umich.edu double gate_leak_L1_nand2 = cmos_Ig_leakage(w_L1_nand2_n[0], w_L1_nand2_p[0], 2, nand, is_dram_); 91210152Satgutier@umich.edu if (number_inputs_L1_gate != 3) { 91310152Satgutier@umich.edu leak_L1_nand3 = 0; 91410152Satgutier@umich.edu gate_leak_L1_nand3 =0; 91510152Satgutier@umich.edu } 91610152Satgutier@umich.edu else { 91710152Satgutier@umich.edu leak_L1_nand3 = cmos_Isub_leakage(w_L1_nand3_n[0], w_L1_nand3_p[0], 3, nand); 91810152Satgutier@umich.edu gate_leak_L1_nand3 = cmos_Ig_leakage(w_L1_nand3_n[0], w_L1_nand3_p[0], 3, nand); 91910152Satgutier@umich.edu } 92010152Satgutier@umich.edu 92110152Satgutier@umich.edu switch (number_input_addr_bits) 92210152Satgutier@umich.edu { 92310152Satgutier@umich.edu case 1: //2 NAND2 gates 92410152Satgutier@umich.edu num_L1_nand2 = 2; 92510152Satgutier@umich.edu num_L2 = 0; 92610152Satgutier@umich.edu num_L1_active_nand2_path =1; 92710152Satgutier@umich.edu num_L1_active_nand3_path =0; 92810152Satgutier@umich.edu break; 92910152Satgutier@umich.edu case 2: //4 NAND2 gates 93010152Satgutier@umich.edu num_L1_nand2 = 4; 93110152Satgutier@umich.edu num_L2 = 0; 93210152Satgutier@umich.edu num_L1_active_nand2_path =1; 93310152Satgutier@umich.edu num_L1_active_nand3_path =0; 93410152Satgutier@umich.edu break; 93510152Satgutier@umich.edu case 3: //8 NAND3 gates 93610152Satgutier@umich.edu num_L1_nand3 = 8; 93710152Satgutier@umich.edu num_L2 = 0; 93810152Satgutier@umich.edu num_L1_active_nand2_path =0; 93910152Satgutier@umich.edu num_L1_active_nand3_path =1; 94010152Satgutier@umich.edu break; 94110152Satgutier@umich.edu case 4: //4 + 4 NAND2 gates 94210152Satgutier@umich.edu num_L1_nand2 = 8; 94310152Satgutier@umich.edu num_L2 = 16; 94410152Satgutier@umich.edu num_L1_active_nand2_path =2; 94510152Satgutier@umich.edu num_L1_active_nand3_path =0; 94610152Satgutier@umich.edu break; 94710152Satgutier@umich.edu case 5: //4 NAND2 gates, 8 NAND3 gates 94810152Satgutier@umich.edu num_L1_nand2 = 4; 94910152Satgutier@umich.edu num_L1_nand3 = 8; 95010152Satgutier@umich.edu num_L2 = 32; 95110152Satgutier@umich.edu num_L1_active_nand2_path =1; 95210152Satgutier@umich.edu num_L1_active_nand3_path =1; 95310152Satgutier@umich.edu break; 95410152Satgutier@umich.edu case 6: //8 + 8 NAND3 gates 95510152Satgutier@umich.edu num_L1_nand3 = 16; 95610152Satgutier@umich.edu num_L2 = 64; 95710152Satgutier@umich.edu num_L1_active_nand2_path =0; 95810152Satgutier@umich.edu num_L1_active_nand3_path =2; 95910152Satgutier@umich.edu break; 96010152Satgutier@umich.edu case 7: //4 + 4 NAND2 gates, 8 NAND3 gates 96110152Satgutier@umich.edu num_L1_nand2 = 8; 96210152Satgutier@umich.edu num_L1_nand3 = 8; 96310152Satgutier@umich.edu num_L2 = 128; 96410152Satgutier@umich.edu num_L1_active_nand2_path =2; 96510152Satgutier@umich.edu num_L1_active_nand3_path =1; 96610152Satgutier@umich.edu break; 96710152Satgutier@umich.edu case 8: //4 NAND2 gates, 8 + 8 NAND3 gates 96810152Satgutier@umich.edu num_L1_nand2 = 4; 96910152Satgutier@umich.edu num_L1_nand3 = 16; 97010152Satgutier@umich.edu num_L2 = 256; 97110152Satgutier@umich.edu num_L1_active_nand2_path =2; 97210152Satgutier@umich.edu num_L1_active_nand3_path =2; 97310152Satgutier@umich.edu break; 97410152Satgutier@umich.edu case 9: //8 + 8 + 8 NAND3 gates 97510152Satgutier@umich.edu num_L1_nand3 = 24; 97610152Satgutier@umich.edu num_L2 = 512; 97710152Satgutier@umich.edu num_L1_active_nand2_path =0; 97810152Satgutier@umich.edu num_L1_active_nand3_path =3; 97910152Satgutier@umich.edu break; 98010152Satgutier@umich.edu default: 98110152Satgutier@umich.edu break; 98210152Satgutier@umich.edu } 98310152Satgutier@umich.edu 98410152Satgutier@umich.edu for (int i = 1; i < number_gates_L1_nand2_path; ++i) 98510152Satgutier@umich.edu { 98610152Satgutier@umich.edu leak_L1_nand2 += cmos_Isub_leakage(w_L1_nand2_n[i], w_L1_nand2_p[i], 2, nand, is_dram_); 98710152Satgutier@umich.edu gate_leak_L1_nand2 += cmos_Ig_leakage(w_L1_nand2_n[i], w_L1_nand2_p[i], 2, nand, is_dram_); 98810152Satgutier@umich.edu } 98910152Satgutier@umich.edu leak_L1_nand2 *= num_L1_nand2; 99010152Satgutier@umich.edu gate_leak_L1_nand2 *= num_L1_nand2; 99110152Satgutier@umich.edu 99210152Satgutier@umich.edu for (int i = 1; i < number_gates_L1_nand3_path; ++i) 99310152Satgutier@umich.edu { 99410152Satgutier@umich.edu leak_L1_nand3 += cmos_Isub_leakage(w_L1_nand3_n[i], w_L1_nand3_p[i], 3, nand, is_dram_); 99510152Satgutier@umich.edu gate_leak_L1_nand3 += cmos_Ig_leakage(w_L1_nand3_n[i], w_L1_nand3_p[i], 3, nand, is_dram_); 99610152Satgutier@umich.edu } 99710152Satgutier@umich.edu leak_L1_nand3 *= num_L1_nand3; 99810152Satgutier@umich.edu gate_leak_L1_nand3 *= num_L1_nand3; 99910152Satgutier@umich.edu 100010152Satgutier@umich.edu double leakage_L2 = 0.0; 100110152Satgutier@umich.edu double gate_leakage_L2 = 0.0; 100210152Satgutier@umich.edu 100310152Satgutier@umich.edu if (flag_L2_gate == 2) 100410152Satgutier@umich.edu { 100510152Satgutier@umich.edu leakage_L2 = cmos_Isub_leakage(w_L2_n[0], w_L2_p[0], 2, nand, is_dram_); 100610152Satgutier@umich.edu gate_leakage_L2 = cmos_Ig_leakage(w_L2_n[0], w_L2_p[0], 2, nand, is_dram_); 100710152Satgutier@umich.edu } 100810152Satgutier@umich.edu else if (flag_L2_gate == 3) 100910152Satgutier@umich.edu { 101010152Satgutier@umich.edu leakage_L2 = cmos_Isub_leakage(w_L2_n[0], w_L2_p[0], 3, nand, is_dram_); 101110152Satgutier@umich.edu gate_leakage_L2 = cmos_Ig_leakage(w_L2_n[0], w_L2_p[0], 3, nand, is_dram_); 101210152Satgutier@umich.edu } 101310152Satgutier@umich.edu 101410152Satgutier@umich.edu for (int i = 1; i < number_gates_L2; ++i) 101510152Satgutier@umich.edu { 101610152Satgutier@umich.edu leakage_L2 += cmos_Isub_leakage(w_L2_n[i], w_L2_p[i], 2, inv, is_dram_); 101710152Satgutier@umich.edu gate_leakage_L2 += cmos_Ig_leakage(w_L2_n[i], w_L2_p[i], 2, inv, is_dram_); 101810152Satgutier@umich.edu } 101910152Satgutier@umich.edu leakage_L2 *= num_L2; 102010152Satgutier@umich.edu gate_leakage_L2 *= num_L2; 102110152Satgutier@umich.edu 102210152Satgutier@umich.edu power_nand2_path.readOp.leakage = leak_L1_nand2 * g_tp.peri_global.Vdd; 102310152Satgutier@umich.edu power_nand3_path.readOp.leakage = leak_L1_nand3 * g_tp.peri_global.Vdd; 102410152Satgutier@umich.edu power_L2.readOp.leakage = leakage_L2 * g_tp.peri_global.Vdd; 102510152Satgutier@umich.edu 102610152Satgutier@umich.edu power_nand2_path.readOp.gate_leakage = gate_leak_L1_nand2 * g_tp.peri_global.Vdd; 102710152Satgutier@umich.edu power_nand3_path.readOp.gate_leakage = gate_leak_L1_nand3 * g_tp.peri_global.Vdd; 102810152Satgutier@umich.edu power_L2.readOp.gate_leakage = gate_leakage_L2 * g_tp.peri_global.Vdd; 102910152Satgutier@umich.edu } 103010152Satgutier@umich.edu} 103110152Satgutier@umich.edu 103210152Satgutier@umich.eduPredecBlkDrv::PredecBlkDrv( 103310152Satgutier@umich.edu int way_select_, 103410152Satgutier@umich.edu PredecBlk * blk_, 103510152Satgutier@umich.edu bool is_dram) 103610152Satgutier@umich.edu :flag_driver_exists(0), 103710152Satgutier@umich.edu number_gates_nand2_path(0), 103810152Satgutier@umich.edu number_gates_nand3_path(0), 103910152Satgutier@umich.edu min_number_gates(2), 104010152Satgutier@umich.edu num_buffers_driving_1_nand2_load(0), 104110152Satgutier@umich.edu num_buffers_driving_2_nand2_load(0), 104210152Satgutier@umich.edu num_buffers_driving_4_nand2_load(0), 104310152Satgutier@umich.edu num_buffers_driving_2_nand3_load(0), 104410152Satgutier@umich.edu num_buffers_driving_8_nand3_load(0), 104510152Satgutier@umich.edu num_buffers_nand3_path(0), 104610152Satgutier@umich.edu c_load_nand2_path_out(0), 104710152Satgutier@umich.edu c_load_nand3_path_out(0), 104810152Satgutier@umich.edu r_load_nand2_path_out(0), 104910152Satgutier@umich.edu r_load_nand3_path_out(0), 105010152Satgutier@umich.edu delay_nand2_path(0), 105110152Satgutier@umich.edu delay_nand3_path(0), 105210152Satgutier@umich.edu power_nand2_path(), 105310152Satgutier@umich.edu power_nand3_path(), 105410152Satgutier@umich.edu blk(blk_), dec(blk->dec), 105510152Satgutier@umich.edu is_dram_(is_dram), 105610152Satgutier@umich.edu way_select(way_select_) 105710152Satgutier@umich.edu{ 105810152Satgutier@umich.edu for (int i = 0; i < MAX_NUMBER_GATES_STAGE; i++) 105910152Satgutier@umich.edu { 106010152Satgutier@umich.edu width_nand2_path_n[i] = 0; 106110152Satgutier@umich.edu width_nand2_path_p[i] = 0; 106210152Satgutier@umich.edu width_nand3_path_n[i] = 0; 106310152Satgutier@umich.edu width_nand3_path_p[i] = 0; 106410152Satgutier@umich.edu } 106510152Satgutier@umich.edu 106610152Satgutier@umich.edu number_input_addr_bits = blk->number_input_addr_bits; 106710152Satgutier@umich.edu 106810152Satgutier@umich.edu if (way_select > 1) 106910152Satgutier@umich.edu { 107010152Satgutier@umich.edu flag_driver_exists = 1; 107110152Satgutier@umich.edu number_input_addr_bits = way_select; 107210152Satgutier@umich.edu if (dec->num_in_signals == 2) 107310152Satgutier@umich.edu { 107410152Satgutier@umich.edu c_load_nand2_path_out = gate_C(dec->w_dec_n[0] + dec->w_dec_p[0], 0, is_dram_); 107510152Satgutier@umich.edu num_buffers_driving_2_nand2_load = number_input_addr_bits; 107610152Satgutier@umich.edu } 107710152Satgutier@umich.edu else if (dec->num_in_signals == 3) 107810152Satgutier@umich.edu { 107910152Satgutier@umich.edu c_load_nand3_path_out = gate_C(dec->w_dec_n[0] + dec->w_dec_p[0], 0, is_dram_); 108010152Satgutier@umich.edu num_buffers_driving_2_nand3_load = number_input_addr_bits; 108110152Satgutier@umich.edu } 108210152Satgutier@umich.edu } 108310152Satgutier@umich.edu else if (way_select == 0) 108410152Satgutier@umich.edu { 108510152Satgutier@umich.edu if (blk->exist) 108610152Satgutier@umich.edu { 108710152Satgutier@umich.edu flag_driver_exists = 1; 108810152Satgutier@umich.edu } 108910152Satgutier@umich.edu } 109010152Satgutier@umich.edu 109110152Satgutier@umich.edu compute_widths(); 109210152Satgutier@umich.edu compute_area(); 109310152Satgutier@umich.edu} 109410152Satgutier@umich.edu 109510152Satgutier@umich.edu 109610152Satgutier@umich.edu 109710152Satgutier@umich.eduvoid PredecBlkDrv::compute_widths() 109810152Satgutier@umich.edu{ 109910152Satgutier@umich.edu // The predecode block driver accepts as input the address bits from the h-tree network. For 110010152Satgutier@umich.edu // each addr bit it then generates addr and addrbar as outputs. For now ignore the effect of 110110152Satgutier@umich.edu // inversion to generate addrbar and simply treat addrbar as addr. 110210152Satgutier@umich.edu 110310152Satgutier@umich.edu double F; 110410152Satgutier@umich.edu double p_to_n_sz_ratio = pmos_to_nmos_sz_ratio(is_dram_); 110510152Satgutier@umich.edu 110610152Satgutier@umich.edu if (flag_driver_exists) 110710152Satgutier@umich.edu { 110810152Satgutier@umich.edu double C_nand2_gate_blk = gate_C(blk->w_L1_nand2_n[0] + blk->w_L1_nand2_p[0], 0, is_dram_); 110910152Satgutier@umich.edu double C_nand3_gate_blk = gate_C(blk->w_L1_nand3_n[0] + blk->w_L1_nand3_p[0], 0, is_dram_); 111010152Satgutier@umich.edu 111110152Satgutier@umich.edu if (way_select == 0) 111210152Satgutier@umich.edu { 111310152Satgutier@umich.edu if (blk->number_input_addr_bits == 1) 111410152Satgutier@umich.edu { //2 NAND2 gates 111510152Satgutier@umich.edu num_buffers_driving_2_nand2_load = 1; 111610152Satgutier@umich.edu c_load_nand2_path_out = 2 * C_nand2_gate_blk; 111710152Satgutier@umich.edu } 111810152Satgutier@umich.edu else if (blk->number_input_addr_bits == 2) 111910152Satgutier@umich.edu { //4 NAND2 gates one 2-4 decoder 112010152Satgutier@umich.edu num_buffers_driving_4_nand2_load = 2; 112110152Satgutier@umich.edu c_load_nand2_path_out = 4 * C_nand2_gate_blk; 112210152Satgutier@umich.edu } 112310152Satgutier@umich.edu else if (blk->number_input_addr_bits == 3) 112410152Satgutier@umich.edu { //8 NAND3 gates one 3-8 decoder 112510152Satgutier@umich.edu num_buffers_driving_8_nand3_load = 3; 112610152Satgutier@umich.edu c_load_nand3_path_out = 8 * C_nand3_gate_blk; 112710152Satgutier@umich.edu } 112810152Satgutier@umich.edu else if (blk->number_input_addr_bits == 4) 112910152Satgutier@umich.edu { //4 + 4 NAND2 gates two 2-4 decoder 113010152Satgutier@umich.edu num_buffers_driving_4_nand2_load = 4; 113110152Satgutier@umich.edu c_load_nand2_path_out = 4 * C_nand2_gate_blk; 113210152Satgutier@umich.edu } 113310152Satgutier@umich.edu else if (blk->number_input_addr_bits == 5) 113410152Satgutier@umich.edu { //4 NAND2 gates, 8 NAND3 gates one 2-4 decoder and one 3-8 decoder 113510152Satgutier@umich.edu num_buffers_driving_4_nand2_load = 2; 113610152Satgutier@umich.edu num_buffers_driving_8_nand3_load = 3; 113710152Satgutier@umich.edu c_load_nand2_path_out = 4 * C_nand2_gate_blk; 113810152Satgutier@umich.edu c_load_nand3_path_out = 8 * C_nand3_gate_blk; 113910152Satgutier@umich.edu } 114010152Satgutier@umich.edu else if (blk->number_input_addr_bits == 6) 114110152Satgutier@umich.edu { //8 + 8 NAND3 gates two 3-8 decoder 114210152Satgutier@umich.edu num_buffers_driving_8_nand3_load = 6; 114310152Satgutier@umich.edu c_load_nand3_path_out = 8 * C_nand3_gate_blk; 114410152Satgutier@umich.edu } 114510152Satgutier@umich.edu else if (blk->number_input_addr_bits == 7) 114610152Satgutier@umich.edu { //4 + 4 NAND2 gates, 8 NAND3 gates two 2-4 decoder and one 3-8 decoder 114710152Satgutier@umich.edu num_buffers_driving_4_nand2_load = 4; 114810152Satgutier@umich.edu num_buffers_driving_8_nand3_load = 3; 114910152Satgutier@umich.edu c_load_nand2_path_out = 4 * C_nand2_gate_blk; 115010152Satgutier@umich.edu c_load_nand3_path_out = 8 * C_nand3_gate_blk; 115110152Satgutier@umich.edu } 115210152Satgutier@umich.edu else if (blk->number_input_addr_bits == 8) 115310152Satgutier@umich.edu { //4 NAND2 gates, 8 + 8 NAND3 gates one 2-4 decoder and two 3-8 decoder 115410152Satgutier@umich.edu num_buffers_driving_4_nand2_load = 2; 115510152Satgutier@umich.edu num_buffers_driving_8_nand3_load = 6; 115610152Satgutier@umich.edu c_load_nand2_path_out = 4 * C_nand2_gate_blk; 115710152Satgutier@umich.edu c_load_nand3_path_out = 8 * C_nand3_gate_blk; 115810152Satgutier@umich.edu } 115910152Satgutier@umich.edu else if (blk->number_input_addr_bits == 9) 116010152Satgutier@umich.edu { //8 + 8 + 8 NAND3 gates three 3-8 decoder 116110152Satgutier@umich.edu num_buffers_driving_8_nand3_load = 9; 116210152Satgutier@umich.edu c_load_nand3_path_out = 8 * C_nand3_gate_blk; 116310152Satgutier@umich.edu } 116410152Satgutier@umich.edu } 116510152Satgutier@umich.edu 116610152Satgutier@umich.edu if ((blk->flag_two_unique_paths) || 116710152Satgutier@umich.edu (blk->number_inputs_L1_gate == 2) || 116810152Satgutier@umich.edu (number_input_addr_bits == 0) || 116910152Satgutier@umich.edu ((way_select)&&(dec->num_in_signals == 2))) 117010152Satgutier@umich.edu { //this means that way_select is driving NAND2 in decoder. 117110152Satgutier@umich.edu width_nand2_path_n[0] = g_tp.min_w_nmos_; 117210152Satgutier@umich.edu width_nand2_path_p[0] = p_to_n_sz_ratio * width_nand2_path_n[0]; 117310152Satgutier@umich.edu F = c_load_nand2_path_out / gate_C(width_nand2_path_n[0] + width_nand2_path_p[0], 0, is_dram_); 117410152Satgutier@umich.edu number_gates_nand2_path = logical_effort( 117510152Satgutier@umich.edu min_number_gates, 117610152Satgutier@umich.edu 1, 117710152Satgutier@umich.edu F, 117810152Satgutier@umich.edu width_nand2_path_n, 117910152Satgutier@umich.edu width_nand2_path_p, 118010152Satgutier@umich.edu c_load_nand2_path_out, 118110152Satgutier@umich.edu p_to_n_sz_ratio, 118210152Satgutier@umich.edu is_dram_, false, g_tp.max_w_nmos_); 118310152Satgutier@umich.edu } 118410152Satgutier@umich.edu 118510152Satgutier@umich.edu if ((blk->flag_two_unique_paths) || 118610152Satgutier@umich.edu (blk->number_inputs_L1_gate == 3) || 118710152Satgutier@umich.edu ((way_select)&&(dec->num_in_signals == 3))) 118810152Satgutier@umich.edu { //this means that way_select is driving NAND3 in decoder. 118910152Satgutier@umich.edu width_nand3_path_n[0] = g_tp.min_w_nmos_; 119010152Satgutier@umich.edu width_nand3_path_p[0] = p_to_n_sz_ratio * width_nand3_path_n[0]; 119110152Satgutier@umich.edu F = c_load_nand3_path_out / gate_C(width_nand3_path_n[0] + width_nand3_path_p[0], 0, is_dram_); 119210152Satgutier@umich.edu number_gates_nand3_path = logical_effort( 119310152Satgutier@umich.edu min_number_gates, 119410152Satgutier@umich.edu 1, 119510152Satgutier@umich.edu F, 119610152Satgutier@umich.edu width_nand3_path_n, 119710152Satgutier@umich.edu width_nand3_path_p, 119810152Satgutier@umich.edu c_load_nand3_path_out, 119910152Satgutier@umich.edu p_to_n_sz_ratio, 120010152Satgutier@umich.edu is_dram_, false, g_tp.max_w_nmos_); 120110152Satgutier@umich.edu } 120210152Satgutier@umich.edu } 120310152Satgutier@umich.edu} 120410152Satgutier@umich.edu 120510152Satgutier@umich.edu 120610152Satgutier@umich.edu 120710152Satgutier@umich.eduvoid PredecBlkDrv::compute_area() 120810152Satgutier@umich.edu{ 120910152Satgutier@umich.edu double area_nand2_path = 0; 121010152Satgutier@umich.edu double area_nand3_path = 0; 121110152Satgutier@umich.edu double leak_nand2_path = 0; 121210152Satgutier@umich.edu double leak_nand3_path = 0; 121310152Satgutier@umich.edu double gate_leak_nand2_path = 0; 121410152Satgutier@umich.edu double gate_leak_nand3_path = 0; 121510152Satgutier@umich.edu 121610152Satgutier@umich.edu if (flag_driver_exists) 121710152Satgutier@umich.edu { // first check whether a predecoder block driver is needed 121810152Satgutier@umich.edu for (int i = 0; i < number_gates_nand2_path; ++i) 121910152Satgutier@umich.edu { 122010152Satgutier@umich.edu area_nand2_path += compute_gate_area(INV, 1, width_nand2_path_p[i], width_nand2_path_n[i], g_tp.cell_h_def); 122110152Satgutier@umich.edu leak_nand2_path += cmos_Isub_leakage(width_nand2_path_n[i], width_nand2_path_p[i], 1, inv,is_dram_); 122210152Satgutier@umich.edu gate_leak_nand2_path += cmos_Ig_leakage(width_nand2_path_n[i], width_nand2_path_p[i], 1, inv,is_dram_); 122310152Satgutier@umich.edu } 122410152Satgutier@umich.edu area_nand2_path *= (num_buffers_driving_1_nand2_load + 122510152Satgutier@umich.edu num_buffers_driving_2_nand2_load + 122610152Satgutier@umich.edu num_buffers_driving_4_nand2_load); 122710152Satgutier@umich.edu leak_nand2_path *= (num_buffers_driving_1_nand2_load + 122810152Satgutier@umich.edu num_buffers_driving_2_nand2_load + 122910152Satgutier@umich.edu num_buffers_driving_4_nand2_load); 123010152Satgutier@umich.edu gate_leak_nand2_path *= (num_buffers_driving_1_nand2_load + 123110152Satgutier@umich.edu num_buffers_driving_2_nand2_load + 123210152Satgutier@umich.edu num_buffers_driving_4_nand2_load); 123310152Satgutier@umich.edu 123410152Satgutier@umich.edu for (int i = 0; i < number_gates_nand3_path; ++i) 123510152Satgutier@umich.edu { 123610152Satgutier@umich.edu area_nand3_path += compute_gate_area(INV, 1, width_nand3_path_p[i], width_nand3_path_n[i], g_tp.cell_h_def); 123710152Satgutier@umich.edu leak_nand3_path += cmos_Isub_leakage(width_nand3_path_n[i], width_nand3_path_p[i], 1, inv,is_dram_); 123810152Satgutier@umich.edu gate_leak_nand3_path += cmos_Ig_leakage(width_nand3_path_n[i], width_nand3_path_p[i], 1, inv,is_dram_); 123910152Satgutier@umich.edu } 124010152Satgutier@umich.edu area_nand3_path *= (num_buffers_driving_2_nand3_load + num_buffers_driving_8_nand3_load); 124110152Satgutier@umich.edu leak_nand3_path *= (num_buffers_driving_2_nand3_load + num_buffers_driving_8_nand3_load); 124210152Satgutier@umich.edu gate_leak_nand3_path *= (num_buffers_driving_2_nand3_load + num_buffers_driving_8_nand3_load); 124310152Satgutier@umich.edu 124410152Satgutier@umich.edu power_nand2_path.readOp.leakage = leak_nand2_path * g_tp.peri_global.Vdd; 124510152Satgutier@umich.edu power_nand3_path.readOp.leakage = leak_nand3_path * g_tp.peri_global.Vdd; 124610152Satgutier@umich.edu power_nand2_path.readOp.gate_leakage = gate_leak_nand2_path * g_tp.peri_global.Vdd; 124710152Satgutier@umich.edu power_nand3_path.readOp.gate_leakage = gate_leak_nand3_path * g_tp.peri_global.Vdd; 124810152Satgutier@umich.edu area.set_area(area_nand2_path + area_nand3_path); 124910152Satgutier@umich.edu } 125010152Satgutier@umich.edu} 125110152Satgutier@umich.edu 125210152Satgutier@umich.edu 125310152Satgutier@umich.edu 125410152Satgutier@umich.edupair<double, double> PredecBlkDrv::compute_delays( 125510152Satgutier@umich.edu double inrisetime_nand2_path, 125610152Satgutier@umich.edu double inrisetime_nand3_path) 125710152Satgutier@umich.edu{ 125810152Satgutier@umich.edu pair<double, double> ret_val; 125910152Satgutier@umich.edu ret_val.first = 0; // outrisetime_nand2_path 126010152Satgutier@umich.edu ret_val.second = 0; // outrisetime_nand3_path 126110152Satgutier@umich.edu int i; 126210152Satgutier@umich.edu double rd, c_gate_load, c_load, c_intrinsic, tf, this_delay; 126310152Satgutier@umich.edu double Vdd = g_tp.peri_global.Vdd; 126410152Satgutier@umich.edu 126510152Satgutier@umich.edu if (flag_driver_exists) 126610152Satgutier@umich.edu { 126710152Satgutier@umich.edu for (i = 0; i < number_gates_nand2_path - 1; ++i) 126810152Satgutier@umich.edu { 126910152Satgutier@umich.edu rd = tr_R_on(width_nand2_path_n[i], NCH, 1, is_dram_); 127010152Satgutier@umich.edu c_gate_load = gate_C(width_nand2_path_p[i+1] + width_nand2_path_n[i+1], 0.0, is_dram_); 127110152Satgutier@umich.edu c_intrinsic = drain_C_(width_nand2_path_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 127210152Satgutier@umich.edu drain_C_(width_nand2_path_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 127310152Satgutier@umich.edu tf = rd * (c_intrinsic + c_gate_load); 127410152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 127510152Satgutier@umich.edu delay_nand2_path += this_delay; 127610152Satgutier@umich.edu inrisetime_nand2_path = this_delay / (1.0 - 0.5); 127710152Satgutier@umich.edu power_nand2_path.readOp.dynamic += (c_gate_load + c_intrinsic) * 0.5 * Vdd * Vdd; 127810152Satgutier@umich.edu } 127910152Satgutier@umich.edu 128010152Satgutier@umich.edu // Final inverter drives the predecoder block or the decoder output load 128110152Satgutier@umich.edu if (number_gates_nand2_path != 0) 128210152Satgutier@umich.edu { 128310152Satgutier@umich.edu i = number_gates_nand2_path - 1; 128410152Satgutier@umich.edu rd = tr_R_on(width_nand2_path_n[i], NCH, 1, is_dram_); 128510152Satgutier@umich.edu c_intrinsic = drain_C_(width_nand2_path_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 128610152Satgutier@umich.edu drain_C_(width_nand2_path_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 128710152Satgutier@umich.edu c_load = c_load_nand2_path_out; 128810152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load) + r_load_nand2_path_out*c_load/ 2; 128910152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 129010152Satgutier@umich.edu delay_nand2_path += this_delay; 129110152Satgutier@umich.edu ret_val.first = this_delay / (1.0 - 0.5); 129210152Satgutier@umich.edu power_nand2_path.readOp.dynamic += (c_intrinsic + c_load) * 0.5 * Vdd * Vdd; 129310152Satgutier@umich.edu// cout<< "c_intrinsic = " << c_intrinsic << "c_load" << c_load <<endl; 129410152Satgutier@umich.edu } 129510152Satgutier@umich.edu 129610152Satgutier@umich.edu for (i = 0; i < number_gates_nand3_path - 1; ++i) 129710152Satgutier@umich.edu { 129810152Satgutier@umich.edu rd = tr_R_on(width_nand3_path_n[i], NCH, 1, is_dram_); 129910152Satgutier@umich.edu c_gate_load = gate_C(width_nand3_path_p[i+1] + width_nand3_path_n[i+1], 0.0, is_dram_); 130010152Satgutier@umich.edu c_intrinsic = drain_C_(width_nand3_path_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 130110152Satgutier@umich.edu drain_C_(width_nand3_path_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 130210152Satgutier@umich.edu tf = rd * (c_intrinsic + c_gate_load); 130310152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 130410152Satgutier@umich.edu delay_nand3_path += this_delay; 130510152Satgutier@umich.edu inrisetime_nand3_path = this_delay / (1.0 - 0.5); 130610152Satgutier@umich.edu power_nand3_path.readOp.dynamic += (c_gate_load + c_intrinsic) * 0.5 * Vdd * Vdd; 130710152Satgutier@umich.edu } 130810152Satgutier@umich.edu 130910152Satgutier@umich.edu // Final inverter drives the predecoder block or the decoder output load 131010152Satgutier@umich.edu if (number_gates_nand3_path != 0) 131110152Satgutier@umich.edu { 131210152Satgutier@umich.edu i = number_gates_nand3_path - 1; 131310152Satgutier@umich.edu rd = tr_R_on(width_nand3_path_n[i], NCH, 1, is_dram_); 131410152Satgutier@umich.edu c_intrinsic = drain_C_(width_nand3_path_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 131510152Satgutier@umich.edu drain_C_(width_nand3_path_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 131610152Satgutier@umich.edu c_load = c_load_nand3_path_out; 131710152Satgutier@umich.edu tf = rd*(c_intrinsic + c_load) + r_load_nand3_path_out*c_load / 2; 131810152Satgutier@umich.edu this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 131910152Satgutier@umich.edu delay_nand3_path += this_delay; 132010152Satgutier@umich.edu ret_val.second = this_delay / (1.0 - 0.5); 132110152Satgutier@umich.edu power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * 0.5 * Vdd * Vdd; 132210152Satgutier@umich.edu } 132310152Satgutier@umich.edu } 132410152Satgutier@umich.edu return ret_val; 132510152Satgutier@umich.edu} 132610152Satgutier@umich.edu 132710152Satgutier@umich.edu 132810152Satgutier@umich.edudouble PredecBlkDrv::get_rdOp_dynamic_E(int num_act_mats_hor_dir) 132910152Satgutier@umich.edu{ 133010152Satgutier@umich.edu return (num_addr_bits_nand2_path()*power_nand2_path.readOp.dynamic + 133110152Satgutier@umich.edu num_addr_bits_nand3_path()*power_nand3_path.readOp.dynamic) * num_act_mats_hor_dir; 133210152Satgutier@umich.edu} 133310152Satgutier@umich.edu 133410152Satgutier@umich.edu 133510152Satgutier@umich.edu 133610152Satgutier@umich.eduPredec::Predec( 133710152Satgutier@umich.edu PredecBlkDrv * drv1_, 133810152Satgutier@umich.edu PredecBlkDrv * drv2_) 133910152Satgutier@umich.edu:blk1(drv1_->blk), blk2(drv2_->blk), drv1(drv1_), drv2(drv2_) 134010152Satgutier@umich.edu{ 134110152Satgutier@umich.edu driver_power.readOp.leakage = drv1->power_nand2_path.readOp.leakage + 134210152Satgutier@umich.edu drv1->power_nand3_path.readOp.leakage + 134310152Satgutier@umich.edu drv2->power_nand2_path.readOp.leakage + 134410152Satgutier@umich.edu drv2->power_nand3_path.readOp.leakage; 134510152Satgutier@umich.edu block_power.readOp.leakage = blk1->power_nand2_path.readOp.leakage + 134610152Satgutier@umich.edu blk1->power_nand3_path.readOp.leakage + 134710152Satgutier@umich.edu blk1->power_L2.readOp.leakage + 134810152Satgutier@umich.edu blk2->power_nand2_path.readOp.leakage + 134910152Satgutier@umich.edu blk2->power_nand3_path.readOp.leakage + 135010152Satgutier@umich.edu blk2->power_L2.readOp.leakage; 135110152Satgutier@umich.edu power.readOp.leakage = driver_power.readOp.leakage + block_power.readOp.leakage; 135210152Satgutier@umich.edu 135310152Satgutier@umich.edu driver_power.readOp.gate_leakage = drv1->power_nand2_path.readOp.gate_leakage + 135410152Satgutier@umich.edu drv1->power_nand3_path.readOp.gate_leakage + 135510152Satgutier@umich.edu drv2->power_nand2_path.readOp.gate_leakage + 135610152Satgutier@umich.edu drv2->power_nand3_path.readOp.gate_leakage; 135710152Satgutier@umich.edu block_power.readOp.gate_leakage = blk1->power_nand2_path.readOp.gate_leakage + 135810152Satgutier@umich.edu blk1->power_nand3_path.readOp.gate_leakage + 135910152Satgutier@umich.edu blk1->power_L2.readOp.gate_leakage + 136010152Satgutier@umich.edu blk2->power_nand2_path.readOp.gate_leakage + 136110152Satgutier@umich.edu blk2->power_nand3_path.readOp.gate_leakage + 136210152Satgutier@umich.edu blk2->power_L2.readOp.gate_leakage; 136310152Satgutier@umich.edu power.readOp.gate_leakage = driver_power.readOp.gate_leakage + block_power.readOp.gate_leakage; 136410152Satgutier@umich.edu} 136510152Satgutier@umich.edu 136610152Satgutier@umich.eduvoid PredecBlkDrv::leakage_feedback(double temperature) 136710152Satgutier@umich.edu{ 136810152Satgutier@umich.edu double leak_nand2_path = 0; 136910152Satgutier@umich.edu double leak_nand3_path = 0; 137010152Satgutier@umich.edu double gate_leak_nand2_path = 0; 137110152Satgutier@umich.edu double gate_leak_nand3_path = 0; 137210152Satgutier@umich.edu 137310152Satgutier@umich.edu if (flag_driver_exists) 137410152Satgutier@umich.edu { // first check whether a predecoder block driver is needed 137510152Satgutier@umich.edu for (int i = 0; i < number_gates_nand2_path; ++i) 137610152Satgutier@umich.edu { 137710152Satgutier@umich.edu leak_nand2_path += cmos_Isub_leakage(width_nand2_path_n[i], width_nand2_path_p[i], 1, inv,is_dram_); 137810152Satgutier@umich.edu gate_leak_nand2_path += cmos_Ig_leakage(width_nand2_path_n[i], width_nand2_path_p[i], 1, inv,is_dram_); 137910152Satgutier@umich.edu } 138010152Satgutier@umich.edu leak_nand2_path *= (num_buffers_driving_1_nand2_load + 138110152Satgutier@umich.edu num_buffers_driving_2_nand2_load + 138210152Satgutier@umich.edu num_buffers_driving_4_nand2_load); 138310152Satgutier@umich.edu gate_leak_nand2_path *= (num_buffers_driving_1_nand2_load + 138410152Satgutier@umich.edu num_buffers_driving_2_nand2_load + 138510152Satgutier@umich.edu num_buffers_driving_4_nand2_load); 138610152Satgutier@umich.edu 138710152Satgutier@umich.edu for (int i = 0; i < number_gates_nand3_path; ++i) 138810152Satgutier@umich.edu { 138910152Satgutier@umich.edu leak_nand3_path += cmos_Isub_leakage(width_nand3_path_n[i], width_nand3_path_p[i], 1, inv,is_dram_); 139010152Satgutier@umich.edu gate_leak_nand3_path += cmos_Ig_leakage(width_nand3_path_n[i], width_nand3_path_p[i], 1, inv,is_dram_); 139110152Satgutier@umich.edu } 139210152Satgutier@umich.edu leak_nand3_path *= (num_buffers_driving_2_nand3_load + num_buffers_driving_8_nand3_load); 139310152Satgutier@umich.edu gate_leak_nand3_path *= (num_buffers_driving_2_nand3_load + num_buffers_driving_8_nand3_load); 139410152Satgutier@umich.edu 139510152Satgutier@umich.edu power_nand2_path.readOp.leakage = leak_nand2_path * g_tp.peri_global.Vdd; 139610152Satgutier@umich.edu power_nand3_path.readOp.leakage = leak_nand3_path * g_tp.peri_global.Vdd; 139710152Satgutier@umich.edu power_nand2_path.readOp.gate_leakage = gate_leak_nand2_path * g_tp.peri_global.Vdd; 139810152Satgutier@umich.edu power_nand3_path.readOp.gate_leakage = gate_leak_nand3_path * g_tp.peri_global.Vdd; 139910152Satgutier@umich.edu } 140010152Satgutier@umich.edu} 140110152Satgutier@umich.edu 140210152Satgutier@umich.edudouble Predec::compute_delays(double inrisetime) 140310152Satgutier@umich.edu{ 140410152Satgutier@umich.edu // TODO: Jung Ho thinks that predecoder block driver locates between decoder and predecoder block. 140510152Satgutier@umich.edu pair<double, double> tmp_pair1, tmp_pair2; 140610152Satgutier@umich.edu tmp_pair1 = drv1->compute_delays(inrisetime, inrisetime); 140710152Satgutier@umich.edu tmp_pair1 = blk1->compute_delays(tmp_pair1); 140810152Satgutier@umich.edu tmp_pair2 = drv2->compute_delays(inrisetime, inrisetime); 140910152Satgutier@umich.edu tmp_pair2 = blk2->compute_delays(tmp_pair2); 141010152Satgutier@umich.edu tmp_pair1 = get_max_delay_before_decoder(tmp_pair1, tmp_pair2); 141110152Satgutier@umich.edu 141210152Satgutier@umich.edu driver_power.readOp.dynamic = 141310152Satgutier@umich.edu drv1->num_addr_bits_nand2_path() * drv1->power_nand2_path.readOp.dynamic + 141410152Satgutier@umich.edu drv1->num_addr_bits_nand3_path() * drv1->power_nand3_path.readOp.dynamic + 141510152Satgutier@umich.edu drv2->num_addr_bits_nand2_path() * drv2->power_nand2_path.readOp.dynamic + 141610152Satgutier@umich.edu drv2->num_addr_bits_nand3_path() * drv2->power_nand3_path.readOp.dynamic; 141710152Satgutier@umich.edu 141810152Satgutier@umich.edu block_power.readOp.dynamic = 141910152Satgutier@umich.edu blk1->power_nand2_path.readOp.dynamic*blk1->num_L1_active_nand2_path + 142010152Satgutier@umich.edu blk1->power_nand3_path.readOp.dynamic*blk1->num_L1_active_nand3_path + 142110152Satgutier@umich.edu blk1->power_L2.readOp.dynamic + 142210152Satgutier@umich.edu blk2->power_nand2_path.readOp.dynamic*blk1->num_L1_active_nand2_path + 142310152Satgutier@umich.edu blk2->power_nand3_path.readOp.dynamic*blk1->num_L1_active_nand3_path + 142410152Satgutier@umich.edu blk2->power_L2.readOp.dynamic; 142510152Satgutier@umich.edu 142610152Satgutier@umich.edu power.readOp.dynamic = driver_power.readOp.dynamic + block_power.readOp.dynamic; 142710152Satgutier@umich.edu 142810152Satgutier@umich.edu delay = tmp_pair1.first; 142910152Satgutier@umich.edu return tmp_pair1.second; 143010152Satgutier@umich.edu} 143110152Satgutier@umich.edu 143210152Satgutier@umich.edu 143310152Satgutier@umich.eduvoid Predec::leakage_feedback(double temperature) 143410152Satgutier@umich.edu{ 143510152Satgutier@umich.edu drv1->leakage_feedback(temperature); 143610152Satgutier@umich.edu drv2->leakage_feedback(temperature); 143710152Satgutier@umich.edu blk1->leakage_feedback(temperature); 143810152Satgutier@umich.edu blk2->leakage_feedback(temperature); 143910152Satgutier@umich.edu 144010152Satgutier@umich.edu driver_power.readOp.leakage = drv1->power_nand2_path.readOp.leakage + 144110152Satgutier@umich.edu drv1->power_nand3_path.readOp.leakage + 144210152Satgutier@umich.edu drv2->power_nand2_path.readOp.leakage + 144310152Satgutier@umich.edu drv2->power_nand3_path.readOp.leakage; 144410152Satgutier@umich.edu block_power.readOp.leakage = blk1->power_nand2_path.readOp.leakage + 144510152Satgutier@umich.edu blk1->power_nand3_path.readOp.leakage + 144610152Satgutier@umich.edu blk1->power_L2.readOp.leakage + 144710152Satgutier@umich.edu blk2->power_nand2_path.readOp.leakage + 144810152Satgutier@umich.edu blk2->power_nand3_path.readOp.leakage + 144910152Satgutier@umich.edu blk2->power_L2.readOp.leakage; 145010152Satgutier@umich.edu power.readOp.leakage = driver_power.readOp.leakage + block_power.readOp.leakage; 145110152Satgutier@umich.edu 145210152Satgutier@umich.edu driver_power.readOp.gate_leakage = drv1->power_nand2_path.readOp.gate_leakage + 145310152Satgutier@umich.edu drv1->power_nand3_path.readOp.gate_leakage + 145410152Satgutier@umich.edu drv2->power_nand2_path.readOp.gate_leakage + 145510152Satgutier@umich.edu drv2->power_nand3_path.readOp.gate_leakage; 145610152Satgutier@umich.edu block_power.readOp.gate_leakage = blk1->power_nand2_path.readOp.gate_leakage + 145710152Satgutier@umich.edu blk1->power_nand3_path.readOp.gate_leakage + 145810152Satgutier@umich.edu blk1->power_L2.readOp.gate_leakage + 145910152Satgutier@umich.edu blk2->power_nand2_path.readOp.gate_leakage + 146010152Satgutier@umich.edu blk2->power_nand3_path.readOp.gate_leakage + 146110152Satgutier@umich.edu blk2->power_L2.readOp.gate_leakage; 146210152Satgutier@umich.edu power.readOp.gate_leakage = driver_power.readOp.gate_leakage + block_power.readOp.gate_leakage; 146310152Satgutier@umich.edu} 146410152Satgutier@umich.edu 146510152Satgutier@umich.edu// returns <delay, risetime> 146610152Satgutier@umich.edupair<double, double> Predec::get_max_delay_before_decoder( 146710152Satgutier@umich.edu pair<double, double> input_pair1, 146810152Satgutier@umich.edu pair<double, double> input_pair2) 146910152Satgutier@umich.edu{ 147010152Satgutier@umich.edu pair<double, double> ret_val; 147110152Satgutier@umich.edu double delay; 147210152Satgutier@umich.edu 147310152Satgutier@umich.edu delay = drv1->delay_nand2_path + blk1->delay_nand2_path; 147410152Satgutier@umich.edu ret_val.first = delay; 147510152Satgutier@umich.edu ret_val.second = input_pair1.first; 147610152Satgutier@umich.edu delay = drv1->delay_nand3_path + blk1->delay_nand3_path; 147710152Satgutier@umich.edu if (ret_val.first < delay) 147810152Satgutier@umich.edu { 147910152Satgutier@umich.edu ret_val.first = delay; 148010152Satgutier@umich.edu ret_val.second = input_pair1.second; 148110152Satgutier@umich.edu } 148210152Satgutier@umich.edu delay = drv2->delay_nand2_path + blk2->delay_nand2_path; 148310152Satgutier@umich.edu if (ret_val.first < delay) 148410152Satgutier@umich.edu { 148510152Satgutier@umich.edu ret_val.first = delay; 148610152Satgutier@umich.edu ret_val.second = input_pair2.first; 148710152Satgutier@umich.edu } 148810152Satgutier@umich.edu delay = drv2->delay_nand3_path + blk2->delay_nand3_path; 148910152Satgutier@umich.edu if (ret_val.first < delay) 149010152Satgutier@umich.edu { 149110152Satgutier@umich.edu ret_val.first = delay; 149210152Satgutier@umich.edu ret_val.second = input_pair2.second; 149310152Satgutier@umich.edu } 149410152Satgutier@umich.edu 149510152Satgutier@umich.edu return ret_val; 149610152Satgutier@umich.edu} 149710152Satgutier@umich.edu 149810152Satgutier@umich.edu 149910152Satgutier@umich.edu 150010152Satgutier@umich.eduDriver::Driver(double c_gate_load_, double c_wire_load_, double r_wire_load_, bool is_dram) 150110152Satgutier@umich.edu:number_gates(0), 150210152Satgutier@umich.edu min_number_gates(2), 150310152Satgutier@umich.edu c_gate_load(c_gate_load_), 150410152Satgutier@umich.edu c_wire_load(c_wire_load_), 150510152Satgutier@umich.edu r_wire_load(r_wire_load_), 150610152Satgutier@umich.edu delay(0), 150710152Satgutier@umich.edu power(), 150810152Satgutier@umich.edu is_dram_(is_dram) 150910152Satgutier@umich.edu{ 151010152Satgutier@umich.edu for (int i = 0; i < MAX_NUMBER_GATES_STAGE; i++) 151110152Satgutier@umich.edu { 151210152Satgutier@umich.edu width_n[i] = 0; 151310152Satgutier@umich.edu width_p[i] = 0; 151410152Satgutier@umich.edu } 151510152Satgutier@umich.edu 151610152Satgutier@umich.edu compute_widths(); 151710152Satgutier@umich.edu} 151810152Satgutier@umich.edu 151910152Satgutier@umich.edu 152010152Satgutier@umich.eduvoid Driver::compute_widths() 152110152Satgutier@umich.edu{ 152210152Satgutier@umich.edu double p_to_n_sz_ratio = pmos_to_nmos_sz_ratio(is_dram_); 152310152Satgutier@umich.edu double c_load = c_gate_load + c_wire_load; 152410152Satgutier@umich.edu width_n[0] = g_tp.min_w_nmos_; 152510152Satgutier@umich.edu width_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 152610152Satgutier@umich.edu 152710152Satgutier@umich.edu double F = c_load / gate_C(width_n[0] + width_p[0], 0, is_dram_); 152810152Satgutier@umich.edu number_gates = logical_effort( 152910152Satgutier@umich.edu min_number_gates, 153010152Satgutier@umich.edu 1, 153110152Satgutier@umich.edu F, 153210152Satgutier@umich.edu width_n, 153310152Satgutier@umich.edu width_p, 153410152Satgutier@umich.edu c_load, 153510152Satgutier@umich.edu p_to_n_sz_ratio, 153610152Satgutier@umich.edu is_dram_, false, 153710152Satgutier@umich.edu g_tp.max_w_nmos_); 153810152Satgutier@umich.edu} 153910152Satgutier@umich.edu 154010152Satgutier@umich.edu 154110152Satgutier@umich.edu 154210152Satgutier@umich.edudouble Driver::compute_delay(double inrisetime) 154310152Satgutier@umich.edu{ 154410152Satgutier@umich.edu int i; 154510152Satgutier@umich.edu double rd, c_load, c_intrinsic, tf; 154610152Satgutier@umich.edu double this_delay = 0; 154710152Satgutier@umich.edu 154810152Satgutier@umich.edu for (i = 0; i < number_gates - 1; ++i) 154910152Satgutier@umich.edu { 155010152Satgutier@umich.edu rd = tr_R_on(width_n[i], NCH, 1, is_dram_); 155110152Satgutier@umich.edu c_load = gate_C(width_n[i+1] + width_p[i+1], 0.0, is_dram_); 155210152Satgutier@umich.edu c_intrinsic = drain_C_(width_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 155310152Satgutier@umich.edu drain_C_(width_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 155410152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load); 155510152Satgutier@umich.edu this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE); 155610152Satgutier@umich.edu delay += this_delay; 155710152Satgutier@umich.edu inrisetime = this_delay / (1.0 - 0.5); 155810152Satgutier@umich.edu power.readOp.dynamic += (c_intrinsic + c_load) * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd; 155910152Satgutier@umich.edu power.readOp.leakage += cmos_Isub_leakage(width_n[i], width_p[i], 1, inv, is_dram_) *g_tp.peri_global.Vdd; 156010152Satgutier@umich.edu power.readOp.gate_leakage += cmos_Ig_leakage(width_n[i], width_p[i], 1, inv, is_dram_)* g_tp.peri_global.Vdd; 156110152Satgutier@umich.edu } 156210152Satgutier@umich.edu 156310152Satgutier@umich.edu i = number_gates - 1; 156410152Satgutier@umich.edu c_load = c_gate_load + c_wire_load; 156510152Satgutier@umich.edu rd = tr_R_on(width_n[i], NCH, 1, is_dram_); 156610152Satgutier@umich.edu c_intrinsic = drain_C_(width_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 156710152Satgutier@umich.edu drain_C_(width_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 156810152Satgutier@umich.edu tf = rd * (c_intrinsic + c_load) + r_wire_load * (c_wire_load / 2 + c_gate_load); 156910152Satgutier@umich.edu this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE); 157010152Satgutier@umich.edu delay += this_delay; 157110152Satgutier@umich.edu power.readOp.dynamic += (c_intrinsic + c_load) * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd; 157210152Satgutier@umich.edu power.readOp.leakage += cmos_Isub_leakage(width_n[i], width_p[i], 1, inv, is_dram_) * g_tp.peri_global.Vdd; 157310152Satgutier@umich.edu power.readOp.gate_leakage += cmos_Ig_leakage(width_n[i], width_p[i], 1, inv, is_dram_)* g_tp.peri_global.Vdd; 157410152Satgutier@umich.edu 157510152Satgutier@umich.edu return this_delay / (1.0 - 0.5); 157610152Satgutier@umich.edu} 157710152Satgutier@umich.edu 1578