110152Satgutier@umich.edu/***************************************************************************** 210152Satgutier@umich.edu * McPAT/CACTI 310152Satgutier@umich.edu * SOFTWARE LICENSE AGREEMENT 410152Satgutier@umich.edu * Copyright 2012 Hewlett-Packard Development Company, L.P. 510234Syasuko.eckert@amd.com * Copyright (c) 2010-2013 Advanced Micro Devices, Inc. 610152Satgutier@umich.edu * All Rights Reserved 710152Satgutier@umich.edu * 810152Satgutier@umich.edu * Redistribution and use in source and binary forms, with or without 910152Satgutier@umich.edu * modification, are permitted provided that the following conditions are 1010152Satgutier@umich.edu * met: redistributions of source code must retain the above copyright 1110152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer; 1210152Satgutier@umich.edu * redistributions in binary form must reproduce the above copyright 1310152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer in the 1410152Satgutier@umich.edu * documentation and/or other materials provided with the distribution; 1510152Satgutier@umich.edu * neither the name of the copyright holders nor the names of its 1610152Satgutier@umich.edu * contributors may be used to endorse or promote products derived from 1710152Satgutier@umich.edu * this software without specific prior written permission. 1810152Satgutier@umich.edu 1910152Satgutier@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2010152Satgutier@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2110152Satgutier@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2210152Satgutier@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2310152Satgutier@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2410152Satgutier@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2510152Satgutier@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2610152Satgutier@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2710152Satgutier@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2810152Satgutier@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2910234Syasuko.eckert@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3010152Satgutier@umich.edu * 3110152Satgutier@umich.edu ***************************************************************************/ 3210152Satgutier@umich.edu 3310152Satgutier@umich.edu 3410152Satgutier@umich.edu 3510152Satgutier@umich.edu 3610152Satgutier@umich.edu#include <cassert> 3710152Satgutier@umich.edu#include <cmath> 3810152Satgutier@umich.edu#include <iostream> 3910152Satgutier@umich.edu 4010152Satgutier@umich.edu#include "bank.h" 4110152Satgutier@umich.edu#include "component.h" 4210152Satgutier@umich.edu#include "decoder.h" 4310152Satgutier@umich.edu 4410152Satgutier@umich.eduusing namespace std; 4510152Satgutier@umich.edu 4610152Satgutier@umich.edu 4710152Satgutier@umich.edu 4810152Satgutier@umich.eduComponent::Component() 4910234Syasuko.eckert@amd.com : area(), power(), rt_power(), delay(0) { 5010152Satgutier@umich.edu} 5110152Satgutier@umich.edu 5210152Satgutier@umich.edu 5310152Satgutier@umich.edu 5410234Syasuko.eckert@amd.comComponent::~Component() { 5510152Satgutier@umich.edu} 5610152Satgutier@umich.edu 5710152Satgutier@umich.edu 5810152Satgutier@umich.edu 5910234Syasuko.eckert@amd.comdouble Component::compute_diffusion_width(int num_stacked_in, int num_folded_tr) { 6010234Syasuko.eckert@amd.com double w_poly = g_ip->F_sz_um; 6110234Syasuko.eckert@amd.com double spacing_poly_to_poly = g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact; 6210234Syasuko.eckert@amd.com double total_diff_w = 2 * spacing_poly_to_poly + // for both source and drain 6310234Syasuko.eckert@amd.com num_stacked_in * w_poly + 6410234Syasuko.eckert@amd.com (num_stacked_in - 1) * g_tp.spacing_poly_to_poly; 6510152Satgutier@umich.edu 6610234Syasuko.eckert@amd.com if (num_folded_tr > 1) { 6710234Syasuko.eckert@amd.com total_diff_w += (num_folded_tr - 2) * 2 * spacing_poly_to_poly + 6810234Syasuko.eckert@amd.com (num_folded_tr - 1) * num_stacked_in * w_poly + 6910234Syasuko.eckert@amd.com (num_folded_tr - 1) * (num_stacked_in - 1) * g_tp.spacing_poly_to_poly; 7010234Syasuko.eckert@amd.com } 7110152Satgutier@umich.edu 7210234Syasuko.eckert@amd.com return total_diff_w; 7310152Satgutier@umich.edu} 7410152Satgutier@umich.edu 7510152Satgutier@umich.edu 7610152Satgutier@umich.edu 7710152Satgutier@umich.edudouble Component::compute_gate_area( 7810152Satgutier@umich.edu int gate_type, 7910152Satgutier@umich.edu int num_inputs, 8010152Satgutier@umich.edu double w_pmos, 8110152Satgutier@umich.edu double w_nmos, 8210234Syasuko.eckert@amd.com double h_gate) { 8310234Syasuko.eckert@amd.com if (w_pmos <= 0.0 || w_nmos <= 0.0) { 8410234Syasuko.eckert@amd.com return 0.0; 8510234Syasuko.eckert@amd.com } 8610152Satgutier@umich.edu 8710234Syasuko.eckert@amd.com double w_folded_pmos, w_folded_nmos; 8810234Syasuko.eckert@amd.com int num_folded_pmos, num_folded_nmos; 8910234Syasuko.eckert@amd.com double total_ndiff_w, total_pdiff_w; 9010234Syasuko.eckert@amd.com Area gate; 9110152Satgutier@umich.edu 9210234Syasuko.eckert@amd.com double h_tr_region = h_gate - 2 * g_tp.HPOWERRAIL; 9310234Syasuko.eckert@amd.com double ratio_p_to_n = w_pmos / (w_pmos + w_nmos); 9410152Satgutier@umich.edu 9510234Syasuko.eckert@amd.com if (ratio_p_to_n >= 1 || ratio_p_to_n <= 0) { 9610234Syasuko.eckert@amd.com return 0.0; 9710234Syasuko.eckert@amd.com } 9810152Satgutier@umich.edu 9910234Syasuko.eckert@amd.com w_folded_pmos = (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS) * ratio_p_to_n; 10010234Syasuko.eckert@amd.com w_folded_nmos = (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS) * (1 - ratio_p_to_n); 10110234Syasuko.eckert@amd.com assert(w_folded_pmos > 0); 10210152Satgutier@umich.edu 10310234Syasuko.eckert@amd.com num_folded_pmos = (int) (ceil(w_pmos / w_folded_pmos)); 10410234Syasuko.eckert@amd.com num_folded_nmos = (int) (ceil(w_nmos / w_folded_nmos)); 10510152Satgutier@umich.edu 10610234Syasuko.eckert@amd.com switch (gate_type) { 10710152Satgutier@umich.edu case INV: 10810234Syasuko.eckert@amd.com total_ndiff_w = compute_diffusion_width(1, num_folded_nmos); 10910234Syasuko.eckert@amd.com total_pdiff_w = compute_diffusion_width(1, num_folded_pmos); 11010234Syasuko.eckert@amd.com break; 11110152Satgutier@umich.edu 11210152Satgutier@umich.edu case NOR: 11310234Syasuko.eckert@amd.com total_ndiff_w = compute_diffusion_width(1, num_inputs * num_folded_nmos); 11410234Syasuko.eckert@amd.com total_pdiff_w = compute_diffusion_width(num_inputs, num_folded_pmos); 11510234Syasuko.eckert@amd.com break; 11610152Satgutier@umich.edu 11710152Satgutier@umich.edu case NAND: 11810234Syasuko.eckert@amd.com total_ndiff_w = compute_diffusion_width(num_inputs, num_folded_nmos); 11910234Syasuko.eckert@amd.com total_pdiff_w = compute_diffusion_width(1, num_inputs * num_folded_pmos); 12010234Syasuko.eckert@amd.com break; 12110152Satgutier@umich.edu default: 12210234Syasuko.eckert@amd.com cout << "Unknown gate type: " << gate_type << endl; 12310234Syasuko.eckert@amd.com exit(1); 12410234Syasuko.eckert@amd.com } 12510152Satgutier@umich.edu 12610234Syasuko.eckert@amd.com gate.w = MAX(total_ndiff_w, total_pdiff_w); 12710152Satgutier@umich.edu 12810234Syasuko.eckert@amd.com if (w_folded_nmos > w_nmos) { 12910234Syasuko.eckert@amd.com //means that the height of the gate can 13010234Syasuko.eckert@amd.com //be made smaller than the input height specified, so calculate the height of the gate. 13110234Syasuko.eckert@amd.com gate.h = w_nmos + w_pmos + g_tp.MIN_GAP_BET_P_AND_N_DIFFS + 2 * g_tp.HPOWERRAIL; 13210234Syasuko.eckert@amd.com } else { 13310234Syasuko.eckert@amd.com gate.h = h_gate; 13410234Syasuko.eckert@amd.com } 13510234Syasuko.eckert@amd.com return gate.get_area(); 13610152Satgutier@umich.edu} 13710152Satgutier@umich.edu 13810152Satgutier@umich.edu 13910152Satgutier@umich.edu 14010152Satgutier@umich.edudouble Component::compute_tr_width_after_folding( 14110152Satgutier@umich.edu double input_width, 14210234Syasuko.eckert@amd.com double threshold_folding_width) { 14310234Syasuko.eckert@amd.com //This is actually the width of the cell not the width of a device. 14410234Syasuko.eckert@amd.com //The width of a cell and the width of a device is orthogonal. 14510234Syasuko.eckert@amd.com if (input_width <= 0) { 14610234Syasuko.eckert@amd.com return 0; 14710234Syasuko.eckert@amd.com } 14810152Satgutier@umich.edu 14910234Syasuko.eckert@amd.com int num_folded_tr = (int) (ceil(input_width / threshold_folding_width)); 15010234Syasuko.eckert@amd.com double spacing_poly_to_poly = g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact; 15110234Syasuko.eckert@amd.com double width_poly = g_ip->F_sz_um; 15210234Syasuko.eckert@amd.com double total_diff_width = num_folded_tr * width_poly + (num_folded_tr + 1) * spacing_poly_to_poly; 15310152Satgutier@umich.edu 15410234Syasuko.eckert@amd.com return total_diff_width; 15510152Satgutier@umich.edu} 15610152Satgutier@umich.edu 15710152Satgutier@umich.edu 15810152Satgutier@umich.edu 15910234Syasuko.eckert@amd.comdouble Component::height_sense_amplifier(double pitch_sense_amp) { 16010234Syasuko.eckert@amd.com // compute the height occupied by all PMOS transistors 16110234Syasuko.eckert@amd.com double h_pmos_tr = compute_tr_width_after_folding(g_tp.w_sense_p, pitch_sense_amp) * 2 + 16210234Syasuko.eckert@amd.com compute_tr_width_after_folding(g_tp.w_iso, pitch_sense_amp) + 16310234Syasuko.eckert@amd.com 2 * g_tp.MIN_GAP_BET_SAME_TYPE_DIFFS; 16410152Satgutier@umich.edu 16510234Syasuko.eckert@amd.com // compute the height occupied by all NMOS transistors 16610234Syasuko.eckert@amd.com double h_nmos_tr = compute_tr_width_after_folding(g_tp.w_sense_n, pitch_sense_amp) * 2 + 16710234Syasuko.eckert@amd.com compute_tr_width_after_folding(g_tp.w_sense_en, pitch_sense_amp) + 16810234Syasuko.eckert@amd.com 2 * g_tp.MIN_GAP_BET_SAME_TYPE_DIFFS; 16910152Satgutier@umich.edu 17010234Syasuko.eckert@amd.com // compute total height by considering gap between the p and n diffusion areas 17110234Syasuko.eckert@amd.com return h_pmos_tr + h_nmos_tr + g_tp.MIN_GAP_BET_P_AND_N_DIFFS; 17210152Satgutier@umich.edu} 17310152Satgutier@umich.edu 17410152Satgutier@umich.edu 17510152Satgutier@umich.edu 17610152Satgutier@umich.eduint Component::logical_effort( 17710152Satgutier@umich.edu int num_gates_min, 17810152Satgutier@umich.edu double g, 17910152Satgutier@umich.edu double F, 18010152Satgutier@umich.edu double * w_n, 18110152Satgutier@umich.edu double * w_p, 18210152Satgutier@umich.edu double C_load, 18310152Satgutier@umich.edu double p_to_n_sz_ratio, 18410152Satgutier@umich.edu bool is_dram_, 18510152Satgutier@umich.edu bool is_wl_tr_, 18610234Syasuko.eckert@amd.com double max_w_nmos) { 18710234Syasuko.eckert@amd.com int num_gates = (int) (log(F) / log(fopt)); 18810152Satgutier@umich.edu 18910234Syasuko.eckert@amd.com // check if num_gates is odd. if so, add 1 to make it even 19010234Syasuko.eckert@amd.com num_gates += (num_gates % 2) ? 1 : 0; 19110234Syasuko.eckert@amd.com num_gates = MAX(num_gates, num_gates_min); 19210152Satgutier@umich.edu 19310234Syasuko.eckert@amd.com // recalculate the effective fanout of each stage 19410234Syasuko.eckert@amd.com double f = pow(F, 1.0 / num_gates); 19510234Syasuko.eckert@amd.com int i = num_gates - 1; 19610234Syasuko.eckert@amd.com double C_in = C_load / f; 19710234Syasuko.eckert@amd.com w_n[i] = (1.0 / (1.0 + p_to_n_sz_ratio)) * C_in / gate_C(1, 0, is_dram_, false, is_wl_tr_); 19810234Syasuko.eckert@amd.com w_n[i] = MAX(w_n[i], g_tp.min_w_nmos_); 19910234Syasuko.eckert@amd.com w_p[i] = p_to_n_sz_ratio * w_n[i]; 20010152Satgutier@umich.edu 20110234Syasuko.eckert@amd.com if (w_n[i] > max_w_nmos) { 20210234Syasuko.eckert@amd.com double C_ld = gate_C((1 + p_to_n_sz_ratio) * max_w_nmos, 0, is_dram_, false, is_wl_tr_); 20310234Syasuko.eckert@amd.com F = g * C_ld / gate_C(w_n[0] + w_p[0], 0, is_dram_, false, is_wl_tr_); 20410234Syasuko.eckert@amd.com num_gates = (int) (log(F) / log(fopt)) + 1; 20510234Syasuko.eckert@amd.com num_gates += (num_gates % 2) ? 1 : 0; 20610234Syasuko.eckert@amd.com num_gates = MAX(num_gates, num_gates_min); 20710234Syasuko.eckert@amd.com f = pow(F, 1.0 / (num_gates - 1)); 20810234Syasuko.eckert@amd.com i = num_gates - 1; 20910234Syasuko.eckert@amd.com w_n[i] = max_w_nmos; 21010234Syasuko.eckert@amd.com w_p[i] = p_to_n_sz_ratio * w_n[i]; 21110234Syasuko.eckert@amd.com } 21210152Satgutier@umich.edu 21310234Syasuko.eckert@amd.com for (i = num_gates - 2; i >= 1; i--) { 21410234Syasuko.eckert@amd.com w_n[i] = MAX(w_n[i+1] / f, g_tp.min_w_nmos_); 21510234Syasuko.eckert@amd.com w_p[i] = p_to_n_sz_ratio * w_n[i]; 21610234Syasuko.eckert@amd.com } 21710152Satgutier@umich.edu 21810234Syasuko.eckert@amd.com assert(num_gates <= MAX_NUMBER_GATES_STAGE); 21910234Syasuko.eckert@amd.com return num_gates; 22010152Satgutier@umich.edu} 22110152Satgutier@umich.edu 222