summaryrefslogtreecommitdiff
path: root/ext/mcpat/interconnect.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ext/mcpat/interconnect.cc')
-rw-r--r--ext/mcpat/interconnect.cc310
1 files changed, 159 insertions, 151 deletions
diff --git a/ext/mcpat/interconnect.cc b/ext/mcpat/interconnect.cc
index ba502b6a8..98fbc3e54 100644
--- a/ext/mcpat/interconnect.cc
+++ b/ext/mcpat/interconnect.cc
@@ -2,6 +2,7 @@
* McPAT
* 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
@@ -25,7 +26,7 @@
* 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.”
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
***************************************************************************/
@@ -33,173 +34,178 @@
#include <cassert>
#include <iostream>
-#include "globalvar.h"
+#include "basic_components.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;
- }
- }
- }
+double Interconnect::width_scaling_threshold = 3.0;
+
+Interconnect::Interconnect(XMLNode* _xml_data, 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_, double _clockRate,
+ 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)
+ : McPATComponent(_xml_data), 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), opt_local(opt_local_), core_ty(core_ty_),
+ pipelinable(pipelinable_), route_over_perc(route_over_perc_),
+ deviceType(dt) {
+ name = name_;
+ clockRate = _clockRate;
+ l_ip = *configure_interface;
+ local_result = init_interface(&l_ip, name);
+
+ max_unpipelined_link_delay = 0;
+ 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;
+
+ if (pipelinable == false) {
+ //Non-pipelinable wires, such as bypass logic, care latency
+ calcWireData();
+ if (opt_for_clk && opt_local) {
+ while (delay > latency &&
+ width_scaling < width_scaling_threshold) {
+ width_scaling *= 2;
+ space_scaling *= 2;
+ Wire winit(width_scaling, space_scaling);
+ calcWireData();
+ }
+ if (delay > latency) {
+ latency_overflow = true;
+ }
+ }
+ } else {
+ //Pipelinable wires, such as bus, does not care latency but throughput
+ calcWireData();
+ if (opt_for_clk && opt_local) {
+ while (delay > throughput &&
+ width_scaling < width_scaling_threshold) {
+ width_scaling *= 2;
+ space_scaling *= 2;
+ Wire winit(width_scaling, space_scaling);
+ calcWireData();
+ }
+ 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;
+
+ //Only global wires has the option to choose whether routing over or not
+ if (pipelinable)
+ area.set_area(area.get_area() * route_over_perc +
+ no_device_under_wire_area.get_area() *
+ (1 - route_over_perc));
+
+ Wire wreset();
+}
- 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;
+void
+Interconnect::calcWireData() {
- assert(power.readOp.dynamic > 0);
- assert(power.readOp.leakage > 0);
- assert(power.readOp.gate_leakage > 0);
+ 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;
- double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty);
+ 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;
- double sckRation = g_tp.sckt_co_eff;
- power.readOp.dynamic *= sckRation;
- power.writeOp.dynamic *= sckRation;
- power.searchOp.dynamic *= sckRation;
+ if (wtemp1)
+ delete wtemp1;
- 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;
+Interconnect::computeEnergy() {
+ double pppm_t[4] = {1, 1, 1, 1};
+
+ // Compute TDP
+ power_t.reset();
+ set_pppm(pppm_t, int_params.active_ports * int_stats.duty_cycle,
+ int_params.active_ports, int_params.active_ports,
+ int_params.active_ports * int_stats.duty_cycle);
+ power_t = power * pppm_t;
+
+ rt_power.reset();
+ set_pppm(pppm_t, int_stats.accesses, int_params.active_ports,
+ int_params.active_ports, int_stats.accesses);
+ rt_power = power * pppm_t;
+
+ output_data.peak_dynamic_power = power_t.readOp.dynamic * clockRate;
+ output_data.subthreshold_leakage_power = power_t.readOp.leakage;
+ output_data.gate_leakage_power = power_t.readOp.gate_leakage;
+ output_data.runtime_dynamic_energy = rt_power.readOp.dynamic;
+}
- if (wtemp1)
- delete wtemp1;
+void
+Interconnect::computeArea() {
+ output_data.area = area.get_area() / 1e6;
+}
+void
+Interconnect::set_params_stats(double active_ports,
+ double duty_cycle, double accesses) {
+ int_params.active_ports = active_ports;
+ int_stats.duty_cycle = duty_cycle;
+ int_stats.accesses = accesses;
}
-void interconnect::leakage_feedback(double temperature)
-{
+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
+ uca_org_t init_result = init_interface(&l_ip, name); // init_result is dummy
- compute();
+ calcWireData();
power_bit = power;
power.readOp.dynamic *= data_width;
@@ -210,13 +216,15 @@ void interconnect::leakage_feedback(double temperature)
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 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;
+ power.readOp.longer_channel_leakage =
+ power.readOp.leakage*long_channel_device_reduction;
}