diff options
Diffstat (limited to 'ext/mcpat/interconnect.cc')
-rw-r--r-- | ext/mcpat/interconnect.cc | 310 |
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; } |