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#include <algorithm> 3410152Satgutier@umich.edu#include <cassert> 3510152Satgutier@umich.edu#include <cmath> 3610152Satgutier@umich.edu#include <iostream> 3710152Satgutier@umich.edu#include <string> 3810152Satgutier@umich.edu 3910152Satgutier@umich.edu#include "basic_circuit.h" 4010234Syasuko.eckert@amd.com#include "common.h" 4110152Satgutier@umich.edu#include "const.h" 4210152Satgutier@umich.edu#include "io.h" 4310152Satgutier@umich.edu#include "noc.h" 4410152Satgutier@umich.edu#include "parameter.h" 4510152Satgutier@umich.edu 4610234Syasuko.eckert@amd.comOnChipNetwork::OnChipNetwork(XMLNode* _xml_data, int ithNoC_, 4710234Syasuko.eckert@amd.com InputParameter* interface_ip_) 4810234Syasuko.eckert@amd.com : McPATComponent(_xml_data), router(NULL), link_bus(NULL), ithNoC(ithNoC_), 4910234Syasuko.eckert@amd.com interface_ip(*interface_ip_), link_bus_exist(false), 5010234Syasuko.eckert@amd.com router_exist(false) { 5110234Syasuko.eckert@amd.com name = "On-Chip Network"; 5210234Syasuko.eckert@amd.com set_param_stats(); 5310234Syasuko.eckert@amd.com local_result = init_interface(&interface_ip, name); 5410234Syasuko.eckert@amd.com scktRatio = g_tp.sckt_co_eff; 5510152Satgutier@umich.edu 5610234Syasuko.eckert@amd.com // TODO: Routers and links should be children of the NOC component 5710234Syasuko.eckert@amd.com if (noc_params.type) { 5810234Syasuko.eckert@amd.com init_router(); 5910234Syasuko.eckert@amd.com } else { 6010234Syasuko.eckert@amd.com init_link_bus(); 6110234Syasuko.eckert@amd.com } 6210152Satgutier@umich.edu} 6310152Satgutier@umich.edu 6410234Syasuko.eckert@amd.comvoid OnChipNetwork::init_router() { 6510234Syasuko.eckert@amd.com router = new Router(noc_params.flit_size, 6610234Syasuko.eckert@amd.com noc_params.virtual_channel_per_port * 6710234Syasuko.eckert@amd.com noc_params.input_buffer_entries_per_vc, 6810234Syasuko.eckert@amd.com noc_params.virtual_channel_per_port, 6910234Syasuko.eckert@amd.com &(g_tp.peri_global), 7010234Syasuko.eckert@amd.com noc_params.input_ports, noc_params.output_ports, 7110234Syasuko.eckert@amd.com noc_params.M_traffic_pattern); 7210234Syasuko.eckert@amd.com // TODO: Make a router class within McPAT that descends from McPATComponent 7310234Syasuko.eckert@amd.com // children.push_back(router); 7410234Syasuko.eckert@amd.com area.set_area(area.get_area() + router->area.get_area() * 7510234Syasuko.eckert@amd.com noc_params.total_nodes); 7610152Satgutier@umich.edu 7710234Syasuko.eckert@amd.com double long_channel_device_reduction = longer_channel_device_reduction(Uncore_device); 7810234Syasuko.eckert@amd.com router->power.readOp.longer_channel_leakage = router->power.readOp.leakage * long_channel_device_reduction; 7910234Syasuko.eckert@amd.com router->buffer.power.readOp.longer_channel_leakage = router->buffer.power.readOp.leakage * long_channel_device_reduction; 8010234Syasuko.eckert@amd.com router->crossbar.power.readOp.longer_channel_leakage = router->crossbar.power.readOp.leakage * long_channel_device_reduction; 8110234Syasuko.eckert@amd.com router->arbiter.power.readOp.longer_channel_leakage = router->arbiter.power.readOp.leakage * long_channel_device_reduction; 8210234Syasuko.eckert@amd.com router_exist = true; 8310152Satgutier@umich.edu} 8410152Satgutier@umich.edu 8510234Syasuko.eckert@amd.comvoid OnChipNetwork::init_link_bus() { 8610234Syasuko.eckert@amd.com if (noc_params.type) { 8710234Syasuko.eckert@amd.com link_name = "Links"; 8810234Syasuko.eckert@amd.com } else { 8910234Syasuko.eckert@amd.com link_name = "Bus"; 9010234Syasuko.eckert@amd.com } 9110152Satgutier@umich.edu 9210234Syasuko.eckert@amd.com interface_ip.throughput = noc_params.link_throughput / 9310234Syasuko.eckert@amd.com noc_params.clockRate; 9410234Syasuko.eckert@amd.com interface_ip.latency = noc_params.link_latency / noc_params.clockRate; 9510152Satgutier@umich.edu 9610234Syasuko.eckert@amd.com link_len /= (noc_params.horizontal_nodes + noc_params.vertical_nodes) / 2; 9710152Satgutier@umich.edu 9810234Syasuko.eckert@amd.com if (noc_params.total_nodes > 1) { 9910234Syasuko.eckert@amd.com //All links are shared by neighbors 10010234Syasuko.eckert@amd.com link_len /= 2; 10110234Syasuko.eckert@amd.com } 10210234Syasuko.eckert@amd.com link_bus = new Interconnect(xml_data, "Link", Uncore_device, 10310234Syasuko.eckert@amd.com noc_params.link_base_width, 10410234Syasuko.eckert@amd.com noc_params.link_base_height, 10510234Syasuko.eckert@amd.com noc_params.flit_size, link_len, &interface_ip, 10610234Syasuko.eckert@amd.com noc_params.link_start_wiring_level, 10710234Syasuko.eckert@amd.com noc_params.clockRate, true/*pipelinable*/, 10810234Syasuko.eckert@amd.com noc_params.route_over_perc); 10910234Syasuko.eckert@amd.com children.push_back(link_bus); 11010152Satgutier@umich.edu 11110234Syasuko.eckert@amd.com link_bus_exist = true; 11210152Satgutier@umich.edu} 11310152Satgutier@umich.edu 11410234Syasuko.eckert@amd.com// TODO: This should use the McPATComponent::computeEnergy function to 11510234Syasuko.eckert@amd.com// recursively calculate energy of routers and links and then add 11610234Syasuko.eckert@amd.comvoid OnChipNetwork::computeEnergy() { 11710234Syasuko.eckert@amd.com double pppm_t[4] = {1, 1, 1, 1}; 11810152Satgutier@umich.edu 11910234Syasuko.eckert@amd.com // Initialize stats for TDP 12010234Syasuko.eckert@amd.com tdp_stats.reset(); 12110234Syasuko.eckert@amd.com tdp_stats.readAc.access = noc_stats.duty_cycle; 12210234Syasuko.eckert@amd.com if (router_exist) { 12310234Syasuko.eckert@amd.com // TODO: Define a regression to exercise routers 12410234Syasuko.eckert@amd.com // TODO: Clean this up: it is too invasive and breaks abstraction 12510234Syasuko.eckert@amd.com set_pppm(pppm_t, 1 * tdp_stats.readAc.access, 1, 1, 1); 12610234Syasuko.eckert@amd.com router->power = router->power * pppm_t; 12710234Syasuko.eckert@amd.com set_pppm(pppm_t, noc_params.total_nodes, 12810234Syasuko.eckert@amd.com noc_params.total_nodes, 12910234Syasuko.eckert@amd.com noc_params.total_nodes, 13010234Syasuko.eckert@amd.com noc_params.total_nodes); 13110234Syasuko.eckert@amd.com } 13210234Syasuko.eckert@amd.com if (link_bus_exist) { 13310234Syasuko.eckert@amd.com if (noc_params.type) { 13410234Syasuko.eckert@amd.com link_bus->int_params.active_ports = noc_params.min_ports - 1; 13510234Syasuko.eckert@amd.com } else { 13610234Syasuko.eckert@amd.com link_bus->int_params.active_ports = noc_params.min_ports; 13710234Syasuko.eckert@amd.com } 13810234Syasuko.eckert@amd.com link_bus->int_stats.duty_cycle = 13910234Syasuko.eckert@amd.com noc_params.M_traffic_pattern * noc_stats.duty_cycle; 14010152Satgutier@umich.edu 14110234Syasuko.eckert@amd.com // TODO: Decide how to roll multiple routers into a single top-level 14210234Syasuko.eckert@amd.com // NOC module. I would prefer not to, but it might be a nice feature 14310234Syasuko.eckert@amd.com set_pppm(pppm_t, noc_params.total_nodes, 14410234Syasuko.eckert@amd.com noc_params.total_nodes, 14510234Syasuko.eckert@amd.com noc_params.total_nodes, 14610234Syasuko.eckert@amd.com noc_params.total_nodes); 14710234Syasuko.eckert@amd.com } 14810152Satgutier@umich.edu 14910234Syasuko.eckert@amd.com // Initialize stats for runtime energy and power 15010234Syasuko.eckert@amd.com rtp_stats.reset(); 15110234Syasuko.eckert@amd.com rtp_stats.readAc.access = noc_stats.total_access; 15210234Syasuko.eckert@amd.com set_pppm(pppm_t, 1, 0 , 0, 0); 15310234Syasuko.eckert@amd.com if (router_exist) { 15410234Syasuko.eckert@amd.com // TODO: Move this to a McPATComponent parent class of Router 15510234Syasuko.eckert@amd.com router->buffer.rt_power.readOp.dynamic = 15610234Syasuko.eckert@amd.com (router->buffer.power.readOp.dynamic + 15710234Syasuko.eckert@amd.com router->buffer.power.writeOp.dynamic) * rtp_stats.readAc.access; 15810234Syasuko.eckert@amd.com router->crossbar.rt_power.readOp.dynamic = 15910234Syasuko.eckert@amd.com router->crossbar.power.readOp.dynamic * rtp_stats.readAc.access; 16010234Syasuko.eckert@amd.com router->arbiter.rt_power.readOp.dynamic = 16110234Syasuko.eckert@amd.com router->arbiter.power.readOp.dynamic * rtp_stats.readAc.access; 16210152Satgutier@umich.edu 16310234Syasuko.eckert@amd.com router->rt_power = router->rt_power + 16410234Syasuko.eckert@amd.com (router->buffer.rt_power + router->crossbar.rt_power + 16510234Syasuko.eckert@amd.com router->arbiter.rt_power) * pppm_t + 16610234Syasuko.eckert@amd.com router->power * pppm_lkg;//TDP power must be calculated first! 16710234Syasuko.eckert@amd.com } 16810234Syasuko.eckert@amd.com if (link_bus_exist) { 16910234Syasuko.eckert@amd.com link_bus->int_stats.accesses = noc_stats.total_access; 17010234Syasuko.eckert@amd.com } 17110234Syasuko.eckert@amd.com 17210234Syasuko.eckert@amd.com // Recursively compute energy 17310234Syasuko.eckert@amd.com McPATComponent::computeEnergy(); 17410152Satgutier@umich.edu} 17510152Satgutier@umich.edu 17610234Syasuko.eckert@amd.comvoid OnChipNetwork::set_param_stats() { 17710234Syasuko.eckert@amd.com // TODO: Remove this or move initialization elsewhere 17810234Syasuko.eckert@amd.com memset(&noc_params, 0, sizeof(OnChipNetworkParameters)); 17910152Satgutier@umich.edu 18010234Syasuko.eckert@amd.com int num_children = xml_data->nChildNode("param"); 18110234Syasuko.eckert@amd.com int i; 18210234Syasuko.eckert@amd.com int mat_type; 18310234Syasuko.eckert@amd.com for (i = 0; i < num_children; i++) { 18410234Syasuko.eckert@amd.com XMLNode* paramNode = xml_data->getChildNodePtr("param", &i); 18510234Syasuko.eckert@amd.com XMLCSTR node_name = paramNode->getAttribute("name"); 18610234Syasuko.eckert@amd.com XMLCSTR value = paramNode->getAttribute("value"); 18710152Satgutier@umich.edu 18810234Syasuko.eckert@amd.com if (!node_name) 18910234Syasuko.eckert@amd.com warnMissingParamName(paramNode->getAttribute("id")); 19010234Syasuko.eckert@amd.com 19110234Syasuko.eckert@amd.com ASSIGN_INT_IF("type", noc_params.type); 19210234Syasuko.eckert@amd.com ASSIGN_FP_IF("clockrate", noc_params.clockRate); 19310234Syasuko.eckert@amd.com ASSIGN_INT_IF("flit_bits", noc_params.flit_size); 19410234Syasuko.eckert@amd.com ASSIGN_FP_IF("link_len", link_len); 19510234Syasuko.eckert@amd.com ASSIGN_FP_IF("link_throughput", noc_params.link_throughput); 19610234Syasuko.eckert@amd.com ASSIGN_FP_IF("link_latency", noc_params.link_latency); 19710234Syasuko.eckert@amd.com ASSIGN_INT_IF("input_ports", noc_params.input_ports); 19810234Syasuko.eckert@amd.com ASSIGN_INT_IF("output_ports", noc_params.output_ports); 19910234Syasuko.eckert@amd.com ASSIGN_INT_IF("global_linked_ports", noc_params.global_linked_ports); 20010234Syasuko.eckert@amd.com ASSIGN_INT_IF("horizontal_nodes", noc_params.horizontal_nodes); 20110234Syasuko.eckert@amd.com ASSIGN_INT_IF("vertical_nodes", noc_params.vertical_nodes); 20210234Syasuko.eckert@amd.com ASSIGN_FP_IF("chip_coverage", noc_params.chip_coverage); 20310234Syasuko.eckert@amd.com ASSIGN_FP_IF("link_routing_over_percentage", 20410234Syasuko.eckert@amd.com noc_params.route_over_perc); 20510234Syasuko.eckert@amd.com ASSIGN_INT_IF("has_global_link", noc_params.has_global_link); 20610234Syasuko.eckert@amd.com ASSIGN_INT_IF("virtual_channel_per_port", 20710234Syasuko.eckert@amd.com noc_params.virtual_channel_per_port); 20810234Syasuko.eckert@amd.com ASSIGN_INT_IF("input_buffer_entries_per_vc", 20910234Syasuko.eckert@amd.com noc_params.input_buffer_entries_per_vc); 21010234Syasuko.eckert@amd.com ASSIGN_FP_IF("M_traffic_pattern", noc_params.M_traffic_pattern); 21110234Syasuko.eckert@amd.com ASSIGN_FP_IF("link_base_width", noc_params.link_base_width); 21210234Syasuko.eckert@amd.com ASSIGN_FP_IF("link_base_height", noc_params.link_base_height); 21310234Syasuko.eckert@amd.com ASSIGN_INT_IF("link_start_wiring_level", 21410234Syasuko.eckert@amd.com noc_params.link_start_wiring_level); 21510234Syasuko.eckert@amd.com ASSIGN_INT_IF("wire_mat_type", mat_type); 21610234Syasuko.eckert@amd.com ASSIGN_ENUM_IF("wire_type", interface_ip.wt, Wire_type); 21710234Syasuko.eckert@amd.com 21810234Syasuko.eckert@amd.com else { 21910234Syasuko.eckert@amd.com warnUnrecognizedParam(node_name); 22010152Satgutier@umich.edu } 22110234Syasuko.eckert@amd.com } 22210234Syasuko.eckert@amd.com 22310234Syasuko.eckert@amd.com // Change from MHz to Hz 22410234Syasuko.eckert@amd.com noc_params.clockRate *= 1e6; 22510234Syasuko.eckert@amd.com 22610234Syasuko.eckert@amd.com interface_ip.wire_is_mat_type = mat_type; 22710234Syasuko.eckert@amd.com interface_ip.wire_os_mat_type = mat_type; 22810234Syasuko.eckert@amd.com 22910234Syasuko.eckert@amd.com num_children = xml_data->nChildNode("stat"); 23010234Syasuko.eckert@amd.com for (i = 0; i < num_children; i++) { 23110234Syasuko.eckert@amd.com XMLNode* statNode = xml_data->getChildNodePtr("stat", &i); 23210234Syasuko.eckert@amd.com XMLCSTR node_name = statNode->getAttribute("name"); 23310234Syasuko.eckert@amd.com XMLCSTR value = statNode->getAttribute("value"); 23410234Syasuko.eckert@amd.com 23510234Syasuko.eckert@amd.com if (!node_name) 23610234Syasuko.eckert@amd.com warnMissingStatName(statNode->getAttribute("id")); 23710234Syasuko.eckert@amd.com 23810234Syasuko.eckert@amd.com ASSIGN_FP_IF("duty_cycle", noc_stats.duty_cycle); 23910234Syasuko.eckert@amd.com ASSIGN_FP_IF("total_accesses", noc_stats.total_access); 24010234Syasuko.eckert@amd.com 24110234Syasuko.eckert@amd.com else { 24210234Syasuko.eckert@amd.com warnUnrecognizedStat(node_name); 24310152Satgutier@umich.edu } 24410234Syasuko.eckert@amd.com } 24510152Satgutier@umich.edu 24610234Syasuko.eckert@amd.com clockRate = noc_params.clockRate; 24710234Syasuko.eckert@amd.com noc_params.min_ports = 24810234Syasuko.eckert@amd.com min(noc_params.input_ports, noc_params.output_ports); 24910234Syasuko.eckert@amd.com if (noc_params.type) { 25010234Syasuko.eckert@amd.com noc_params.global_linked_ports = (noc_params.input_ports - 1) + 25110234Syasuko.eckert@amd.com (noc_params.output_ports - 1); 25210234Syasuko.eckert@amd.com } 25310234Syasuko.eckert@amd.com noc_params.total_nodes = 25410234Syasuko.eckert@amd.com noc_params.horizontal_nodes * noc_params.vertical_nodes; 25510152Satgutier@umich.edu 25610234Syasuko.eckert@amd.com assert(noc_params.chip_coverage <= 1); 25710234Syasuko.eckert@amd.com assert(noc_params.route_over_perc <= 1); 25810234Syasuko.eckert@amd.com assert(link_len > 0); 25910152Satgutier@umich.edu} 26010152Satgutier@umich.edu 26110234Syasuko.eckert@amd.comOnChipNetwork ::~OnChipNetwork() { 26210152Satgutier@umich.edu 26310234Syasuko.eckert@amd.com if (router) { 26410234Syasuko.eckert@amd.com delete router; 26510234Syasuko.eckert@amd.com router = 0; 26610234Syasuko.eckert@amd.com } 26710234Syasuko.eckert@amd.com if (link_bus) { 26810234Syasuko.eckert@amd.com delete link_bus; 26910234Syasuko.eckert@amd.com link_bus = 0; 27010234Syasuko.eckert@amd.com } 27110152Satgutier@umich.edu} 272