110152Satgutier@umich.edu/***************************************************************************** 210152Satgutier@umich.edu * McPAT 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#include <cassert> 3510152Satgutier@umich.edu#include <iostream> 3610152Satgutier@umich.edu 3710234Syasuko.eckert@amd.com#include "basic_components.h" 3810152Satgutier@umich.edu#include "interconnect.h" 3910152Satgutier@umich.edu#include "wire.h" 4010152Satgutier@umich.edu 4110234Syasuko.eckert@amd.comdouble Interconnect::width_scaling_threshold = 3.0; 4210152Satgutier@umich.edu 4310234Syasuko.eckert@amd.comInterconnect::Interconnect(XMLNode* _xml_data, string name_, 4410234Syasuko.eckert@amd.com enum Device_ty device_ty_, double base_w, 4510234Syasuko.eckert@amd.com double base_h, int data_w, 4610234Syasuko.eckert@amd.com double len, 4710234Syasuko.eckert@amd.com const InputParameter *configure_interface, 4810234Syasuko.eckert@amd.com int start_wiring_level_, double _clockRate, 4910234Syasuko.eckert@amd.com bool pipelinable_, double route_over_perc_, 5010234Syasuko.eckert@amd.com bool opt_local_, enum Core_type core_ty_, 5110234Syasuko.eckert@amd.com enum Wire_type wire_model, 5210234Syasuko.eckert@amd.com double width_s, double space_s, 5310234Syasuko.eckert@amd.com TechnologyParameter::DeviceType *dt) 5410234Syasuko.eckert@amd.com : McPATComponent(_xml_data), device_ty(device_ty_), in_rise_time(0), 5510234Syasuko.eckert@amd.com out_rise_time(0), base_width(base_w), base_height(base_h), 5610234Syasuko.eckert@amd.com data_width(data_w), wt(wire_model), width_scaling(width_s), 5710234Syasuko.eckert@amd.com space_scaling(space_s), start_wiring_level(start_wiring_level_), 5810234Syasuko.eckert@amd.com length(len), opt_local(opt_local_), core_ty(core_ty_), 5910234Syasuko.eckert@amd.com pipelinable(pipelinable_), route_over_perc(route_over_perc_), 6010234Syasuko.eckert@amd.com deviceType(dt) { 6110234Syasuko.eckert@amd.com name = name_; 6210234Syasuko.eckert@amd.com clockRate = _clockRate; 6310234Syasuko.eckert@amd.com l_ip = *configure_interface; 6410234Syasuko.eckert@amd.com local_result = init_interface(&l_ip, name); 6510152Satgutier@umich.edu 6610234Syasuko.eckert@amd.com max_unpipelined_link_delay = 0; 6710234Syasuko.eckert@amd.com min_w_nmos = g_tp.min_w_nmos_; 6810234Syasuko.eckert@amd.com min_w_pmos = deviceType->n_to_p_eff_curr_drv_ratio * min_w_nmos; 6910152Satgutier@umich.edu 7010152Satgutier@umich.edu 7110152Satgutier@umich.edu 7210234Syasuko.eckert@amd.com latency = l_ip.latency; 7310234Syasuko.eckert@amd.com throughput = l_ip.throughput; 7410234Syasuko.eckert@amd.com latency_overflow = false; 7510234Syasuko.eckert@amd.com throughput_overflow = false; 7610152Satgutier@umich.edu 7710234Syasuko.eckert@amd.com if (pipelinable == false) { 7810234Syasuko.eckert@amd.com //Non-pipelinable wires, such as bypass logic, care latency 7910234Syasuko.eckert@amd.com calcWireData(); 8010234Syasuko.eckert@amd.com if (opt_for_clk && opt_local) { 8110234Syasuko.eckert@amd.com while (delay > latency && 8210234Syasuko.eckert@amd.com width_scaling < width_scaling_threshold) { 8310234Syasuko.eckert@amd.com width_scaling *= 2; 8410234Syasuko.eckert@amd.com space_scaling *= 2; 8510234Syasuko.eckert@amd.com Wire winit(width_scaling, space_scaling); 8610234Syasuko.eckert@amd.com calcWireData(); 8710234Syasuko.eckert@amd.com } 8810234Syasuko.eckert@amd.com if (delay > latency) { 8910234Syasuko.eckert@amd.com latency_overflow = true; 9010234Syasuko.eckert@amd.com } 9110234Syasuko.eckert@amd.com } 9210234Syasuko.eckert@amd.com } else { 9310234Syasuko.eckert@amd.com //Pipelinable wires, such as bus, does not care latency but throughput 9410234Syasuko.eckert@amd.com calcWireData(); 9510234Syasuko.eckert@amd.com if (opt_for_clk && opt_local) { 9610234Syasuko.eckert@amd.com while (delay > throughput && 9710234Syasuko.eckert@amd.com width_scaling < width_scaling_threshold) { 9810234Syasuko.eckert@amd.com width_scaling *= 2; 9910234Syasuko.eckert@amd.com space_scaling *= 2; 10010234Syasuko.eckert@amd.com Wire winit(width_scaling, space_scaling); 10110234Syasuko.eckert@amd.com calcWireData(); 10210234Syasuko.eckert@amd.com } 10310234Syasuko.eckert@amd.com if (delay > throughput) { 10410234Syasuko.eckert@amd.com // insert pipeline stages 10510234Syasuko.eckert@amd.com num_pipe_stages = (int)ceil(delay / throughput); 10610234Syasuko.eckert@amd.com assert(num_pipe_stages > 0); 10710234Syasuko.eckert@amd.com delay = delay / num_pipe_stages + num_pipe_stages * 0.05 * delay; 10810234Syasuko.eckert@amd.com } 10910234Syasuko.eckert@amd.com } 11010234Syasuko.eckert@amd.com } 11110152Satgutier@umich.edu 11210234Syasuko.eckert@amd.com power_bit = power; 11310234Syasuko.eckert@amd.com power.readOp.dynamic *= data_width; 11410234Syasuko.eckert@amd.com power.readOp.leakage *= data_width; 11510234Syasuko.eckert@amd.com power.readOp.gate_leakage *= data_width; 11610234Syasuko.eckert@amd.com area.set_area(area.get_area()*data_width); 11710234Syasuko.eckert@amd.com no_device_under_wire_area.h *= data_width; 11810152Satgutier@umich.edu 11910234Syasuko.eckert@amd.com if (latency_overflow == true) { 12010234Syasuko.eckert@amd.com cout << "Warning: " << name 12110234Syasuko.eckert@amd.com << " wire structure cannot satisfy latency constraint." << endl; 12210234Syasuko.eckert@amd.com } 12310152Satgutier@umich.edu 12410234Syasuko.eckert@amd.com assert(power.readOp.dynamic > 0); 12510234Syasuko.eckert@amd.com assert(power.readOp.leakage > 0); 12610234Syasuko.eckert@amd.com assert(power.readOp.gate_leakage > 0); 12710152Satgutier@umich.edu 12810234Syasuko.eckert@amd.com double long_channel_device_reduction = 12910234Syasuko.eckert@amd.com longer_channel_device_reduction(device_ty, core_ty); 13010152Satgutier@umich.edu 13110234Syasuko.eckert@amd.com double sckRation = g_tp.sckt_co_eff; 13210234Syasuko.eckert@amd.com power.readOp.dynamic *= sckRation; 13310234Syasuko.eckert@amd.com power.writeOp.dynamic *= sckRation; 13410234Syasuko.eckert@amd.com power.searchOp.dynamic *= sckRation; 13510152Satgutier@umich.edu 13610234Syasuko.eckert@amd.com power.readOp.longer_channel_leakage = 13710234Syasuko.eckert@amd.com power.readOp.leakage * long_channel_device_reduction; 13810152Satgutier@umich.edu 13910234Syasuko.eckert@amd.com //Only global wires has the option to choose whether routing over or not 14010234Syasuko.eckert@amd.com if (pipelinable) 14110234Syasuko.eckert@amd.com area.set_area(area.get_area() * route_over_perc + 14210234Syasuko.eckert@amd.com no_device_under_wire_area.get_area() * 14310234Syasuko.eckert@amd.com (1 - route_over_perc)); 14410152Satgutier@umich.edu 14510234Syasuko.eckert@amd.com Wire wreset(); 14610152Satgutier@umich.edu} 14710152Satgutier@umich.edu 14810152Satgutier@umich.edu 14910152Satgutier@umich.edu 15010152Satgutier@umich.eduvoid 15110234Syasuko.eckert@amd.comInterconnect::calcWireData() { 15210152Satgutier@umich.edu 15310234Syasuko.eckert@amd.com Wire *wtemp1 = 0; 15410234Syasuko.eckert@amd.com wtemp1 = new Wire(wt, length, 1, width_scaling, space_scaling); 15510234Syasuko.eckert@amd.com delay = wtemp1->delay; 15610234Syasuko.eckert@amd.com power.readOp.dynamic = wtemp1->power.readOp.dynamic; 15710234Syasuko.eckert@amd.com power.readOp.leakage = wtemp1->power.readOp.leakage; 15810234Syasuko.eckert@amd.com power.readOp.gate_leakage = wtemp1->power.readOp.gate_leakage; 15910152Satgutier@umich.edu 16010234Syasuko.eckert@amd.com area.set_area(wtemp1->area.get_area()); 16110234Syasuko.eckert@amd.com no_device_under_wire_area.h = (wtemp1->wire_width + wtemp1->wire_spacing); 16210234Syasuko.eckert@amd.com no_device_under_wire_area.w = length; 16310152Satgutier@umich.edu 16410234Syasuko.eckert@amd.com if (wtemp1) 16510234Syasuko.eckert@amd.com delete wtemp1; 16610152Satgutier@umich.edu 16710152Satgutier@umich.edu} 16810152Satgutier@umich.edu 16910234Syasuko.eckert@amd.comvoid 17010234Syasuko.eckert@amd.comInterconnect::computeEnergy() { 17110234Syasuko.eckert@amd.com double pppm_t[4] = {1, 1, 1, 1}; 17210234Syasuko.eckert@amd.com 17310234Syasuko.eckert@amd.com // Compute TDP 17410234Syasuko.eckert@amd.com power_t.reset(); 17510234Syasuko.eckert@amd.com set_pppm(pppm_t, int_params.active_ports * int_stats.duty_cycle, 17610234Syasuko.eckert@amd.com int_params.active_ports, int_params.active_ports, 17710234Syasuko.eckert@amd.com int_params.active_ports * int_stats.duty_cycle); 17810234Syasuko.eckert@amd.com power_t = power * pppm_t; 17910234Syasuko.eckert@amd.com 18010234Syasuko.eckert@amd.com rt_power.reset(); 18110234Syasuko.eckert@amd.com set_pppm(pppm_t, int_stats.accesses, int_params.active_ports, 18210234Syasuko.eckert@amd.com int_params.active_ports, int_stats.accesses); 18310234Syasuko.eckert@amd.com rt_power = power * pppm_t; 18410234Syasuko.eckert@amd.com 18510234Syasuko.eckert@amd.com output_data.peak_dynamic_power = power_t.readOp.dynamic * clockRate; 18610234Syasuko.eckert@amd.com output_data.subthreshold_leakage_power = power_t.readOp.leakage; 18710234Syasuko.eckert@amd.com output_data.gate_leakage_power = power_t.readOp.gate_leakage; 18810234Syasuko.eckert@amd.com output_data.runtime_dynamic_energy = rt_power.readOp.dynamic; 18910234Syasuko.eckert@amd.com} 19010234Syasuko.eckert@amd.com 19110234Syasuko.eckert@amd.comvoid 19210234Syasuko.eckert@amd.comInterconnect::computeArea() { 19310234Syasuko.eckert@amd.com output_data.area = area.get_area() / 1e6; 19410234Syasuko.eckert@amd.com} 19510234Syasuko.eckert@amd.com 19610234Syasuko.eckert@amd.comvoid 19710234Syasuko.eckert@amd.comInterconnect::set_params_stats(double active_ports, 19810234Syasuko.eckert@amd.com double duty_cycle, double accesses) { 19910234Syasuko.eckert@amd.com int_params.active_ports = active_ports; 20010234Syasuko.eckert@amd.com int_stats.duty_cycle = duty_cycle; 20110234Syasuko.eckert@amd.com int_stats.accesses = accesses; 20210234Syasuko.eckert@amd.com} 20310234Syasuko.eckert@amd.com 20410234Syasuko.eckert@amd.comvoid Interconnect::leakage_feedback(double temperature) { 20510152Satgutier@umich.edu l_ip.temp = (unsigned int)round(temperature/10.0)*10; 20610234Syasuko.eckert@amd.com uca_org_t init_result = init_interface(&l_ip, name); // init_result is dummy 20710152Satgutier@umich.edu 20810234Syasuko.eckert@amd.com calcWireData(); 20910152Satgutier@umich.edu 21010152Satgutier@umich.edu power_bit = power; 21110152Satgutier@umich.edu power.readOp.dynamic *= data_width; 21210152Satgutier@umich.edu power.readOp.leakage *= data_width; 21310152Satgutier@umich.edu power.readOp.gate_leakage *= data_width; 21410152Satgutier@umich.edu 21510152Satgutier@umich.edu assert(power.readOp.dynamic > 0); 21610152Satgutier@umich.edu assert(power.readOp.leakage > 0); 21710152Satgutier@umich.edu assert(power.readOp.gate_leakage > 0); 21810152Satgutier@umich.edu 21910234Syasuko.eckert@amd.com double long_channel_device_reduction = 22010234Syasuko.eckert@amd.com longer_channel_device_reduction(device_ty,core_ty); 22110152Satgutier@umich.edu 22210152Satgutier@umich.edu double sckRation = g_tp.sckt_co_eff; 22310152Satgutier@umich.edu power.readOp.dynamic *= sckRation; 22410152Satgutier@umich.edu power.writeOp.dynamic *= sckRation; 22510152Satgutier@umich.edu power.searchOp.dynamic *= sckRation; 22610152Satgutier@umich.edu 22710234Syasuko.eckert@amd.com power.readOp.longer_channel_leakage = 22810234Syasuko.eckert@amd.com power.readOp.leakage*long_channel_device_reduction; 22910152Satgutier@umich.edu} 23010152Satgutier@umich.edu 231