110152Satgutier@umich.edu/***************************************************************************** 210152Satgutier@umich.edu * McPAT/CACTI 310152Satgutier@umich.edu * SOFTWARE LICENSE AGREEMENT 410152Satgutier@umich.edu * Copyright 2012 Hewlett-Packard Development Company, L.P. 510234Syasuko.eckert@amd.com * Copyright (c) 2010-2013 Advanced Micro Devices, Inc. 610152Satgutier@umich.edu * All Rights Reserved 710152Satgutier@umich.edu * 810152Satgutier@umich.edu * Redistribution and use in source and binary forms, with or without 910152Satgutier@umich.edu * modification, are permitted provided that the following conditions are 1010152Satgutier@umich.edu * met: redistributions of source code must retain the above copyright 1110152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer; 1210152Satgutier@umich.edu * redistributions in binary form must reproduce the above copyright 1310152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer in the 1410152Satgutier@umich.edu * documentation and/or other materials provided with the distribution; 1510152Satgutier@umich.edu * neither the name of the copyright holders nor the names of its 1610152Satgutier@umich.edu * contributors may be used to endorse or promote products derived from 1710152Satgutier@umich.edu * this software without specific prior written permission. 1810152Satgutier@umich.edu 1910152Satgutier@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2010152Satgutier@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2110152Satgutier@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2210152Satgutier@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2310152Satgutier@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2410152Satgutier@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2510152Satgutier@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2610152Satgutier@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2710152Satgutier@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2810152Satgutier@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2910234Syasuko.eckert@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3010152Satgutier@umich.edu * 3110152Satgutier@umich.edu ***************************************************************************/ 3210152Satgutier@umich.edu 3310152Satgutier@umich.edu 3410152Satgutier@umich.edu 3510152Satgutier@umich.edu#include <cassert> 3610152Satgutier@umich.edu#include <cmath> 3710152Satgutier@umich.edu#include <iostream> 3810152Satgutier@umich.edu 3910152Satgutier@umich.edu#include "area.h" 4010152Satgutier@umich.edu#include "decoder.h" 4110152Satgutier@umich.edu#include "parameter.h" 4210152Satgutier@umich.edu 4310152Satgutier@umich.eduusing namespace std; 4410152Satgutier@umich.edu 4510152Satgutier@umich.edu 4610152Satgutier@umich.eduDecoder::Decoder( 4710152Satgutier@umich.edu int _num_dec_signals, 4810152Satgutier@umich.edu bool flag_way_select, 4910152Satgutier@umich.edu double _C_ld_dec_out, 5010152Satgutier@umich.edu double _R_wire_dec_out, 5110152Satgutier@umich.edu bool fully_assoc_, 5210152Satgutier@umich.edu bool is_dram_, 5310152Satgutier@umich.edu bool is_wl_tr_, 5410152Satgutier@umich.edu const Area & cell_) 5510234Syasuko.eckert@amd.com : exist(false), 5610234Syasuko.eckert@amd.com C_ld_dec_out(_C_ld_dec_out), 5710234Syasuko.eckert@amd.com R_wire_dec_out(_R_wire_dec_out), 5810234Syasuko.eckert@amd.com num_gates(0), num_gates_min(2), 5910234Syasuko.eckert@amd.com delay(0), 6010234Syasuko.eckert@amd.com //power(), 6110234Syasuko.eckert@amd.com fully_assoc(fully_assoc_), is_dram(is_dram_), 6210234Syasuko.eckert@amd.com is_wl_tr(is_wl_tr_), cell(cell_) { 6310152Satgutier@umich.edu 6410234Syasuko.eckert@amd.com for (int i = 0; i < MAX_NUMBER_GATES_STAGE; i++) { 6510234Syasuko.eckert@amd.com w_dec_n[i] = 0; 6610234Syasuko.eckert@amd.com w_dec_p[i] = 0; 6710234Syasuko.eckert@amd.com } 6810152Satgutier@umich.edu 6910234Syasuko.eckert@amd.com /* 7010234Syasuko.eckert@amd.com * _num_dec_signals is the number of decoded signal as output 7110234Syasuko.eckert@amd.com * num_addr_bits_dec is the number of signal to be decoded 7210234Syasuko.eckert@amd.com * as the decoders input. 7310234Syasuko.eckert@amd.com */ 7410234Syasuko.eckert@amd.com int num_addr_bits_dec = _log2(_num_dec_signals); 7510152Satgutier@umich.edu 7610234Syasuko.eckert@amd.com if (num_addr_bits_dec < 4) { 7710234Syasuko.eckert@amd.com if (flag_way_select) { 7810234Syasuko.eckert@amd.com exist = true; 7910234Syasuko.eckert@amd.com num_in_signals = 2; 8010234Syasuko.eckert@amd.com } else { 8110234Syasuko.eckert@amd.com num_in_signals = 0; 8210234Syasuko.eckert@amd.com } 8310234Syasuko.eckert@amd.com } else { 8410234Syasuko.eckert@amd.com exist = true; 8510234Syasuko.eckert@amd.com 8610234Syasuko.eckert@amd.com if (flag_way_select) { 8710234Syasuko.eckert@amd.com num_in_signals = 3; 8810234Syasuko.eckert@amd.com } else { 8910234Syasuko.eckert@amd.com num_in_signals = 2; 9010234Syasuko.eckert@amd.com } 9110152Satgutier@umich.edu } 9210152Satgutier@umich.edu 9310234Syasuko.eckert@amd.com assert(cell.h > 0); 9410234Syasuko.eckert@amd.com assert(cell.w > 0); 9510234Syasuko.eckert@amd.com // the height of a row-decoder-driver cell is fixed to be 4 * cell.h; 9610234Syasuko.eckert@amd.com //area.h = 4 * cell.h; 9710234Syasuko.eckert@amd.com area.h = g_tp.h_dec * cell.h; 9810152Satgutier@umich.edu 9910234Syasuko.eckert@amd.com compute_widths(); 10010234Syasuko.eckert@amd.com compute_area(); 10110152Satgutier@umich.edu} 10210152Satgutier@umich.edu 10310152Satgutier@umich.edu 10410152Satgutier@umich.edu 10510234Syasuko.eckert@amd.comvoid Decoder::compute_widths() { 10610234Syasuko.eckert@amd.com double F; 10710234Syasuko.eckert@amd.com double p_to_n_sz_ratio = pmos_to_nmos_sz_ratio(is_dram, is_wl_tr); 10810234Syasuko.eckert@amd.com double gnand2 = (2 + p_to_n_sz_ratio) / (1 + p_to_n_sz_ratio); 10910234Syasuko.eckert@amd.com double gnand3 = (3 + p_to_n_sz_ratio) / (1 + p_to_n_sz_ratio); 11010152Satgutier@umich.edu 11110234Syasuko.eckert@amd.com if (exist) { 11210234Syasuko.eckert@amd.com if (num_in_signals == 2 || fully_assoc) { 11310234Syasuko.eckert@amd.com w_dec_n[0] = 2 * g_tp.min_w_nmos_; 11410234Syasuko.eckert@amd.com w_dec_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 11510234Syasuko.eckert@amd.com F = gnand2; 11610234Syasuko.eckert@amd.com } else { 11710234Syasuko.eckert@amd.com w_dec_n[0] = 3 * g_tp.min_w_nmos_; 11810234Syasuko.eckert@amd.com w_dec_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 11910234Syasuko.eckert@amd.com F = gnand3; 12010234Syasuko.eckert@amd.com } 12110234Syasuko.eckert@amd.com 12210234Syasuko.eckert@amd.com F *= C_ld_dec_out / (gate_C(w_dec_n[0], 0, is_dram, false, is_wl_tr) + 12310234Syasuko.eckert@amd.com gate_C(w_dec_p[0], 0, is_dram, false, is_wl_tr)); 12410234Syasuko.eckert@amd.com num_gates = logical_effort( 12510234Syasuko.eckert@amd.com num_gates_min, 12610234Syasuko.eckert@amd.com num_in_signals == 2 ? gnand2 : gnand3, 12710234Syasuko.eckert@amd.com F, 12810234Syasuko.eckert@amd.com w_dec_n, 12910234Syasuko.eckert@amd.com w_dec_p, 13010234Syasuko.eckert@amd.com C_ld_dec_out, 13110234Syasuko.eckert@amd.com p_to_n_sz_ratio, 13210234Syasuko.eckert@amd.com is_dram, 13310234Syasuko.eckert@amd.com is_wl_tr, 13410234Syasuko.eckert@amd.com g_tp.max_w_nmos_dec); 13510152Satgutier@umich.edu } 13610152Satgutier@umich.edu} 13710152Satgutier@umich.edu 13810152Satgutier@umich.edu 13910152Satgutier@umich.edu 14010234Syasuko.eckert@amd.comvoid Decoder::compute_area() { 14110234Syasuko.eckert@amd.com double cumulative_area = 0; 14210234Syasuko.eckert@amd.com double cumulative_curr = 0; // cumulative leakage current 14310234Syasuko.eckert@amd.com double cumulative_curr_Ig = 0; // cumulative leakage current 14410152Satgutier@umich.edu 14510234Syasuko.eckert@amd.com if (exist) { // First check if this decoder exists 14610234Syasuko.eckert@amd.com if (num_in_signals == 2) { 14710234Syasuko.eckert@amd.com cumulative_area = 14810234Syasuko.eckert@amd.com compute_gate_area(NAND, 2, w_dec_p[0], w_dec_n[0], area.h); 14910234Syasuko.eckert@amd.com cumulative_curr = 15010234Syasuko.eckert@amd.com cmos_Isub_leakage(w_dec_n[0], w_dec_p[0], 2, nand, is_dram); 15110234Syasuko.eckert@amd.com cumulative_curr_Ig = 15210234Syasuko.eckert@amd.com cmos_Ig_leakage(w_dec_n[0], w_dec_p[0], 2, nand, is_dram); 15310234Syasuko.eckert@amd.com } else if (num_in_signals == 3) { 15410234Syasuko.eckert@amd.com cumulative_area = 15510234Syasuko.eckert@amd.com compute_gate_area(NAND, 3, w_dec_p[0], w_dec_n[0], area.h); 15610234Syasuko.eckert@amd.com cumulative_curr = 15710234Syasuko.eckert@amd.com cmos_Isub_leakage(w_dec_n[0], w_dec_p[0], 3, nand, is_dram);; 15810234Syasuko.eckert@amd.com cumulative_curr_Ig = 15910234Syasuko.eckert@amd.com cmos_Ig_leakage(w_dec_n[0], w_dec_p[0], 3, nand, is_dram); 16010234Syasuko.eckert@amd.com } 16110234Syasuko.eckert@amd.com 16210234Syasuko.eckert@amd.com for (int i = 1; i < num_gates; i++) { 16310234Syasuko.eckert@amd.com cumulative_area += 16410234Syasuko.eckert@amd.com compute_gate_area(INV, 1, w_dec_p[i], w_dec_n[i], area.h); 16510234Syasuko.eckert@amd.com cumulative_curr += 16610234Syasuko.eckert@amd.com cmos_Isub_leakage(w_dec_n[i], w_dec_p[i], 1, inv, is_dram); 16710234Syasuko.eckert@amd.com cumulative_curr_Ig = 16810234Syasuko.eckert@amd.com cmos_Ig_leakage(w_dec_n[i], w_dec_p[i], 1, inv, is_dram); 16910234Syasuko.eckert@amd.com } 17010234Syasuko.eckert@amd.com power.readOp.leakage = cumulative_curr * g_tp.peri_global.Vdd; 17110234Syasuko.eckert@amd.com power.readOp.gate_leakage = cumulative_curr_Ig * g_tp.peri_global.Vdd; 17210234Syasuko.eckert@amd.com 17310234Syasuko.eckert@amd.com area.w = (cumulative_area / area.h); 17410152Satgutier@umich.edu } 17510152Satgutier@umich.edu} 17610152Satgutier@umich.edu 17710152Satgutier@umich.edu 17810152Satgutier@umich.edu 17910234Syasuko.eckert@amd.comdouble Decoder::compute_delays(double inrisetime) { 18010234Syasuko.eckert@amd.com if (exist) { 18110234Syasuko.eckert@amd.com double ret_val = 0; // outrisetime 18210234Syasuko.eckert@amd.com int i; 18310234Syasuko.eckert@amd.com double rd, tf, this_delay, c_load, c_intrinsic, Vpp; 18410234Syasuko.eckert@amd.com double Vdd = g_tp.peri_global.Vdd; 18510152Satgutier@umich.edu 18610234Syasuko.eckert@amd.com if ((is_wl_tr) && (is_dram)) { 18710234Syasuko.eckert@amd.com Vpp = g_tp.vpp; 18810234Syasuko.eckert@amd.com } else if (is_wl_tr) { 18910234Syasuko.eckert@amd.com Vpp = g_tp.sram_cell.Vdd; 19010234Syasuko.eckert@amd.com } else { 19110234Syasuko.eckert@amd.com Vpp = g_tp.peri_global.Vdd; 19210234Syasuko.eckert@amd.com } 19310234Syasuko.eckert@amd.com 19410234Syasuko.eckert@amd.com // first check whether a decoder is required at all 19510234Syasuko.eckert@amd.com rd = tr_R_on(w_dec_n[0], NCH, num_in_signals, is_dram, false, is_wl_tr); 19610234Syasuko.eckert@amd.com c_load = gate_C(w_dec_n[1] + w_dec_p[1], 0.0, is_dram, false, is_wl_tr); 19710234Syasuko.eckert@amd.com c_intrinsic = drain_C_(w_dec_p[0], PCH, 1, 1, area.h, is_dram, false, is_wl_tr) * num_in_signals + 19810234Syasuko.eckert@amd.com drain_C_(w_dec_n[0], NCH, num_in_signals, 1, area.h, is_dram, false, is_wl_tr); 19910234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load); 20010234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE); 20110234Syasuko.eckert@amd.com delay += this_delay; 20210234Syasuko.eckert@amd.com inrisetime = this_delay / (1.0 - 0.5); 20310234Syasuko.eckert@amd.com power.readOp.dynamic += (c_load + c_intrinsic) * Vdd * Vdd; 20410234Syasuko.eckert@amd.com 20510234Syasuko.eckert@amd.com for (i = 1; i < num_gates - 1; ++i) { 20610234Syasuko.eckert@amd.com rd = tr_R_on(w_dec_n[i], NCH, 1, is_dram, false, is_wl_tr); 20710234Syasuko.eckert@amd.com c_load = gate_C(w_dec_p[i+1] + w_dec_n[i+1], 0.0, is_dram, false, is_wl_tr); 20810234Syasuko.eckert@amd.com c_intrinsic = drain_C_(w_dec_p[i], PCH, 1, 1, area.h, is_dram, false, is_wl_tr) + 20910234Syasuko.eckert@amd.com drain_C_(w_dec_n[i], NCH, 1, 1, area.h, is_dram, false, is_wl_tr); 21010234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load); 21110234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE); 21210234Syasuko.eckert@amd.com delay += this_delay; 21310234Syasuko.eckert@amd.com inrisetime = this_delay / (1.0 - 0.5); 21410234Syasuko.eckert@amd.com power.readOp.dynamic += (c_load + c_intrinsic) * Vdd * Vdd; 21510234Syasuko.eckert@amd.com } 21610234Syasuko.eckert@amd.com 21710234Syasuko.eckert@amd.com // add delay of final inverter that drives the wordline 21810234Syasuko.eckert@amd.com i = num_gates - 1; 21910234Syasuko.eckert@amd.com c_load = C_ld_dec_out; 22010234Syasuko.eckert@amd.com rd = tr_R_on(w_dec_n[i], NCH, 1, is_dram, false, is_wl_tr); 22110234Syasuko.eckert@amd.com c_intrinsic = drain_C_(w_dec_p[i], PCH, 1, 1, area.h, is_dram, false, is_wl_tr) + 22210234Syasuko.eckert@amd.com drain_C_(w_dec_n[i], NCH, 1, 1, area.h, is_dram, false, is_wl_tr); 22310234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load) + R_wire_dec_out * c_load / 2; 22410234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE); 22510234Syasuko.eckert@amd.com delay += this_delay; 22610234Syasuko.eckert@amd.com ret_val = this_delay / (1.0 - 0.5); 22710234Syasuko.eckert@amd.com power.readOp.dynamic += c_load * Vpp * Vpp + c_intrinsic * Vdd * Vdd; 22810234Syasuko.eckert@amd.com 22910234Syasuko.eckert@amd.com return ret_val; 23010234Syasuko.eckert@amd.com } else { 23110234Syasuko.eckert@amd.com return 0.0; 23210152Satgutier@umich.edu } 23310152Satgutier@umich.edu} 23410152Satgutier@umich.edu 23510152Satgutier@umich.eduvoid Decoder::leakage_feedback(double temperature) 23610152Satgutier@umich.edu{ 23710152Satgutier@umich.edu double cumulative_curr = 0; // cumulative leakage current 23810152Satgutier@umich.edu double cumulative_curr_Ig = 0; // cumulative leakage current 23910152Satgutier@umich.edu 24010152Satgutier@umich.edu if (exist) 24110152Satgutier@umich.edu { // First check if this decoder exists 24210152Satgutier@umich.edu if (num_in_signals == 2) 24310152Satgutier@umich.edu { 24410152Satgutier@umich.edu cumulative_curr = cmos_Isub_leakage(w_dec_n[0], w_dec_p[0], 2, nand,is_dram); 24510152Satgutier@umich.edu cumulative_curr_Ig = cmos_Ig_leakage(w_dec_n[0], w_dec_p[0], 2, nand,is_dram); 24610152Satgutier@umich.edu } 24710152Satgutier@umich.edu else if (num_in_signals == 3) 24810152Satgutier@umich.edu { 24910152Satgutier@umich.edu cumulative_curr = cmos_Isub_leakage(w_dec_n[0], w_dec_p[0], 3, nand, is_dram);; 25010152Satgutier@umich.edu cumulative_curr_Ig = cmos_Ig_leakage(w_dec_n[0], w_dec_p[0], 3, nand, is_dram); 25110152Satgutier@umich.edu } 25210152Satgutier@umich.edu 25310152Satgutier@umich.edu for (int i = 1; i < num_gates; i++) 25410152Satgutier@umich.edu { 25510152Satgutier@umich.edu cumulative_curr += cmos_Isub_leakage(w_dec_n[i], w_dec_p[i], 1, inv, is_dram); 25610152Satgutier@umich.edu cumulative_curr_Ig = cmos_Ig_leakage(w_dec_n[i], w_dec_p[i], 1, inv, is_dram); 25710152Satgutier@umich.edu } 25810152Satgutier@umich.edu 25910152Satgutier@umich.edu power.readOp.leakage = cumulative_curr * g_tp.peri_global.Vdd; 26010152Satgutier@umich.edu power.readOp.gate_leakage = cumulative_curr_Ig * g_tp.peri_global.Vdd; 26110152Satgutier@umich.edu } 26210152Satgutier@umich.edu} 26310152Satgutier@umich.edu 26410152Satgutier@umich.eduPredecBlk::PredecBlk( 26510152Satgutier@umich.edu int num_dec_signals, 26610152Satgutier@umich.edu Decoder * dec_, 26710152Satgutier@umich.edu double C_wire_predec_blk_out, 26810152Satgutier@umich.edu double R_wire_predec_blk_out_, 26910152Satgutier@umich.edu int num_dec_per_predec, 27010152Satgutier@umich.edu bool is_dram, 27110152Satgutier@umich.edu bool is_blk1) 27210234Syasuko.eckert@amd.com : dec(dec_), 27310234Syasuko.eckert@amd.com exist(false), 27410234Syasuko.eckert@amd.com number_input_addr_bits(0), 27510234Syasuko.eckert@amd.com C_ld_predec_blk_out(0), 27610234Syasuko.eckert@amd.com R_wire_predec_blk_out(0), 27710234Syasuko.eckert@amd.com branch_effort_nand2_gate_output(1), 27810234Syasuko.eckert@amd.com branch_effort_nand3_gate_output(1), 27910234Syasuko.eckert@amd.com flag_two_unique_paths(false), 28010234Syasuko.eckert@amd.com flag_L2_gate(0), 28110234Syasuko.eckert@amd.com number_inputs_L1_gate(0), 28210234Syasuko.eckert@amd.com number_gates_L1_nand2_path(0), 28310234Syasuko.eckert@amd.com number_gates_L1_nand3_path(0), 28410234Syasuko.eckert@amd.com number_gates_L2(0), 28510234Syasuko.eckert@amd.com min_number_gates_L1(2), 28610234Syasuko.eckert@amd.com min_number_gates_L2(2), 28710234Syasuko.eckert@amd.com num_L1_active_nand2_path(0), 28810234Syasuko.eckert@amd.com num_L1_active_nand3_path(0), 28910234Syasuko.eckert@amd.com delay_nand2_path(0), 29010234Syasuko.eckert@amd.com delay_nand3_path(0), 29110234Syasuko.eckert@amd.com power_nand2_path(), 29210234Syasuko.eckert@amd.com power_nand3_path(), 29310234Syasuko.eckert@amd.com power_L2(), 29410234Syasuko.eckert@amd.com is_dram_(is_dram) { 29510234Syasuko.eckert@amd.com int branch_effort_predec_out; 29610234Syasuko.eckert@amd.com double C_ld_dec_gate; 29710234Syasuko.eckert@amd.com int num_addr_bits_dec = _log2(num_dec_signals); 29810234Syasuko.eckert@amd.com int blk1_num_input_addr_bits = (num_addr_bits_dec + 1) / 2; 29910234Syasuko.eckert@amd.com int blk2_num_input_addr_bits = num_addr_bits_dec - blk1_num_input_addr_bits; 30010152Satgutier@umich.edu 30110234Syasuko.eckert@amd.com w_L1_nand2_n[0] = 0; 30210234Syasuko.eckert@amd.com w_L1_nand2_p[0] = 0; 30310234Syasuko.eckert@amd.com w_L1_nand3_n[0] = 0; 30410234Syasuko.eckert@amd.com w_L1_nand3_p[0] = 0; 30510152Satgutier@umich.edu 30610234Syasuko.eckert@amd.com if (is_blk1 == true) { 30710234Syasuko.eckert@amd.com if (num_addr_bits_dec <= 0) { 30810234Syasuko.eckert@amd.com return; 30910234Syasuko.eckert@amd.com } else if (num_addr_bits_dec < 4) { 31010234Syasuko.eckert@amd.com // Just one predecoder block is required with NAND2 gates. No decoder required. 31110234Syasuko.eckert@amd.com // The first level of predecoding directly drives the decoder output load 31210234Syasuko.eckert@amd.com exist = true; 31310234Syasuko.eckert@amd.com number_input_addr_bits = num_addr_bits_dec; 31410234Syasuko.eckert@amd.com R_wire_predec_blk_out = dec->R_wire_dec_out; 31510234Syasuko.eckert@amd.com C_ld_predec_blk_out = dec->C_ld_dec_out; 31610234Syasuko.eckert@amd.com } else { 31710234Syasuko.eckert@amd.com exist = true; 31810234Syasuko.eckert@amd.com number_input_addr_bits = blk1_num_input_addr_bits; 31910234Syasuko.eckert@amd.com branch_effort_predec_out = (1 << blk2_num_input_addr_bits); 32010234Syasuko.eckert@amd.com 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); 32110234Syasuko.eckert@amd.com R_wire_predec_blk_out = R_wire_predec_blk_out_; 32210234Syasuko.eckert@amd.com C_ld_predec_blk_out = branch_effort_predec_out * C_ld_dec_gate + C_wire_predec_blk_out; 32310234Syasuko.eckert@amd.com } 32410234Syasuko.eckert@amd.com } else { 32510234Syasuko.eckert@amd.com if (num_addr_bits_dec >= 4) { 32610234Syasuko.eckert@amd.com exist = true; 32710234Syasuko.eckert@amd.com number_input_addr_bits = blk2_num_input_addr_bits; 32810234Syasuko.eckert@amd.com branch_effort_predec_out = (1 << blk1_num_input_addr_bits); 32910234Syasuko.eckert@amd.com 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); 33010234Syasuko.eckert@amd.com R_wire_predec_blk_out = R_wire_predec_blk_out_; 33110234Syasuko.eckert@amd.com C_ld_predec_blk_out = branch_effort_predec_out * C_ld_dec_gate + C_wire_predec_blk_out; 33210234Syasuko.eckert@amd.com } 33310152Satgutier@umich.edu } 33410152Satgutier@umich.edu 33510234Syasuko.eckert@amd.com compute_widths(); 33610234Syasuko.eckert@amd.com compute_area(); 33710152Satgutier@umich.edu} 33810152Satgutier@umich.edu 33910152Satgutier@umich.edu 34010152Satgutier@umich.edu 34110234Syasuko.eckert@amd.comvoid PredecBlk::compute_widths() { 34210234Syasuko.eckert@amd.com double F, c_load_nand3_path, c_load_nand2_path; 34310234Syasuko.eckert@amd.com double p_to_n_sz_ratio = pmos_to_nmos_sz_ratio(is_dram_); 34410234Syasuko.eckert@amd.com double gnand2 = (2 + p_to_n_sz_ratio) / (1 + p_to_n_sz_ratio); 34510234Syasuko.eckert@amd.com double gnand3 = (3 + p_to_n_sz_ratio) / (1 + p_to_n_sz_ratio); 34610152Satgutier@umich.edu 34710234Syasuko.eckert@amd.com if (exist == false) return; 34810152Satgutier@umich.edu 34910152Satgutier@umich.edu 35010234Syasuko.eckert@amd.com switch (number_input_addr_bits) { 35110152Satgutier@umich.edu case 1: 35210234Syasuko.eckert@amd.com flag_two_unique_paths = false; 35310234Syasuko.eckert@amd.com number_inputs_L1_gate = 2; 35410234Syasuko.eckert@amd.com flag_L2_gate = 0; 35510234Syasuko.eckert@amd.com break; 35610152Satgutier@umich.edu case 2: 35710234Syasuko.eckert@amd.com flag_two_unique_paths = false; 35810234Syasuko.eckert@amd.com number_inputs_L1_gate = 2; 35910234Syasuko.eckert@amd.com flag_L2_gate = 0; 36010234Syasuko.eckert@amd.com break; 36110152Satgutier@umich.edu case 3: 36210234Syasuko.eckert@amd.com flag_two_unique_paths = false; 36310234Syasuko.eckert@amd.com number_inputs_L1_gate = 3; 36410234Syasuko.eckert@amd.com flag_L2_gate = 0; 36510234Syasuko.eckert@amd.com break; 36610152Satgutier@umich.edu case 4: 36710234Syasuko.eckert@amd.com flag_two_unique_paths = false; 36810234Syasuko.eckert@amd.com number_inputs_L1_gate = 2; 36910234Syasuko.eckert@amd.com flag_L2_gate = 2; 37010234Syasuko.eckert@amd.com branch_effort_nand2_gate_output = 4; 37110234Syasuko.eckert@amd.com break; 37210152Satgutier@umich.edu case 5: 37310234Syasuko.eckert@amd.com flag_two_unique_paths = true; 37410234Syasuko.eckert@amd.com flag_L2_gate = 2; 37510234Syasuko.eckert@amd.com branch_effort_nand2_gate_output = 8; 37610234Syasuko.eckert@amd.com branch_effort_nand3_gate_output = 4; 37710234Syasuko.eckert@amd.com break; 37810152Satgutier@umich.edu case 6: 37910234Syasuko.eckert@amd.com flag_two_unique_paths = false; 38010234Syasuko.eckert@amd.com number_inputs_L1_gate = 3; 38110234Syasuko.eckert@amd.com flag_L2_gate = 2; 38210234Syasuko.eckert@amd.com branch_effort_nand3_gate_output = 8; 38310234Syasuko.eckert@amd.com break; 38410152Satgutier@umich.edu case 7: 38510234Syasuko.eckert@amd.com flag_two_unique_paths = true; 38610234Syasuko.eckert@amd.com flag_L2_gate = 3; 38710234Syasuko.eckert@amd.com branch_effort_nand2_gate_output = 32; 38810234Syasuko.eckert@amd.com branch_effort_nand3_gate_output = 16; 38910234Syasuko.eckert@amd.com break; 39010152Satgutier@umich.edu case 8: 39110234Syasuko.eckert@amd.com flag_two_unique_paths = true; 39210234Syasuko.eckert@amd.com flag_L2_gate = 3; 39310234Syasuko.eckert@amd.com branch_effort_nand2_gate_output = 64; 39410234Syasuko.eckert@amd.com branch_effort_nand3_gate_output = 32; 39510234Syasuko.eckert@amd.com break; 39610152Satgutier@umich.edu case 9: 39710234Syasuko.eckert@amd.com flag_two_unique_paths = false; 39810234Syasuko.eckert@amd.com number_inputs_L1_gate = 3; 39910234Syasuko.eckert@amd.com flag_L2_gate = 3; 40010234Syasuko.eckert@amd.com branch_effort_nand3_gate_output = 64; 40110234Syasuko.eckert@amd.com break; 40210152Satgutier@umich.edu default: 40310234Syasuko.eckert@amd.com assert(0); 40410152Satgutier@umich.edu break; 40510152Satgutier@umich.edu } 40610152Satgutier@umich.edu 40710234Syasuko.eckert@amd.com // find the number of gates and sizing in second level of predecoder (if there is a second level) 40810234Syasuko.eckert@amd.com if (flag_L2_gate) { 40910234Syasuko.eckert@amd.com if (flag_L2_gate == 2) { // 2nd level is a NAND2 gate 41010234Syasuko.eckert@amd.com w_L2_n[0] = 2 * g_tp.min_w_nmos_; 41110234Syasuko.eckert@amd.com F = gnand2; 41210234Syasuko.eckert@amd.com } else { // 2nd level is a NAND3 gate 41310234Syasuko.eckert@amd.com w_L2_n[0] = 3 * g_tp.min_w_nmos_; 41410234Syasuko.eckert@amd.com F = gnand3; 41510234Syasuko.eckert@amd.com } 41610234Syasuko.eckert@amd.com w_L2_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 41710234Syasuko.eckert@amd.com F *= C_ld_predec_blk_out / (gate_C(w_L2_n[0], 0, is_dram_) + gate_C(w_L2_p[0], 0, is_dram_)); 41810234Syasuko.eckert@amd.com number_gates_L2 = logical_effort( 41910234Syasuko.eckert@amd.com min_number_gates_L2, 42010234Syasuko.eckert@amd.com flag_L2_gate == 2 ? gnand2 : gnand3, 42110234Syasuko.eckert@amd.com F, 42210234Syasuko.eckert@amd.com w_L2_n, 42310234Syasuko.eckert@amd.com w_L2_p, 42410234Syasuko.eckert@amd.com C_ld_predec_blk_out, 42510234Syasuko.eckert@amd.com p_to_n_sz_ratio, 42610234Syasuko.eckert@amd.com is_dram_, false, 42710234Syasuko.eckert@amd.com g_tp.max_w_nmos_); 42810234Syasuko.eckert@amd.com 42910234Syasuko.eckert@amd.com // Now find the number of gates and widths in first level of predecoder 43010234Syasuko.eckert@amd.com if ((flag_two_unique_paths) || (number_inputs_L1_gate == 2)) { 43110234Syasuko.eckert@amd.com // Whenever flag_two_unique_paths is true, it means first level of 43210234Syasuko.eckert@amd.com // decoder employs 43310234Syasuko.eckert@amd.com // both NAND2 and NAND3 gates. Or when number_inputs_L1_gate is 2, 43410234Syasuko.eckert@amd.com // it means 43510234Syasuko.eckert@amd.com // a NAND2 gate is used in the first level of the predecoder 43610234Syasuko.eckert@amd.com c_load_nand2_path = branch_effort_nand2_gate_output * 43710234Syasuko.eckert@amd.com (gate_C(w_L2_n[0], 0, is_dram_) + 43810234Syasuko.eckert@amd.com gate_C(w_L2_p[0], 0, is_dram_)); 43910234Syasuko.eckert@amd.com w_L1_nand2_n[0] = 2 * g_tp.min_w_nmos_; 44010234Syasuko.eckert@amd.com w_L1_nand2_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 44110234Syasuko.eckert@amd.com F = gnand2 * c_load_nand2_path / 44210234Syasuko.eckert@amd.com (gate_C(w_L1_nand2_n[0], 0, is_dram_) + 44310234Syasuko.eckert@amd.com gate_C(w_L1_nand2_p[0], 0, is_dram_)); 44410234Syasuko.eckert@amd.com number_gates_L1_nand2_path = logical_effort( 44510234Syasuko.eckert@amd.com min_number_gates_L1, 44610234Syasuko.eckert@amd.com gnand2, 44710234Syasuko.eckert@amd.com F, 44810234Syasuko.eckert@amd.com w_L1_nand2_n, 44910234Syasuko.eckert@amd.com w_L1_nand2_p, 45010234Syasuko.eckert@amd.com c_load_nand2_path, 45110234Syasuko.eckert@amd.com p_to_n_sz_ratio, 45210234Syasuko.eckert@amd.com is_dram_, false, 45310234Syasuko.eckert@amd.com g_tp.max_w_nmos_); 45410234Syasuko.eckert@amd.com } 45510234Syasuko.eckert@amd.com 45610234Syasuko.eckert@amd.com //Now find widths of gates along path in which first gate is a NAND3 45710234Syasuko.eckert@amd.com if ((flag_two_unique_paths) || (number_inputs_L1_gate == 3)) { // Whenever flag_two_unique_paths is TRUE, it means first level of decoder employs 45810234Syasuko.eckert@amd.com // both NAND2 and NAND3 gates. Or when number_inputs_L1_gate is 3, it means 45910234Syasuko.eckert@amd.com // a NAND3 gate is used in the first level of the predecoder 46010234Syasuko.eckert@amd.com c_load_nand3_path = branch_effort_nand3_gate_output * 46110234Syasuko.eckert@amd.com (gate_C(w_L2_n[0], 0, is_dram_) + 46210234Syasuko.eckert@amd.com gate_C(w_L2_p[0], 0, is_dram_)); 46310234Syasuko.eckert@amd.com w_L1_nand3_n[0] = 3 * g_tp.min_w_nmos_; 46410234Syasuko.eckert@amd.com w_L1_nand3_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 46510234Syasuko.eckert@amd.com F = gnand3 * c_load_nand3_path / 46610234Syasuko.eckert@amd.com (gate_C(w_L1_nand3_n[0], 0, is_dram_) + 46710234Syasuko.eckert@amd.com gate_C(w_L1_nand3_p[0], 0, is_dram_)); 46810234Syasuko.eckert@amd.com number_gates_L1_nand3_path = logical_effort( 46910234Syasuko.eckert@amd.com min_number_gates_L1, 47010234Syasuko.eckert@amd.com gnand3, 47110234Syasuko.eckert@amd.com F, 47210234Syasuko.eckert@amd.com w_L1_nand3_n, 47310234Syasuko.eckert@amd.com w_L1_nand3_p, 47410234Syasuko.eckert@amd.com c_load_nand3_path, 47510234Syasuko.eckert@amd.com p_to_n_sz_ratio, 47610234Syasuko.eckert@amd.com is_dram_, false, 47710234Syasuko.eckert@amd.com g_tp.max_w_nmos_); 47810234Syasuko.eckert@amd.com } 47910234Syasuko.eckert@amd.com } else { // find number of gates and widths in first level of predecoder block when there is no second level 48010234Syasuko.eckert@amd.com if (number_inputs_L1_gate == 2) { 48110234Syasuko.eckert@amd.com w_L1_nand2_n[0] = 2 * g_tp.min_w_nmos_; 48210234Syasuko.eckert@amd.com w_L1_nand2_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 48310234Syasuko.eckert@amd.com F = gnand2 * C_ld_predec_blk_out / 48410234Syasuko.eckert@amd.com (gate_C(w_L1_nand2_n[0], 0, is_dram_) + 48510234Syasuko.eckert@amd.com gate_C(w_L1_nand2_p[0], 0, is_dram_)); 48610234Syasuko.eckert@amd.com number_gates_L1_nand2_path = logical_effort( 48710234Syasuko.eckert@amd.com min_number_gates_L1, 48810234Syasuko.eckert@amd.com gnand2, 48910234Syasuko.eckert@amd.com F, 49010234Syasuko.eckert@amd.com w_L1_nand2_n, 49110234Syasuko.eckert@amd.com w_L1_nand2_p, 49210234Syasuko.eckert@amd.com C_ld_predec_blk_out, 49310234Syasuko.eckert@amd.com p_to_n_sz_ratio, 49410234Syasuko.eckert@amd.com is_dram_, false, 49510234Syasuko.eckert@amd.com g_tp.max_w_nmos_); 49610234Syasuko.eckert@amd.com } else if (number_inputs_L1_gate == 3) { 49710234Syasuko.eckert@amd.com w_L1_nand3_n[0] = 3 * g_tp.min_w_nmos_; 49810234Syasuko.eckert@amd.com w_L1_nand3_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 49910234Syasuko.eckert@amd.com F = gnand3 * C_ld_predec_blk_out / 50010234Syasuko.eckert@amd.com (gate_C(w_L1_nand3_n[0], 0, is_dram_) + 50110234Syasuko.eckert@amd.com gate_C(w_L1_nand3_p[0], 0, is_dram_)); 50210234Syasuko.eckert@amd.com number_gates_L1_nand3_path = logical_effort( 50310234Syasuko.eckert@amd.com min_number_gates_L1, 50410234Syasuko.eckert@amd.com gnand3, 50510234Syasuko.eckert@amd.com F, 50610234Syasuko.eckert@amd.com w_L1_nand3_n, 50710234Syasuko.eckert@amd.com w_L1_nand3_p, 50810234Syasuko.eckert@amd.com C_ld_predec_blk_out, 50910234Syasuko.eckert@amd.com p_to_n_sz_ratio, 51010234Syasuko.eckert@amd.com is_dram_, false, 51110234Syasuko.eckert@amd.com g_tp.max_w_nmos_); 51210234Syasuko.eckert@amd.com } 51310152Satgutier@umich.edu } 51410234Syasuko.eckert@amd.com} 51510152Satgutier@umich.edu 51610234Syasuko.eckert@amd.com 51710234Syasuko.eckert@amd.com 51810234Syasuko.eckert@amd.comvoid PredecBlk::compute_area() { 51910234Syasuko.eckert@amd.com if (exist) { // First check whether a predecoder block is needed 52010234Syasuko.eckert@amd.com int num_L1_nand2 = 0; 52110234Syasuko.eckert@amd.com int num_L1_nand3 = 0; 52210234Syasuko.eckert@amd.com int num_L2 = 0; 52310234Syasuko.eckert@amd.com double tot_area_L1_nand3 = 0; 52410234Syasuko.eckert@amd.com double leak_L1_nand3 = 0; 52510234Syasuko.eckert@amd.com double gate_leak_L1_nand3 = 0; 52610234Syasuko.eckert@amd.com 52710234Syasuko.eckert@amd.com 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); 52810234Syasuko.eckert@amd.com double leak_L1_nand2 = cmos_Isub_leakage(w_L1_nand2_n[0], w_L1_nand2_p[0], 2, nand, is_dram_); 52910234Syasuko.eckert@amd.com double gate_leak_L1_nand2 = cmos_Ig_leakage(w_L1_nand2_n[0], w_L1_nand2_p[0], 2, nand, is_dram_); 53010234Syasuko.eckert@amd.com if (number_inputs_L1_gate != 3) { 53110234Syasuko.eckert@amd.com tot_area_L1_nand3 = 0; 53210234Syasuko.eckert@amd.com leak_L1_nand3 = 0; 53310234Syasuko.eckert@amd.com gate_leak_L1_nand3 = 0; 53410234Syasuko.eckert@amd.com } else { 53510234Syasuko.eckert@amd.com tot_area_L1_nand3 = compute_gate_area(NAND, 3, w_L1_nand3_p[0], w_L1_nand3_n[0], g_tp.cell_h_def); 53610234Syasuko.eckert@amd.com leak_L1_nand3 = cmos_Isub_leakage(w_L1_nand3_n[0], w_L1_nand3_p[0], 3, nand); 53710234Syasuko.eckert@amd.com gate_leak_L1_nand3 = cmos_Ig_leakage(w_L1_nand3_n[0], w_L1_nand3_p[0], 3, nand); 53810234Syasuko.eckert@amd.com } 53910234Syasuko.eckert@amd.com 54010234Syasuko.eckert@amd.com switch (number_input_addr_bits) { 54110234Syasuko.eckert@amd.com case 1: //2 NAND2 gates 54210234Syasuko.eckert@amd.com num_L1_nand2 = 2; 54310234Syasuko.eckert@amd.com num_L2 = 0; 54410234Syasuko.eckert@amd.com num_L1_active_nand2_path = 1; 54510234Syasuko.eckert@amd.com num_L1_active_nand3_path = 0; 54610234Syasuko.eckert@amd.com break; 54710234Syasuko.eckert@amd.com case 2: //4 NAND2 gates 54810234Syasuko.eckert@amd.com num_L1_nand2 = 4; 54910234Syasuko.eckert@amd.com num_L2 = 0; 55010234Syasuko.eckert@amd.com num_L1_active_nand2_path = 1; 55110234Syasuko.eckert@amd.com num_L1_active_nand3_path = 0; 55210234Syasuko.eckert@amd.com break; 55310234Syasuko.eckert@amd.com case 3: //8 NAND3 gates 55410234Syasuko.eckert@amd.com num_L1_nand3 = 8; 55510234Syasuko.eckert@amd.com num_L2 = 0; 55610234Syasuko.eckert@amd.com num_L1_active_nand2_path = 0; 55710234Syasuko.eckert@amd.com num_L1_active_nand3_path = 1; 55810234Syasuko.eckert@amd.com break; 55910234Syasuko.eckert@amd.com case 4: //4 + 4 NAND2 gates 56010234Syasuko.eckert@amd.com num_L1_nand2 = 8; 56110234Syasuko.eckert@amd.com num_L2 = 16; 56210234Syasuko.eckert@amd.com num_L1_active_nand2_path = 2; 56310234Syasuko.eckert@amd.com num_L1_active_nand3_path = 0; 56410234Syasuko.eckert@amd.com break; 56510234Syasuko.eckert@amd.com case 5: //4 NAND2 gates, 8 NAND3 gates 56610234Syasuko.eckert@amd.com num_L1_nand2 = 4; 56710234Syasuko.eckert@amd.com num_L1_nand3 = 8; 56810234Syasuko.eckert@amd.com num_L2 = 32; 56910234Syasuko.eckert@amd.com num_L1_active_nand2_path = 1; 57010234Syasuko.eckert@amd.com num_L1_active_nand3_path = 1; 57110234Syasuko.eckert@amd.com break; 57210234Syasuko.eckert@amd.com case 6: //8 + 8 NAND3 gates 57310234Syasuko.eckert@amd.com num_L1_nand3 = 16; 57410234Syasuko.eckert@amd.com num_L2 = 64; 57510234Syasuko.eckert@amd.com num_L1_active_nand2_path = 0; 57610234Syasuko.eckert@amd.com num_L1_active_nand3_path = 2; 57710234Syasuko.eckert@amd.com break; 57810234Syasuko.eckert@amd.com case 7: //4 + 4 NAND2 gates, 8 NAND3 gates 57910234Syasuko.eckert@amd.com num_L1_nand2 = 8; 58010234Syasuko.eckert@amd.com num_L1_nand3 = 8; 58110234Syasuko.eckert@amd.com num_L2 = 128; 58210234Syasuko.eckert@amd.com num_L1_active_nand2_path = 2; 58310234Syasuko.eckert@amd.com num_L1_active_nand3_path = 1; 58410234Syasuko.eckert@amd.com break; 58510234Syasuko.eckert@amd.com case 8: //4 NAND2 gates, 8 + 8 NAND3 gates 58610234Syasuko.eckert@amd.com num_L1_nand2 = 4; 58710234Syasuko.eckert@amd.com num_L1_nand3 = 16; 58810234Syasuko.eckert@amd.com num_L2 = 256; 58910234Syasuko.eckert@amd.com num_L1_active_nand2_path = 2; 59010234Syasuko.eckert@amd.com num_L1_active_nand3_path = 2; 59110234Syasuko.eckert@amd.com break; 59210234Syasuko.eckert@amd.com case 9: //8 + 8 + 8 NAND3 gates 59310234Syasuko.eckert@amd.com num_L1_nand3 = 24; 59410234Syasuko.eckert@amd.com num_L2 = 512; 59510234Syasuko.eckert@amd.com num_L1_active_nand2_path = 0; 59610234Syasuko.eckert@amd.com num_L1_active_nand3_path = 3; 59710234Syasuko.eckert@amd.com break; 59810234Syasuko.eckert@amd.com default: 59910234Syasuko.eckert@amd.com break; 60010234Syasuko.eckert@amd.com } 60110234Syasuko.eckert@amd.com 60210234Syasuko.eckert@amd.com for (int i = 1; i < number_gates_L1_nand2_path; ++i) { 60310234Syasuko.eckert@amd.com tot_area_L1_nand2 += compute_gate_area(INV, 1, w_L1_nand2_p[i], w_L1_nand2_n[i], g_tp.cell_h_def); 60410234Syasuko.eckert@amd.com leak_L1_nand2 += cmos_Isub_leakage(w_L1_nand2_n[i], w_L1_nand2_p[i], 2, nand, is_dram_); 60510234Syasuko.eckert@amd.com gate_leak_L1_nand2 += cmos_Ig_leakage(w_L1_nand2_n[i], w_L1_nand2_p[i], 2, nand, is_dram_); 60610234Syasuko.eckert@amd.com } 60710234Syasuko.eckert@amd.com tot_area_L1_nand2 *= num_L1_nand2; 60810234Syasuko.eckert@amd.com leak_L1_nand2 *= num_L1_nand2; 60910234Syasuko.eckert@amd.com gate_leak_L1_nand2 *= num_L1_nand2; 61010234Syasuko.eckert@amd.com 61110234Syasuko.eckert@amd.com for (int i = 1; i < number_gates_L1_nand3_path; ++i) { 61210234Syasuko.eckert@amd.com tot_area_L1_nand3 += compute_gate_area(INV, 1, w_L1_nand3_p[i], w_L1_nand3_n[i], g_tp.cell_h_def); 61310234Syasuko.eckert@amd.com leak_L1_nand3 += cmos_Isub_leakage(w_L1_nand3_n[i], w_L1_nand3_p[i], 3, nand, is_dram_); 61410234Syasuko.eckert@amd.com gate_leak_L1_nand3 += cmos_Ig_leakage(w_L1_nand3_n[i], w_L1_nand3_p[i], 3, nand, is_dram_); 61510234Syasuko.eckert@amd.com } 61610234Syasuko.eckert@amd.com tot_area_L1_nand3 *= num_L1_nand3; 61710234Syasuko.eckert@amd.com leak_L1_nand3 *= num_L1_nand3; 61810234Syasuko.eckert@amd.com gate_leak_L1_nand3 *= num_L1_nand3; 61910234Syasuko.eckert@amd.com 62010234Syasuko.eckert@amd.com double cumulative_area_L1 = tot_area_L1_nand2 + tot_area_L1_nand3; 62110234Syasuko.eckert@amd.com double cumulative_area_L2 = 0.0; 62210234Syasuko.eckert@amd.com double leakage_L2 = 0.0; 62310234Syasuko.eckert@amd.com double gate_leakage_L2 = 0.0; 62410234Syasuko.eckert@amd.com 62510234Syasuko.eckert@amd.com if (flag_L2_gate == 2) { 62610234Syasuko.eckert@amd.com cumulative_area_L2 = compute_gate_area(NAND, 2, w_L2_p[0], w_L2_n[0], g_tp.cell_h_def); 62710234Syasuko.eckert@amd.com leakage_L2 = cmos_Isub_leakage(w_L2_n[0], w_L2_p[0], 2, nand, is_dram_); 62810234Syasuko.eckert@amd.com gate_leakage_L2 = cmos_Ig_leakage(w_L2_n[0], w_L2_p[0], 2, nand, is_dram_); 62910234Syasuko.eckert@amd.com } else if (flag_L2_gate == 3) { 63010234Syasuko.eckert@amd.com cumulative_area_L2 = compute_gate_area(NAND, 3, w_L2_p[0], w_L2_n[0], g_tp.cell_h_def); 63110234Syasuko.eckert@amd.com leakage_L2 = cmos_Isub_leakage(w_L2_n[0], w_L2_p[0], 3, nand, is_dram_); 63210234Syasuko.eckert@amd.com gate_leakage_L2 = cmos_Ig_leakage(w_L2_n[0], w_L2_p[0], 3, nand, is_dram_); 63310234Syasuko.eckert@amd.com } 63410234Syasuko.eckert@amd.com 63510234Syasuko.eckert@amd.com for (int i = 1; i < number_gates_L2; ++i) { 63610234Syasuko.eckert@amd.com cumulative_area_L2 += compute_gate_area(INV, 1, w_L2_p[i], w_L2_n[i], g_tp.cell_h_def); 63710234Syasuko.eckert@amd.com leakage_L2 += cmos_Isub_leakage(w_L2_n[i], w_L2_p[i], 2, inv, is_dram_); 63810234Syasuko.eckert@amd.com gate_leakage_L2 += cmos_Ig_leakage(w_L2_n[i], w_L2_p[i], 2, inv, is_dram_); 63910234Syasuko.eckert@amd.com } 64010234Syasuko.eckert@amd.com cumulative_area_L2 *= num_L2; 64110234Syasuko.eckert@amd.com leakage_L2 *= num_L2; 64210234Syasuko.eckert@amd.com gate_leakage_L2 *= num_L2; 64310234Syasuko.eckert@amd.com 64410234Syasuko.eckert@amd.com power_nand2_path.readOp.leakage = leak_L1_nand2 * g_tp.peri_global.Vdd; 64510234Syasuko.eckert@amd.com power_nand3_path.readOp.leakage = leak_L1_nand3 * g_tp.peri_global.Vdd; 64610234Syasuko.eckert@amd.com power_L2.readOp.leakage = leakage_L2 * g_tp.peri_global.Vdd; 64710234Syasuko.eckert@amd.com area.set_area(cumulative_area_L1 + cumulative_area_L2); 64810234Syasuko.eckert@amd.com power_nand2_path.readOp.gate_leakage = gate_leak_L1_nand2 * g_tp.peri_global.Vdd; 64910234Syasuko.eckert@amd.com power_nand3_path.readOp.gate_leakage = gate_leak_L1_nand3 * g_tp.peri_global.Vdd; 65010234Syasuko.eckert@amd.com power_L2.readOp.gate_leakage = gate_leakage_L2 * g_tp.peri_global.Vdd; 65110152Satgutier@umich.edu } 65210234Syasuko.eckert@amd.com} 65310152Satgutier@umich.edu 65410152Satgutier@umich.edu 65510234Syasuko.eckert@amd.com 65610234Syasuko.eckert@amd.compair<double, double> PredecBlk::compute_delays( 65710234Syasuko.eckert@amd.com pair<double, double> inrisetime) { // <nand2, nand3> 65810234Syasuko.eckert@amd.com pair<double, double> ret_val; 65910234Syasuko.eckert@amd.com ret_val.first = 0; // outrisetime_nand2_path 66010234Syasuko.eckert@amd.com ret_val.second = 0; // outrisetime_nand3_path 66110234Syasuko.eckert@amd.com 66210234Syasuko.eckert@amd.com double inrisetime_nand2_path = inrisetime.first; 66310234Syasuko.eckert@amd.com double inrisetime_nand3_path = inrisetime.second; 66410234Syasuko.eckert@amd.com int i; 66510234Syasuko.eckert@amd.com double rd, c_load, c_intrinsic, tf, this_delay; 66610234Syasuko.eckert@amd.com double Vdd = g_tp.peri_global.Vdd; 66710234Syasuko.eckert@amd.com 66810234Syasuko.eckert@amd.com // TODO: following delay calculation part can be greatly simplified. 66910234Syasuko.eckert@amd.com // first check whether a predecoder block is required 67010234Syasuko.eckert@amd.com if (exist) { 67110234Syasuko.eckert@amd.com //Find delay in first level of predecoder block 67210234Syasuko.eckert@amd.com //First find delay in path 67310234Syasuko.eckert@amd.com if ((flag_two_unique_paths) || (number_inputs_L1_gate == 2)) { 67410234Syasuko.eckert@amd.com //First gate is a NAND2 gate 67510234Syasuko.eckert@amd.com rd = tr_R_on(w_L1_nand2_n[0], NCH, 2, is_dram_); 67610234Syasuko.eckert@amd.com c_load = gate_C(w_L1_nand2_n[1] + w_L1_nand2_p[1], 0.0, is_dram_); 67710234Syasuko.eckert@amd.com c_intrinsic = 2 * drain_C_(w_L1_nand2_p[0], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 67810234Syasuko.eckert@amd.com drain_C_(w_L1_nand2_n[0], NCH, 2, 1, g_tp.cell_h_def, is_dram_); 67910234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load); 68010234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 68110234Syasuko.eckert@amd.com delay_nand2_path += this_delay; 68210234Syasuko.eckert@amd.com inrisetime_nand2_path = this_delay / (1.0 - 0.5); 68310234Syasuko.eckert@amd.com power_nand2_path.readOp.dynamic += (c_load + c_intrinsic) * Vdd * Vdd; 68410234Syasuko.eckert@amd.com 68510234Syasuko.eckert@amd.com //Add delays of all but the last inverter in the chain 68610234Syasuko.eckert@amd.com for (i = 1; i < number_gates_L1_nand2_path - 1; ++i) { 68710234Syasuko.eckert@amd.com rd = tr_R_on(w_L1_nand2_n[i], NCH, 1, is_dram_); 68810234Syasuko.eckert@amd.com c_load = gate_C(w_L1_nand2_n[i+1] + w_L1_nand2_p[i+1], 0.0, is_dram_); 68910234Syasuko.eckert@amd.com c_intrinsic = drain_C_(w_L1_nand2_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 69010234Syasuko.eckert@amd.com drain_C_(w_L1_nand2_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 69110234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load); 69210234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 69310234Syasuko.eckert@amd.com delay_nand2_path += this_delay; 69410234Syasuko.eckert@amd.com inrisetime_nand2_path = this_delay / (1.0 - 0.5); 69510234Syasuko.eckert@amd.com power_nand2_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 69610234Syasuko.eckert@amd.com } 69710234Syasuko.eckert@amd.com 69810234Syasuko.eckert@amd.com //Add delay of the last inverter 69910234Syasuko.eckert@amd.com i = number_gates_L1_nand2_path - 1; 70010234Syasuko.eckert@amd.com rd = tr_R_on(w_L1_nand2_n[i], NCH, 1, is_dram_); 70110234Syasuko.eckert@amd.com if (flag_L2_gate) { 70210234Syasuko.eckert@amd.com c_load = branch_effort_nand2_gate_output * 70310234Syasuko.eckert@amd.com (gate_C(w_L2_n[0], 0, is_dram_) + 70410234Syasuko.eckert@amd.com gate_C(w_L2_p[0], 0, is_dram_)); 70510234Syasuko.eckert@amd.com c_intrinsic = drain_C_(w_L1_nand2_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 70610234Syasuko.eckert@amd.com drain_C_(w_L1_nand2_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 70710234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load); 70810234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 70910234Syasuko.eckert@amd.com delay_nand2_path += this_delay; 71010234Syasuko.eckert@amd.com inrisetime_nand2_path = this_delay / (1.0 - 0.5); 71110234Syasuko.eckert@amd.com power_nand2_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 71210234Syasuko.eckert@amd.com } else { //First level directly drives decoder output load 71310234Syasuko.eckert@amd.com c_load = C_ld_predec_blk_out; 71410234Syasuko.eckert@amd.com c_intrinsic = drain_C_(w_L1_nand2_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 71510234Syasuko.eckert@amd.com drain_C_(w_L1_nand2_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 71610234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load) + R_wire_predec_blk_out * c_load / 2; 71710234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 71810234Syasuko.eckert@amd.com delay_nand2_path += this_delay; 71910234Syasuko.eckert@amd.com ret_val.first = this_delay / (1.0 - 0.5); 72010234Syasuko.eckert@amd.com power_nand2_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 72110234Syasuko.eckert@amd.com } 72210234Syasuko.eckert@amd.com } 72310234Syasuko.eckert@amd.com 72410234Syasuko.eckert@amd.com if ((flag_two_unique_paths) || (number_inputs_L1_gate == 3)) { 72510234Syasuko.eckert@amd.com //Check if the number of gates in the first level is more than 1. 72610234Syasuko.eckert@amd.com //First gate is a NAND3 gate 72710234Syasuko.eckert@amd.com rd = tr_R_on(w_L1_nand3_n[0], NCH, 3, is_dram_); 72810234Syasuko.eckert@amd.com c_load = gate_C(w_L1_nand3_n[1] + w_L1_nand3_p[1], 0.0, is_dram_); 72910234Syasuko.eckert@amd.com c_intrinsic = 3 * drain_C_(w_L1_nand3_p[0], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 73010234Syasuko.eckert@amd.com drain_C_(w_L1_nand3_n[0], NCH, 3, 1, g_tp.cell_h_def, is_dram_); 73110234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load); 73210234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 73310234Syasuko.eckert@amd.com delay_nand3_path += this_delay; 73410234Syasuko.eckert@amd.com inrisetime_nand3_path = this_delay / (1.0 - 0.5); 73510234Syasuko.eckert@amd.com power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 73610234Syasuko.eckert@amd.com 73710234Syasuko.eckert@amd.com //Add delays of all but the last inverter in the chain 73810234Syasuko.eckert@amd.com for (i = 1; i < number_gates_L1_nand3_path - 1; ++i) { 73910234Syasuko.eckert@amd.com rd = tr_R_on(w_L1_nand3_n[i], NCH, 1, is_dram_); 74010234Syasuko.eckert@amd.com c_load = gate_C(w_L1_nand3_n[i+1] + w_L1_nand3_p[i+1], 0.0, is_dram_); 74110234Syasuko.eckert@amd.com c_intrinsic = drain_C_(w_L1_nand3_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 74210234Syasuko.eckert@amd.com drain_C_(w_L1_nand3_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 74310234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load); 74410234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 74510234Syasuko.eckert@amd.com delay_nand3_path += this_delay; 74610234Syasuko.eckert@amd.com inrisetime_nand3_path = this_delay / (1.0 - 0.5); 74710234Syasuko.eckert@amd.com power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 74810234Syasuko.eckert@amd.com } 74910234Syasuko.eckert@amd.com 75010234Syasuko.eckert@amd.com //Add delay of the last inverter 75110234Syasuko.eckert@amd.com i = number_gates_L1_nand3_path - 1; 75210234Syasuko.eckert@amd.com rd = tr_R_on(w_L1_nand3_n[i], NCH, 1, is_dram_); 75310234Syasuko.eckert@amd.com if (flag_L2_gate) { 75410234Syasuko.eckert@amd.com c_load = branch_effort_nand3_gate_output * 75510234Syasuko.eckert@amd.com (gate_C(w_L2_n[0], 0, is_dram_) + gate_C(w_L2_p[0], 0, 75610234Syasuko.eckert@amd.com is_dram_)); 75710234Syasuko.eckert@amd.com c_intrinsic = drain_C_(w_L1_nand3_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 75810234Syasuko.eckert@amd.com drain_C_(w_L1_nand3_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 75910234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load); 76010234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 76110234Syasuko.eckert@amd.com delay_nand3_path += this_delay; 76210234Syasuko.eckert@amd.com inrisetime_nand3_path = this_delay / (1.0 - 0.5); 76310234Syasuko.eckert@amd.com power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 76410234Syasuko.eckert@amd.com } else { //First level directly drives decoder output load 76510234Syasuko.eckert@amd.com c_load = C_ld_predec_blk_out; 76610234Syasuko.eckert@amd.com c_intrinsic = drain_C_(w_L1_nand3_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 76710234Syasuko.eckert@amd.com drain_C_(w_L1_nand3_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 76810234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load) + R_wire_predec_blk_out * c_load / 2; 76910234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 77010234Syasuko.eckert@amd.com delay_nand3_path += this_delay; 77110234Syasuko.eckert@amd.com ret_val.second = this_delay / (1.0 - 0.5); 77210234Syasuko.eckert@amd.com power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 77310234Syasuko.eckert@amd.com } 77410234Syasuko.eckert@amd.com } 77510234Syasuko.eckert@amd.com 77610234Syasuko.eckert@amd.com // Find delay through second level 77710234Syasuko.eckert@amd.com if (flag_L2_gate) { 77810234Syasuko.eckert@amd.com if (flag_L2_gate == 2) { 77910234Syasuko.eckert@amd.com rd = tr_R_on(w_L2_n[0], NCH, 2, is_dram_); 78010234Syasuko.eckert@amd.com c_load = gate_C(w_L2_n[1] + w_L2_p[1], 0.0, is_dram_); 78110234Syasuko.eckert@amd.com c_intrinsic = 2 * drain_C_(w_L2_p[0], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 78210234Syasuko.eckert@amd.com drain_C_(w_L2_n[0], NCH, 2, 1, g_tp.cell_h_def, is_dram_); 78310234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load); 78410234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 78510234Syasuko.eckert@amd.com delay_nand2_path += this_delay; 78610234Syasuko.eckert@amd.com inrisetime_nand2_path = this_delay / (1.0 - 0.5); 78710234Syasuko.eckert@amd.com power_L2.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 78810234Syasuko.eckert@amd.com } else { // flag_L2_gate = 3 78910234Syasuko.eckert@amd.com rd = tr_R_on(w_L2_n[0], NCH, 3, is_dram_); 79010234Syasuko.eckert@amd.com c_load = gate_C(w_L2_n[1] + w_L2_p[1], 0.0, is_dram_); 79110234Syasuko.eckert@amd.com c_intrinsic = 3 * drain_C_(w_L2_p[0], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 79210234Syasuko.eckert@amd.com drain_C_(w_L2_n[0], NCH, 3, 1, g_tp.cell_h_def, is_dram_); 79310234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load); 79410234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 79510234Syasuko.eckert@amd.com delay_nand3_path += this_delay; 79610234Syasuko.eckert@amd.com inrisetime_nand3_path = this_delay / (1.0 - 0.5); 79710234Syasuko.eckert@amd.com power_L2.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 79810234Syasuko.eckert@amd.com } 79910234Syasuko.eckert@amd.com 80010234Syasuko.eckert@amd.com for (i = 1; i < number_gates_L2 - 1; ++i) { 80110234Syasuko.eckert@amd.com rd = tr_R_on(w_L2_n[i], NCH, 1, is_dram_); 80210234Syasuko.eckert@amd.com c_load = gate_C(w_L2_n[i+1] + w_L2_p[i+1], 0.0, is_dram_); 80310234Syasuko.eckert@amd.com c_intrinsic = drain_C_(w_L2_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 80410234Syasuko.eckert@amd.com drain_C_(w_L2_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 80510234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load); 80610234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 80710234Syasuko.eckert@amd.com delay_nand2_path += this_delay; 80810234Syasuko.eckert@amd.com inrisetime_nand2_path = this_delay / (1.0 - 0.5); 80910234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 81010234Syasuko.eckert@amd.com delay_nand3_path += this_delay; 81110234Syasuko.eckert@amd.com inrisetime_nand3_path = this_delay / (1.0 - 0.5); 81210234Syasuko.eckert@amd.com power_L2.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 81310234Syasuko.eckert@amd.com } 81410234Syasuko.eckert@amd.com 81510234Syasuko.eckert@amd.com //Add delay of final inverter that drives the wordline decoders 81610234Syasuko.eckert@amd.com i = number_gates_L2 - 1; 81710234Syasuko.eckert@amd.com c_load = C_ld_predec_blk_out; 81810234Syasuko.eckert@amd.com rd = tr_R_on(w_L2_n[i], NCH, 1, is_dram_); 81910234Syasuko.eckert@amd.com c_intrinsic = drain_C_(w_L2_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 82010234Syasuko.eckert@amd.com drain_C_(w_L2_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 82110234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load) + R_wire_predec_blk_out * c_load / 2; 82210234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 82310234Syasuko.eckert@amd.com delay_nand2_path += this_delay; 82410234Syasuko.eckert@amd.com ret_val.first = this_delay / (1.0 - 0.5); 82510234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 82610234Syasuko.eckert@amd.com delay_nand3_path += this_delay; 82710234Syasuko.eckert@amd.com ret_val.second = this_delay / (1.0 - 0.5); 82810234Syasuko.eckert@amd.com power_L2.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd; 82910234Syasuko.eckert@amd.com } 83010152Satgutier@umich.edu } 83110152Satgutier@umich.edu 83210234Syasuko.eckert@amd.com delay = (ret_val.first > ret_val.second) ? ret_val.first : ret_val.second; 83310234Syasuko.eckert@amd.com return ret_val; 83410152Satgutier@umich.edu} 83510152Satgutier@umich.edu 83610152Satgutier@umich.eduvoid PredecBlk::leakage_feedback(double temperature) 83710152Satgutier@umich.edu{ 83810152Satgutier@umich.edu if (exist) 83910152Satgutier@umich.edu { // First check whether a predecoder block is needed 84010152Satgutier@umich.edu int num_L1_nand2 = 0; 84110152Satgutier@umich.edu int num_L1_nand3 = 0; 84210152Satgutier@umich.edu int num_L2 = 0; 84310152Satgutier@umich.edu double leak_L1_nand3 =0; 84410152Satgutier@umich.edu double gate_leak_L1_nand3 =0; 84510152Satgutier@umich.edu 84610152Satgutier@umich.edu double leak_L1_nand2 = cmos_Isub_leakage(w_L1_nand2_n[0], w_L1_nand2_p[0], 2, nand, is_dram_); 84710152Satgutier@umich.edu double gate_leak_L1_nand2 = cmos_Ig_leakage(w_L1_nand2_n[0], w_L1_nand2_p[0], 2, nand, is_dram_); 84810152Satgutier@umich.edu if (number_inputs_L1_gate != 3) { 84910152Satgutier@umich.edu leak_L1_nand3 = 0; 85010152Satgutier@umich.edu gate_leak_L1_nand3 =0; 85110152Satgutier@umich.edu } 85210152Satgutier@umich.edu else { 85310152Satgutier@umich.edu leak_L1_nand3 = cmos_Isub_leakage(w_L1_nand3_n[0], w_L1_nand3_p[0], 3, nand); 85410152Satgutier@umich.edu gate_leak_L1_nand3 = cmos_Ig_leakage(w_L1_nand3_n[0], w_L1_nand3_p[0], 3, nand); 85510152Satgutier@umich.edu } 85610152Satgutier@umich.edu 85710152Satgutier@umich.edu switch (number_input_addr_bits) 85810152Satgutier@umich.edu { 85910152Satgutier@umich.edu case 1: //2 NAND2 gates 86010152Satgutier@umich.edu num_L1_nand2 = 2; 86110152Satgutier@umich.edu num_L2 = 0; 86210152Satgutier@umich.edu num_L1_active_nand2_path =1; 86310152Satgutier@umich.edu num_L1_active_nand3_path =0; 86410152Satgutier@umich.edu break; 86510152Satgutier@umich.edu case 2: //4 NAND2 gates 86610152Satgutier@umich.edu num_L1_nand2 = 4; 86710152Satgutier@umich.edu num_L2 = 0; 86810152Satgutier@umich.edu num_L1_active_nand2_path =1; 86910152Satgutier@umich.edu num_L1_active_nand3_path =0; 87010152Satgutier@umich.edu break; 87110152Satgutier@umich.edu case 3: //8 NAND3 gates 87210152Satgutier@umich.edu num_L1_nand3 = 8; 87310152Satgutier@umich.edu num_L2 = 0; 87410152Satgutier@umich.edu num_L1_active_nand2_path =0; 87510152Satgutier@umich.edu num_L1_active_nand3_path =1; 87610152Satgutier@umich.edu break; 87710152Satgutier@umich.edu case 4: //4 + 4 NAND2 gates 87810152Satgutier@umich.edu num_L1_nand2 = 8; 87910152Satgutier@umich.edu num_L2 = 16; 88010152Satgutier@umich.edu num_L1_active_nand2_path =2; 88110152Satgutier@umich.edu num_L1_active_nand3_path =0; 88210152Satgutier@umich.edu break; 88310152Satgutier@umich.edu case 5: //4 NAND2 gates, 8 NAND3 gates 88410152Satgutier@umich.edu num_L1_nand2 = 4; 88510152Satgutier@umich.edu num_L1_nand3 = 8; 88610152Satgutier@umich.edu num_L2 = 32; 88710152Satgutier@umich.edu num_L1_active_nand2_path =1; 88810152Satgutier@umich.edu num_L1_active_nand3_path =1; 88910152Satgutier@umich.edu break; 89010152Satgutier@umich.edu case 6: //8 + 8 NAND3 gates 89110152Satgutier@umich.edu num_L1_nand3 = 16; 89210152Satgutier@umich.edu num_L2 = 64; 89310152Satgutier@umich.edu num_L1_active_nand2_path =0; 89410152Satgutier@umich.edu num_L1_active_nand3_path =2; 89510152Satgutier@umich.edu break; 89610152Satgutier@umich.edu case 7: //4 + 4 NAND2 gates, 8 NAND3 gates 89710152Satgutier@umich.edu num_L1_nand2 = 8; 89810152Satgutier@umich.edu num_L1_nand3 = 8; 89910152Satgutier@umich.edu num_L2 = 128; 90010152Satgutier@umich.edu num_L1_active_nand2_path =2; 90110152Satgutier@umich.edu num_L1_active_nand3_path =1; 90210152Satgutier@umich.edu break; 90310152Satgutier@umich.edu case 8: //4 NAND2 gates, 8 + 8 NAND3 gates 90410152Satgutier@umich.edu num_L1_nand2 = 4; 90510152Satgutier@umich.edu num_L1_nand3 = 16; 90610152Satgutier@umich.edu num_L2 = 256; 90710152Satgutier@umich.edu num_L1_active_nand2_path =2; 90810152Satgutier@umich.edu num_L1_active_nand3_path =2; 90910152Satgutier@umich.edu break; 91010152Satgutier@umich.edu case 9: //8 + 8 + 8 NAND3 gates 91110152Satgutier@umich.edu num_L1_nand3 = 24; 91210152Satgutier@umich.edu num_L2 = 512; 91310152Satgutier@umich.edu num_L1_active_nand2_path =0; 91410152Satgutier@umich.edu num_L1_active_nand3_path =3; 91510152Satgutier@umich.edu break; 91610152Satgutier@umich.edu default: 91710152Satgutier@umich.edu break; 91810152Satgutier@umich.edu } 91910152Satgutier@umich.edu 92010152Satgutier@umich.edu for (int i = 1; i < number_gates_L1_nand2_path; ++i) 92110152Satgutier@umich.edu { 92210152Satgutier@umich.edu leak_L1_nand2 += cmos_Isub_leakage(w_L1_nand2_n[i], w_L1_nand2_p[i], 2, nand, is_dram_); 92310152Satgutier@umich.edu gate_leak_L1_nand2 += cmos_Ig_leakage(w_L1_nand2_n[i], w_L1_nand2_p[i], 2, nand, is_dram_); 92410152Satgutier@umich.edu } 92510152Satgutier@umich.edu leak_L1_nand2 *= num_L1_nand2; 92610152Satgutier@umich.edu gate_leak_L1_nand2 *= num_L1_nand2; 92710152Satgutier@umich.edu 92810152Satgutier@umich.edu for (int i = 1; i < number_gates_L1_nand3_path; ++i) 92910152Satgutier@umich.edu { 93010152Satgutier@umich.edu leak_L1_nand3 += cmos_Isub_leakage(w_L1_nand3_n[i], w_L1_nand3_p[i], 3, nand, is_dram_); 93110152Satgutier@umich.edu gate_leak_L1_nand3 += cmos_Ig_leakage(w_L1_nand3_n[i], w_L1_nand3_p[i], 3, nand, is_dram_); 93210152Satgutier@umich.edu } 93310152Satgutier@umich.edu leak_L1_nand3 *= num_L1_nand3; 93410152Satgutier@umich.edu gate_leak_L1_nand3 *= num_L1_nand3; 93510152Satgutier@umich.edu 93610152Satgutier@umich.edu double leakage_L2 = 0.0; 93710152Satgutier@umich.edu double gate_leakage_L2 = 0.0; 93810152Satgutier@umich.edu 93910152Satgutier@umich.edu if (flag_L2_gate == 2) 94010152Satgutier@umich.edu { 94110152Satgutier@umich.edu leakage_L2 = cmos_Isub_leakage(w_L2_n[0], w_L2_p[0], 2, nand, is_dram_); 94210152Satgutier@umich.edu gate_leakage_L2 = cmos_Ig_leakage(w_L2_n[0], w_L2_p[0], 2, nand, is_dram_); 94310152Satgutier@umich.edu } 94410152Satgutier@umich.edu else if (flag_L2_gate == 3) 94510152Satgutier@umich.edu { 94610152Satgutier@umich.edu leakage_L2 = cmos_Isub_leakage(w_L2_n[0], w_L2_p[0], 3, nand, is_dram_); 94710152Satgutier@umich.edu gate_leakage_L2 = cmos_Ig_leakage(w_L2_n[0], w_L2_p[0], 3, nand, is_dram_); 94810152Satgutier@umich.edu } 94910152Satgutier@umich.edu 95010152Satgutier@umich.edu for (int i = 1; i < number_gates_L2; ++i) 95110152Satgutier@umich.edu { 95210152Satgutier@umich.edu leakage_L2 += cmos_Isub_leakage(w_L2_n[i], w_L2_p[i], 2, inv, is_dram_); 95310152Satgutier@umich.edu gate_leakage_L2 += cmos_Ig_leakage(w_L2_n[i], w_L2_p[i], 2, inv, is_dram_); 95410152Satgutier@umich.edu } 95510152Satgutier@umich.edu leakage_L2 *= num_L2; 95610152Satgutier@umich.edu gate_leakage_L2 *= num_L2; 95710152Satgutier@umich.edu 95810152Satgutier@umich.edu power_nand2_path.readOp.leakage = leak_L1_nand2 * g_tp.peri_global.Vdd; 95910152Satgutier@umich.edu power_nand3_path.readOp.leakage = leak_L1_nand3 * g_tp.peri_global.Vdd; 96010152Satgutier@umich.edu power_L2.readOp.leakage = leakage_L2 * g_tp.peri_global.Vdd; 96110152Satgutier@umich.edu 96210152Satgutier@umich.edu power_nand2_path.readOp.gate_leakage = gate_leak_L1_nand2 * g_tp.peri_global.Vdd; 96310152Satgutier@umich.edu power_nand3_path.readOp.gate_leakage = gate_leak_L1_nand3 * g_tp.peri_global.Vdd; 96410152Satgutier@umich.edu power_L2.readOp.gate_leakage = gate_leakage_L2 * g_tp.peri_global.Vdd; 96510152Satgutier@umich.edu } 96610152Satgutier@umich.edu} 96710152Satgutier@umich.edu 96810152Satgutier@umich.eduPredecBlkDrv::PredecBlkDrv( 96910152Satgutier@umich.edu int way_select_, 97010152Satgutier@umich.edu PredecBlk * blk_, 97110152Satgutier@umich.edu bool is_dram) 97210234Syasuko.eckert@amd.com : flag_driver_exists(0), 97310234Syasuko.eckert@amd.com number_gates_nand2_path(0), 97410234Syasuko.eckert@amd.com number_gates_nand3_path(0), 97510234Syasuko.eckert@amd.com min_number_gates(2), 97610234Syasuko.eckert@amd.com num_buffers_driving_1_nand2_load(0), 97710234Syasuko.eckert@amd.com num_buffers_driving_2_nand2_load(0), 97810234Syasuko.eckert@amd.com num_buffers_driving_4_nand2_load(0), 97910234Syasuko.eckert@amd.com num_buffers_driving_2_nand3_load(0), 98010234Syasuko.eckert@amd.com num_buffers_driving_8_nand3_load(0), 98110234Syasuko.eckert@amd.com num_buffers_nand3_path(0), 98210234Syasuko.eckert@amd.com c_load_nand2_path_out(0), 98310234Syasuko.eckert@amd.com c_load_nand3_path_out(0), 98410234Syasuko.eckert@amd.com r_load_nand2_path_out(0), 98510234Syasuko.eckert@amd.com r_load_nand3_path_out(0), 98610234Syasuko.eckert@amd.com delay_nand2_path(0), 98710234Syasuko.eckert@amd.com delay_nand3_path(0), 98810234Syasuko.eckert@amd.com power_nand2_path(), 98910234Syasuko.eckert@amd.com power_nand3_path(), 99010234Syasuko.eckert@amd.com blk(blk_), dec(blk->dec), 99110234Syasuko.eckert@amd.com is_dram_(is_dram), 99210234Syasuko.eckert@amd.com way_select(way_select_) { 99310234Syasuko.eckert@amd.com for (int i = 0; i < MAX_NUMBER_GATES_STAGE; i++) { 99410234Syasuko.eckert@amd.com width_nand2_path_n[i] = 0; 99510234Syasuko.eckert@amd.com width_nand2_path_p[i] = 0; 99610234Syasuko.eckert@amd.com width_nand3_path_n[i] = 0; 99710234Syasuko.eckert@amd.com width_nand3_path_p[i] = 0; 99810234Syasuko.eckert@amd.com } 99910152Satgutier@umich.edu 100010234Syasuko.eckert@amd.com number_input_addr_bits = blk->number_input_addr_bits; 100110152Satgutier@umich.edu 100210234Syasuko.eckert@amd.com if (way_select > 1) { 100310234Syasuko.eckert@amd.com flag_driver_exists = 1; 100410234Syasuko.eckert@amd.com number_input_addr_bits = way_select; 100510234Syasuko.eckert@amd.com if (dec->num_in_signals == 2) { 100610234Syasuko.eckert@amd.com c_load_nand2_path_out = gate_C(dec->w_dec_n[0] + dec->w_dec_p[0], 0, is_dram_); 100710234Syasuko.eckert@amd.com num_buffers_driving_2_nand2_load = number_input_addr_bits; 100810234Syasuko.eckert@amd.com } else if (dec->num_in_signals == 3) { 100910234Syasuko.eckert@amd.com c_load_nand3_path_out = gate_C(dec->w_dec_n[0] + dec->w_dec_p[0], 0, is_dram_); 101010234Syasuko.eckert@amd.com num_buffers_driving_2_nand3_load = number_input_addr_bits; 101110234Syasuko.eckert@amd.com } 101210234Syasuko.eckert@amd.com } else if (way_select == 0) { 101310234Syasuko.eckert@amd.com if (blk->exist) { 101410234Syasuko.eckert@amd.com flag_driver_exists = 1; 101510234Syasuko.eckert@amd.com } 101610152Satgutier@umich.edu } 101710152Satgutier@umich.edu 101810234Syasuko.eckert@amd.com compute_widths(); 101910234Syasuko.eckert@amd.com compute_area(); 102010152Satgutier@umich.edu} 102110152Satgutier@umich.edu 102210152Satgutier@umich.edu 102310152Satgutier@umich.edu 102410234Syasuko.eckert@amd.comvoid PredecBlkDrv::compute_widths() { 102510234Syasuko.eckert@amd.com // The predecode block driver accepts as input the address bits from the h-tree network. For 102610234Syasuko.eckert@amd.com // each addr bit it then generates addr and addrbar as outputs. For now ignore the effect of 102710234Syasuko.eckert@amd.com // inversion to generate addrbar and simply treat addrbar as addr. 102810152Satgutier@umich.edu 102910234Syasuko.eckert@amd.com double F; 103010234Syasuko.eckert@amd.com double p_to_n_sz_ratio = pmos_to_nmos_sz_ratio(is_dram_); 103110152Satgutier@umich.edu 103210234Syasuko.eckert@amd.com if (flag_driver_exists) { 103310234Syasuko.eckert@amd.com double C_nand2_gate_blk = gate_C(blk->w_L1_nand2_n[0] + blk->w_L1_nand2_p[0], 0, is_dram_); 103410234Syasuko.eckert@amd.com double C_nand3_gate_blk = gate_C(blk->w_L1_nand3_n[0] + blk->w_L1_nand3_p[0], 0, is_dram_); 103510152Satgutier@umich.edu 103610234Syasuko.eckert@amd.com if (way_select == 0) { 103710234Syasuko.eckert@amd.com if (blk->number_input_addr_bits == 1) { 103810234Syasuko.eckert@amd.com //2 NAND2 gates 103910234Syasuko.eckert@amd.com num_buffers_driving_2_nand2_load = 1; 104010234Syasuko.eckert@amd.com c_load_nand2_path_out = 2 * C_nand2_gate_blk; 104110234Syasuko.eckert@amd.com } else if (blk->number_input_addr_bits == 2) { 104210234Syasuko.eckert@amd.com //4 NAND2 gates one 2-4 decoder 104310234Syasuko.eckert@amd.com num_buffers_driving_4_nand2_load = 2; 104410234Syasuko.eckert@amd.com c_load_nand2_path_out = 4 * C_nand2_gate_blk; 104510234Syasuko.eckert@amd.com } else if (blk->number_input_addr_bits == 3) { 104610234Syasuko.eckert@amd.com //8 NAND3 gates one 3-8 decoder 104710234Syasuko.eckert@amd.com num_buffers_driving_8_nand3_load = 3; 104810234Syasuko.eckert@amd.com c_load_nand3_path_out = 8 * C_nand3_gate_blk; 104910234Syasuko.eckert@amd.com } else if (blk->number_input_addr_bits == 4) { 105010234Syasuko.eckert@amd.com //4 + 4 NAND2 gates two 2-4 decoder 105110234Syasuko.eckert@amd.com num_buffers_driving_4_nand2_load = 4; 105210234Syasuko.eckert@amd.com c_load_nand2_path_out = 4 * C_nand2_gate_blk; 105310234Syasuko.eckert@amd.com } else if (blk->number_input_addr_bits == 5) { 105410234Syasuko.eckert@amd.com //4 NAND2 gates, 8 NAND3 gates one 2-4 decoder and one 3-8 105510234Syasuko.eckert@amd.com //decoder 105610234Syasuko.eckert@amd.com num_buffers_driving_4_nand2_load = 2; 105710234Syasuko.eckert@amd.com num_buffers_driving_8_nand3_load = 3; 105810234Syasuko.eckert@amd.com c_load_nand2_path_out = 4 * C_nand2_gate_blk; 105910234Syasuko.eckert@amd.com c_load_nand3_path_out = 8 * C_nand3_gate_blk; 106010234Syasuko.eckert@amd.com } else if (blk->number_input_addr_bits == 6) { 106110234Syasuko.eckert@amd.com //8 + 8 NAND3 gates two 3-8 decoder 106210234Syasuko.eckert@amd.com num_buffers_driving_8_nand3_load = 6; 106310234Syasuko.eckert@amd.com c_load_nand3_path_out = 8 * C_nand3_gate_blk; 106410234Syasuko.eckert@amd.com } else if (blk->number_input_addr_bits == 7) { 106510234Syasuko.eckert@amd.com //4 + 4 NAND2 gates, 8 NAND3 gates two 2-4 decoder and one 3-8 106610234Syasuko.eckert@amd.com //decoder 106710234Syasuko.eckert@amd.com num_buffers_driving_4_nand2_load = 4; 106810234Syasuko.eckert@amd.com num_buffers_driving_8_nand3_load = 3; 106910234Syasuko.eckert@amd.com c_load_nand2_path_out = 4 * C_nand2_gate_blk; 107010234Syasuko.eckert@amd.com c_load_nand3_path_out = 8 * C_nand3_gate_blk; 107110234Syasuko.eckert@amd.com } else if (blk->number_input_addr_bits == 8) { 107210234Syasuko.eckert@amd.com //4 NAND2 gates, 8 + 8 NAND3 gates one 2-4 decoder and two 3-8 107310234Syasuko.eckert@amd.com //decoder 107410234Syasuko.eckert@amd.com num_buffers_driving_4_nand2_load = 2; 107510234Syasuko.eckert@amd.com num_buffers_driving_8_nand3_load = 6; 107610234Syasuko.eckert@amd.com c_load_nand2_path_out = 4 * C_nand2_gate_blk; 107710234Syasuko.eckert@amd.com c_load_nand3_path_out = 8 * C_nand3_gate_blk; 107810234Syasuko.eckert@amd.com } else if (blk->number_input_addr_bits == 9) { 107910234Syasuko.eckert@amd.com //8 + 8 + 8 NAND3 gates three 3-8 decoder 108010234Syasuko.eckert@amd.com num_buffers_driving_8_nand3_load = 9; 108110234Syasuko.eckert@amd.com c_load_nand3_path_out = 8 * C_nand3_gate_blk; 108210234Syasuko.eckert@amd.com } 108310234Syasuko.eckert@amd.com } 108410234Syasuko.eckert@amd.com 108510234Syasuko.eckert@amd.com if ((blk->flag_two_unique_paths) || 108610234Syasuko.eckert@amd.com (blk->number_inputs_L1_gate == 2) || 108710234Syasuko.eckert@amd.com (number_input_addr_bits == 0) || 108810234Syasuko.eckert@amd.com ((way_select) && (dec->num_in_signals == 2))) { 108910234Syasuko.eckert@amd.com //this means that way_select is driving NAND2 in decoder. 109010234Syasuko.eckert@amd.com width_nand2_path_n[0] = g_tp.min_w_nmos_; 109110234Syasuko.eckert@amd.com width_nand2_path_p[0] = p_to_n_sz_ratio * width_nand2_path_n[0]; 109210234Syasuko.eckert@amd.com F = c_load_nand2_path_out / gate_C(width_nand2_path_n[0] + width_nand2_path_p[0], 0, is_dram_); 109310234Syasuko.eckert@amd.com number_gates_nand2_path = logical_effort( 109410234Syasuko.eckert@amd.com min_number_gates, 109510234Syasuko.eckert@amd.com 1, 109610234Syasuko.eckert@amd.com F, 109710234Syasuko.eckert@amd.com width_nand2_path_n, 109810234Syasuko.eckert@amd.com width_nand2_path_p, 109910234Syasuko.eckert@amd.com c_load_nand2_path_out, 110010234Syasuko.eckert@amd.com p_to_n_sz_ratio, 110110234Syasuko.eckert@amd.com is_dram_, false, g_tp.max_w_nmos_); 110210234Syasuko.eckert@amd.com } 110310234Syasuko.eckert@amd.com 110410234Syasuko.eckert@amd.com if ((blk->flag_two_unique_paths) || 110510234Syasuko.eckert@amd.com (blk->number_inputs_L1_gate == 3) || 110610234Syasuko.eckert@amd.com ((way_select) && (dec->num_in_signals == 3))) { 110710234Syasuko.eckert@amd.com //this means that way_select is driving NAND3 in decoder. 110810234Syasuko.eckert@amd.com width_nand3_path_n[0] = g_tp.min_w_nmos_; 110910234Syasuko.eckert@amd.com width_nand3_path_p[0] = p_to_n_sz_ratio * width_nand3_path_n[0]; 111010234Syasuko.eckert@amd.com F = c_load_nand3_path_out / gate_C(width_nand3_path_n[0] + width_nand3_path_p[0], 0, is_dram_); 111110234Syasuko.eckert@amd.com number_gates_nand3_path = logical_effort( 111210234Syasuko.eckert@amd.com min_number_gates, 111310234Syasuko.eckert@amd.com 1, 111410234Syasuko.eckert@amd.com F, 111510234Syasuko.eckert@amd.com width_nand3_path_n, 111610234Syasuko.eckert@amd.com width_nand3_path_p, 111710234Syasuko.eckert@amd.com c_load_nand3_path_out, 111810234Syasuko.eckert@amd.com p_to_n_sz_ratio, 111910234Syasuko.eckert@amd.com is_dram_, false, g_tp.max_w_nmos_); 112010234Syasuko.eckert@amd.com } 112110152Satgutier@umich.edu } 112210152Satgutier@umich.edu} 112310152Satgutier@umich.edu 112410152Satgutier@umich.edu 112510152Satgutier@umich.edu 112610234Syasuko.eckert@amd.comvoid PredecBlkDrv::compute_area() { 112710234Syasuko.eckert@amd.com double area_nand2_path = 0; 112810234Syasuko.eckert@amd.com double area_nand3_path = 0; 112910234Syasuko.eckert@amd.com double leak_nand2_path = 0; 113010234Syasuko.eckert@amd.com double leak_nand3_path = 0; 113110234Syasuko.eckert@amd.com double gate_leak_nand2_path = 0; 113210234Syasuko.eckert@amd.com double gate_leak_nand3_path = 0; 113310152Satgutier@umich.edu 113410234Syasuko.eckert@amd.com if (flag_driver_exists) { 113510234Syasuko.eckert@amd.com // first check whether a predecoder block driver is needed 113610234Syasuko.eckert@amd.com for (int i = 0; i < number_gates_nand2_path; ++i) { 113710234Syasuko.eckert@amd.com area_nand2_path += 113810234Syasuko.eckert@amd.com compute_gate_area(INV, 1, width_nand2_path_p[i], 113910234Syasuko.eckert@amd.com width_nand2_path_n[i], g_tp.cell_h_def); 114010234Syasuko.eckert@amd.com leak_nand2_path += 114110234Syasuko.eckert@amd.com cmos_Isub_leakage(width_nand2_path_n[i], width_nand2_path_p[i], 114210234Syasuko.eckert@amd.com 1, inv, is_dram_); 114310234Syasuko.eckert@amd.com gate_leak_nand2_path += 114410234Syasuko.eckert@amd.com cmos_Ig_leakage(width_nand2_path_n[i], width_nand2_path_p[i], 114510234Syasuko.eckert@amd.com 1, inv, is_dram_); 114610234Syasuko.eckert@amd.com } 114710234Syasuko.eckert@amd.com area_nand2_path *= (num_buffers_driving_1_nand2_load + 114810152Satgutier@umich.edu num_buffers_driving_2_nand2_load + 114910152Satgutier@umich.edu num_buffers_driving_4_nand2_load); 115010234Syasuko.eckert@amd.com leak_nand2_path *= (num_buffers_driving_1_nand2_load + 115110234Syasuko.eckert@amd.com num_buffers_driving_2_nand2_load + 115210234Syasuko.eckert@amd.com num_buffers_driving_4_nand2_load); 115310234Syasuko.eckert@amd.com gate_leak_nand2_path *= (num_buffers_driving_1_nand2_load + 115410234Syasuko.eckert@amd.com num_buffers_driving_2_nand2_load + 115510234Syasuko.eckert@amd.com num_buffers_driving_4_nand2_load); 115610152Satgutier@umich.edu 115710234Syasuko.eckert@amd.com for (int i = 0; i < number_gates_nand3_path; ++i) { 115810234Syasuko.eckert@amd.com area_nand3_path += 115910234Syasuko.eckert@amd.com compute_gate_area(INV, 1, width_nand3_path_p[i], 116010234Syasuko.eckert@amd.com width_nand3_path_n[i], g_tp.cell_h_def); 116110234Syasuko.eckert@amd.com leak_nand3_path += 116210234Syasuko.eckert@amd.com cmos_Isub_leakage(width_nand3_path_n[i], width_nand3_path_p[i], 116310234Syasuko.eckert@amd.com 1, inv, is_dram_); 116410234Syasuko.eckert@amd.com gate_leak_nand3_path += 116510234Syasuko.eckert@amd.com cmos_Ig_leakage(width_nand3_path_n[i], width_nand3_path_p[i], 116610234Syasuko.eckert@amd.com 1, inv, is_dram_); 116710234Syasuko.eckert@amd.com } 116810234Syasuko.eckert@amd.com area_nand3_path *= (num_buffers_driving_2_nand3_load + num_buffers_driving_8_nand3_load); 116910234Syasuko.eckert@amd.com leak_nand3_path *= (num_buffers_driving_2_nand3_load + num_buffers_driving_8_nand3_load); 117010234Syasuko.eckert@amd.com gate_leak_nand3_path *= (num_buffers_driving_2_nand3_load + num_buffers_driving_8_nand3_load); 117110234Syasuko.eckert@amd.com 117210234Syasuko.eckert@amd.com power_nand2_path.readOp.leakage = leak_nand2_path * g_tp.peri_global.Vdd; 117310234Syasuko.eckert@amd.com power_nand3_path.readOp.leakage = leak_nand3_path * g_tp.peri_global.Vdd; 117410234Syasuko.eckert@amd.com power_nand2_path.readOp.gate_leakage = gate_leak_nand2_path * g_tp.peri_global.Vdd; 117510234Syasuko.eckert@amd.com power_nand3_path.readOp.gate_leakage = gate_leak_nand3_path * g_tp.peri_global.Vdd; 117610234Syasuko.eckert@amd.com area.set_area(area_nand2_path + area_nand3_path); 117710152Satgutier@umich.edu } 117810152Satgutier@umich.edu} 117910152Satgutier@umich.edu 118010152Satgutier@umich.edu 118110152Satgutier@umich.edu 118210152Satgutier@umich.edupair<double, double> PredecBlkDrv::compute_delays( 118310152Satgutier@umich.edu double inrisetime_nand2_path, 118410234Syasuko.eckert@amd.com double inrisetime_nand3_path) { 118510234Syasuko.eckert@amd.com pair<double, double> ret_val; 118610234Syasuko.eckert@amd.com ret_val.first = 0; // outrisetime_nand2_path 118710234Syasuko.eckert@amd.com ret_val.second = 0; // outrisetime_nand3_path 118810234Syasuko.eckert@amd.com int i; 118910234Syasuko.eckert@amd.com double rd, c_gate_load, c_load, c_intrinsic, tf, this_delay; 119010234Syasuko.eckert@amd.com double Vdd = g_tp.peri_global.Vdd; 119110152Satgutier@umich.edu 119210234Syasuko.eckert@amd.com if (flag_driver_exists) { 119310234Syasuko.eckert@amd.com for (i = 0; i < number_gates_nand2_path - 1; ++i) { 119410234Syasuko.eckert@amd.com rd = tr_R_on(width_nand2_path_n[i], NCH, 1, is_dram_); 119510234Syasuko.eckert@amd.com c_gate_load = gate_C(width_nand2_path_p[i+1] + width_nand2_path_n[i+1], 0.0, is_dram_); 119610234Syasuko.eckert@amd.com c_intrinsic = drain_C_(width_nand2_path_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 119710234Syasuko.eckert@amd.com drain_C_(width_nand2_path_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 119810234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_gate_load); 119910234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 120010234Syasuko.eckert@amd.com delay_nand2_path += this_delay; 120110234Syasuko.eckert@amd.com inrisetime_nand2_path = this_delay / (1.0 - 0.5); 120210234Syasuko.eckert@amd.com power_nand2_path.readOp.dynamic += (c_gate_load + c_intrinsic) * 0.5 * Vdd * Vdd; 120310234Syasuko.eckert@amd.com } 120410234Syasuko.eckert@amd.com 120510234Syasuko.eckert@amd.com // Final inverter drives the predecoder block or the decoder output load 120610234Syasuko.eckert@amd.com if (number_gates_nand2_path != 0) { 120710234Syasuko.eckert@amd.com i = number_gates_nand2_path - 1; 120810234Syasuko.eckert@amd.com rd = tr_R_on(width_nand2_path_n[i], NCH, 1, is_dram_); 120910234Syasuko.eckert@amd.com c_intrinsic = drain_C_(width_nand2_path_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 121010234Syasuko.eckert@amd.com drain_C_(width_nand2_path_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 121110234Syasuko.eckert@amd.com c_load = c_load_nand2_path_out; 121210234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load) + r_load_nand2_path_out * c_load / 2; 121310234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand2_path, tf, 0.5, 0.5, RISE); 121410234Syasuko.eckert@amd.com delay_nand2_path += this_delay; 121510234Syasuko.eckert@amd.com ret_val.first = this_delay / (1.0 - 0.5); 121610234Syasuko.eckert@amd.com power_nand2_path.readOp.dynamic += (c_intrinsic + c_load) * 0.5 * Vdd * Vdd; 121710234Syasuko.eckert@amd.com// cout<< "c_intrinsic = " << c_intrinsic << "c_load" << c_load <<endl; 121810234Syasuko.eckert@amd.com } 121910234Syasuko.eckert@amd.com 122010234Syasuko.eckert@amd.com for (i = 0; i < number_gates_nand3_path - 1; ++i) { 122110234Syasuko.eckert@amd.com rd = tr_R_on(width_nand3_path_n[i], NCH, 1, is_dram_); 122210234Syasuko.eckert@amd.com c_gate_load = gate_C(width_nand3_path_p[i+1] + width_nand3_path_n[i+1], 0.0, is_dram_); 122310234Syasuko.eckert@amd.com c_intrinsic = drain_C_(width_nand3_path_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 122410234Syasuko.eckert@amd.com drain_C_(width_nand3_path_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 122510234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_gate_load); 122610234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 122710234Syasuko.eckert@amd.com delay_nand3_path += this_delay; 122810234Syasuko.eckert@amd.com inrisetime_nand3_path = this_delay / (1.0 - 0.5); 122910234Syasuko.eckert@amd.com power_nand3_path.readOp.dynamic += (c_gate_load + c_intrinsic) * 0.5 * Vdd * Vdd; 123010234Syasuko.eckert@amd.com } 123110234Syasuko.eckert@amd.com 123210234Syasuko.eckert@amd.com // Final inverter drives the predecoder block or the decoder output load 123310234Syasuko.eckert@amd.com if (number_gates_nand3_path != 0) { 123410234Syasuko.eckert@amd.com i = number_gates_nand3_path - 1; 123510234Syasuko.eckert@amd.com rd = tr_R_on(width_nand3_path_n[i], NCH, 1, is_dram_); 123610234Syasuko.eckert@amd.com c_intrinsic = drain_C_(width_nand3_path_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 123710234Syasuko.eckert@amd.com drain_C_(width_nand3_path_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 123810234Syasuko.eckert@amd.com c_load = c_load_nand3_path_out; 123910234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load) + r_load_nand3_path_out * c_load / 2; 124010234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime_nand3_path, tf, 0.5, 0.5, RISE); 124110234Syasuko.eckert@amd.com delay_nand3_path += this_delay; 124210234Syasuko.eckert@amd.com ret_val.second = this_delay / (1.0 - 0.5); 124310234Syasuko.eckert@amd.com power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * 0.5 * Vdd * Vdd; 124410234Syasuko.eckert@amd.com } 124510152Satgutier@umich.edu } 124610234Syasuko.eckert@amd.com return ret_val; 124710152Satgutier@umich.edu} 124810152Satgutier@umich.edu 124910152Satgutier@umich.edu 125010234Syasuko.eckert@amd.comdouble PredecBlkDrv::get_rdOp_dynamic_E(int num_act_mats_hor_dir) { 125110234Syasuko.eckert@amd.com return (num_addr_bits_nand2_path()*power_nand2_path.readOp.dynamic + 125210234Syasuko.eckert@amd.com num_addr_bits_nand3_path()*power_nand3_path.readOp.dynamic) * num_act_mats_hor_dir; 125310152Satgutier@umich.edu} 125410152Satgutier@umich.edu 125510152Satgutier@umich.edu 125610152Satgutier@umich.edu 125710152Satgutier@umich.eduPredec::Predec( 125810152Satgutier@umich.edu PredecBlkDrv * drv1_, 125910152Satgutier@umich.edu PredecBlkDrv * drv2_) 126010234Syasuko.eckert@amd.com : blk1(drv1_->blk), blk2(drv2_->blk), drv1(drv1_), drv2(drv2_) { 126110234Syasuko.eckert@amd.com driver_power.readOp.leakage = drv1->power_nand2_path.readOp.leakage + 126210234Syasuko.eckert@amd.com drv1->power_nand3_path.readOp.leakage + 126310234Syasuko.eckert@amd.com drv2->power_nand2_path.readOp.leakage + 126410234Syasuko.eckert@amd.com drv2->power_nand3_path.readOp.leakage; 126510234Syasuko.eckert@amd.com block_power.readOp.leakage = blk1->power_nand2_path.readOp.leakage + 126610234Syasuko.eckert@amd.com blk1->power_nand3_path.readOp.leakage + 126710234Syasuko.eckert@amd.com blk1->power_L2.readOp.leakage + 126810234Syasuko.eckert@amd.com blk2->power_nand2_path.readOp.leakage + 126910234Syasuko.eckert@amd.com blk2->power_nand3_path.readOp.leakage + 127010234Syasuko.eckert@amd.com blk2->power_L2.readOp.leakage; 127110234Syasuko.eckert@amd.com power.readOp.leakage = driver_power.readOp.leakage + block_power.readOp.leakage; 127210152Satgutier@umich.edu 127310234Syasuko.eckert@amd.com driver_power.readOp.gate_leakage = drv1->power_nand2_path.readOp.gate_leakage + 127410234Syasuko.eckert@amd.com drv1->power_nand3_path.readOp.gate_leakage + 127510234Syasuko.eckert@amd.com drv2->power_nand2_path.readOp.gate_leakage + 127610234Syasuko.eckert@amd.com drv2->power_nand3_path.readOp.gate_leakage; 127710234Syasuko.eckert@amd.com block_power.readOp.gate_leakage = blk1->power_nand2_path.readOp.gate_leakage + 127810234Syasuko.eckert@amd.com blk1->power_nand3_path.readOp.gate_leakage + 127910234Syasuko.eckert@amd.com blk1->power_L2.readOp.gate_leakage + 128010234Syasuko.eckert@amd.com blk2->power_nand2_path.readOp.gate_leakage + 128110234Syasuko.eckert@amd.com blk2->power_nand3_path.readOp.gate_leakage + 128210234Syasuko.eckert@amd.com blk2->power_L2.readOp.gate_leakage; 128310234Syasuko.eckert@amd.com power.readOp.gate_leakage = driver_power.readOp.gate_leakage + block_power.readOp.gate_leakage; 128410152Satgutier@umich.edu} 128510152Satgutier@umich.edu 128610152Satgutier@umich.eduvoid PredecBlkDrv::leakage_feedback(double temperature) 128710152Satgutier@umich.edu{ 128810152Satgutier@umich.edu double leak_nand2_path = 0; 128910152Satgutier@umich.edu double leak_nand3_path = 0; 129010152Satgutier@umich.edu double gate_leak_nand2_path = 0; 129110152Satgutier@umich.edu double gate_leak_nand3_path = 0; 129210152Satgutier@umich.edu 129310152Satgutier@umich.edu if (flag_driver_exists) 129410152Satgutier@umich.edu { // first check whether a predecoder block driver is needed 129510152Satgutier@umich.edu for (int i = 0; i < number_gates_nand2_path; ++i) 129610152Satgutier@umich.edu { 129710152Satgutier@umich.edu leak_nand2_path += cmos_Isub_leakage(width_nand2_path_n[i], width_nand2_path_p[i], 1, inv,is_dram_); 129810152Satgutier@umich.edu gate_leak_nand2_path += cmos_Ig_leakage(width_nand2_path_n[i], width_nand2_path_p[i], 1, inv,is_dram_); 129910152Satgutier@umich.edu } 130010152Satgutier@umich.edu leak_nand2_path *= (num_buffers_driving_1_nand2_load + 130110152Satgutier@umich.edu num_buffers_driving_2_nand2_load + 130210152Satgutier@umich.edu num_buffers_driving_4_nand2_load); 130310152Satgutier@umich.edu gate_leak_nand2_path *= (num_buffers_driving_1_nand2_load + 130410152Satgutier@umich.edu num_buffers_driving_2_nand2_load + 130510152Satgutier@umich.edu num_buffers_driving_4_nand2_load); 130610152Satgutier@umich.edu 130710152Satgutier@umich.edu for (int i = 0; i < number_gates_nand3_path; ++i) 130810152Satgutier@umich.edu { 130910152Satgutier@umich.edu leak_nand3_path += cmos_Isub_leakage(width_nand3_path_n[i], width_nand3_path_p[i], 1, inv,is_dram_); 131010152Satgutier@umich.edu gate_leak_nand3_path += cmos_Ig_leakage(width_nand3_path_n[i], width_nand3_path_p[i], 1, inv,is_dram_); 131110152Satgutier@umich.edu } 131210152Satgutier@umich.edu leak_nand3_path *= (num_buffers_driving_2_nand3_load + num_buffers_driving_8_nand3_load); 131310152Satgutier@umich.edu gate_leak_nand3_path *= (num_buffers_driving_2_nand3_load + num_buffers_driving_8_nand3_load); 131410152Satgutier@umich.edu 131510152Satgutier@umich.edu power_nand2_path.readOp.leakage = leak_nand2_path * g_tp.peri_global.Vdd; 131610152Satgutier@umich.edu power_nand3_path.readOp.leakage = leak_nand3_path * g_tp.peri_global.Vdd; 131710152Satgutier@umich.edu power_nand2_path.readOp.gate_leakage = gate_leak_nand2_path * g_tp.peri_global.Vdd; 131810152Satgutier@umich.edu power_nand3_path.readOp.gate_leakage = gate_leak_nand3_path * g_tp.peri_global.Vdd; 131910152Satgutier@umich.edu } 132010152Satgutier@umich.edu} 132110152Satgutier@umich.edu 132210234Syasuko.eckert@amd.comdouble Predec::compute_delays(double inrisetime) { 132310234Syasuko.eckert@amd.com // TODO: Jung Ho thinks that predecoder block driver locates between decoder and predecoder block. 132410234Syasuko.eckert@amd.com pair<double, double> tmp_pair1, tmp_pair2; 132510234Syasuko.eckert@amd.com tmp_pair1 = drv1->compute_delays(inrisetime, inrisetime); 132610234Syasuko.eckert@amd.com tmp_pair1 = blk1->compute_delays(tmp_pair1); 132710234Syasuko.eckert@amd.com tmp_pair2 = drv2->compute_delays(inrisetime, inrisetime); 132810234Syasuko.eckert@amd.com tmp_pair2 = blk2->compute_delays(tmp_pair2); 132910234Syasuko.eckert@amd.com tmp_pair1 = get_max_delay_before_decoder(tmp_pair1, tmp_pair2); 133010152Satgutier@umich.edu 133110234Syasuko.eckert@amd.com driver_power.readOp.dynamic = 133210234Syasuko.eckert@amd.com drv1->num_addr_bits_nand2_path() * drv1->power_nand2_path.readOp.dynamic + 133310234Syasuko.eckert@amd.com drv1->num_addr_bits_nand3_path() * drv1->power_nand3_path.readOp.dynamic + 133410234Syasuko.eckert@amd.com drv2->num_addr_bits_nand2_path() * drv2->power_nand2_path.readOp.dynamic + 133510234Syasuko.eckert@amd.com drv2->num_addr_bits_nand3_path() * drv2->power_nand3_path.readOp.dynamic; 133610152Satgutier@umich.edu 133710234Syasuko.eckert@amd.com block_power.readOp.dynamic = 133810234Syasuko.eckert@amd.com blk1->power_nand2_path.readOp.dynamic * blk1->num_L1_active_nand2_path + 133910234Syasuko.eckert@amd.com blk1->power_nand3_path.readOp.dynamic * blk1->num_L1_active_nand3_path + 134010234Syasuko.eckert@amd.com blk1->power_L2.readOp.dynamic + 134110234Syasuko.eckert@amd.com blk2->power_nand2_path.readOp.dynamic * blk1->num_L1_active_nand2_path + 134210234Syasuko.eckert@amd.com blk2->power_nand3_path.readOp.dynamic * blk1->num_L1_active_nand3_path + 134310234Syasuko.eckert@amd.com blk2->power_L2.readOp.dynamic; 134410152Satgutier@umich.edu 134510234Syasuko.eckert@amd.com power.readOp.dynamic = driver_power.readOp.dynamic + block_power.readOp.dynamic; 134610152Satgutier@umich.edu 134710234Syasuko.eckert@amd.com delay = tmp_pair1.first; 134810234Syasuko.eckert@amd.com return tmp_pair1.second; 134910152Satgutier@umich.edu} 135010152Satgutier@umich.edu 135110152Satgutier@umich.eduvoid Predec::leakage_feedback(double temperature) 135210152Satgutier@umich.edu{ 135310152Satgutier@umich.edu drv1->leakage_feedback(temperature); 135410152Satgutier@umich.edu drv2->leakage_feedback(temperature); 135510152Satgutier@umich.edu blk1->leakage_feedback(temperature); 135610152Satgutier@umich.edu blk2->leakage_feedback(temperature); 135710152Satgutier@umich.edu 135810152Satgutier@umich.edu driver_power.readOp.leakage = drv1->power_nand2_path.readOp.leakage + 135910152Satgutier@umich.edu drv1->power_nand3_path.readOp.leakage + 136010152Satgutier@umich.edu drv2->power_nand2_path.readOp.leakage + 136110152Satgutier@umich.edu drv2->power_nand3_path.readOp.leakage; 136210152Satgutier@umich.edu block_power.readOp.leakage = blk1->power_nand2_path.readOp.leakage + 136310152Satgutier@umich.edu blk1->power_nand3_path.readOp.leakage + 136410152Satgutier@umich.edu blk1->power_L2.readOp.leakage + 136510152Satgutier@umich.edu blk2->power_nand2_path.readOp.leakage + 136610152Satgutier@umich.edu blk2->power_nand3_path.readOp.leakage + 136710152Satgutier@umich.edu blk2->power_L2.readOp.leakage; 136810152Satgutier@umich.edu power.readOp.leakage = driver_power.readOp.leakage + block_power.readOp.leakage; 136910152Satgutier@umich.edu 137010152Satgutier@umich.edu driver_power.readOp.gate_leakage = drv1->power_nand2_path.readOp.gate_leakage + 137110152Satgutier@umich.edu drv1->power_nand3_path.readOp.gate_leakage + 137210152Satgutier@umich.edu drv2->power_nand2_path.readOp.gate_leakage + 137310152Satgutier@umich.edu drv2->power_nand3_path.readOp.gate_leakage; 137410152Satgutier@umich.edu block_power.readOp.gate_leakage = blk1->power_nand2_path.readOp.gate_leakage + 137510152Satgutier@umich.edu blk1->power_nand3_path.readOp.gate_leakage + 137610152Satgutier@umich.edu blk1->power_L2.readOp.gate_leakage + 137710152Satgutier@umich.edu blk2->power_nand2_path.readOp.gate_leakage + 137810152Satgutier@umich.edu blk2->power_nand3_path.readOp.gate_leakage + 137910152Satgutier@umich.edu blk2->power_L2.readOp.gate_leakage; 138010152Satgutier@umich.edu power.readOp.gate_leakage = driver_power.readOp.gate_leakage + block_power.readOp.gate_leakage; 138110152Satgutier@umich.edu} 138210152Satgutier@umich.edu 138310152Satgutier@umich.edu// returns <delay, risetime> 138410152Satgutier@umich.edupair<double, double> Predec::get_max_delay_before_decoder( 138510152Satgutier@umich.edu pair<double, double> input_pair1, 138610234Syasuko.eckert@amd.com pair<double, double> input_pair2) { 138710234Syasuko.eckert@amd.com pair<double, double> ret_val; 138810234Syasuko.eckert@amd.com double delay; 138910152Satgutier@umich.edu 139010234Syasuko.eckert@amd.com delay = drv1->delay_nand2_path + blk1->delay_nand2_path; 139110152Satgutier@umich.edu ret_val.first = delay; 139210234Syasuko.eckert@amd.com ret_val.second = input_pair1.first; 139310234Syasuko.eckert@amd.com delay = drv1->delay_nand3_path + blk1->delay_nand3_path; 139410234Syasuko.eckert@amd.com if (ret_val.first < delay) { 139510234Syasuko.eckert@amd.com ret_val.first = delay; 139610234Syasuko.eckert@amd.com ret_val.second = input_pair1.second; 139710234Syasuko.eckert@amd.com } 139810234Syasuko.eckert@amd.com delay = drv2->delay_nand2_path + blk2->delay_nand2_path; 139910234Syasuko.eckert@amd.com if (ret_val.first < delay) { 140010234Syasuko.eckert@amd.com ret_val.first = delay; 140110234Syasuko.eckert@amd.com ret_val.second = input_pair2.first; 140210234Syasuko.eckert@amd.com } 140310234Syasuko.eckert@amd.com delay = drv2->delay_nand3_path + blk2->delay_nand3_path; 140410234Syasuko.eckert@amd.com if (ret_val.first < delay) { 140510234Syasuko.eckert@amd.com ret_val.first = delay; 140610234Syasuko.eckert@amd.com ret_val.second = input_pair2.second; 140710234Syasuko.eckert@amd.com } 140810152Satgutier@umich.edu 140910234Syasuko.eckert@amd.com return ret_val; 141010152Satgutier@umich.edu} 141110152Satgutier@umich.edu 141210152Satgutier@umich.edu 141310152Satgutier@umich.edu 141410234Syasuko.eckert@amd.comDriver::Driver(double c_gate_load_, double c_wire_load_, double r_wire_load_, 141510234Syasuko.eckert@amd.com bool is_dram) 141610234Syasuko.eckert@amd.com : number_gates(0), 141710234Syasuko.eckert@amd.com min_number_gates(2), 141810234Syasuko.eckert@amd.com c_gate_load(c_gate_load_), 141910234Syasuko.eckert@amd.com c_wire_load(c_wire_load_), 142010234Syasuko.eckert@amd.com r_wire_load(r_wire_load_), 142110234Syasuko.eckert@amd.com delay(0), 142210234Syasuko.eckert@amd.com power(), 142310234Syasuko.eckert@amd.com is_dram_(is_dram) { 142410234Syasuko.eckert@amd.com for (int i = 0; i < MAX_NUMBER_GATES_STAGE; i++) { 142510234Syasuko.eckert@amd.com width_n[i] = 0; 142610234Syasuko.eckert@amd.com width_p[i] = 0; 142710234Syasuko.eckert@amd.com } 142810152Satgutier@umich.edu 142910234Syasuko.eckert@amd.com compute_widths(); 143010152Satgutier@umich.edu} 143110152Satgutier@umich.edu 143210152Satgutier@umich.edu 143310234Syasuko.eckert@amd.comvoid Driver::compute_widths() { 143410234Syasuko.eckert@amd.com double p_to_n_sz_ratio = pmos_to_nmos_sz_ratio(is_dram_); 143510234Syasuko.eckert@amd.com double c_load = c_gate_load + c_wire_load; 143610234Syasuko.eckert@amd.com width_n[0] = g_tp.min_w_nmos_; 143710234Syasuko.eckert@amd.com width_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_; 143810152Satgutier@umich.edu 143910234Syasuko.eckert@amd.com double F = c_load / gate_C(width_n[0] + width_p[0], 0, is_dram_); 144010234Syasuko.eckert@amd.com number_gates = logical_effort( 144110234Syasuko.eckert@amd.com min_number_gates, 144210234Syasuko.eckert@amd.com 1, 144310234Syasuko.eckert@amd.com F, 144410234Syasuko.eckert@amd.com width_n, 144510234Syasuko.eckert@amd.com width_p, 144610234Syasuko.eckert@amd.com c_load, 144710234Syasuko.eckert@amd.com p_to_n_sz_ratio, 144810234Syasuko.eckert@amd.com is_dram_, false, 144910234Syasuko.eckert@amd.com g_tp.max_w_nmos_); 145010152Satgutier@umich.edu} 145110152Satgutier@umich.edu 145210152Satgutier@umich.edu 145310152Satgutier@umich.edu 145410234Syasuko.eckert@amd.comdouble Driver::compute_delay(double inrisetime) { 145510234Syasuko.eckert@amd.com int i; 145610234Syasuko.eckert@amd.com double rd, c_load, c_intrinsic, tf; 145710234Syasuko.eckert@amd.com double this_delay = 0; 145810152Satgutier@umich.edu 145910234Syasuko.eckert@amd.com for (i = 0; i < number_gates - 1; ++i) { 146010234Syasuko.eckert@amd.com rd = tr_R_on(width_n[i], NCH, 1, is_dram_); 146110234Syasuko.eckert@amd.com c_load = gate_C(width_n[i+1] + width_p[i+1], 0.0, is_dram_); 146210234Syasuko.eckert@amd.com c_intrinsic = drain_C_(width_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 146310234Syasuko.eckert@amd.com drain_C_(width_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 146410234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load); 146510234Syasuko.eckert@amd.com this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE); 146610234Syasuko.eckert@amd.com delay += this_delay; 146710234Syasuko.eckert@amd.com inrisetime = this_delay / (1.0 - 0.5); 146810234Syasuko.eckert@amd.com power.readOp.dynamic += (c_intrinsic + c_load) * g_tp.peri_global.Vdd * 146910234Syasuko.eckert@amd.com g_tp.peri_global.Vdd; 147010234Syasuko.eckert@amd.com power.readOp.leakage += 147110234Syasuko.eckert@amd.com cmos_Isub_leakage(width_n[i], width_p[i], 1, inv, is_dram_) * 147210234Syasuko.eckert@amd.com g_tp.peri_global.Vdd; 147310234Syasuko.eckert@amd.com power.readOp.gate_leakage += 147410234Syasuko.eckert@amd.com cmos_Ig_leakage(width_n[i], width_p[i], 1, inv, is_dram_) * 147510234Syasuko.eckert@amd.com g_tp.peri_global.Vdd; 147610234Syasuko.eckert@amd.com } 147710234Syasuko.eckert@amd.com 147810234Syasuko.eckert@amd.com i = number_gates - 1; 147910234Syasuko.eckert@amd.com c_load = c_gate_load + c_wire_load; 148010152Satgutier@umich.edu rd = tr_R_on(width_n[i], NCH, 1, is_dram_); 148110152Satgutier@umich.edu c_intrinsic = drain_C_(width_p[i], PCH, 1, 1, g_tp.cell_h_def, is_dram_) + 148210234Syasuko.eckert@amd.com drain_C_(width_n[i], NCH, 1, 1, g_tp.cell_h_def, is_dram_); 148310234Syasuko.eckert@amd.com tf = rd * (c_intrinsic + c_load) + r_wire_load * 148410234Syasuko.eckert@amd.com (c_wire_load / 2 + c_gate_load); 148510152Satgutier@umich.edu this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE); 148610152Satgutier@umich.edu delay += this_delay; 148710234Syasuko.eckert@amd.com power.readOp.dynamic += (c_intrinsic + c_load) * g_tp.peri_global.Vdd * 148810234Syasuko.eckert@amd.com g_tp.peri_global.Vdd; 148910234Syasuko.eckert@amd.com power.readOp.leakage += 149010234Syasuko.eckert@amd.com cmos_Isub_leakage(width_n[i], width_p[i], 1, inv, is_dram_) * 149110234Syasuko.eckert@amd.com g_tp.peri_global.Vdd; 149210234Syasuko.eckert@amd.com power.readOp.gate_leakage += 149310234Syasuko.eckert@amd.com cmos_Ig_leakage(width_n[i], width_p[i], 1, inv, is_dram_) * 149410234Syasuko.eckert@amd.com g_tp.peri_global.Vdd; 149510152Satgutier@umich.edu 149610234Syasuko.eckert@amd.com return this_delay / (1.0 - 0.5); 149710152Satgutier@umich.edu} 149810152Satgutier@umich.edu 1499