wire.cc revision 10234
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#include "wire.h" 3410152Satgutier@umich.edu#include "cmath" 3510152Satgutier@umich.edu// use this constructor to calculate wire stats 3610152Satgutier@umich.eduWire::Wire( 3710152Satgutier@umich.edu enum Wire_type wire_model, 3810152Satgutier@umich.edu double wl, 3910152Satgutier@umich.edu int n, 4010152Satgutier@umich.edu double w_s, 4110152Satgutier@umich.edu double s_s, 4210152Satgutier@umich.edu enum Wire_placement wp, 4310152Satgutier@umich.edu double resistivity, 4410152Satgutier@umich.edu TechnologyParameter::DeviceType *dt 4510234Syasuko.eckert@amd.com ): wt(wire_model), wire_length(wl*1e-6), nsense(n), w_scale(w_s), 4610234Syasuko.eckert@amd.com s_scale(s_s), 4710234Syasuko.eckert@amd.com resistivity(resistivity), deviceType(dt) { 4810234Syasuko.eckert@amd.com wire_placement = wp; 4910234Syasuko.eckert@amd.com min_w_pmos = deviceType->n_to_p_eff_curr_drv_ratio * g_tp.min_w_nmos_; 5010234Syasuko.eckert@amd.com in_rise_time = 0; 5110234Syasuko.eckert@amd.com out_rise_time = 0; 5210234Syasuko.eckert@amd.com if (initialized != 1) { 5310234Syasuko.eckert@amd.com cout << "Wire not initialized. Initializing it with default values\n"; 5410234Syasuko.eckert@amd.com Wire winit; 5510234Syasuko.eckert@amd.com } 5610234Syasuko.eckert@amd.com calculate_wire_stats(); 5710234Syasuko.eckert@amd.com // change everything back to seconds, microns, and Joules 5810234Syasuko.eckert@amd.com repeater_spacing *= 1e6; 5910234Syasuko.eckert@amd.com wire_length *= 1e6; 6010234Syasuko.eckert@amd.com wire_width *= 1e6; 6110234Syasuko.eckert@amd.com wire_spacing *= 1e6; 6210234Syasuko.eckert@amd.com assert(wire_length > 0); 6310234Syasuko.eckert@amd.com assert(power.readOp.dynamic > 0); 6410234Syasuko.eckert@amd.com assert(power.readOp.leakage > 0); 6510234Syasuko.eckert@amd.com assert(power.readOp.gate_leakage > 0); 6610152Satgutier@umich.edu} 6710152Satgutier@umich.edu 6810234Syasuko.eckert@amd.com// the following values are for peripheral global technology 6910234Syasuko.eckert@amd.com// specified in the input config file 7010234Syasuko.eckert@amd.comComponent Wire::global; 7110234Syasuko.eckert@amd.comComponent Wire::global_5; 7210234Syasuko.eckert@amd.comComponent Wire::global_10; 7310234Syasuko.eckert@amd.comComponent Wire::global_20; 7410234Syasuko.eckert@amd.comComponent Wire::global_30; 7510234Syasuko.eckert@amd.comComponent Wire::low_swing; 7610152Satgutier@umich.edu 7710234Syasuko.eckert@amd.comint Wire::initialized; 7810234Syasuko.eckert@amd.comdouble Wire::wire_width_init; 7910234Syasuko.eckert@amd.comdouble Wire::wire_spacing_init; 8010152Satgutier@umich.edu 8110152Satgutier@umich.edu 8210234Syasuko.eckert@amd.comWire::Wire(double w_s, double s_s, enum Wire_placement wp, double resis, 8310234Syasuko.eckert@amd.com TechnologyParameter::DeviceType *dt) { 8410234Syasuko.eckert@amd.com w_scale = w_s; 8510234Syasuko.eckert@amd.com s_scale = s_s; 8610234Syasuko.eckert@amd.com deviceType = dt; 8710234Syasuko.eckert@amd.com wire_placement = wp; 8810234Syasuko.eckert@amd.com resistivity = resis; 8910234Syasuko.eckert@amd.com min_w_pmos = deviceType->n_to_p_eff_curr_drv_ratio * g_tp.min_w_nmos_; 9010234Syasuko.eckert@amd.com in_rise_time = 0; 9110234Syasuko.eckert@amd.com out_rise_time = 0; 9210152Satgutier@umich.edu 9310234Syasuko.eckert@amd.com switch (wire_placement) { 9410234Syasuko.eckert@amd.com case outside_mat: 9510234Syasuko.eckert@amd.com wire_width = g_tp.wire_outside_mat.pitch; 9610234Syasuko.eckert@amd.com break; 9710234Syasuko.eckert@amd.com case inside_mat : 9810234Syasuko.eckert@amd.com wire_width = g_tp.wire_inside_mat.pitch; 9910234Syasuko.eckert@amd.com break; 10010234Syasuko.eckert@amd.com default: 10110234Syasuko.eckert@amd.com wire_width = g_tp.wire_local.pitch; 10210234Syasuko.eckert@amd.com break; 10310234Syasuko.eckert@amd.com } 10410152Satgutier@umich.edu 10510234Syasuko.eckert@amd.com wire_spacing = wire_width; 10610152Satgutier@umich.edu 10710234Syasuko.eckert@amd.com wire_width *= (w_scale * 1e-6 / 2) /* (m) */; 10810234Syasuko.eckert@amd.com wire_spacing *= (s_scale * 1e-6 / 2) /* (m) */; 10910152Satgutier@umich.edu 11010234Syasuko.eckert@amd.com initialized = 1; 11110234Syasuko.eckert@amd.com init_wire(); 11210234Syasuko.eckert@amd.com wire_width_init = wire_width; 11310234Syasuko.eckert@amd.com wire_spacing_init = wire_spacing; 11410152Satgutier@umich.edu 11510234Syasuko.eckert@amd.com assert(power.readOp.dynamic > 0); 11610234Syasuko.eckert@amd.com assert(power.readOp.leakage > 0); 11710234Syasuko.eckert@amd.com assert(power.readOp.gate_leakage > 0); 11810152Satgutier@umich.edu} 11910152Satgutier@umich.edu 12010152Satgutier@umich.edu 12110152Satgutier@umich.edu 12210234Syasuko.eckert@amd.comWire::~Wire() { 12310152Satgutier@umich.edu} 12410152Satgutier@umich.edu 12510152Satgutier@umich.edu 12610152Satgutier@umich.edu 12710152Satgutier@umich.eduvoid 12810234Syasuko.eckert@amd.comWire::calculate_wire_stats() { 12910152Satgutier@umich.edu 13010234Syasuko.eckert@amd.com if (wire_placement == outside_mat) { 13110234Syasuko.eckert@amd.com wire_width = g_tp.wire_outside_mat.pitch; 13210234Syasuko.eckert@amd.com } else if (wire_placement == inside_mat) { 13310234Syasuko.eckert@amd.com wire_width = g_tp.wire_inside_mat.pitch; 13410234Syasuko.eckert@amd.com } else { 13510234Syasuko.eckert@amd.com wire_width = g_tp.wire_local.pitch; 13610234Syasuko.eckert@amd.com } 13710152Satgutier@umich.edu 13810234Syasuko.eckert@amd.com wire_spacing = wire_width; 13910152Satgutier@umich.edu 14010234Syasuko.eckert@amd.com wire_width *= (w_scale * 1e-6 / 2) /* (m) */; 14110234Syasuko.eckert@amd.com wire_spacing *= (s_scale * 1e-6 / 2) /* (m) */; 14210152Satgutier@umich.edu 14310152Satgutier@umich.edu 14410234Syasuko.eckert@amd.com if (wt != Low_swing) { 14510152Satgutier@umich.edu 14610234Syasuko.eckert@amd.com // delay_optimal_wire(); 14710152Satgutier@umich.edu 14810234Syasuko.eckert@amd.com if (wt == Global) { 14910234Syasuko.eckert@amd.com delay = global.delay * wire_length; 15010234Syasuko.eckert@amd.com power.readOp.dynamic = global.power.readOp.dynamic * wire_length; 15110234Syasuko.eckert@amd.com power.readOp.leakage = global.power.readOp.leakage * wire_length; 15210234Syasuko.eckert@amd.com power.readOp.gate_leakage = global.power.readOp.gate_leakage * wire_length; 15310234Syasuko.eckert@amd.com repeater_spacing = global.area.w; 15410234Syasuko.eckert@amd.com repeater_size = global.area.h; 15510234Syasuko.eckert@amd.com area.set_area((wire_length / repeater_spacing) * 15610234Syasuko.eckert@amd.com compute_gate_area(INV, 1, min_w_pmos * repeater_size, 15710234Syasuko.eckert@amd.com g_tp.min_w_nmos_ * repeater_size, 15810234Syasuko.eckert@amd.com g_tp.cell_h_def)); 15910234Syasuko.eckert@amd.com } else if (wt == Global_5) { 16010234Syasuko.eckert@amd.com delay = global_5.delay * wire_length; 16110234Syasuko.eckert@amd.com power.readOp.dynamic = global_5.power.readOp.dynamic * wire_length; 16210234Syasuko.eckert@amd.com power.readOp.leakage = global_5.power.readOp.leakage * wire_length; 16310234Syasuko.eckert@amd.com power.readOp.gate_leakage = global_5.power.readOp.gate_leakage * wire_length; 16410234Syasuko.eckert@amd.com repeater_spacing = global_5.area.w; 16510234Syasuko.eckert@amd.com repeater_size = global_5.area.h; 16610234Syasuko.eckert@amd.com area.set_area((wire_length / repeater_spacing) * 16710234Syasuko.eckert@amd.com compute_gate_area(INV, 1, min_w_pmos * repeater_size, 16810234Syasuko.eckert@amd.com g_tp.min_w_nmos_ * repeater_size, 16910234Syasuko.eckert@amd.com g_tp.cell_h_def)); 17010234Syasuko.eckert@amd.com } else if (wt == Global_10) { 17110234Syasuko.eckert@amd.com delay = global_10.delay * wire_length; 17210234Syasuko.eckert@amd.com power.readOp.dynamic = global_10.power.readOp.dynamic * wire_length; 17310234Syasuko.eckert@amd.com power.readOp.leakage = global_10.power.readOp.leakage * wire_length; 17410234Syasuko.eckert@amd.com power.readOp.gate_leakage = global_10.power.readOp.gate_leakage * wire_length; 17510234Syasuko.eckert@amd.com repeater_spacing = global_10.area.w; 17610234Syasuko.eckert@amd.com repeater_size = global_10.area.h; 17710234Syasuko.eckert@amd.com area.set_area((wire_length / repeater_spacing) * 17810234Syasuko.eckert@amd.com compute_gate_area(INV, 1, min_w_pmos * repeater_size, 17910234Syasuko.eckert@amd.com g_tp.min_w_nmos_ * repeater_size, 18010234Syasuko.eckert@amd.com g_tp.cell_h_def)); 18110234Syasuko.eckert@amd.com } else if (wt == Global_20) { 18210234Syasuko.eckert@amd.com delay = global_20.delay * wire_length; 18310234Syasuko.eckert@amd.com power.readOp.dynamic = global_20.power.readOp.dynamic * wire_length; 18410234Syasuko.eckert@amd.com power.readOp.leakage = global_20.power.readOp.leakage * wire_length; 18510234Syasuko.eckert@amd.com power.readOp.gate_leakage = global_20.power.readOp.gate_leakage * wire_length; 18610234Syasuko.eckert@amd.com repeater_spacing = global_20.area.w; 18710234Syasuko.eckert@amd.com repeater_size = global_20.area.h; 18810234Syasuko.eckert@amd.com area.set_area((wire_length / repeater_spacing) * 18910234Syasuko.eckert@amd.com compute_gate_area(INV, 1, min_w_pmos * repeater_size, 19010234Syasuko.eckert@amd.com g_tp.min_w_nmos_ * repeater_size, 19110234Syasuko.eckert@amd.com g_tp.cell_h_def)); 19210234Syasuko.eckert@amd.com } else if (wt == Global_30) { 19310234Syasuko.eckert@amd.com delay = global_30.delay * wire_length; 19410234Syasuko.eckert@amd.com power.readOp.dynamic = global_30.power.readOp.dynamic * wire_length; 19510234Syasuko.eckert@amd.com power.readOp.leakage = global_30.power.readOp.leakage * wire_length; 19610234Syasuko.eckert@amd.com power.readOp.gate_leakage = global_30.power.readOp.gate_leakage * wire_length; 19710234Syasuko.eckert@amd.com repeater_spacing = global_30.area.w; 19810234Syasuko.eckert@amd.com repeater_size = global_30.area.h; 19910234Syasuko.eckert@amd.com area.set_area((wire_length / repeater_spacing) * 20010234Syasuko.eckert@amd.com compute_gate_area(INV, 1, min_w_pmos * repeater_size, 20110234Syasuko.eckert@amd.com g_tp.min_w_nmos_ * repeater_size, 20210234Syasuko.eckert@amd.com g_tp.cell_h_def)); 20310234Syasuko.eckert@amd.com } 20410234Syasuko.eckert@amd.com out_rise_time = delay * repeater_spacing / deviceType->Vth; 20510234Syasuko.eckert@amd.com } else if (wt == Low_swing) { 20610234Syasuko.eckert@amd.com low_swing_model (); 20710234Syasuko.eckert@amd.com repeater_spacing = wire_length; 20810234Syasuko.eckert@amd.com repeater_size = 1; 20910234Syasuko.eckert@amd.com } else { 21010234Syasuko.eckert@amd.com assert(0); 21110234Syasuko.eckert@amd.com } 21210152Satgutier@umich.edu} 21310152Satgutier@umich.edu 21410152Satgutier@umich.edu 21510152Satgutier@umich.edu 21610152Satgutier@umich.edu/* 21710152Satgutier@umich.edu * The fall time of an input signal to the first stage of a circuit is 21810152Satgutier@umich.edu * assumed to be same as the fall time of the output signal of two 21910152Satgutier@umich.edu * inverters connected in series (refer: CACTI 1 Technical report, 22010152Satgutier@umich.edu * section 6.1.3) 22110152Satgutier@umich.edu */ 22210234Syasuko.eckert@amd.comdouble 22310234Syasuko.eckert@amd.comWire::signal_fall_time () { 22410152Satgutier@umich.edu 22510234Syasuko.eckert@amd.com /* rise time of inverter 1's output */ 22610234Syasuko.eckert@amd.com double rt; 22710234Syasuko.eckert@amd.com /* fall time of inverter 2's output */ 22810234Syasuko.eckert@amd.com double ft; 22910234Syasuko.eckert@amd.com double timeconst; 23010152Satgutier@umich.edu 23110234Syasuko.eckert@amd.com timeconst = (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + 23210234Syasuko.eckert@amd.com drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + 23310234Syasuko.eckert@amd.com gate_C(min_w_pmos + g_tp.min_w_nmos_, 0)) * 23410234Syasuko.eckert@amd.com tr_R_on(min_w_pmos, PCH, 1); 23510234Syasuko.eckert@amd.com rt = horowitz (0, timeconst, deviceType->Vth / deviceType->Vdd, 23610234Syasuko.eckert@amd.com deviceType->Vth / deviceType->Vdd, FALL) / 23710234Syasuko.eckert@amd.com (deviceType->Vdd - deviceType->Vth); 23810234Syasuko.eckert@amd.com timeconst = (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + 23910234Syasuko.eckert@amd.com drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + 24010234Syasuko.eckert@amd.com gate_C(min_w_pmos + g_tp.min_w_nmos_, 0)) * 24110234Syasuko.eckert@amd.com tr_R_on(g_tp.min_w_nmos_, NCH, 1); 24210234Syasuko.eckert@amd.com ft = horowitz (rt, timeconst, deviceType->Vth / deviceType->Vdd, 24310234Syasuko.eckert@amd.com deviceType->Vth / deviceType->Vdd, RISE) / deviceType->Vth; 24410234Syasuko.eckert@amd.com return ft; 24510152Satgutier@umich.edu} 24610152Satgutier@umich.edu 24710152Satgutier@umich.edu 24810152Satgutier@umich.edu 24910234Syasuko.eckert@amd.comdouble Wire::signal_rise_time () { 25010152Satgutier@umich.edu 25110234Syasuko.eckert@amd.com /* rise time of inverter 1's output */ 25210234Syasuko.eckert@amd.com double ft; 25310234Syasuko.eckert@amd.com /* fall time of inverter 2's output */ 25410234Syasuko.eckert@amd.com double rt; 25510234Syasuko.eckert@amd.com double timeconst; 25610152Satgutier@umich.edu 25710234Syasuko.eckert@amd.com timeconst = (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + 25810234Syasuko.eckert@amd.com drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + 25910234Syasuko.eckert@amd.com gate_C(min_w_pmos + g_tp.min_w_nmos_, 0)) * 26010234Syasuko.eckert@amd.com tr_R_on(g_tp.min_w_nmos_, NCH, 1); 26110234Syasuko.eckert@amd.com rt = horowitz (0, timeconst, deviceType->Vth / deviceType->Vdd, 26210234Syasuko.eckert@amd.com deviceType->Vth / deviceType->Vdd, RISE) / deviceType->Vth; 26310234Syasuko.eckert@amd.com timeconst = (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + 26410234Syasuko.eckert@amd.com drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + 26510234Syasuko.eckert@amd.com gate_C(min_w_pmos + g_tp.min_w_nmos_, 0)) * 26610234Syasuko.eckert@amd.com tr_R_on(min_w_pmos, PCH, 1); 26710234Syasuko.eckert@amd.com ft = horowitz (rt, timeconst, deviceType->Vth / deviceType->Vdd, 26810234Syasuko.eckert@amd.com deviceType->Vth / deviceType->Vdd, FALL) / 26910234Syasuko.eckert@amd.com (deviceType->Vdd - deviceType->Vth); 27010234Syasuko.eckert@amd.com return ft; //sec 27110152Satgutier@umich.edu} 27210152Satgutier@umich.edu 27310152Satgutier@umich.edu 27410152Satgutier@umich.edu 27510152Satgutier@umich.edu/* Wire resistance and capacitance calculations 27610152Satgutier@umich.edu * wire width 27710152Satgutier@umich.edu * 27810152Satgutier@umich.edu * /__/ 27910152Satgutier@umich.edu * | | 28010152Satgutier@umich.edu * | | height = ASPECT_RATIO*wire width (ASPECT_RATIO = 2.2, ref: ITRS) 28110152Satgutier@umich.edu * |__|/ 28210152Satgutier@umich.edu * 28310152Satgutier@umich.edu * spacing between wires in same level = wire width 28410152Satgutier@umich.edu * spacing between wires in adjacent levels = wire width---this is incorrect, 28510152Satgutier@umich.edu * according to R.Ho's paper and thesis. ILD != wire width 28610152Satgutier@umich.edu * 28710152Satgutier@umich.edu */ 28810152Satgutier@umich.edu 28910234Syasuko.eckert@amd.comdouble Wire::wire_cap (double len /* in m */, bool call_from_outside) { 29010234Syasuko.eckert@amd.com //TODO: this should be consistent with the wire_res in technology file 29110234Syasuko.eckert@amd.com double sidewall, adj, tot_cap; 29210234Syasuko.eckert@amd.com double wire_height; 29310234Syasuko.eckert@amd.com double epsilon0 = 8.8542e-12; 29410234Syasuko.eckert@amd.com double aspect_ratio; 29510234Syasuko.eckert@amd.com double horiz_dielectric_constant; 29610234Syasuko.eckert@amd.com double vert_dielectric_constant; 29710234Syasuko.eckert@amd.com double miller_value; 29810234Syasuko.eckert@amd.com double ild_thickness; 29910152Satgutier@umich.edu 30010234Syasuko.eckert@amd.com switch (wire_placement) { 30110234Syasuko.eckert@amd.com case outside_mat: { 30210234Syasuko.eckert@amd.com aspect_ratio = g_tp.wire_outside_mat.aspect_ratio; 30310234Syasuko.eckert@amd.com horiz_dielectric_constant = g_tp.wire_outside_mat.horiz_dielectric_constant; 30410234Syasuko.eckert@amd.com vert_dielectric_constant = g_tp.wire_outside_mat.vert_dielectric_constant; 30510234Syasuko.eckert@amd.com miller_value = g_tp.wire_outside_mat.miller_value; 30610234Syasuko.eckert@amd.com ild_thickness = g_tp.wire_outside_mat.ild_thickness; 30710234Syasuko.eckert@amd.com break; 30810234Syasuko.eckert@amd.com } 30910234Syasuko.eckert@amd.com case inside_mat : { 31010234Syasuko.eckert@amd.com aspect_ratio = g_tp.wire_inside_mat.aspect_ratio; 31110234Syasuko.eckert@amd.com horiz_dielectric_constant = g_tp.wire_inside_mat.horiz_dielectric_constant; 31210234Syasuko.eckert@amd.com vert_dielectric_constant = g_tp.wire_inside_mat.vert_dielectric_constant; 31310234Syasuko.eckert@amd.com miller_value = g_tp.wire_inside_mat.miller_value; 31410234Syasuko.eckert@amd.com ild_thickness = g_tp.wire_inside_mat.ild_thickness; 31510234Syasuko.eckert@amd.com break; 31610234Syasuko.eckert@amd.com } 31710234Syasuko.eckert@amd.com default: { 31810234Syasuko.eckert@amd.com aspect_ratio = g_tp.wire_local.aspect_ratio; 31910234Syasuko.eckert@amd.com horiz_dielectric_constant = g_tp.wire_local.horiz_dielectric_constant; 32010234Syasuko.eckert@amd.com vert_dielectric_constant = g_tp.wire_local.vert_dielectric_constant; 32110234Syasuko.eckert@amd.com miller_value = g_tp.wire_local.miller_value; 32210234Syasuko.eckert@amd.com ild_thickness = g_tp.wire_local.ild_thickness; 32310234Syasuko.eckert@amd.com break; 32410234Syasuko.eckert@amd.com } 32510234Syasuko.eckert@amd.com } 32610152Satgutier@umich.edu 32710234Syasuko.eckert@amd.com if (call_from_outside) { 32810234Syasuko.eckert@amd.com wire_width *= 1e-6; 32910234Syasuko.eckert@amd.com wire_spacing *= 1e-6; 33010234Syasuko.eckert@amd.com } 33110234Syasuko.eckert@amd.com wire_height = wire_width / w_scale * aspect_ratio; 33210234Syasuko.eckert@amd.com /* 33310234Syasuko.eckert@amd.com * assuming height does not change. wire_width = width_original*w_scale 33410234Syasuko.eckert@amd.com * So wire_height does not change as wire width increases 33510234Syasuko.eckert@amd.com */ 33610152Satgutier@umich.edu 33710152Satgutier@umich.edu// capacitance between wires in the same level 33810152Satgutier@umich.edu// sidewall = 2*miller_value * horiz_dielectric_constant * (wire_height/wire_spacing) 33910152Satgutier@umich.edu// * epsilon0; 34010152Satgutier@umich.edu 34110234Syasuko.eckert@amd.com sidewall = miller_value * horiz_dielectric_constant * 34210234Syasuko.eckert@amd.com (wire_height / wire_spacing) 34310234Syasuko.eckert@amd.com * epsilon0; 34410152Satgutier@umich.edu 34510152Satgutier@umich.edu 34610234Syasuko.eckert@amd.com // capacitance between wires in adjacent levels 34710234Syasuko.eckert@amd.com //adj = miller_value * vert_dielectric_constant *w_scale * epsilon0; 34810234Syasuko.eckert@amd.com //adj = 2*vert_dielectric_constant *wire_width/(ild_thickness*1e-6) * epsilon0; 34910152Satgutier@umich.edu 35010234Syasuko.eckert@amd.com adj = miller_value * vert_dielectric_constant * wire_width / 35110234Syasuko.eckert@amd.com (ild_thickness * 1e-6) * epsilon0; 35210234Syasuko.eckert@amd.com //Change ild_thickness from micron to M 35310152Satgutier@umich.edu 35410234Syasuko.eckert@amd.com //tot_cap = (sidewall + adj + (deviceType->C_fringe * 1e6)); //F/m 35510234Syasuko.eckert@amd.com tot_cap = (sidewall + adj + (g_tp.fringe_cap * 1e6)); //F/m 35610152Satgutier@umich.edu 35710234Syasuko.eckert@amd.com if (call_from_outside) { 35810234Syasuko.eckert@amd.com wire_width *= 1e6; 35910234Syasuko.eckert@amd.com wire_spacing *= 1e6; 36010234Syasuko.eckert@amd.com } 36110234Syasuko.eckert@amd.com return (tot_cap*len); // (F) 36210152Satgutier@umich.edu} 36310152Satgutier@umich.edu 36410152Satgutier@umich.edu 36510234Syasuko.eckert@amd.comdouble 36610234Syasuko.eckert@amd.comWire::wire_res (double len /*(in m)*/) { 36710152Satgutier@umich.edu 36810234Syasuko.eckert@amd.com double aspect_ratio; 36910234Syasuko.eckert@amd.com double alpha_scatter = 1.05; 37010234Syasuko.eckert@amd.com double dishing_thickness = 0; 37110234Syasuko.eckert@amd.com double barrier_thickness = 0; 37210234Syasuko.eckert@amd.com //TODO: this should be consistent with the wire_res in technology file 37310234Syasuko.eckert@amd.com //The whole computation should be consistent with the wire_res in technology.cc too! 37410152Satgutier@umich.edu 37510234Syasuko.eckert@amd.com switch (wire_placement) { 37610234Syasuko.eckert@amd.com case outside_mat: { 37710234Syasuko.eckert@amd.com aspect_ratio = g_tp.wire_outside_mat.aspect_ratio; 37810234Syasuko.eckert@amd.com break; 37910234Syasuko.eckert@amd.com } 38010234Syasuko.eckert@amd.com case inside_mat : { 38110234Syasuko.eckert@amd.com aspect_ratio = g_tp.wire_inside_mat.aspect_ratio; 38210234Syasuko.eckert@amd.com break; 38310234Syasuko.eckert@amd.com } 38410234Syasuko.eckert@amd.com default: { 38510234Syasuko.eckert@amd.com aspect_ratio = g_tp.wire_local.aspect_ratio; 38610234Syasuko.eckert@amd.com break; 38710234Syasuko.eckert@amd.com } 38810234Syasuko.eckert@amd.com } 38910234Syasuko.eckert@amd.com return (alpha_scatter * resistivity * 1e-6 * len / 39010234Syasuko.eckert@amd.com ((aspect_ratio*wire_width / w_scale - dishing_thickness - 39110234Syasuko.eckert@amd.com barrier_thickness)* 39210234Syasuko.eckert@amd.com (wire_width - 2*barrier_thickness))); 39310152Satgutier@umich.edu} 39410152Satgutier@umich.edu 39510152Satgutier@umich.edu/* 39610152Satgutier@umich.edu * Calculates the delay, power and area of the transmitter circuit. 39710152Satgutier@umich.edu * 39810152Satgutier@umich.edu * The transmitter delay is the sum of nand gate delay, inverter delay 39910152Satgutier@umich.edu * low swing nmos delay, and the wire delay 40010152Satgutier@umich.edu * (ref: Technical report 6) 40110152Satgutier@umich.edu */ 40210234Syasuko.eckert@amd.comvoid 40310234Syasuko.eckert@amd.comWire::low_swing_model() { 40410234Syasuko.eckert@amd.com double len = wire_length; 40510234Syasuko.eckert@amd.com double beta = pmos_to_nmos_sz_ratio(); 40610152Satgutier@umich.edu 40710152Satgutier@umich.edu 40810234Syasuko.eckert@amd.com double inputrise = (in_rise_time == 0) ? signal_rise_time() : in_rise_time; 40910152Satgutier@umich.edu 41010234Syasuko.eckert@amd.com /* Final nmos low swing driver size calculation: 41110234Syasuko.eckert@amd.com * Try to size the driver such that the delay 41210234Syasuko.eckert@amd.com * is less than 8FO4. 41310234Syasuko.eckert@amd.com * If the driver size is greater than 41410234Syasuko.eckert@amd.com * the max allowable size, assume max size for the driver. 41510234Syasuko.eckert@amd.com * In either case, recalculate the delay using 41610234Syasuko.eckert@amd.com * the final driver size assuming slow input with 41710234Syasuko.eckert@amd.com * finite rise time instead of ideal step input 41810234Syasuko.eckert@amd.com * 41910234Syasuko.eckert@amd.com * (ref: Technical report 6) 42010234Syasuko.eckert@amd.com */ 42110234Syasuko.eckert@amd.com double cwire = wire_cap(len); /* load capacitance */ 42210234Syasuko.eckert@amd.com double rwire = wire_res(len); 42310152Satgutier@umich.edu 42410152Satgutier@umich.edu#define RES_ADJ (8.6) // Increase in resistance due to low driving vol. 42510152Satgutier@umich.edu 42610234Syasuko.eckert@amd.com double driver_res = (-8 * g_tp.FO4 / (log(0.5) * cwire)) / RES_ADJ; 42710234Syasuko.eckert@amd.com double nsize = R_to_w(driver_res, NCH); 42810152Satgutier@umich.edu 42910234Syasuko.eckert@amd.com nsize = MIN(nsize, g_tp.max_w_nmos_); 43010234Syasuko.eckert@amd.com nsize = MAX(nsize, g_tp.min_w_nmos_); 43110152Satgutier@umich.edu 43210234Syasuko.eckert@amd.com if (rwire*cwire > 8*g_tp.FO4) { 43310234Syasuko.eckert@amd.com nsize = g_tp.max_w_nmos_; 43410234Syasuko.eckert@amd.com } 43510152Satgutier@umich.edu 43610234Syasuko.eckert@amd.com // size the inverter appropriately to minimize the transmitter delay 43710234Syasuko.eckert@amd.com // Note - In order to minimize leakage, we are not adding a set of inverters to 43810234Syasuko.eckert@amd.com // bring down delay. Instead, we are sizing the single gate 43910234Syasuko.eckert@amd.com // based on the logical effort. 44010234Syasuko.eckert@amd.com double st_eff = sqrt((2 + beta / 1 + beta) * gate_C(nsize, 0) / 44110234Syasuko.eckert@amd.com (gate_C(2 * g_tp.min_w_nmos_, 0) 44210234Syasuko.eckert@amd.com + gate_C(2 * min_w_pmos, 0))); 44310234Syasuko.eckert@amd.com double req_cin = ((2 + beta / 1 + beta) * gate_C(nsize, 0)) / st_eff; 44410234Syasuko.eckert@amd.com double inv_size = req_cin / (gate_C(min_w_pmos, 0) + 44510234Syasuko.eckert@amd.com gate_C(g_tp.min_w_nmos_, 0)); 44610234Syasuko.eckert@amd.com inv_size = MAX(inv_size, 1); 44710152Satgutier@umich.edu 44810234Syasuko.eckert@amd.com /* nand gate delay */ 44910234Syasuko.eckert@amd.com double res_eq = (2 * tr_R_on(g_tp.min_w_nmos_, NCH, 1)); 45010234Syasuko.eckert@amd.com double cap_eq = 2 * drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + 45110234Syasuko.eckert@amd.com drain_C_(2 * g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + 45210234Syasuko.eckert@amd.com gate_C(inv_size * g_tp.min_w_nmos_, 0) + 45310234Syasuko.eckert@amd.com gate_C(inv_size * min_w_pmos, 0); 45410152Satgutier@umich.edu 45510234Syasuko.eckert@amd.com double timeconst = res_eq * cap_eq; 45610152Satgutier@umich.edu 45710234Syasuko.eckert@amd.com delay = horowitz(inputrise, timeconst, deviceType->Vth / deviceType->Vdd, 45810234Syasuko.eckert@amd.com deviceType->Vth / deviceType->Vdd, RISE); 45910234Syasuko.eckert@amd.com double temp_power = cap_eq * deviceType->Vdd * deviceType->Vdd; 46010152Satgutier@umich.edu 46110234Syasuko.eckert@amd.com inputrise = delay / (deviceType->Vdd - deviceType->Vth); /* for the next stage */ 46210152Satgutier@umich.edu 46310234Syasuko.eckert@amd.com /* Inverter delay: 46410234Syasuko.eckert@amd.com * The load capacitance of this inv depends on 46510234Syasuko.eckert@amd.com * the gate capacitance of the final stage nmos 46610234Syasuko.eckert@amd.com * transistor which in turn depends on nsize 46710234Syasuko.eckert@amd.com */ 46810234Syasuko.eckert@amd.com res_eq = tr_R_on(inv_size * min_w_pmos, PCH, 1); 46910234Syasuko.eckert@amd.com cap_eq = drain_C_(inv_size * min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + 47010234Syasuko.eckert@amd.com drain_C_(inv_size * g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + 47110234Syasuko.eckert@amd.com gate_C(nsize, 0); 47210234Syasuko.eckert@amd.com timeconst = res_eq * cap_eq; 47310152Satgutier@umich.edu 47410234Syasuko.eckert@amd.com delay += horowitz(inputrise, timeconst, deviceType->Vth / deviceType->Vdd, 47510234Syasuko.eckert@amd.com deviceType->Vth / deviceType->Vdd, FALL); 47610234Syasuko.eckert@amd.com temp_power += cap_eq * deviceType->Vdd * deviceType->Vdd; 47710152Satgutier@umich.edu 47810152Satgutier@umich.edu 47910234Syasuko.eckert@amd.com transmitter.delay = delay; 48010234Syasuko.eckert@amd.com /* since it is a diff. model*/ 48110234Syasuko.eckert@amd.com transmitter.power.readOp.dynamic = temp_power * 2; 48210234Syasuko.eckert@amd.com transmitter.power.readOp.leakage = deviceType->Vdd * 48310234Syasuko.eckert@amd.com (4 * cmos_Isub_leakage(g_tp.min_w_nmos_, min_w_pmos, 2, nand) + 48410234Syasuko.eckert@amd.com 4 * cmos_Isub_leakage(g_tp.min_w_nmos_, min_w_pmos, 1, inv)); 48510152Satgutier@umich.edu 48610234Syasuko.eckert@amd.com transmitter.power.readOp.gate_leakage = deviceType->Vdd * 48710234Syasuko.eckert@amd.com (4 * cmos_Ig_leakage(g_tp.min_w_nmos_, min_w_pmos, 2, nand) + 48810234Syasuko.eckert@amd.com 4 * cmos_Ig_leakage(g_tp.min_w_nmos_, min_w_pmos, 1, inv)); 48910152Satgutier@umich.edu 49010234Syasuko.eckert@amd.com inputrise = delay / deviceType->Vth; 49110152Satgutier@umich.edu 49210234Syasuko.eckert@amd.com /* nmos delay + wire delay */ 49310234Syasuko.eckert@amd.com cap_eq = cwire + drain_C_(nsize, NCH, 1, 1, g_tp.cell_h_def) * 2 + 49410234Syasuko.eckert@amd.com nsense * sense_amp_input_cap(); //+receiver cap 49510234Syasuko.eckert@amd.com /* 49610234Syasuko.eckert@amd.com * NOTE: nmos is used as both pull up and pull down transistor 49710234Syasuko.eckert@amd.com * in the transmitter. This is because for low voltage swing, drive 49810234Syasuko.eckert@amd.com * resistance of nmos is less than pmos 49910234Syasuko.eckert@amd.com * (for a detailed graph ref: On-Chip Wires: Scaling and Efficiency) 50010234Syasuko.eckert@amd.com */ 50110234Syasuko.eckert@amd.com timeconst = (tr_R_on(nsize, NCH, 1) * RES_ADJ) * (cwire + 50210234Syasuko.eckert@amd.com drain_C_(nsize, NCH, 1, 1, g_tp.cell_h_def) * 2) + 50310234Syasuko.eckert@amd.com rwire * cwire / 2 + 50410234Syasuko.eckert@amd.com (tr_R_on(nsize, NCH, 1) * RES_ADJ + rwire) * 50510234Syasuko.eckert@amd.com nsense * sense_amp_input_cap(); 50610152Satgutier@umich.edu 50710234Syasuko.eckert@amd.com /* 50810234Syasuko.eckert@amd.com * since we are pre-equalizing and overdriving the low 50910234Syasuko.eckert@amd.com * swing wires, the net time constant is less 51010234Syasuko.eckert@amd.com * than the actual value 51110234Syasuko.eckert@amd.com */ 51210234Syasuko.eckert@amd.com delay += horowitz(inputrise, timeconst, deviceType->Vth / 51310234Syasuko.eckert@amd.com deviceType->Vdd, .25, 0); 51410152Satgutier@umich.edu#define VOL_SWING .1 51510234Syasuko.eckert@amd.com temp_power += cap_eq * VOL_SWING * .400; /* .4v is the over drive voltage */ 51610234Syasuko.eckert@amd.com temp_power *= 2; /* differential wire */ 51710152Satgutier@umich.edu 51810234Syasuko.eckert@amd.com l_wire.delay = delay - transmitter.delay; 51910234Syasuko.eckert@amd.com l_wire.power.readOp.dynamic = temp_power - transmitter.power.readOp.dynamic; 52010234Syasuko.eckert@amd.com l_wire.power.readOp.leakage = deviceType->Vdd * 52110234Syasuko.eckert@amd.com (4 * cmos_Isub_leakage(nsize, 0, 1, nmos)); 52210152Satgutier@umich.edu 52310234Syasuko.eckert@amd.com l_wire.power.readOp.gate_leakage = deviceType->Vdd * 52410234Syasuko.eckert@amd.com (4 * cmos_Ig_leakage(nsize, 0, 1, nmos)); 52510152Satgutier@umich.edu 52610234Syasuko.eckert@amd.com //double rt = horowitz(inputrise, timeconst, deviceType->Vth/deviceType->Vdd, 52710234Syasuko.eckert@amd.com // deviceType->Vth/deviceType->Vdd, RISE)/deviceType->Vth; 52810152Satgutier@umich.edu 52910234Syasuko.eckert@amd.com delay += g_tp.sense_delay; 53010152Satgutier@umich.edu 53110234Syasuko.eckert@amd.com sense_amp.delay = g_tp.sense_delay; 53210234Syasuko.eckert@amd.com out_rise_time = g_tp.sense_delay / (deviceType->Vth); 53310234Syasuko.eckert@amd.com sense_amp.power.readOp.dynamic = g_tp.sense_dy_power; 53410234Syasuko.eckert@amd.com sense_amp.power.readOp.leakage = 0; //FIXME 53510234Syasuko.eckert@amd.com sense_amp.power.readOp.gate_leakage = 0; 53610152Satgutier@umich.edu 53710234Syasuko.eckert@amd.com power.readOp.dynamic = temp_power + sense_amp.power.readOp.dynamic; 53810234Syasuko.eckert@amd.com power.readOp.leakage = transmitter.power.readOp.leakage + 53910234Syasuko.eckert@amd.com l_wire.power.readOp.leakage + 54010234Syasuko.eckert@amd.com sense_amp.power.readOp.leakage; 54110234Syasuko.eckert@amd.com power.readOp.gate_leakage = transmitter.power.readOp.gate_leakage + 54210234Syasuko.eckert@amd.com l_wire.power.readOp.gate_leakage + 54310234Syasuko.eckert@amd.com sense_amp.power.readOp.gate_leakage; 54410152Satgutier@umich.edu} 54510152Satgutier@umich.edu 54610234Syasuko.eckert@amd.comdouble 54710234Syasuko.eckert@amd.comWire::sense_amp_input_cap() { 54810234Syasuko.eckert@amd.com return drain_C_(g_tp.w_iso, PCH, 1, 1, g_tp.cell_h_def) + 54910234Syasuko.eckert@amd.com gate_C(g_tp.w_sense_en + g_tp.w_sense_n, 0) + 55010234Syasuko.eckert@amd.com drain_C_(g_tp.w_sense_n, NCH, 1, 1, g_tp.cell_h_def) + 55110234Syasuko.eckert@amd.com drain_C_(g_tp.w_sense_p, PCH, 1, 1, g_tp.cell_h_def); 55210152Satgutier@umich.edu} 55310152Satgutier@umich.edu 55410152Satgutier@umich.edu 55510234Syasuko.eckert@amd.comvoid Wire::delay_optimal_wire () { 55610234Syasuko.eckert@amd.com double len = wire_length; 55710234Syasuko.eckert@amd.com //double min_wire_width = wire_width; //m 55810234Syasuko.eckert@amd.com double beta = pmos_to_nmos_sz_ratio(); 55910234Syasuko.eckert@amd.com double switching = 0; // switching energy 56010234Syasuko.eckert@amd.com double short_ckt = 0; // short-circuit energy 56110234Syasuko.eckert@amd.com double tc = 0; // time constant 56210234Syasuko.eckert@amd.com // input cap of min sized driver 56310234Syasuko.eckert@amd.com double input_cap = gate_C(g_tp.min_w_nmos_ + min_w_pmos, 0); 56410152Satgutier@umich.edu 56510234Syasuko.eckert@amd.com // output parasitic capacitance of 56610234Syasuko.eckert@amd.com // the min. sized driver 56710234Syasuko.eckert@amd.com double out_cap = drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + 56810234Syasuko.eckert@amd.com drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def); 56910234Syasuko.eckert@amd.com // drive resistance 57010234Syasuko.eckert@amd.com double out_res = (tr_R_on(g_tp.min_w_nmos_, NCH, 1) + 57110234Syasuko.eckert@amd.com tr_R_on(min_w_pmos, PCH, 1)) / 2; 57210234Syasuko.eckert@amd.com double wr = wire_res(len); //ohm 57310152Satgutier@umich.edu 57410234Syasuko.eckert@amd.com // wire cap /m 57510234Syasuko.eckert@amd.com double wc = wire_cap(len); 57610152Satgutier@umich.edu 57710234Syasuko.eckert@amd.com // size the repeater such that the delay of the wire is minimum 57810234Syasuko.eckert@amd.com // len will cancel 57910234Syasuko.eckert@amd.com double repeater_scaling = sqrt(out_res * wc / (wr * input_cap)); 58010152Satgutier@umich.edu 58110234Syasuko.eckert@amd.com // calc the optimum spacing between the repeaters (m) 58210152Satgutier@umich.edu 58310234Syasuko.eckert@amd.com repeater_spacing = sqrt(2 * out_res * (out_cap + input_cap) / 58410234Syasuko.eckert@amd.com ((wr / len) * (wc / len))); 58510234Syasuko.eckert@amd.com repeater_size = repeater_scaling; 58610152Satgutier@umich.edu 58710234Syasuko.eckert@amd.com switching = (repeater_scaling * (input_cap + out_cap) + 58810234Syasuko.eckert@amd.com repeater_spacing * (wc / len)) * deviceType->Vdd * 58910234Syasuko.eckert@amd.com deviceType->Vdd; 59010152Satgutier@umich.edu 59110234Syasuko.eckert@amd.com tc = out_res * (input_cap + out_cap) + 59210234Syasuko.eckert@amd.com out_res * wc / len * repeater_spacing / repeater_scaling + 59310234Syasuko.eckert@amd.com wr / len * repeater_spacing * input_cap * repeater_scaling + 59410234Syasuko.eckert@amd.com 0.5 * (wr / len) * (wc / len) * repeater_spacing * repeater_spacing; 59510152Satgutier@umich.edu 59610234Syasuko.eckert@amd.com delay = 0.693 * tc * len / repeater_spacing; 59710152Satgutier@umich.edu 59810152Satgutier@umich.edu#define Ishort_ckt 65e-6 /* across all tech Ref:Banerjee et al. {IEEE TED} */ 59910234Syasuko.eckert@amd.com short_ckt = deviceType->Vdd * g_tp.min_w_nmos_ * Ishort_ckt * 1.0986 * 60010234Syasuko.eckert@amd.com repeater_scaling * tc; 60110152Satgutier@umich.edu 60210234Syasuko.eckert@amd.com area.set_area((len / repeater_spacing) * 60310234Syasuko.eckert@amd.com compute_gate_area(INV, 1, min_w_pmos * repeater_scaling, 60410234Syasuko.eckert@amd.com g_tp.min_w_nmos_ * repeater_scaling, 60510234Syasuko.eckert@amd.com g_tp.cell_h_def)); 60610234Syasuko.eckert@amd.com power.readOp.dynamic = ((len / repeater_spacing) * (switching + short_ckt)); 60710234Syasuko.eckert@amd.com power.readOp.leakage = ((len / repeater_spacing) * 60810234Syasuko.eckert@amd.com deviceType->Vdd * 60910234Syasuko.eckert@amd.com cmos_Isub_leakage(g_tp.min_w_nmos_ * 61010234Syasuko.eckert@amd.com repeater_scaling, beta * 61110234Syasuko.eckert@amd.com g_tp.min_w_nmos_ * 61210234Syasuko.eckert@amd.com repeater_scaling, 1, inv)); 61310234Syasuko.eckert@amd.com power.readOp.gate_leakage = ((len / repeater_spacing) * 61410234Syasuko.eckert@amd.com deviceType->Vdd * 61510234Syasuko.eckert@amd.com cmos_Ig_leakage(g_tp.min_w_nmos_ * 61610234Syasuko.eckert@amd.com repeater_scaling, beta * 61710234Syasuko.eckert@amd.com g_tp.min_w_nmos_ * 61810234Syasuko.eckert@amd.com repeater_scaling, 1, inv)); 61910152Satgutier@umich.edu} 62010152Satgutier@umich.edu 62110152Satgutier@umich.edu 62210152Satgutier@umich.edu 62310152Satgutier@umich.edu// calculate power/delay values for wires with suboptimal repeater sizing/spacing 62410152Satgutier@umich.eduvoid 62510234Syasuko.eckert@amd.comWire::init_wire() { 62610234Syasuko.eckert@amd.com wire_length = 1; 62710234Syasuko.eckert@amd.com delay_optimal_wire(); 62810152Satgutier@umich.edu double sp, si; 62910234Syasuko.eckert@amd.com powerDef pow; 63010234Syasuko.eckert@amd.com si = repeater_size; 63110234Syasuko.eckert@amd.com sp = repeater_spacing; 63210234Syasuko.eckert@amd.com sp *= 1e6; // in microns 63310152Satgutier@umich.edu 63410234Syasuko.eckert@amd.com double i, j, del; 63510234Syasuko.eckert@amd.com repeated_wire.push_back(Component()); 63610234Syasuko.eckert@amd.com for (j = sp; j < 4*sp; j += 100) { 63710234Syasuko.eckert@amd.com for (i = si; i > 1; i--) { 63810234Syasuko.eckert@amd.com pow = wire_model(j * 1e-6, i, &del); 63910234Syasuko.eckert@amd.com if (j == sp && i == si) { 64010234Syasuko.eckert@amd.com global.delay = del; 64110234Syasuko.eckert@amd.com global.power = pow; 64210234Syasuko.eckert@amd.com global.area.h = si; 64310234Syasuko.eckert@amd.com global.area.w = sp * 1e-6; // m 64410234Syasuko.eckert@amd.com } 64510152Satgutier@umich.edu// cout << "Repeater size - "<< i << 64610152Satgutier@umich.edu// " Repeater spacing - " << j << 64710152Satgutier@umich.edu// " Delay - " << del << 64810152Satgutier@umich.edu// " PowerD - " << pow.readOp.dynamic << 64910152Satgutier@umich.edu// " PowerL - " << pow.readOp.leakage <<endl; 65010234Syasuko.eckert@amd.com repeated_wire.back().delay = del; 65110234Syasuko.eckert@amd.com repeated_wire.back().power.readOp = pow.readOp; 65210234Syasuko.eckert@amd.com repeated_wire.back().area.w = j * 1e-6; //m 65310234Syasuko.eckert@amd.com repeated_wire.back().area.h = i; 65410234Syasuko.eckert@amd.com repeated_wire.push_back(Component()); 65510152Satgutier@umich.edu 65610234Syasuko.eckert@amd.com } 65710152Satgutier@umich.edu } 65810234Syasuko.eckert@amd.com repeated_wire.pop_back(); 65910234Syasuko.eckert@amd.com update_fullswing(); 66010234Syasuko.eckert@amd.com Wire *l_wire = new Wire(Low_swing, 0.001/* 1 mm*/, 1); 66110234Syasuko.eckert@amd.com low_swing.delay = l_wire->delay; 66210234Syasuko.eckert@amd.com low_swing.power = l_wire->power; 66310234Syasuko.eckert@amd.com delete l_wire; 66410152Satgutier@umich.edu} 66510152Satgutier@umich.edu 66610152Satgutier@umich.edu 66710152Satgutier@umich.edu 66810234Syasuko.eckert@amd.comvoid Wire::update_fullswing() { 66910152Satgutier@umich.edu 67010234Syasuko.eckert@amd.com list<Component>::iterator citer; 67110234Syasuko.eckert@amd.com double del[4]; 67210234Syasuko.eckert@amd.com del[3] = this->global.delay + this->global.delay * .3; 67310234Syasuko.eckert@amd.com del[2] = global.delay + global.delay * .2; 67410234Syasuko.eckert@amd.com del[1] = global.delay + global.delay * .1; 67510234Syasuko.eckert@amd.com del[0] = global.delay + global.delay * .05; 67610234Syasuko.eckert@amd.com double threshold; 67710234Syasuko.eckert@amd.com double ncost; 67810234Syasuko.eckert@amd.com double cost; 67910234Syasuko.eckert@amd.com int i = 4; 68010234Syasuko.eckert@amd.com while (i > 0) { 68110234Syasuko.eckert@amd.com threshold = del[i-1]; 68210234Syasuko.eckert@amd.com cost = BIGNUM; 68310234Syasuko.eckert@amd.com for (citer = repeated_wire.begin(); citer != repeated_wire.end(); 68410234Syasuko.eckert@amd.com citer++) { 68510234Syasuko.eckert@amd.com if (citer->delay > threshold) { 68610234Syasuko.eckert@amd.com citer = repeated_wire.erase(citer); 68710234Syasuko.eckert@amd.com citer --; 68810234Syasuko.eckert@amd.com } else { 68910234Syasuko.eckert@amd.com ncost = citer->power.readOp.dynamic / 69010234Syasuko.eckert@amd.com global.power.readOp.dynamic + 69110234Syasuko.eckert@amd.com citer->power.readOp.leakage / global.power.readOp.leakage; 69210234Syasuko.eckert@amd.com if (ncost < cost) { 69310234Syasuko.eckert@amd.com cost = ncost; 69410234Syasuko.eckert@amd.com if (i == 4) { 69510234Syasuko.eckert@amd.com global_30.delay = citer->delay; 69610234Syasuko.eckert@amd.com global_30.power = citer->power; 69710234Syasuko.eckert@amd.com global_30.area = citer->area; 69810234Syasuko.eckert@amd.com } else if (i == 3) { 69910234Syasuko.eckert@amd.com global_20.delay = citer->delay; 70010234Syasuko.eckert@amd.com global_20.power = citer->power; 70110234Syasuko.eckert@amd.com global_20.area = citer->area; 70210234Syasuko.eckert@amd.com } else if (i == 2) { 70310234Syasuko.eckert@amd.com global_10.delay = citer->delay; 70410234Syasuko.eckert@amd.com global_10.power = citer->power; 70510234Syasuko.eckert@amd.com global_10.area = citer->area; 70610234Syasuko.eckert@amd.com } else if (i == 1) { 70710234Syasuko.eckert@amd.com global_5.delay = citer->delay; 70810234Syasuko.eckert@amd.com global_5.power = citer->power; 70910234Syasuko.eckert@amd.com global_5.area = citer->area; 71010234Syasuko.eckert@amd.com } 71110234Syasuko.eckert@amd.com } 71210234Syasuko.eckert@amd.com } 71310152Satgutier@umich.edu } 71410234Syasuko.eckert@amd.com i--; 71510152Satgutier@umich.edu } 71610152Satgutier@umich.edu} 71710152Satgutier@umich.edu 71810152Satgutier@umich.edu 71910152Satgutier@umich.edu 72010234Syasuko.eckert@amd.compowerDef Wire::wire_model (double space, double size, double *delay) { 72110234Syasuko.eckert@amd.com powerDef ptemp; 72210234Syasuko.eckert@amd.com double len = 1; 72310234Syasuko.eckert@amd.com //double min_wire_width = wire_width; //m 72410234Syasuko.eckert@amd.com double beta = pmos_to_nmos_sz_ratio(); 72510234Syasuko.eckert@amd.com // switching energy 72610234Syasuko.eckert@amd.com double switching = 0; 72710234Syasuko.eckert@amd.com // short-circuit energy 72810234Syasuko.eckert@amd.com double short_ckt = 0; 72910234Syasuko.eckert@amd.com // time constant 73010234Syasuko.eckert@amd.com double tc = 0; 73110234Syasuko.eckert@amd.com // input cap of min sized driver 73210234Syasuko.eckert@amd.com double input_cap = gate_C (g_tp.min_w_nmos_ + 73310234Syasuko.eckert@amd.com min_w_pmos, 0); 73410152Satgutier@umich.edu 73510234Syasuko.eckert@amd.com // output parasitic capacitance of 73610234Syasuko.eckert@amd.com // the min. sized driver 73710234Syasuko.eckert@amd.com double out_cap = drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + 73810234Syasuko.eckert@amd.com drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def); 73910234Syasuko.eckert@amd.com // drive resistance 74010234Syasuko.eckert@amd.com double out_res = (tr_R_on(g_tp.min_w_nmos_, NCH, 1) + 74110234Syasuko.eckert@amd.com tr_R_on(min_w_pmos, PCH, 1)) / 2; 74210234Syasuko.eckert@amd.com double wr = wire_res(len); //ohm 74310152Satgutier@umich.edu 74410234Syasuko.eckert@amd.com // wire cap /m 74510234Syasuko.eckert@amd.com double wc = wire_cap(len); 74610152Satgutier@umich.edu 74710234Syasuko.eckert@amd.com repeater_spacing = space; 74810234Syasuko.eckert@amd.com repeater_size = size; 74910152Satgutier@umich.edu 75010234Syasuko.eckert@amd.com switching = (repeater_size * (input_cap + out_cap) + 75110234Syasuko.eckert@amd.com repeater_spacing * (wc / len)) * deviceType->Vdd * 75210234Syasuko.eckert@amd.com deviceType->Vdd; 75310152Satgutier@umich.edu 75410234Syasuko.eckert@amd.com tc = out_res * (input_cap + out_cap) + 75510234Syasuko.eckert@amd.com out_res * wc / len * repeater_spacing / repeater_size + 75610234Syasuko.eckert@amd.com wr / len * repeater_spacing * out_cap * repeater_size + 75710234Syasuko.eckert@amd.com 0.5 * (wr / len) * (wc / len) * repeater_spacing * repeater_spacing; 75810152Satgutier@umich.edu 75910234Syasuko.eckert@amd.com *delay = 0.693 * tc * len / repeater_spacing; 76010152Satgutier@umich.edu 76110152Satgutier@umich.edu#define Ishort_ckt 65e-6 /* across all tech Ref:Banerjee et al. {IEEE TED} */ 76210234Syasuko.eckert@amd.com short_ckt = deviceType->Vdd * g_tp.min_w_nmos_ * Ishort_ckt * 1.0986 * 76310234Syasuko.eckert@amd.com repeater_size * tc; 76410152Satgutier@umich.edu 76510234Syasuko.eckert@amd.com ptemp.readOp.dynamic = ((len / repeater_spacing) * (switching + short_ckt)); 76610234Syasuko.eckert@amd.com ptemp.readOp.leakage = ((len / repeater_spacing) * 76710234Syasuko.eckert@amd.com deviceType->Vdd * 76810234Syasuko.eckert@amd.com cmos_Isub_leakage(g_tp.min_w_nmos_ * 76910234Syasuko.eckert@amd.com repeater_size, beta * 77010234Syasuko.eckert@amd.com g_tp.min_w_nmos_ * 77110234Syasuko.eckert@amd.com repeater_size, 1, inv)); 77210152Satgutier@umich.edu 77310234Syasuko.eckert@amd.com ptemp.readOp.gate_leakage = ((len / repeater_spacing) * 77410234Syasuko.eckert@amd.com deviceType->Vdd * 77510234Syasuko.eckert@amd.com cmos_Ig_leakage(g_tp.min_w_nmos_ * 77610234Syasuko.eckert@amd.com repeater_size, beta * 77710234Syasuko.eckert@amd.com g_tp.min_w_nmos_ * 77810234Syasuko.eckert@amd.com repeater_size, 1, inv)); 77910152Satgutier@umich.edu 78010234Syasuko.eckert@amd.com return ptemp; 78110152Satgutier@umich.edu} 78210152Satgutier@umich.edu 78310152Satgutier@umich.eduvoid 78410234Syasuko.eckert@amd.comWire::print_wire() { 78510152Satgutier@umich.edu 78610234Syasuko.eckert@amd.com cout << "\nWire Properties:\n\n"; 78710234Syasuko.eckert@amd.com cout << " Delay Optimal\n\tRepeater size - " << global.area.h << 78810234Syasuko.eckert@amd.com " \n\tRepeater spacing - " << global.area.w*1e3 << " (mm)" 78910234Syasuko.eckert@amd.com " \n\tDelay - " << global.delay*1e6 << " (ns/mm)" 79010234Syasuko.eckert@amd.com " \n\tPowerD - " << global.power.readOp.dynamic *1e6 << " (nJ/mm)" 79110234Syasuko.eckert@amd.com " \n\tPowerL - " << global.power.readOp.leakage << " (mW/mm)" 79210234Syasuko.eckert@amd.com " \n\tPowerLgate - " << global.power.readOp.gate_leakage << 79310234Syasuko.eckert@amd.com " (mW/mm)\n"; 79410234Syasuko.eckert@amd.com cout << "\tWire width - " << wire_width_init*1e6 << " microns\n"; 79510234Syasuko.eckert@amd.com cout << "\tWire spacing - " << wire_spacing_init*1e6 << " microns\n"; 79610234Syasuko.eckert@amd.com cout << endl; 79710152Satgutier@umich.edu 79810234Syasuko.eckert@amd.com cout << " 5% Overhead\n\tRepeater size - " << global_5.area.h << 79910234Syasuko.eckert@amd.com " \n\tRepeater spacing - " << global_5.area.w*1e3 << " (mm)" 80010234Syasuko.eckert@amd.com " \n\tDelay - " << global_5.delay *1e6 << " (ns/mm)" 80110234Syasuko.eckert@amd.com " \n\tPowerD - " << global_5.power.readOp.dynamic *1e6 << " (nJ/mm)" 80210234Syasuko.eckert@amd.com " \n\tPowerL - " << global_5.power.readOp.leakage << " (mW/mm)" 80310234Syasuko.eckert@amd.com " \n\tPowerLgate - " << global_5.power.readOp.gate_leakage << 80410234Syasuko.eckert@amd.com " (mW/mm)\n"; 80510234Syasuko.eckert@amd.com cout << "\tWire width - " << wire_width_init*1e6 << " microns\n"; 80610234Syasuko.eckert@amd.com cout << "\tWire spacing - " << wire_spacing_init*1e6 << " microns\n"; 80710234Syasuko.eckert@amd.com cout << endl; 80810234Syasuko.eckert@amd.com cout << " 10% Overhead\n\tRepeater size - " << global_10.area.h << 80910234Syasuko.eckert@amd.com " \n\tRepeater spacing - " << global_10.area.w*1e3 << " (mm)" 81010234Syasuko.eckert@amd.com " \n\tDelay - " << global_10.delay *1e6 << " (ns/mm)" 81110234Syasuko.eckert@amd.com " \n\tPowerD - " << global_10.power.readOp.dynamic *1e6 << " (nJ/mm)" 81210234Syasuko.eckert@amd.com " \n\tPowerL - " << global_10.power.readOp.leakage << " (mW/mm)" 81310234Syasuko.eckert@amd.com " \n\tPowerLgate - " << global_10.power.readOp.gate_leakage << 81410234Syasuko.eckert@amd.com " (mW/mm)\n"; 81510234Syasuko.eckert@amd.com cout << "\tWire width - " << wire_width_init*1e6 << " microns\n"; 81610234Syasuko.eckert@amd.com cout << "\tWire spacing - " << wire_spacing_init*1e6 << " microns\n"; 81710234Syasuko.eckert@amd.com cout << endl; 81810234Syasuko.eckert@amd.com cout << " 20% Overhead\n\tRepeater size - " << global_20.area.h << 81910234Syasuko.eckert@amd.com " \n\tRepeater spacing - " << global_20.area.w*1e3 << " (mm)" 82010234Syasuko.eckert@amd.com " \n\tDelay - " << global_20.delay *1e6 << " (ns/mm)" 82110234Syasuko.eckert@amd.com " \n\tPowerD - " << global_20.power.readOp.dynamic *1e6 << " (nJ/mm)" 82210234Syasuko.eckert@amd.com " \n\tPowerL - " << global_20.power.readOp.leakage << " (mW/mm)" 82310234Syasuko.eckert@amd.com " \n\tPowerLgate - " << global_20.power.readOp.gate_leakage << 82410234Syasuko.eckert@amd.com " (mW/mm)\n"; 82510234Syasuko.eckert@amd.com cout << "\tWire width - " << wire_width_init*1e6 << " microns\n"; 82610234Syasuko.eckert@amd.com cout << "\tWire spacing - " << wire_spacing_init*1e6 << " microns\n"; 82710234Syasuko.eckert@amd.com cout << endl; 82810234Syasuko.eckert@amd.com cout << " 30% Overhead\n\tRepeater size - " << global_30.area.h << 82910234Syasuko.eckert@amd.com " \n\tRepeater spacing - " << global_30.area.w*1e3 << " (mm)" 83010234Syasuko.eckert@amd.com " \n\tDelay - " << global_30.delay *1e6 << " (ns/mm)" 83110234Syasuko.eckert@amd.com " \n\tPowerD - " << global_30.power.readOp.dynamic *1e6 << " (nJ/mm)" 83210234Syasuko.eckert@amd.com " \n\tPowerL - " << global_30.power.readOp.leakage << " (mW/mm)" 83310234Syasuko.eckert@amd.com " \n\tPowerLgate - " << global_30.power.readOp.gate_leakage << 83410234Syasuko.eckert@amd.com " (mW/mm)\n"; 83510234Syasuko.eckert@amd.com cout << "\tWire width - " << wire_width_init*1e6 << " microns\n"; 83610234Syasuko.eckert@amd.com cout << "\tWire spacing - " << wire_spacing_init*1e6 << " microns\n"; 83710234Syasuko.eckert@amd.com cout << endl; 83810234Syasuko.eckert@amd.com cout << " Low-swing wire (1 mm) - Note: Unlike repeated wires, \n\t" << 83910234Syasuko.eckert@amd.com "delay and power values of low-swing wires do not\n\t" << 84010234Syasuko.eckert@amd.com "have a linear relationship with length." << 84110234Syasuko.eckert@amd.com " \n\tdelay - " << low_swing.delay *1e9 << " (ns)" 84210234Syasuko.eckert@amd.com " \n\tpowerD - " << low_swing.power.readOp.dynamic *1e9 << " (nJ)" 84310234Syasuko.eckert@amd.com " \n\tPowerL - " << low_swing.power.readOp.leakage << " (mW)" 84410234Syasuko.eckert@amd.com " \n\tPowerLgate - " << low_swing.power.readOp.gate_leakage << 84510234Syasuko.eckert@amd.com " (mW)\n"; 84610234Syasuko.eckert@amd.com cout << "\tWire width - " << wire_width_init * 2 /* differential */ << 84710234Syasuko.eckert@amd.com " microns\n"; 84810234Syasuko.eckert@amd.com cout << "\tWire spacing - " << wire_spacing_init * 2 /* differential */ << 84910234Syasuko.eckert@amd.com " microns\n"; 85010234Syasuko.eckert@amd.com cout << endl; 85110234Syasuko.eckert@amd.com cout << endl; 85210152Satgutier@umich.edu 85310152Satgutier@umich.edu} 85410152Satgutier@umich.edu 855