blob: d3368d94662dbd1c4dd48fb4191d37505cf01174 [file] [log] [blame]
/*****************************************************************************
* McPAT/CACTI
* SOFTWARE LICENSE AGREEMENT
* Copyright 2012 Hewlett-Packard Development Company, L.P.
* Copyright (c) 2010-2013 Advanced Micro Devices, Inc.
* 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 "router.h"
Router::Router(
double flit_size_,
double vc_buf, /* vc size = vc_buffer_size * flit_size */
double vc_c,
TechnologyParameter::DeviceType *dt,
double I_,
double O_,
double M_
): flit_size(flit_size_),
deviceType(dt),
I(I_),
O(O_),
M(M_) {
vc_buffer_size = vc_buf;
vc_count = vc_c;
min_w_pmos = deviceType->n_to_p_eff_curr_drv_ratio * g_tp.min_w_nmos_;
double technology = g_ip->F_sz_um;
Vdd = dt->Vdd;
/*Crossbar parameters. Transmisson gate is employed for connector*/
NTtr = 10 * technology * 1e-6 / 2; /*Transmission gate's nmos tr. length*/
PTtr = 20 * technology * 1e-6 / 2; /* pmos tr. length*/
wt = 15 * technology * 1e-6 / 2; /*track width*/
ht = 15 * technology * 1e-6 / 2; /*track height*/
// I = 5; /*Number of crossbar input ports*/
// O = 5; /*Number of crossbar output ports*/
NTi = 12.5 * technology * 1e-6 / 2;
PTi = 25 * technology * 1e-6 / 2;
NTid = 60 * technology * 1e-6 / 2; //m
PTid = 120 * technology * 1e-6 / 2; // m
NTod = 60 * technology * 1e-6 / 2; // m
PTod = 120 * technology * 1e-6 / 2; // m
calc_router_parameters();
}
Router::~Router() {}
double //wire cap with triple spacing
Router::Cw3(double length) {
Wire wc(g_ip->wt, length, 1, 3, 3);
return (wc.wire_cap(length));
}
/*Function to calculate the gate capacitance*/
double
Router::gate_cap(double w) {
return (double) gate_C (w*1e6 /*u*/, 0);
}
/*Function to calculate the diffusion capacitance*/
double
Router::diff_cap(double w, int type /*0 for n-mos and 1 for p-mos*/,
double s /*number of stacking transistors*/) {
return (double) drain_C_(w*1e6 /*u*/, type, (int) s, 1, g_tp.cell_h_def);
}
/*crossbar related functions */
// Model for simple transmission gate
double
Router::transmission_buf_inpcap() {
return diff_cap(NTtr, 0, 1) + diff_cap(PTtr, 1, 1);
}
double
Router::transmission_buf_outcap() {
return diff_cap(NTtr, 0, 1) + diff_cap(PTtr, 1, 1);
}
double
Router::transmission_buf_ctrcap() {
return gate_cap(NTtr) + gate_cap(PTtr);
}
double
Router::crossbar_inpline() {
return (Cw3(O*flit_size*wt) + O*transmission_buf_inpcap() + gate_cap(NTid) +
gate_cap(PTid) + diff_cap(NTid, 0, 1) + diff_cap(PTid, 1, 1));
}
double
Router::crossbar_outline() {
return (Cw3(I*flit_size*ht) + I*transmission_buf_outcap() + gate_cap(NTod) +
gate_cap(PTod) + diff_cap(NTod, 0, 1) + diff_cap(PTod, 1, 1));
}
double
Router::crossbar_ctrline() {
return (Cw3(0.5*O*flit_size*wt) + flit_size*transmission_buf_ctrcap() +
diff_cap(NTi, 0, 1) + diff_cap(PTi, 1, 1) +
gate_cap(NTi) + gate_cap(PTi));
}
double
Router::tr_crossbar_power() {
return (crossbar_inpline()*Vdd*Vdd*flit_size / 2 +
crossbar_outline()*Vdd*Vdd*flit_size / 2) * 2;
}
void Router::buffer_stats() {
DynamicParameter dyn_p;
dyn_p.is_tag = false;
dyn_p.pure_cam = false;
dyn_p.fully_assoc = false;
dyn_p.pure_ram = true;
dyn_p.is_dram = false;
dyn_p.is_main_mem = false;
dyn_p.num_subarrays = 1;
dyn_p.num_mats = 1;
dyn_p.Ndbl = 1;
dyn_p.Ndwl = 1;
dyn_p.Nspd = 1;
dyn_p.deg_bl_muxing = 1;
dyn_p.deg_senseamp_muxing_non_associativity = 1;
dyn_p.Ndsam_lev_1 = 1;
dyn_p.Ndsam_lev_2 = 1;
dyn_p.Ndcm = 1;
dyn_p.number_addr_bits_mat = 8;
dyn_p.number_way_select_signals_mat = 1;
dyn_p.number_subbanks_decode = 0;
dyn_p.num_act_mats_hor_dir = 1;
dyn_p.V_b_sense = Vdd; // FIXME check power calc.
dyn_p.ram_cell_tech_type = 0;
dyn_p.num_r_subarray = (int) vc_buffer_size;
dyn_p.num_c_subarray = (int) flit_size * (int) vc_count;
dyn_p.num_mats_h_dir = 1;
dyn_p.num_mats_v_dir = 1;
dyn_p.num_do_b_subbank = (int)flit_size;
dyn_p.num_di_b_subbank = (int)flit_size;
dyn_p.num_do_b_mat = (int) flit_size;
dyn_p.num_di_b_mat = (int) flit_size;
dyn_p.num_do_b_mat = (int) flit_size;
dyn_p.num_di_b_mat = (int) flit_size;
dyn_p.num_do_b_bank_per_port = (int) flit_size;
dyn_p.num_di_b_bank_per_port = (int) flit_size;
dyn_p.out_w = (int) flit_size;
dyn_p.use_inp_params = 1;
dyn_p.num_wr_ports = (unsigned int) vc_count;
dyn_p.num_rd_ports = 1;//(unsigned int) vc_count;//based on Bill Dally's book
dyn_p.num_rw_ports = 0;
dyn_p.num_se_rd_ports = 0;
dyn_p.num_search_ports = 0;
dyn_p.cell.h = g_tp.sram.b_h + 2 * g_tp.wire_outside_mat.pitch * (dyn_p.num_wr_ports +
dyn_p.num_rw_ports - 1 + dyn_p.num_rd_ports);
dyn_p.cell.w = g_tp.sram.b_w + 2 * g_tp.wire_outside_mat.pitch * (dyn_p.num_rw_ports - 1 +
(dyn_p.num_rd_ports - dyn_p.num_se_rd_ports) +
dyn_p.num_wr_ports) + g_tp.wire_outside_mat.pitch * dyn_p.num_se_rd_ports;
Mat buff(dyn_p);
buff.compute_delays(0);
buff.compute_power_energy();
buffer.power.readOp = buff.power.readOp;
buffer.power.writeOp = buffer.power.readOp; //FIXME
buffer.area = buff.area;
}
void
Router::cb_stats () {
if (1) {
Crossbar c_b(I, O, flit_size);
c_b.compute_power();
crossbar.delay = c_b.delay;
crossbar.power.readOp.dynamic = c_b.power.readOp.dynamic;
crossbar.power.readOp.leakage = c_b.power.readOp.leakage;
crossbar.power.readOp.gate_leakage = c_b.power.readOp.gate_leakage;
crossbar.area = c_b.area;
// c_b.print_crossbar();
} else {
crossbar.power.readOp.dynamic = tr_crossbar_power();
crossbar.power.readOp.leakage = flit_size * I * O *
cmos_Isub_leakage(NTtr * g_tp.min_w_nmos_, PTtr * min_w_pmos, 1, tg);
crossbar.power.readOp.gate_leakage = flit_size * I * O *
cmos_Ig_leakage(NTtr * g_tp.min_w_nmos_, PTtr * min_w_pmos, 1, tg);
}
}
void
Router::get_router_power() {
/* calculate buffer stats */
buffer_stats();
/* calculate cross-bar stats */
cb_stats();
/* calculate arbiter stats */
Arbiter vcarb(vc_count, flit_size, buffer.area.w);
Arbiter cbarb(I, flit_size, crossbar.area.w);
vcarb.compute_power();
cbarb.compute_power();
arbiter.power.readOp.dynamic = vcarb.power.readOp.dynamic * I +
cbarb.power.readOp.dynamic * O;
arbiter.power.readOp.leakage = vcarb.power.readOp.leakage * I +
cbarb.power.readOp.leakage * O;
arbiter.power.readOp.gate_leakage = vcarb.power.readOp.gate_leakage * I +
cbarb.power.readOp.gate_leakage * O;
// arb_stats();
power.readOp.dynamic = ((buffer.power.readOp.dynamic +
buffer.power.writeOp.dynamic) +
crossbar.power.readOp.dynamic +
arbiter.power.readOp.dynamic) * MIN(I, O) * M;
double pppm_t[4] = {1, I, I, 1};
power = power + (buffer.power * pppm_t + crossbar.power + arbiter.power) *
pppm_lkg;
}
void
Router::get_router_delay () {
FREQUENCY = 5; // move this to config file --TODO
cycle_time = (1 / (double)FREQUENCY) * 1e3; //ps
delay = 4;
max_cyc = 17 * g_tp.FO4; //s
max_cyc *= 1e12; //ps
if (cycle_time < max_cyc) {
FREQUENCY = (1 / max_cyc) * 1e3; //GHz
}
}
void
Router::get_router_area() {
area.h = I * buffer.area.h;
area.w = buffer.area.w + crossbar.area.w;
}
void
Router::calc_router_parameters() {
/* calculate router frequency and pipeline cycles */
get_router_delay();
/* router power stats */
get_router_power();
/* area stats */
get_router_area();
}
void
Router::print_router() {
cout << "\n\nRouter stats:\n";
cout << "\tRouter Area - " << area.get_area()*1e-6 << "(mm^2)\n";
cout << "\tMaximum possible network frequency - " << (1 / max_cyc)*1e3
<< "GHz\n";
cout << "\tNetwork frequency - " << FREQUENCY << " GHz\n";
cout << "\tNo. of Virtual channels - " << vc_count << "\n";
cout << "\tNo. of pipeline stages - " << delay << endl;
cout << "\tLink bandwidth - " << flit_size << " (bits)\n";
cout << "\tNo. of buffer entries per virtual channel - "
<< vc_buffer_size << "\n";
cout << "\tSimple buffer Area - " << buffer.area.get_area()*1e-6
<< "(mm^2)\n";
cout << "\tSimple buffer access (Read) - "
<< buffer.power.readOp.dynamic * 1e9 << " (nJ)\n";
cout << "\tSimple buffer leakage - " << buffer.power.readOp.leakage * 1e3
<< " (mW)\n";
cout << "\tCrossbar Area - " << crossbar.area.get_area()*1e-6
<< "(mm^2)\n";
cout << "\tCross bar access energy - "
<< crossbar.power.readOp.dynamic * 1e9 << " (nJ)\n";
cout << "\tCross bar leakage power - "
<< crossbar.power.readOp.leakage * 1e3 << " (mW)\n";
cout << "\tArbiter access energy (VC arb + Crossbar arb) - "
<< arbiter.power.readOp.dynamic * 1e9 << " (nJ)\n";
cout << "\tArbiter leakage (VC arb + Crossbar arb) - "
<< arbiter.power.readOp.leakage * 1e3 << " (mW)\n";
}