/***************************************************************************** * 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.” * ***************************************************************************/ /******************************************************************** * Modified by: * Jingwen Leng, University of Texas, Austin * Syed Gilani, University of Wisconsin–Madison * Tayler Hetherington, University of British Columbia * Ahmed ElTantawy, University of British Columbia * Vijay Kandiah, Northwestern University ********************************************************************/ #include "processor.h" #include #include #include #include #include #include #include #include "XML_Parse.h" #include "array.h" #include "cacti/basic_circuit.h" #include "const.h" #include "parameter.h" #include "version.h" Processor::Processor(ParseXML *XML_interface) : XML(XML_interface), // TODO: using one global copy may have problems. mc(0), niu(0), pcie(0), flashcontroller(0) { /* * placement and routing overhead is 10%, core scales worse than cache 40% is * accumulated from 90 to 22nm There is no point to have heterogeneous memory * controller on chip, thus McPAT only support homogeneous memory controllers. */ rt_power.reset(); int i; double pppm_t[4] = {1, 1, 1, 1}; l2_power = 0; idle_core_power = 0; set_proc_param(); if (procdynp.homoCore) numCore = procdynp.numCore == 0 ? 0 : 1; else numCore = procdynp.numCore; if (procdynp.homoL2) numL2 = procdynp.numL2 == 0 ? 0 : 1; else numL2 = procdynp.numL2; if (XML->sys.Private_L2 && numCore != numL2) { cout << "Number of private L2 does not match number of cores" << endl; exit(0); } if (procdynp.homoL3) numL3 = procdynp.numL3 == 0 ? 0 : 1; else numL3 = procdynp.numL3; if (procdynp.homoNOC) numNOC = procdynp.numNOC == 0 ? 0 : 1; else numNOC = procdynp.numNOC; // if (!procdynp.homoNOC) // { // cout<<"Current McPAT does not support heterogeneous NOC"<computeEnergy(); cores[i]->computeEnergy(false); if (procdynp.homoCore) { core.area.set_area(core.area.get_area() + cores[i]->area.get_area() * procdynp.numCore); set_pppm(pppm_t, cores[i]->clockRate * procdynp.numCore, procdynp.numCore, procdynp.numCore, procdynp.numCore); // set the exClockRate exClockRate = cores[0]->clockRate; // TODO; get from XML file // cout<<"****EX clock rate:"<power * pppm_t; set_pppm(pppm_t, 1 / cores[i]->executionTime, procdynp.numCore, procdynp.numCore, procdynp.numCore); core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; area.set_area( area.get_area() + core.area.get_area()); // placement and routing overhead is // 10%, core scales worse than cache // 40% is accumulated from 90 to 22nm power = power + core.power; rt_power = rt_power + core.rt_power; } else { core.area.set_area(core.area.get_area() + cores[i]->area.get_area()); area.set_area( area.get_area() + cores[i]->area.get_area()); // placement and routing overhead is 10%, // core scales worse than cache 40% is // accumulated from 90 to 22nm set_pppm(pppm_t, cores[i]->clockRate, 1, 1, 1); // set the exClockRate exClockRate = cores[0]->clockRate; // TODO; get from XML file // cout<<"****EX clock rate:"<power * pppm_t; power = power + cores[i]->power * pppm_t; set_pppm(pppm_t, 1 / cores[i]->executionTime, 1, 1, 1); core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; rt_power = rt_power + cores[i]->rt_power * pppm_t; } } if (!XML->sys.Private_L2) { if (numL2 > 0) for (i = 0; i < numL2; i++) { l2array.push_back(new SharedCache(XML, i, &interface_ip)); l2array[i]->computeEnergy(); l2array[i]->computeEnergy(false); if (procdynp.homoL2) { l2.area.set_area(l2.area.get_area() + l2array[i]->area.get_area() * procdynp.numL2); set_pppm(pppm_t, l2array[i]->cachep.clockRate * procdynp.numL2, procdynp.numL2, procdynp.numL2, procdynp.numL2); l2.power = l2.power + l2array[i]->power * pppm_t; set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, procdynp.numL2, procdynp.numL2, procdynp.numL2); l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; area.set_area( area.get_area() + l2.area.get_area()); // placement and routing overhead is 10%, l2 // scales worse than cache 40% is // accumulated from 90 to 22nm power = power + l2.power; rt_power = rt_power + l2.rt_power; } else { l2.area.set_area(l2.area.get_area() + l2array[i]->area.get_area()); area.set_area( area.get_area() + l2array[i] ->area.get_area()); // placement and routing overhead is 10%, // l2 scales worse than cache 40% is // accumulated from 90 to 22nm set_pppm(pppm_t, l2array[i]->cachep.clockRate, 1, 1, 1); l2.power = l2.power + l2array[i]->power * pppm_t; power = power + l2array[i]->power * pppm_t; ; set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, 1, 1, 1); l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; rt_power = rt_power + l2array[i]->rt_power * pppm_t; } } } if (numL3 > 0) for (i = 0; i < numL3; i++) { l3array.push_back(new SharedCache(XML, i, &interface_ip, L3)); l3array[i]->computeEnergy(); l3array[i]->computeEnergy(false); if (procdynp.homoL3) { l3.area.set_area(l3.area.get_area() + l3array[i]->area.get_area() * procdynp.numL3); set_pppm(pppm_t, l3array[i]->cachep.clockRate * procdynp.numL3, procdynp.numL3, procdynp.numL3, procdynp.numL3); l3.power = l3.power + l3array[i]->power * pppm_t; set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, procdynp.numL3, procdynp.numL3, procdynp.numL3); l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; area.set_area( area.get_area() + l3.area.get_area()); // placement and routing overhead is // 10%, l3 scales worse than cache // 40% is accumulated from 90 to 22nm power = power + l3.power; rt_power = rt_power + l3.rt_power; } else { l3.area.set_area(l3.area.get_area() + l3array[i]->area.get_area()); area.set_area( area.get_area() + l3array[i]->area.get_area()); // placement and routing overhead is // 10%, l3 scales worse than cache // 40% is accumulated from 90 to 22nm set_pppm(pppm_t, l3array[i]->cachep.clockRate, 1, 1, 1); l3.power = l3.power + l3array[i]->power * pppm_t; power = power + l3array[i]->power * pppm_t; set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, 1, 1, 1); l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; rt_power = rt_power + l3array[i]->rt_power * pppm_t; } } if (numL1Dir > 0) for (i = 0; i < numL1Dir; i++) { l1dirarray.push_back(new SharedCache(XML, i, &interface_ip, L1Directory)); l1dirarray[i]->computeEnergy(); l1dirarray[i]->computeEnergy(false); if (procdynp.homoL1Dir) { l1dir.area.set_area(l1dir.area.get_area() + l1dirarray[i]->area.get_area() * procdynp.numL1Dir); set_pppm(pppm_t, l1dirarray[i]->cachep.clockRate * procdynp.numL1Dir, procdynp.numL1Dir, procdynp.numL1Dir, procdynp.numL1Dir); l1dir.power = l1dir.power + l1dirarray[i]->power * pppm_t; set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, procdynp.numL1Dir, procdynp.numL1Dir, procdynp.numL1Dir); l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; area.set_area( area.get_area() + l1dir.area.get_area()); // placement and routing overhead is 10%, // l1dir scales worse than cache 40% is // accumulated from 90 to 22nm power = power + l1dir.power; rt_power = rt_power + l1dir.rt_power; } else { l1dir.area.set_area(l1dir.area.get_area() + l1dirarray[i]->area.get_area()); area.set_area(area.get_area() + l1dirarray[i]->area.get_area()); set_pppm(pppm_t, l1dirarray[i]->cachep.clockRate, 1, 1, 1); l1dir.power = l1dir.power + l1dirarray[i]->power * pppm_t; power = power + l1dirarray[i]->power; set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, 1, 1, 1); l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; rt_power = rt_power + l1dirarray[i]->rt_power; } } if (numL2Dir > 0) for (i = 0; i < numL2Dir; i++) { l2dirarray.push_back(new SharedCache(XML, i, &interface_ip, L2Directory)); l2dirarray[i]->computeEnergy(); l2dirarray[i]->computeEnergy(false); if (procdynp.homoL2Dir) { l2dir.area.set_area(l2dir.area.get_area() + l2dirarray[i]->area.get_area() * procdynp.numL2Dir); set_pppm(pppm_t, l2dirarray[i]->cachep.clockRate * procdynp.numL2Dir, procdynp.numL2Dir, procdynp.numL2Dir, procdynp.numL2Dir); l2dir.power = l2dir.power + l2dirarray[i]->power * pppm_t; set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, procdynp.numL2Dir, procdynp.numL2Dir, procdynp.numL2Dir); l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; area.set_area( area.get_area() + l2dir.area.get_area()); // placement and routing overhead is 10%, // l2dir scales worse than cache 40% is // accumulated from 90 to 22nm power = power + l2dir.power; rt_power = rt_power + l2dir.rt_power; } else { l2dir.area.set_area(l2dir.area.get_area() + l2dirarray[i]->area.get_area()); area.set_area(area.get_area() + l2dirarray[i]->area.get_area()); set_pppm(pppm_t, l2dirarray[i]->cachep.clockRate, 1, 1, 1); l2dir.power = l2dir.power + l2dirarray[i]->power * pppm_t; power = power + l2dirarray[i]->power * pppm_t; set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, 1, 1, 1); l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; rt_power = rt_power + l2dirarray[i]->rt_power * pppm_t; } } if (XML->sys.mc.number_mcs > 0 && XML->sys.mc.memory_channels_per_mc > 0) { if (XML->sys.architecture == 1) // 1 for fermi mc = new MemoryController(XML, &interface_ip, MC, GDDR5); else if (XML->sys.architecture == 2) // 2 for quadro mc = new MemoryController(XML, &interface_ip, MC, GDDR3); else { printf("Architecture %d not defined!\n", XML->sys.architecture); printf("use 1 for fermi and 2 for quadro!\n"); exit(1); } mc->computeEnergy(); mc->computeEnergy(false); mcs.area.set_area(mcs.area.get_area() + mc->area.get_area() * XML->sys.mc.number_mcs); area.set_area(area.get_area() + mc->area.get_area() * XML->sys.mc.number_mcs); set_pppm(pppm_t, XML->sys.mc.number_mcs * mc->mcp.clockRate, XML->sys.mc.number_mcs, XML->sys.mc.number_mcs, XML->sys.mc.number_mcs); mcs.power = mc->power * pppm_t; power = power + mcs.power; set_pppm(pppm_t, 1 / mc->mcp.executionTime, XML->sys.mc.number_mcs, XML->sys.mc.number_mcs, XML->sys.mc.number_mcs); mcs.rt_power = mc->rt_power * pppm_t; rt_power = rt_power + mcs.rt_power; } if (XML->sys.flashc.number_mcs > 0) // flash controller { flashcontroller = new FlashController(XML, &interface_ip); flashcontroller->computeEnergy(); flashcontroller->computeEnergy(false); double number_fcs = flashcontroller->fcp.num_mcs; flashcontrollers.area.set_area(flashcontrollers.area.get_area() + flashcontroller->area.get_area() * number_fcs); area.set_area(area.get_area() + flashcontrollers.area.get_area()); set_pppm(pppm_t, number_fcs, number_fcs, number_fcs, number_fcs); flashcontrollers.power = flashcontroller->power * pppm_t; power = power + flashcontrollers.power; set_pppm(pppm_t, number_fcs, number_fcs, number_fcs, number_fcs); flashcontrollers.rt_power = flashcontroller->rt_power * pppm_t; rt_power = rt_power + flashcontrollers.rt_power; } if (XML->sys.niu.number_units > 0) { niu = new NIUController(XML, &interface_ip); niu->computeEnergy(); niu->computeEnergy(false); nius.area.set_area(nius.area.get_area() + niu->area.get_area() * XML->sys.niu.number_units); area.set_area(area.get_area() + niu->area.get_area() * XML->sys.niu.number_units); set_pppm(pppm_t, XML->sys.niu.number_units * niu->niup.clockRate, XML->sys.niu.number_units, XML->sys.niu.number_units, XML->sys.niu.number_units); nius.power = niu->power * pppm_t; power = power + nius.power; set_pppm(pppm_t, XML->sys.niu.number_units * niu->niup.clockRate, XML->sys.niu.number_units, XML->sys.niu.number_units, XML->sys.niu.number_units); nius.rt_power = niu->rt_power * pppm_t; rt_power = rt_power + nius.rt_power; } if (XML->sys.pcie.number_units > 0 && XML->sys.pcie.num_channels > 0) { pcie = new PCIeController(XML, &interface_ip); pcie->computeEnergy(); pcie->computeEnergy(false); pcies.area.set_area(pcies.area.get_area() + pcie->area.get_area() * XML->sys.pcie.number_units); area.set_area(area.get_area() + pcie->area.get_area() * XML->sys.pcie.number_units); set_pppm(pppm_t, XML->sys.pcie.number_units * pcie->pciep.clockRate, XML->sys.pcie.number_units, XML->sys.pcie.number_units, XML->sys.pcie.number_units); pcies.power = pcie->power * pppm_t; power = power + pcies.power; set_pppm(pppm_t, XML->sys.pcie.number_units * pcie->pciep.clockRate, XML->sys.pcie.number_units, XML->sys.pcie.number_units, XML->sys.pcie.number_units); pcies.rt_power = pcie->rt_power * pppm_t; rt_power = rt_power + pcies.rt_power; } if (numNOC > 0) { for (i = 0; i < numNOC; i++) { if (XML->sys.NoC[i].type) { // First add up area of routers if NoC is // used nocs.push_back(new NoC(XML, i, &interface_ip, 1)); if (procdynp.homoNOC) { noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area() * procdynp.numNOC); area.set_area(area.get_area() + noc.area.get_area()); } else { noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()); area.set_area(area.get_area() + nocs[i]->area.get_area()); } } else { // Bus based interconnect nocs.push_back( new NoC(XML, i, &interface_ip, 1, sqrt(area.get_area() * XML->sys.NoC[i].chip_coverage))); if (procdynp.homoNOC) { noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area() * procdynp.numNOC); area.set_area(area.get_area() + noc.area.get_area()); } else { noc.area.set_area(noc.area.get_area() + nocs[i]->area.get_area()); area.set_area(area.get_area() + nocs[i]->area.get_area()); } } } /* * Compute global links associated with each NOC, if any. This must be done * at the end (even after the NOC router part) since the total chip area * must be obtain to decide the link routing */ for (i = 0; i < numNOC; i++) { if (nocs[i]->nocdynp.has_global_link && XML->sys.NoC[i].type) { nocs[i]->init_link_bus( sqrt(area.get_area() * XML->sys.NoC[i].chip_coverage)); // compute global links if (procdynp.homoNOC) { noc.area.set_area(noc.area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() * nocs[i]->nocdynp.total_nodes * procdynp.numNOC); area.set_area(area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() * nocs[i]->nocdynp.total_nodes * procdynp.numNOC); } else { noc.area.set_area(noc.area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() * nocs[i]->nocdynp.total_nodes); area.set_area(area.get_area() + nocs[i]->link_bus_tot_per_Router.area.get_area() * nocs[i]->nocdynp.total_nodes); } } } // Compute energy of NoC (w or w/o links) or buses for (i = 0; i < numNOC; i++) { // cout<<"******************COMPUTE NOC ENERGY********************"<computeEnergy(); nocs[i]->computeEnergy(false); if (procdynp.homoNOC) { set_pppm(pppm_t, procdynp.numNOC * nocs[i]->nocdynp.clockRate, procdynp.numNOC, procdynp.numNOC, procdynp.numNOC); noc.power = noc.power + nocs[i]->power * pppm_t; set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, procdynp.numNOC, procdynp.numNOC, procdynp.numNOC); noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; power = power + noc.power; rt_power = rt_power + noc.rt_power; } else { set_pppm(pppm_t, nocs[i]->nocdynp.clockRate, 1, 1, 1); noc.power = noc.power + nocs[i]->power * pppm_t; power = power + nocs[i]->power * pppm_t; set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, 1, 1, 1); noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; rt_power = rt_power + nocs[i]->rt_power * pppm_t; } } } // //clock power // globalClock.init_wire_external(is_default, &interface_ip); // globalClock.clk_area =area*1e6; //change it from mm^2 to um^2 // globalClock.end_wiring_level =5;//toplevel metal // globalClock.start_wiring_level =5;//toplevel metal // globalClock.l_ip.with_clock_grid=false;//global clock does not drive local // final nodes globalClock.optimize_wire(); } void Processor::compute() { int i; double pppm_t[4] = {1, 1, 1, 1}; rt_power.reset(); // power.reset(); // core.power.reset(); core.rt_power.reset(); for (i = 0; i < numCore; i++) { cores[i]->executionTime = XML->sys.total_cycles / (XML->sys.core[i].clock_rate * 1e6); cores[i]->rt_power.reset(); cores[i]->compute(); // cores[i]->computeEnergy(false); if (procdynp.homoCore) { set_pppm(pppm_t, 1 / cores[i]->executionTime, procdynp.numCore, procdynp.numCore, procdynp.numCore); core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; rt_power = rt_power + core.rt_power; } else { set_pppm(pppm_t, 1 / cores[i]->executionTime, 1, 1, 1); core.rt_power = core.rt_power + cores[i]->rt_power * pppm_t; rt_power = rt_power + cores[i]->rt_power * pppm_t; } } if (!XML->sys.Private_L2) { if (numL2 > 0) l2.rt_power.reset(); for (i = 0; i < numL2; i++) { l2array[i]->rt_power.reset(); l2array[i]->cachep.executionTime = XML->sys.total_cycles / (XML->sys.core[0].clock_rate * 1e6); l2array[i]->computeEnergy(false); if (procdynp.homoL2) { set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, procdynp.numL2, procdynp.numL2, procdynp.numL2); l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; rt_power = rt_power + l2.rt_power; } else { set_pppm(pppm_t, 1 / l2array[i]->cachep.executionTime, 1, 1, 1); l2.rt_power = l2.rt_power + l2array[i]->rt_power * pppm_t; rt_power = rt_power + l2array[i]->rt_power * pppm_t; } } } l3.rt_power.reset(); if (numL3 > 0) for (i = 0; i < numL3; i++) { l3array[i]->rt_power.reset(); l3array[i]->computeEnergy(false); if (procdynp.homoL3) { set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, procdynp.numL3, procdynp.numL3, procdynp.numL3); l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; rt_power = rt_power + l3.rt_power; } else { set_pppm(pppm_t, 1 / l3array[i]->cachep.executionTime, 1, 1, 1); l3.rt_power = l3.rt_power + l3array[i]->rt_power * pppm_t; rt_power = rt_power + l3array[i]->rt_power * pppm_t; } } l1dir.rt_power.reset(); if (numL1Dir > 0) for (i = 0; i < numL1Dir; i++) { l1dirarray[i]->rt_power.reset(); l1dirarray[i]->computeEnergy(false); if (procdynp.homoL1Dir) { set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, procdynp.numL1Dir, procdynp.numL1Dir, procdynp.numL1Dir); l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; rt_power = rt_power + l1dir.rt_power; } else { set_pppm(pppm_t, 1 / l1dirarray[i]->cachep.executionTime, 1, 1, 1); l1dir.rt_power = l1dir.rt_power + l1dirarray[i]->rt_power * pppm_t; rt_power = rt_power + l1dirarray[i]->rt_power; } } l2dir.rt_power.reset(); if (numL2Dir > 0) for (i = 0; i < numL2Dir; i++) { l2dirarray[i]->rt_power.reset(); l2dirarray[i]->computeEnergy(false); if (procdynp.homoL2Dir) { set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, procdynp.numL2Dir, procdynp.numL2Dir, procdynp.numL2Dir); l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; rt_power = rt_power + l2dir.rt_power; } else { set_pppm(pppm_t, 1 / l2dirarray[i]->cachep.executionTime, 1, 1, 1); l2dir.rt_power = l2dir.rt_power + l2dirarray[i]->rt_power * pppm_t; rt_power = rt_power + l2dirarray[i]->rt_power * pppm_t; } } mcs.rt_power.reset(); if (XML->sys.mc.number_mcs > 0 && XML->sys.mc.memory_channels_per_mc > 0) { mc->rt_power.reset(); mc->mcp.executionTime = XML->sys.total_cycles / (XML->sys.core[0].clock_rate * 1e6); // Jingwen mc->computeEnergy(false); set_pppm(pppm_t, 1 / mc->mcp.executionTime, XML->sys.mc.number_mcs, XML->sys.mc.number_mcs, XML->sys.mc.number_mcs); mcs.rt_power = mc->rt_power * pppm_t; rt_power = rt_power + mcs.rt_power; } /* if (XML->sys.flashc.number_mcs >0 )//flash controller { flashcontrollers.rt_power.reset(); flashcontroller->computeEnergy(false); double number_fcs = flashcontroller->fcp.num_mcs; set_pppm(pppm_t,number_fcs , number_fcs ,number_fcs ,number_fcs ); flashcontrollers.rt_power = flashcontroller->rt_power*pppm_t; rt_power = rt_power + flashcontrollers.rt_power; } if (XML->sys.niu.number_units >0) { niu->computeEnergy(false); nius.rt_power.reset(); set_pppm(pppm_t,XML->sys.niu.number_units*niu->niup.clockRate, XML->sys.niu.number_units,XML->sys.niu.number_units,XML->sys.niu.number_units); nius.rt_power = niu->rt_power*pppm_t; rt_power = rt_power + nius.rt_power; } if (XML->sys.pcie.number_units >0 && XML->sys.pcie.num_channels >0) { pcie->computeEnergy(false); pcies.rt_power.reset(); set_pppm(pppm_t,XML->sys.pcie.number_units*pcie->pciep.clockRate, XML->sys.pcie.number_units,XML->sys.pcie.number_units,XML->sys.pcie.number_units); pcies.rt_power = pcie->rt_power*pppm_t; rt_power = rt_power + pcies.rt_power; } // * Compute global links associated with each NOC, if any. This must be done at the end (even after the NOC router part) since the total chip // * area must be obtain to decide the link routing */ // Compute energy of NoC (w or w/o links) or buses noc.rt_power.reset(); for (i = 0; i < numNOC; i++) { nocs[i]->nocdynp.executionTime = XML->sys.total_cycles / (XML->sys.core[0].clock_rate * 1e6); nocs[i]->computeEnergy(false); if (procdynp.homoNOC) { set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, procdynp.numNOC, procdynp.numNOC, procdynp.numNOC); noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; rt_power = rt_power + noc.rt_power; } else { set_pppm(pppm_t, 1 / nocs[i]->nocdynp.executionTime, 1, 1, 1); noc.rt_power = noc.rt_power + nocs[i]->rt_power * pppm_t; rt_power = rt_power + nocs[i]->rt_power * pppm_t; } } // //clock power // globalClock.init_wire_external(is_default, &interface_ip); // globalClock.clk_area =area*1e6; //change it from mm^2 to um^2 // globalClock.end_wiring_level =5;//toplevel metal // globalClock.start_wiring_level =5;//toplevel metal // globalClock.l_ip.with_clock_grid=false;//global clock does not drive local // final nodes globalClock.optimize_wire(); } void Processor::displayDeviceType(int device_type_, uint32_t indent) { string indent_str(indent, ' '); switch (device_type_) { case 0: cout << indent_str << "Device Type= " << "ITRS high performance device type" << endl; break; case 1: cout << indent_str << "Device Type= " << "ITRS low standby power device type" << endl; break; case 2: cout << indent_str << "Device Type= " << "ITRS low operating power device type" << endl; break; case 3: cout << indent_str << "Device Type= " << "LP-DRAM device type" << endl; break; case 4: cout << indent_str << "Device Type= " << "COMM-DRAM device type" << endl; break; default: { cout << indent_str << "Unknown Device Type" << endl; exit(0); } } } void Processor::displayInterconnectType(int interconnect_type_, uint32_t indent) { string indent_str(indent, ' '); switch (interconnect_type_) { case 0: cout << indent_str << "Interconnect metal projection= " << "aggressive interconnect technology projection" << endl; break; case 1: cout << indent_str << "Interconnect metal projection= " << "conservative interconnect technology projection" << endl; break; default: { cout << indent_str << "Unknown Interconnect Projection Type" << endl; exit(0); } } } void Processor::displayEnergy(uint32_t indent, int plevel, bool is_tdp_parm) { int i; bool long_channel = XML->sys.longer_channel_device; string indent_str(indent, ' '); string indent_str_next(indent + 2, ' '); bool is_tdp = is_tdp_parm; if (is_tdp_parm) { if (plevel < 5) { cout << "\nMcPAT (version " << VER_MAJOR << "." << VER_MINOR << " of " << VER_UPDATE << ") results (current print level is " << plevel << ", please increase print level to see the details in components): " << endl; } else { cout << "\nMcPAT (version " << VER_MAJOR << "." << VER_MINOR << " of " << VER_UPDATE << ") results (current print level is 5)" << endl; } cout << "******************************************************************" "***********************" << endl; cout << indent_str << "Technology " << XML->sys.core_tech_node << " nm" << endl; // cout <sys.interconnect_projection_type<sys.interconnect_projection_type, indent); cout << indent_str << "Core clock Rate(MHz) " << XML->sys.core[0].clock_rate << endl; cout << endl; cout << "******************************************************************" "***********************" << endl; cout << "Processor: " << endl; cout << indent_str << "Area = " << area.get_area() * 1e-6 << " mm^2" << endl; cout << indent_str << "Peak Power = " << power.readOp.dynamic + (long_channel ? power.readOp.longer_channel_leakage : power.readOp.leakage) + power.readOp.gate_leakage << " W" << endl; cout << indent_str << "Total Leakage = " << (long_channel ? power.readOp.longer_channel_leakage : power.readOp.leakage) + power.readOp.gate_leakage << " W" << endl; cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic << " W" << endl; cout << indent_str << "Subthreshold Leakage = " << (long_channel ? power.readOp.longer_channel_leakage : power.readOp.leakage) << " W" << endl; // cout << indent_str << "Subthreshold Leakage = " << // power.readOp.longer_channel_leakage <<" W" << endl; cout << indent_str << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl; cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic << " W" << endl; cout << endl; if (numCore > 0) { cout << indent_str << "Total Cores: " << XML->sys.number_of_cores << " cores " << endl; displayDeviceType(XML->sys.device_type, indent); cout << indent_str_next << "Area = " << core.area.get_area() * 1e-6 << " mm^2" << endl; cout << indent_str_next << "Peak Dynamic = " << core.power.readOp.dynamic << " W" << endl; cout << indent_str_next << "Subthreshold Leakage = " << (long_channel ? core.power.readOp.longer_channel_leakage : core.power.readOp.leakage) << " W" << endl; // cout << indent_str_next << "Subthreshold Leakage = " << // core.power.readOp.longer_channel_leakage <<" W" << endl; cout << indent_str_next << "Gate Leakage = " << core.power.readOp.gate_leakage << " W" << endl; cout << indent_str_next << "Runtime Dynamic = " << core.rt_power.readOp.dynamic << " W" << endl; cout << endl; } if (!XML->sys.Private_L2) { if (numL2 > 0) { cout << indent_str << "Total L2s: " << endl; displayDeviceType(XML->sys.L2[0].device_type, indent); cout << indent_str_next << "Area = " << l2.area.get_area() * 1e-6 << " mm^2" << endl; cout << indent_str_next << "Peak Dynamic = " << l2.power.readOp.dynamic << " W" << endl; cout << indent_str_next << "Subthreshold Leakage = " << (long_channel ? l2.power.readOp.longer_channel_leakage : l2.power.readOp.leakage) << " W" << endl; // cout << indent_str_next << "Subthreshold Leakage = " << // l2.power.readOp.longer_channel_leakage <<" W" << endl; cout << indent_str_next << "Gate Leakage = " << l2.power.readOp.gate_leakage << " W" << endl; cout << indent_str_next << "Runtime Dynamic = " << l2.rt_power.readOp.dynamic << " W" << endl; cout << endl; } } if (numL3 > 0) { cout << indent_str << "Total L3s: " << endl; displayDeviceType(XML->sys.L3[0].device_type, indent); cout << indent_str_next << "Area = " << l3.area.get_area() * 1e-6 << " mm^2" << endl; cout << indent_str_next << "Peak Dynamic = " << l3.power.readOp.dynamic << " W" << endl; cout << indent_str_next << "Subthreshold Leakage = " << (long_channel ? l3.power.readOp.longer_channel_leakage : l3.power.readOp.leakage) << " W" << endl; // cout << indent_str_next << "Subthreshold Leakage = " << // l3.power.readOp.longer_channel_leakage <<" W" << endl; cout << indent_str_next << "Gate Leakage = " << l3.power.readOp.gate_leakage << " W" << endl; cout << indent_str_next << "Runtime Dynamic = " << l3.rt_power.readOp.dynamic << " W" << endl; cout << endl; } if (numL1Dir > 0) { cout << indent_str << "Total First Level Directory: " << endl; displayDeviceType(XML->sys.L1Directory[0].device_type, indent); cout << indent_str_next << "Area = " << l1dir.area.get_area() * 1e-6 << " mm^2" << endl; cout << indent_str_next << "Peak Dynamic = " << l1dir.power.readOp.dynamic << " W" << endl; cout << indent_str_next << "Subthreshold Leakage = " << (long_channel ? l1dir.power.readOp.longer_channel_leakage : l1dir.power.readOp.leakage) << " W" << endl; // cout << indent_str_next << "Subthreshold Leakage = " << // l1dir.power.readOp.longer_channel_leakage <<" W" << endl; cout << indent_str_next << "Gate Leakage = " << l1dir.power.readOp.gate_leakage << " W" << endl; cout << indent_str_next << "Runtime Dynamic = " << l1dir.rt_power.readOp.dynamic << " W" << endl; cout << endl; } if (numL2Dir > 0) { cout << indent_str << "Total First Level Directory: " << endl; displayDeviceType(XML->sys.L1Directory[0].device_type, indent); cout << indent_str_next << "Area = " << l2dir.area.get_area() * 1e-6 << " mm^2" << endl; cout << indent_str_next << "Peak Dynamic = " << l2dir.power.readOp.dynamic << " W" << endl; cout << indent_str_next << "Subthreshold Leakage = " << (long_channel ? l2dir.power.readOp.longer_channel_leakage : l2dir.power.readOp.leakage) << " W" << endl; // cout << indent_str_next << "Subthreshold Leakage = " << // l2dir.power.readOp.longer_channel_leakage <<" W" << endl; cout << indent_str_next << "Gate Leakage = " << l2dir.power.readOp.gate_leakage << " W" << endl; cout << indent_str_next << "Runtime Dynamic = " << l2dir.rt_power.readOp.dynamic << " W" << endl; cout << endl; } if (numNOC > 0) { cout << indent_str << "Total NoCs (Network/Bus): " << endl; displayDeviceType(XML->sys.device_type, indent); cout << indent_str_next << "Area = " << noc.area.get_area() * 1e-6 << " mm^2" << endl; cout << indent_str_next << "Peak Dynamic = " << noc.power.readOp.dynamic << " W" << endl; cout << indent_str_next << "Subthreshold Leakage = " << (long_channel ? noc.power.readOp.longer_channel_leakage : noc.power.readOp.leakage) << " W" << endl; // cout << indent_str_next << "Subthreshold Leakage = " << // noc.power.readOp.longer_channel_leakage <<" W" << endl; cout << indent_str_next << "Gate Leakage = " << noc.power.readOp.gate_leakage << " W" << endl; cout << indent_str_next << "Runtime Dynamic = " << noc.rt_power.readOp.dynamic << " W" << endl; cout << endl; } if (XML->sys.mc.number_mcs > 0 && XML->sys.mc.memory_channels_per_mc > 0) { cout << indent_str << "Total MCs: " << XML->sys.mc.number_mcs << " Memory Controllers " << endl; displayDeviceType(XML->sys.device_type, indent); cout << indent_str_next << "Area = " << mcs.area.get_area() * 1e-6 << " mm^2" << endl; cout << indent_str_next << "Peak Dynamic = " << mcs.power.readOp.dynamic << " W" << endl; cout << indent_str_next << "Subthreshold Leakage = " << (long_channel ? mcs.power.readOp.longer_channel_leakage : mcs.power.readOp.leakage) << " W" << endl; cout << indent_str_next << "Gate Leakage = " << mcs.power.readOp.gate_leakage << " W" << endl; cout << indent_str_next << "Runtime Dynamic = " << mcs.rt_power.readOp.dynamic << " W" << endl; cout << endl; } if (XML->sys.flashc.number_mcs > 0) { cout << indent_str << "Total Flash/SSD Controllers: " << flashcontroller->fcp.num_mcs << " Flash/SSD Controllers " << endl; displayDeviceType(XML->sys.device_type, indent); cout << indent_str_next << "Area = " << flashcontrollers.area.get_area() * 1e-6 << " mm^2" << endl; cout << indent_str_next << "Peak Dynamic = " << flashcontrollers.power.readOp.dynamic << " W" << endl; cout << indent_str_next << "Subthreshold Leakage = " << (long_channel ? flashcontrollers.power.readOp.longer_channel_leakage : flashcontrollers.power.readOp.leakage) << " W" << endl; cout << indent_str_next << "Gate Leakage = " << flashcontrollers.power.readOp.gate_leakage << " W" << endl; cout << indent_str_next << "Runtime Dynamic = " << flashcontrollers.rt_power.readOp.dynamic << " W" << endl; cout << endl; } if (XML->sys.niu.number_units > 0) { cout << indent_str << "Total NIUs: " << niu->niup.num_units << " Network Interface Units " << endl; displayDeviceType(XML->sys.device_type, indent); cout << indent_str_next << "Area = " << nius.area.get_area() * 1e-6 << " mm^2" << endl; cout << indent_str_next << "Peak Dynamic = " << nius.power.readOp.dynamic << " W" << endl; cout << indent_str_next << "Subthreshold Leakage = " << (long_channel ? nius.power.readOp.longer_channel_leakage : nius.power.readOp.leakage) << " W" << endl; cout << indent_str_next << "Gate Leakage = " << nius.power.readOp.gate_leakage << " W" << endl; cout << indent_str_next << "Runtime Dynamic = " << nius.rt_power.readOp.dynamic << " W" << endl; cout << endl; } if (XML->sys.pcie.number_units > 0 && XML->sys.pcie.num_channels > 0) { cout << indent_str << "Total PCIes: " << pcie->pciep.num_units << " PCIe Controllers " << endl; displayDeviceType(XML->sys.device_type, indent); cout << indent_str_next << "Area = " << pcies.area.get_area() * 1e-6 << " mm^2" << endl; cout << indent_str_next << "Peak Dynamic = " << pcies.power.readOp.dynamic << " W" << endl; cout << indent_str_next << "Subthreshold Leakage = " << (long_channel ? pcies.power.readOp.longer_channel_leakage : pcies.power.readOp.leakage) << " W" << endl; cout << indent_str_next << "Gate Leakage = " << pcies.power.readOp.gate_leakage << " W" << endl; cout << indent_str_next << "Runtime Dynamic = " << pcies.rt_power.readOp.dynamic << " W" << endl; cout << endl; } cout << "******************************************************************" "***********************" << endl; if (plevel > 1) { for (i = 0; i < numCore; i++) { cores[i]->displayEnergy(indent + 4, plevel, is_tdp); cout << "**************************************************************" "***************************" << endl; } if (!XML->sys.Private_L2) { for (i = 0; i < numL2; i++) { l2array[i]->displayEnergy(indent + 4, is_tdp); cout << "************************************************************" "*****************************" << endl; } } for (i = 0; i < numL3; i++) { l3array[i]->displayEnergy(indent + 4, is_tdp); cout << "**************************************************************" "***************************" << endl; } for (i = 0; i < numL1Dir; i++) { l1dirarray[i]->displayEnergy(indent + 4, is_tdp); cout << "**************************************************************" "***************************" << endl; } for (i = 0; i < numL2Dir; i++) { l2dirarray[i]->displayEnergy(indent + 4, is_tdp); cout << "**************************************************************" "***************************" << endl; } if (XML->sys.mc.number_mcs > 0 && XML->sys.mc.memory_channels_per_mc > 0) { mc->displayEnergy(indent + 4, is_tdp); cout << "**************************************************************" "***************************" << endl; } if (XML->sys.flashc.number_mcs > 0 && XML->sys.flashc.memory_channels_per_mc > 0) { flashcontroller->displayEnergy(indent + 4, is_tdp); cout << "**************************************************************" "***************************" << endl; } if (XML->sys.niu.number_units > 0) { niu->displayEnergy(indent + 4, is_tdp); cout << "**************************************************************" "***************************" << endl; } if (XML->sys.pcie.number_units > 0 && XML->sys.pcie.num_channels > 0) { pcie->displayEnergy(indent + 4, is_tdp); cout << "**************************************************************" "***************************" << endl; } for (i = 0; i < numNOC; i++) { nocs[i]->displayEnergy(indent + 4, plevel, is_tdp); cout << "**************************************************************" "***************************" << endl; } } } else { } } void Processor::set_proc_param() { bool debug = false; procdynp.homoCore = bool(debug ? 1 : XML->sys.homogeneous_cores); procdynp.homoL2 = bool(debug ? 1 : XML->sys.homogeneous_L2s); procdynp.homoL3 = bool(debug ? 1 : XML->sys.homogeneous_L3s); procdynp.homoNOC = bool(debug ? 1 : XML->sys.homogeneous_NoCs); procdynp.homoL1Dir = bool(debug ? 1 : XML->sys.homogeneous_L1Directories); procdynp.homoL2Dir = bool(debug ? 1 : XML->sys.homogeneous_L2Directories); procdynp.numCore = XML->sys.number_of_cores; procdynp.numL2 = XML->sys.number_of_L2s; procdynp.numL3 = XML->sys.number_of_L3s; procdynp.numNOC = XML->sys.number_of_NoCs; procdynp.numL1Dir = XML->sys.number_of_L1Directories; procdynp.numL2Dir = XML->sys.number_of_L2Directories; procdynp.numMC = XML->sys.mc.number_mcs; procdynp.numMCChannel = XML->sys.mc.memory_channels_per_mc; // if (procdynp.numCore<1) // { // cout<<" The target processor should at least have one core on // chip." //<2) // { // cout <<"number of NOCs must be 1 (only global NOCs) or 2 (both global // and local NOCs)"<sys.device_type; interface_ip.data_arr_peri_global_tech_type = debug ? 0 : XML->sys.device_type; interface_ip.tag_arr_ram_cell_tech_type = debug ? 0 : XML->sys.device_type; interface_ip.tag_arr_peri_global_tech_type = debug ? 0 : XML->sys.device_type; interface_ip.ic_proj_type = debug ? 0 : XML->sys.interconnect_projection_type; interface_ip.delay_wt = 100; // Fixed number, make sure timing can be satisfied. interface_ip.area_wt = 0; // Fixed number, This is used to exhaustive search // for individual components. interface_ip.dynamic_power_wt = 100; // Fixed number, This is used to exhaustive search for individual // components. interface_ip.leakage_power_wt = 0; interface_ip.cycle_time_wt = 0; interface_ip.delay_dev = 10000; // Fixed number, make sure timing can be satisfied. interface_ip.area_dev = 10000; // Fixed number, This is used to exhaustive // search for individual components. interface_ip.dynamic_power_dev = 10000; // Fixed number, This is used to exhaustive search for individual // components. interface_ip.leakage_power_dev = 10000; interface_ip.cycle_time_dev = 10000; interface_ip.ed = 2; interface_ip.burst_len = 1; // parameters are fixed for processor section, // since memory is processed separately interface_ip.int_prefetch_w = 1; interface_ip.page_sz_bits = 0; interface_ip.temp = debug ? 360 : XML->sys.temperature; interface_ip.F_sz_nm = debug ? 90 : XML->sys.core_tech_node; // XML->sys.core_tech_node; interface_ip.F_sz_um = interface_ip.F_sz_nm / 1000; //***********This section of code does not have real meaning, they are just to // ensure all data will have initial value to prevent errors. They will be // overridden during each components initialization interface_ip.cache_sz = 64; interface_ip.line_sz = 1; interface_ip.assoc = 1; interface_ip.nbanks = 1; interface_ip.out_w = interface_ip.line_sz * 8; interface_ip.specific_tag = 1; interface_ip.tag_w = 64; interface_ip.access_mode = 2; interface_ip.obj_func_dyn_energy = 0; interface_ip.obj_func_dyn_power = 0; interface_ip.obj_func_leak_power = 0; interface_ip.obj_func_cycle_t = 1; interface_ip.is_main_mem = false; interface_ip.rpters_in_htree = true; interface_ip.ver_htree_wires_over_array = 0; interface_ip.broadcast_addr_din_over_ver_htrees = 0; interface_ip.num_rw_ports = 1; interface_ip.num_rd_ports = 0; interface_ip.num_wr_ports = 0; interface_ip.num_se_rd_ports = 0; interface_ip.num_search_ports = 1; interface_ip.nuca = 0; interface_ip.nuca_bank_count = 0; interface_ip.is_cache = true; interface_ip.pure_ram = false; interface_ip.pure_cam = false; interface_ip.force_cache_config = false; if (XML->sys.Embedded) { interface_ip.wt = Global_30; interface_ip.wire_is_mat_type = 0; interface_ip.wire_os_mat_type = 0; } else { interface_ip.wt = Global; interface_ip.wire_is_mat_type = 2; interface_ip.wire_os_mat_type = 2; } interface_ip.force_wiretype = false; interface_ip.print_detail = 1; interface_ip.add_ecc_b_ = true; } Processor::~Processor() { while (!cores.empty()) { delete cores.back(); cores.pop_back(); } while (!l2array.empty()) { delete l2array.back(); l2array.pop_back(); } while (!l3array.empty()) { delete l3array.back(); l3array.pop_back(); } while (!nocs.empty()) { delete nocs.back(); nocs.pop_back(); } if (!mc) { delete mc; } if (!niu) { delete niu; } if (!pcie) { delete pcie; } if (!flashcontroller) { delete flashcontroller; } };