351 lines
14 KiB
C++
351 lines
14 KiB
C++
|
/*****************************************************************************
|
||
|
* McPAT
|
||
|
* SOFTWARE LICENSE AGREEMENT
|
||
|
* 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.
|
||
|
*
|
||
|
* Authors: Joel Hestness
|
||
|
* Yasuko Eckert
|
||
|
*
|
||
|
***************************************************************************/
|
||
|
|
||
|
#include <algorithm>
|
||
|
#include <cmath>
|
||
|
#include <cstdio>
|
||
|
#include <fstream>
|
||
|
#include <iostream>
|
||
|
#include <string>
|
||
|
|
||
|
#include "array.h"
|
||
|
#include "basic_circuit.h"
|
||
|
#include "common.h"
|
||
|
#include "const.h"
|
||
|
#include "parameter.h"
|
||
|
#include "system.h"
|
||
|
#include "version.h"
|
||
|
|
||
|
// TODO: Fix this constructor to default initialize all pointers to NULL
|
||
|
System::System(XMLNode* _xml_data)
|
||
|
: McPATComponent(_xml_data) {
|
||
|
int i;
|
||
|
int currCore = 0;
|
||
|
int currNOC = 0;
|
||
|
name = "System";
|
||
|
set_proc_param();
|
||
|
|
||
|
// TODO: This loop can (and should) be called by every component in
|
||
|
// the hierarchy. Consider moving it to McPATComponent
|
||
|
int numChildren = xml_data->nChildNode("component");
|
||
|
for (i = 0; i < numChildren; i++ ) {
|
||
|
// For each child node of the system,
|
||
|
XMLNode* childXML = xml_data->getChildNodePtr("component", &i);
|
||
|
XMLCSTR type = childXML->getAttribute("type");
|
||
|
|
||
|
if (!type) {
|
||
|
warnMissingComponentType(childXML->getAttribute("id"));
|
||
|
|
||
|
} STRCMP(type, "Core") {
|
||
|
// TODO: If homogeneous cores, and currCore > 0, just copy core 0
|
||
|
children.push_back(new Core(childXML, currCore, &interface_ip));
|
||
|
currCore++;
|
||
|
} STRCMP(type, "CacheUnit") {
|
||
|
children.push_back(new CacheUnit(childXML, &interface_ip));
|
||
|
} STRCMP(type, "CacheController") {
|
||
|
// TODO: Remove reliance on interface_ip - there should be a better
|
||
|
// way to share global variables than passing, copying
|
||
|
children.push_back(new CacheController(childXML, &interface_ip));
|
||
|
} STRCMP(type, "MemoryController") {
|
||
|
children.push_back(new MemoryController(childXML, &interface_ip));
|
||
|
} STRCMP(type, "FlashController") {
|
||
|
children.push_back(new FlashController(childXML, &interface_ip));
|
||
|
} STRCMP(type, "NIUController") {
|
||
|
children.push_back(new NIUController(childXML, &interface_ip));
|
||
|
} STRCMP(type, "PCIeController") {
|
||
|
children.push_back(new PCIeController(childXML, &interface_ip));
|
||
|
} STRCMP(type, "Memory") {
|
||
|
// TODO:
|
||
|
warnIncompleteComponentType(type);
|
||
|
} STRCMP(type, "OnChipNetwork") {
|
||
|
// TODO: Many of the parameters to this constructor should be
|
||
|
// handled in another way
|
||
|
children.push_back(new OnChipNetwork(childXML, currNOC,
|
||
|
&interface_ip));
|
||
|
currNOC++;
|
||
|
warnIncompleteComponentType(type);
|
||
|
} STRCMP(type, "BusInterconnect") {
|
||
|
// TODO: Many of the parameters to this constructor should be
|
||
|
// handled in another way
|
||
|
children.push_back(new BusInterconnect(childXML, &interface_ip));
|
||
|
warnIncompleteComponentType(type);
|
||
|
|
||
|
// TODO: Add a directory data type that can handle the directories
|
||
|
// as defined by certain McScript output
|
||
|
} else {
|
||
|
warnUnrecognizedComponent(type);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void System::displayDeviceType(int device_type_, uint32_t indent) {
|
||
|
string indent_str(indent, ' ');
|
||
|
cout << indent_str << "Device Type = ";
|
||
|
|
||
|
switch ( device_type_ ) {
|
||
|
case 0:
|
||
|
cout << "ITRS high performance device type" << endl;
|
||
|
break;
|
||
|
case 1:
|
||
|
cout << "ITRS low standby power device type" << endl;
|
||
|
break;
|
||
|
case 2:
|
||
|
cout << "ITRS low operating power device type" << endl;
|
||
|
break;
|
||
|
case 3:
|
||
|
cout << "LP-DRAM device type" << endl;
|
||
|
break;
|
||
|
case 4:
|
||
|
cout << "COMM-DRAM device type" << endl;
|
||
|
break;
|
||
|
default:
|
||
|
cout << indent_str << "Unknown!" << endl;
|
||
|
exit(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void System::displayInterconnectType(int interconnect_type_, uint32_t indent) {
|
||
|
string indent_str(indent, ' ');
|
||
|
cout << indent_str << "Interconnect metal projection = ";
|
||
|
|
||
|
switch ( interconnect_type_ ) {
|
||
|
case 0:
|
||
|
cout << "aggressive interconnect technology projection" << endl;
|
||
|
break;
|
||
|
case 1:
|
||
|
cout << "conservative interconnect technology projection" << endl;
|
||
|
break;
|
||
|
default:
|
||
|
cout << indent_str << "Unknown!" << endl;
|
||
|
exit(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// TODO: Migrate this down to the McPATComponent::displayData function
|
||
|
void System::displayData(uint32_t indent, int plevel) {
|
||
|
string indent_str(indent, ' ');
|
||
|
string indent_str_next(indent + 2, ' ');
|
||
|
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 " << core_tech_node << " nm" << endl;
|
||
|
if (longer_channel_device)
|
||
|
cout << indent_str << "Using Long Channel Devices When Appropriate" << endl;
|
||
|
displayInterconnectType(interconnect_projection_type, indent);
|
||
|
cout << indent_str << "Target Clock Rate (MHz) " << target_core_clockrate / 1e6 << endl;
|
||
|
cout << endl;
|
||
|
|
||
|
cout << "*****************************************************************"
|
||
|
<< "************************" << endl;
|
||
|
|
||
|
McPATComponent::displayData(indent, plevel);
|
||
|
}
|
||
|
|
||
|
void System::set_proc_param() {
|
||
|
// TODO: Consider creating a SystemParams class that tracks system-wide
|
||
|
// parameters like these
|
||
|
longer_channel_device = false;
|
||
|
core_tech_node = -1;
|
||
|
temperature = -1;
|
||
|
interconnect_projection_type = -1;
|
||
|
device_type = -1;
|
||
|
physical_address_width = -1;
|
||
|
|
||
|
int num_children = xml_data->nChildNode("param");
|
||
|
int i;
|
||
|
for (i = 0; i < num_children; i++) {
|
||
|
XMLNode* paramNode = xml_data->getChildNodePtr("param", &i);
|
||
|
XMLCSTR node_name = paramNode->getAttribute("name");
|
||
|
XMLCSTR value = paramNode->getAttribute("value");
|
||
|
|
||
|
if (!node_name)
|
||
|
warnMissingParamName(paramNode->getAttribute("id"));
|
||
|
|
||
|
ASSIGN_FP_IF("core_tech_node", core_tech_node);
|
||
|
ASSIGN_INT_IF("target_core_clockrate", target_core_clockrate);
|
||
|
ASSIGN_INT_IF("temperature", temperature);
|
||
|
ASSIGN_INT_IF("device_type", device_type);
|
||
|
ASSIGN_INT_IF("longer_channel_device", longer_channel_device);
|
||
|
ASSIGN_INT_IF("interconnect_projection_type",
|
||
|
interconnect_projection_type);
|
||
|
ASSIGN_INT_IF("machine_bits", data_path_width);
|
||
|
ASSIGN_INT_IF("virtual_address_width", virtual_address_width);
|
||
|
ASSIGN_INT_IF("physical_address_width", physical_address_width);
|
||
|
ASSIGN_INT_IF("virtual_memory_page_size", virtual_memory_page_size);
|
||
|
ASSIGN_INT_IF("wire_is_mat_type", interface_ip.wire_is_mat_type);
|
||
|
ASSIGN_INT_IF("wire_os_mat_type", interface_ip.wire_os_mat_type);
|
||
|
ASSIGN_INT_IF("delay_wt", interface_ip.delay_wt);
|
||
|
ASSIGN_INT_IF("area_wt", interface_ip.area_wt);
|
||
|
ASSIGN_INT_IF("dynamic_power_wt", interface_ip.dynamic_power_wt);
|
||
|
ASSIGN_INT_IF("leakage_power_wt", interface_ip.leakage_power_wt);
|
||
|
ASSIGN_INT_IF("cycle_time_wt", interface_ip.cycle_time_wt);
|
||
|
ASSIGN_INT_IF("delay_dev", interface_ip.delay_dev);
|
||
|
ASSIGN_INT_IF("area_dev", interface_ip.area_dev);
|
||
|
ASSIGN_INT_IF("dynamic_power_dev", interface_ip.dynamic_power_dev);
|
||
|
ASSIGN_INT_IF("leakage_power_dev", interface_ip.leakage_power_dev);
|
||
|
ASSIGN_INT_IF("cycle_time_dev", interface_ip.cycle_time_dev);
|
||
|
ASSIGN_INT_IF("ed", interface_ip.ed);
|
||
|
ASSIGN_INT_IF("burst_len", interface_ip.burst_len);
|
||
|
ASSIGN_INT_IF("int_prefetch_w", interface_ip.int_prefetch_w);
|
||
|
ASSIGN_INT_IF("page_sz_bits", interface_ip.page_sz_bits);
|
||
|
ASSIGN_ENUM_IF("rpters_in_htree", interface_ip.rpters_in_htree, bool);
|
||
|
ASSIGN_INT_IF("ver_htree_wires_over_array",
|
||
|
interface_ip.ver_htree_wires_over_array);
|
||
|
ASSIGN_INT_IF("broadcast_addr_din_over_ver_htrees",
|
||
|
interface_ip.broadcast_addr_din_over_ver_htrees);
|
||
|
ASSIGN_INT_IF("nuca", interface_ip.nuca);
|
||
|
ASSIGN_INT_IF("nuca_bank_count", interface_ip.nuca_bank_count);
|
||
|
ASSIGN_ENUM_IF("force_cache_config",
|
||
|
interface_ip.force_cache_config, bool);
|
||
|
ASSIGN_ENUM_IF("wt", interface_ip.wt, Wire_type);
|
||
|
ASSIGN_INT_IF("force_wiretype", interface_ip.force_wiretype);
|
||
|
ASSIGN_INT_IF("print_detail", interface_ip.print_detail);
|
||
|
ASSIGN_ENUM_IF("add_ecc_b_", interface_ip.add_ecc_b_, bool);
|
||
|
|
||
|
else {
|
||
|
warnUnrecognizedParam(node_name);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Change from MHz to Hz
|
||
|
target_core_clockrate *= 1e6;
|
||
|
interconnect_projection_type =
|
||
|
(interconnect_projection_type == 0) ? 0 : 1;
|
||
|
|
||
|
num_children = xml_data->nChildNode("stat");
|
||
|
for (i = 0; i < num_children; i++) {
|
||
|
XMLNode* statNode = xml_data->getChildNodePtr("stat", &i);
|
||
|
XMLCSTR node_name = statNode->getAttribute("name");
|
||
|
XMLCSTR value = statNode->getAttribute("value");
|
||
|
|
||
|
if (!node_name)
|
||
|
warnMissingStatName(statNode->getAttribute("id"));
|
||
|
|
||
|
ASSIGN_FP_IF("total_cycles", total_cycles);
|
||
|
|
||
|
else {
|
||
|
warnUnrecognizedStat(node_name);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (temperature < 0) {
|
||
|
errorUnspecifiedParam("temperature");
|
||
|
}
|
||
|
|
||
|
if (core_tech_node < 0) {
|
||
|
errorUnspecifiedParam("core_tech_node");
|
||
|
}
|
||
|
|
||
|
if (interconnect_projection_type < 0) {
|
||
|
errorUnspecifiedParam("interconnect_projection_type");
|
||
|
}
|
||
|
|
||
|
if (device_type < 0) {
|
||
|
errorUnspecifiedParam("device_type");
|
||
|
}
|
||
|
|
||
|
if (physical_address_width <= 0) {
|
||
|
errorNonPositiveParam("physical_address_width");
|
||
|
}
|
||
|
|
||
|
if (data_path_width <= 0) {
|
||
|
errorNonPositiveParam("machine_bits");
|
||
|
}
|
||
|
|
||
|
if (total_cycles <= 0) {
|
||
|
fprintf(stderr, "WARNING: total_cycles <= 0 in system component, ",
|
||
|
"power numbers will be funky...\n");
|
||
|
}
|
||
|
|
||
|
clockRate = target_core_clockrate;
|
||
|
execution_time = total_cycles / (target_core_clockrate);
|
||
|
|
||
|
/* Basic parameters*/
|
||
|
interface_ip.data_arr_ram_cell_tech_type = device_type;
|
||
|
interface_ip.data_arr_peri_global_tech_type = device_type;
|
||
|
interface_ip.tag_arr_ram_cell_tech_type = device_type;
|
||
|
interface_ip.tag_arr_peri_global_tech_type = device_type;
|
||
|
|
||
|
interface_ip.ic_proj_type = interconnect_projection_type;
|
||
|
interface_ip.temp = temperature;
|
||
|
interface_ip.F_sz_nm = core_tech_node;
|
||
|
interface_ip.F_sz_um = interface_ip.F_sz_nm / 1000;
|
||
|
interface_ip.is_main_mem = false;
|
||
|
|
||
|
// These are there just to make CACTI's error_checking() happy.
|
||
|
// They are either not actually used or overwritten by each component.
|
||
|
interface_ip.cache_sz = MIN_BUFFER_SIZE;
|
||
|
interface_ip.nbanks = 1;
|
||
|
interface_ip.out_w = 0;
|
||
|
interface_ip.line_sz = 1;
|
||
|
interface_ip.assoc = 1;
|
||
|
interface_ip.num_rw_ports = 1;
|
||
|
interface_ip.num_search_ports = 1;
|
||
|
interface_ip.is_cache = true;
|
||
|
interface_ip.pure_ram = false;
|
||
|
interface_ip.pure_cam = false;
|
||
|
|
||
|
|
||
|
//This section of code does not have real meaning; it is just to ensure
|
||
|
//all data will have initial value to prevent errors.
|
||
|
//They will be overridden during each components initialization
|
||
|
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.num_rw_ports = 1;
|
||
|
interface_ip.num_rd_ports = 0;
|
||
|
interface_ip.num_wr_ports = 0;
|
||
|
interface_ip.num_se_rd_ports = 0;
|
||
|
}
|
||
|
|
||
|
System::~System() {
|
||
|
// TODO: Delete children... do this in McPATComponent
|
||
|
};
|