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