blob: ba502b6a8673ff7361e3c2340badecd45a1f7922 [file] [log] [blame]
/*****************************************************************************
* McPAT
* SOFTWARE LICENSE AGREEMENT
* Copyright 2012 Hewlett-Packard Development Company, L.P.
* All Rights Reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.”
*
***************************************************************************/
#include <cassert>
#include <iostream>
#include "globalvar.h"
#include "interconnect.h"
#include "wire.h"
interconnect::interconnect(
string name_,
enum Device_ty device_ty_,
double base_w, double base_h,
int data_w, double len,const InputParameter *configure_interface,
int start_wiring_level_,
bool pipelinable_ ,
double route_over_perc_ ,
bool opt_local_,
enum Core_type core_ty_,
enum Wire_type wire_model,
double width_s, double space_s,
TechnologyParameter::DeviceType *dt
)
:name(name_),
device_ty(device_ty_),
in_rise_time(0),
out_rise_time(0),
base_width(base_w),
base_height(base_h),
data_width(data_w),
wt(wire_model),
width_scaling(width_s),
space_scaling(space_s),
start_wiring_level(start_wiring_level_),
length(len),
//interconnect_latency(1e-12),
//interconnect_throughput(1e-12),
opt_local(opt_local_),
core_ty(core_ty_),
pipelinable(pipelinable_),
route_over_perc(route_over_perc_),
deviceType(dt)
{
wt = Global;
l_ip=*configure_interface;
local_result = init_interface(&l_ip);
max_unpipelined_link_delay = 0; //TODO
min_w_nmos = g_tp.min_w_nmos_;
min_w_pmos = deviceType->n_to_p_eff_curr_drv_ratio * min_w_nmos;
latency = l_ip.latency;
throughput = l_ip.throughput;
latency_overflow=false;
throughput_overflow=false;
/*
* TODO: Add wiring option from semi-global to global automatically
* And directly jump to global if semi-global cannot satisfy timing
* Fat wires only available for global wires, thus
* if signal wiring layer starts from semi-global,
* the next layer up will be global, i.e., semi-global does
* not have fat wires.
*/
if (pipelinable == false)
//Non-pipelinable wires, such as bypass logic, care latency
{
compute();
if (opt_for_clk && opt_local)
{
while (delay > latency && width_scaling<3.0)
{
width_scaling *= 2;
space_scaling *= 2;
Wire winit(width_scaling, space_scaling);
compute();
}
if (delay > latency)
{
latency_overflow=true;
}
}
}
else //Pipelinable wires, such as bus, does not care latency but throughput
{
/*
* TODO: Add pipe regs power, area, and timing;
* Pipelinable wires optimize latency first.
*/
compute();
if (opt_for_clk && opt_local)
{
while (delay > throughput && width_scaling<3.0)
{
width_scaling *= 2;
space_scaling *= 2;
Wire winit(width_scaling, space_scaling);
compute();
}
if (delay > throughput)
// insert pipeline stages
{
num_pipe_stages = (int)ceil(delay/throughput);
assert(num_pipe_stages>0);
delay = delay/num_pipe_stages + num_pipe_stages*0.05*delay;
}
}
}
power_bit = power;
power.readOp.dynamic *= data_width;
power.readOp.leakage *= data_width;
power.readOp.gate_leakage *= data_width;
area.set_area(area.get_area()*data_width);
no_device_under_wire_area.h *= data_width;
if (latency_overflow==true)
cout<< "Warning: "<< name <<" wire structure cannot satisfy latency constraint." << endl;
assert(power.readOp.dynamic > 0);
assert(power.readOp.leakage > 0);
assert(power.readOp.gate_leakage > 0);
double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty);
double sckRation = g_tp.sckt_co_eff;
power.readOp.dynamic *= sckRation;
power.writeOp.dynamic *= sckRation;
power.searchOp.dynamic *= sckRation;
power.readOp.longer_channel_leakage =
power.readOp.leakage*long_channel_device_reduction;
if (pipelinable)//Only global wires has the option to choose whether routing over or not
area.set_area(area.get_area()*route_over_perc + no_device_under_wire_area.get_area()*(1-route_over_perc));
Wire wreset();
}
void
interconnect::compute()
{
Wire *wtemp1 = 0;
wtemp1 = new Wire(wt, length, 1, width_scaling, space_scaling);
delay = wtemp1->delay;
power.readOp.dynamic = wtemp1->power.readOp.dynamic;
power.readOp.leakage = wtemp1->power.readOp.leakage;
power.readOp.gate_leakage = wtemp1->power.readOp.gate_leakage;
area.set_area(wtemp1->area.get_area());
no_device_under_wire_area.h = (wtemp1->wire_width + wtemp1->wire_spacing);
no_device_under_wire_area.w = length;
if (wtemp1)
delete wtemp1;
}
void interconnect::leakage_feedback(double temperature)
{
l_ip.temp = (unsigned int)round(temperature/10.0)*10;
uca_org_t init_result = init_interface(&l_ip); // init_result is dummy
compute();
power_bit = power;
power.readOp.dynamic *= data_width;
power.readOp.leakage *= data_width;
power.readOp.gate_leakage *= data_width;
assert(power.readOp.dynamic > 0);
assert(power.readOp.leakage > 0);
assert(power.readOp.gate_leakage > 0);
double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty);
double sckRation = g_tp.sckt_co_eff;
power.readOp.dynamic *= sckRation;
power.writeOp.dynamic *= sckRation;
power.searchOp.dynamic *= sckRation;
power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction;
}