1/***************************************************************************** 2 * McPAT 3 * SOFTWARE LICENSE AGREEMENT 4 * Copyright (c) 2010-2013 Advanced Micro Devices, Inc. 5 * All Rights Reserved 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer; 11 * redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution; 14 * neither the name of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Authors: Joel Hestness 31 * Yasuko Eckert 32 * 33 ***************************************************************************/ 34 35#include <algorithm> 36#include <cmath> 37#include <cstdio> 38#include <fstream> 39#include <iostream> 40#include <string> 41 42#include "array.h" 43#include "basic_circuit.h" 44#include "common.h" 45#include "const.h" 46#include "parameter.h" 47#include "system.h" 48#include "version.h" 49 50// TODO: Fix this constructor to default initialize all pointers to NULL 51System::System(XMLNode* _xml_data) 52 : McPATComponent(_xml_data) { 53 int i; 54 int currCore = 0; 55 int currNOC = 0; 56 name = "System"; 57 set_proc_param(); 58 59 // TODO: This loop can (and should) be called by every component in 60 // the hierarchy. Consider moving it to McPATComponent 61 int numChildren = xml_data->nChildNode("component"); 62 for (i = 0; i < numChildren; i++ ) { 63 // For each child node of the system, 64 XMLNode* childXML = xml_data->getChildNodePtr("component", &i); 65 XMLCSTR type = childXML->getAttribute("type"); 66 67 if (!type) { 68 warnMissingComponentType(childXML->getAttribute("id")); 69 70 } STRCMP(type, "Core") { 71 // TODO: If homogeneous cores, and currCore > 0, just copy core 0 72 children.push_back(new Core(childXML, currCore, &interface_ip)); 73 currCore++; 74 } STRCMP(type, "CacheUnit") { 75 children.push_back(new CacheUnit(childXML, &interface_ip)); 76 } STRCMP(type, "CacheController") { 77 // TODO: Remove reliance on interface_ip - there should be a better 78 // way to share global variables than passing, copying 79 children.push_back(new CacheController(childXML, &interface_ip)); 80 } STRCMP(type, "MemoryController") { 81 children.push_back(new MemoryController(childXML, &interface_ip)); 82 } STRCMP(type, "FlashController") { 83 children.push_back(new FlashController(childXML, &interface_ip)); 84 } STRCMP(type, "NIUController") { 85 children.push_back(new NIUController(childXML, &interface_ip)); 86 } STRCMP(type, "PCIeController") { 87 children.push_back(new PCIeController(childXML, &interface_ip)); 88 } STRCMP(type, "Memory") { 89 // TODO: 90 warnIncompleteComponentType(type); 91 } STRCMP(type, "OnChipNetwork") { 92 // TODO: Many of the parameters to this constructor should be 93 // handled in another way 94 children.push_back(new OnChipNetwork(childXML, currNOC, 95 &interface_ip)); 96 currNOC++; 97 warnIncompleteComponentType(type); 98 } STRCMP(type, "BusInterconnect") { 99 // TODO: Many of the parameters to this constructor should be 100 // handled in another way 101 children.push_back(new BusInterconnect(childXML, &interface_ip)); 102 warnIncompleteComponentType(type); 103 104 // TODO: Add a directory data type that can handle the directories 105 // as defined by certain McScript output 106 } else { 107 warnUnrecognizedComponent(type); 108 } 109 } 110} 111 112void System::displayDeviceType(int device_type_, uint32_t indent) { 113 string indent_str(indent, ' '); 114 cout << indent_str << "Device Type = "; 115 116 switch ( device_type_ ) { 117 case 0: 118 cout << "ITRS high performance device type" << endl; 119 break; 120 case 1: 121 cout << "ITRS low standby power device type" << endl; 122 break; 123 case 2: 124 cout << "ITRS low operating power device type" << endl; 125 break; 126 case 3: 127 cout << "LP-DRAM device type" << endl; 128 break; 129 case 4: 130 cout << "COMM-DRAM device type" << endl; 131 break; 132 default: 133 cout << indent_str << "Unknown!" << endl; 134 exit(0); 135 } 136} 137 138void System::displayInterconnectType(int interconnect_type_, uint32_t indent) { 139 string indent_str(indent, ' '); 140 cout << indent_str << "Interconnect metal projection = "; 141 142 switch ( interconnect_type_ ) { 143 case 0: 144 cout << "aggressive interconnect technology projection" << endl; 145 break; 146 case 1: 147 cout << "conservative interconnect technology projection" << endl; 148 break; 149 default: 150 cout << indent_str << "Unknown!" << endl; 151 exit(0); 152 } 153} 154 155// TODO: Migrate this down to the McPATComponent::displayData function 156void System::displayData(uint32_t indent, int plevel) { 157 string indent_str(indent, ' '); 158 string indent_str_next(indent + 2, ' '); 159 if (plevel < 5) { 160 cout << "\nMcPAT (version " << VER_MAJOR << "." << VER_MINOR 161 << " of " << VER_UPDATE << ") results (current print level is " 162 << plevel 163 << ", please increase print level to see the details in " 164 << "components) " << endl; 165 } else { 166 cout << "\nMcPAT (version " << VER_MAJOR << "." << VER_MINOR 167 << " of " << VER_UPDATE << ") results (current print level is 5)" 168 << endl; 169 } 170 171 cout << "*****************************************************************" 172 << "************************" << endl; 173 cout << indent_str << "Technology " << core_tech_node << " nm" << endl; 174 if (longer_channel_device) 175 cout << indent_str << "Using Long Channel Devices When Appropriate" << endl; 176 displayInterconnectType(interconnect_projection_type, indent); 177 cout << indent_str << "Target Clock Rate (MHz) " << target_core_clockrate / 1e6 << endl; 178 cout << endl; 179 180 cout << "*****************************************************************" 181 << "************************" << endl; 182 183 McPATComponent::displayData(indent, plevel); 184} 185 186void System::set_proc_param() { 187 // TODO: Consider creating a SystemParams class that tracks system-wide 188 // parameters like these 189 longer_channel_device = false; 190 core_tech_node = -1; 191 temperature = -1; 192 interconnect_projection_type = -1; 193 device_type = -1; 194 physical_address_width = -1; 195 196 int num_children = xml_data->nChildNode("param"); 197 int i; 198 for (i = 0; i < num_children; i++) { 199 XMLNode* paramNode = xml_data->getChildNodePtr("param", &i); 200 XMLCSTR node_name = paramNode->getAttribute("name"); 201 XMLCSTR value = paramNode->getAttribute("value"); 202 203 if (!node_name) 204 warnMissingParamName(paramNode->getAttribute("id")); 205 206 ASSIGN_FP_IF("core_tech_node", core_tech_node); 207 ASSIGN_INT_IF("target_core_clockrate", target_core_clockrate); 208 ASSIGN_INT_IF("temperature", temperature); 209 ASSIGN_INT_IF("device_type", device_type); 210 ASSIGN_INT_IF("longer_channel_device", longer_channel_device); 211 ASSIGN_INT_IF("interconnect_projection_type", 212 interconnect_projection_type); 213 ASSIGN_INT_IF("machine_bits", data_path_width); 214 ASSIGN_INT_IF("virtual_address_width", virtual_address_width); 215 ASSIGN_INT_IF("physical_address_width", physical_address_width); 216 ASSIGN_INT_IF("virtual_memory_page_size", virtual_memory_page_size); 217 ASSIGN_INT_IF("wire_is_mat_type", interface_ip.wire_is_mat_type); 218 ASSIGN_INT_IF("wire_os_mat_type", interface_ip.wire_os_mat_type); 219 ASSIGN_INT_IF("delay_wt", interface_ip.delay_wt); 220 ASSIGN_INT_IF("area_wt", interface_ip.area_wt); 221 ASSIGN_INT_IF("dynamic_power_wt", interface_ip.dynamic_power_wt); 222 ASSIGN_INT_IF("leakage_power_wt", interface_ip.leakage_power_wt); 223 ASSIGN_INT_IF("cycle_time_wt", interface_ip.cycle_time_wt); 224 ASSIGN_INT_IF("delay_dev", interface_ip.delay_dev); 225 ASSIGN_INT_IF("area_dev", interface_ip.area_dev); 226 ASSIGN_INT_IF("dynamic_power_dev", interface_ip.dynamic_power_dev); 227 ASSIGN_INT_IF("leakage_power_dev", interface_ip.leakage_power_dev); 228 ASSIGN_INT_IF("cycle_time_dev", interface_ip.cycle_time_dev); 229 ASSIGN_INT_IF("ed", interface_ip.ed); 230 ASSIGN_INT_IF("burst_len", interface_ip.burst_len); 231 ASSIGN_INT_IF("int_prefetch_w", interface_ip.int_prefetch_w); 232 ASSIGN_INT_IF("page_sz_bits", interface_ip.page_sz_bits); 233 ASSIGN_ENUM_IF("rpters_in_htree", interface_ip.rpters_in_htree, bool); 234 ASSIGN_INT_IF("ver_htree_wires_over_array", 235 interface_ip.ver_htree_wires_over_array); 236 ASSIGN_INT_IF("broadcast_addr_din_over_ver_htrees", 237 interface_ip.broadcast_addr_din_over_ver_htrees); 238 ASSIGN_INT_IF("nuca", interface_ip.nuca); 239 ASSIGN_INT_IF("nuca_bank_count", interface_ip.nuca_bank_count); 240 ASSIGN_ENUM_IF("force_cache_config", 241 interface_ip.force_cache_config, bool); 242 ASSIGN_ENUM_IF("wt", interface_ip.wt, Wire_type); 243 ASSIGN_INT_IF("force_wiretype", interface_ip.force_wiretype); 244 ASSIGN_INT_IF("print_detail", interface_ip.print_detail); 245 ASSIGN_ENUM_IF("add_ecc_b_", interface_ip.add_ecc_b_, bool); 246 247 else { 248 warnUnrecognizedParam(node_name); 249 } 250 } 251 252 // Change from MHz to Hz 253 target_core_clockrate *= 1e6; 254 interconnect_projection_type = 255 (interconnect_projection_type == 0) ? 0 : 1; 256 257 num_children = xml_data->nChildNode("stat"); 258 for (i = 0; i < num_children; i++) { 259 XMLNode* statNode = xml_data->getChildNodePtr("stat", &i); 260 XMLCSTR node_name = statNode->getAttribute("name"); 261 XMLCSTR value = statNode->getAttribute("value"); 262 263 if (!node_name) 264 warnMissingStatName(statNode->getAttribute("id")); 265 266 ASSIGN_FP_IF("total_cycles", total_cycles); 267 268 else { 269 warnUnrecognizedStat(node_name); 270 } 271 } 272 273 if (temperature < 0) { 274 errorUnspecifiedParam("temperature"); 275 } 276 277 if (core_tech_node < 0) { 278 errorUnspecifiedParam("core_tech_node"); 279 } 280 281 if (interconnect_projection_type < 0) { 282 errorUnspecifiedParam("interconnect_projection_type"); 283 } 284 285 if (device_type < 0) { 286 errorUnspecifiedParam("device_type"); 287 } 288 289 if (physical_address_width <= 0) { 290 errorNonPositiveParam("physical_address_width"); 291 } 292 293 if (data_path_width <= 0) { 294 errorNonPositiveParam("machine_bits"); 295 } 296 297 if (total_cycles <= 0) { 298 fprintf(stderr, "WARNING: total_cycles <= 0 in system component, ", 299 "power numbers will be funky...\n"); 300 } 301 302 clockRate = target_core_clockrate; 303 execution_time = total_cycles / (target_core_clockrate); 304 305 /* Basic parameters*/ 306 interface_ip.data_arr_ram_cell_tech_type = device_type; 307 interface_ip.data_arr_peri_global_tech_type = device_type; 308 interface_ip.tag_arr_ram_cell_tech_type = device_type; 309 interface_ip.tag_arr_peri_global_tech_type = device_type; 310 311 interface_ip.ic_proj_type = interconnect_projection_type; 312 interface_ip.temp = temperature; 313 interface_ip.F_sz_nm = core_tech_node; 314 interface_ip.F_sz_um = interface_ip.F_sz_nm / 1000; 315 interface_ip.is_main_mem = false; 316 317 // These are there just to make CACTI's error_checking() happy. 318 // They are either not actually used or overwritten by each component. 319 interface_ip.cache_sz = MIN_BUFFER_SIZE; 320 interface_ip.nbanks = 1; 321 interface_ip.out_w = 0; 322 interface_ip.line_sz = 1; 323 interface_ip.assoc = 1; 324 interface_ip.num_rw_ports = 1; 325 interface_ip.num_search_ports = 1; 326 interface_ip.is_cache = true; 327 interface_ip.pure_ram = false; 328 interface_ip.pure_cam = false; 329 330 331 //This section of code does not have real meaning; it is just to ensure 332 //all data will have initial value to prevent errors. 333 //They will be overridden during each components initialization 334 interface_ip.specific_tag = 1; 335 interface_ip.tag_w = 64; 336 interface_ip.access_mode = 2; 337 338 interface_ip.obj_func_dyn_energy = 0; 339 interface_ip.obj_func_dyn_power = 0; 340 interface_ip.obj_func_leak_power = 0; 341 interface_ip.obj_func_cycle_t = 1; 342 interface_ip.num_rw_ports = 1; 343 interface_ip.num_rd_ports = 0; 344 interface_ip.num_wr_ports = 0; 345 interface_ip.num_se_rd_ports = 0; 346} 347 348System::~System() { 349 // TODO: Delete children... do this in McPATComponent 350}; 351