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 <cstring> 38#include <iostream> 39 40#include "arbiter.h" 41#include "array.h" 42#include "basic_circuit.h" 43#include "cachearray.h" 44#include "cacheunit.h" 45#include "common.h" 46#include "const.h" 47#include "io.h" 48#include "logic.h" 49#include "parameter.h" 50 51bool CacheUnit::is_cache = true; 52bool CacheUnit::pure_cam = false; 53bool CacheUnit::opt_local = true; 54bool CacheUnit::force_cache_config = false; 55 56CacheUnit::CacheUnit(XMLNode* _xml_data, InputParameter* _interface_ip) 57 : dir_overhead(0), McPATComponent(_xml_data, _interface_ip) { 58 59 int tag; 60 int data; 61 62 name = "Cache Unit"; 63 CacheArray* arrayPtr = NULL; 64 65 set_cache_param_from_xml_data(); 66 67 //All lower level cache are physically indexed and tagged. 68 double size; 69 double line; 70 double assoc; 71 double banks; 72 size = cache_params.capacity; 73 line = cache_params.blockW; 74 assoc = cache_params.assoc; 75 banks = cache_params.nbanks; 76 if ((cache_params.dir_ty == ST && 77 cache_params.cache_level == L1Directory) || 78 (cache_params.dir_ty == ST && 79 cache_params.cache_level == L2Directory)) { 80 tag = physical_address_width + EXTRA_TAG_BITS; 81 } else { 82 tag = physical_address_width - int(ceil(log2(size / line / assoc))) - 83 int(ceil(log2(line))) + EXTRA_TAG_BITS; 84 85 if (cache_params.dir_ty == SBT) { 86 dir_overhead = ceil(cache_params.num_cores / BITS_PER_BYTE) * 87 BITS_PER_BYTE / (line * BITS_PER_BYTE); 88 line *= (1 + dir_overhead); 89 size *= (1 + dir_overhead); 90 } 91 } 92 93 interface_ip.cache_sz = (int)size; 94 interface_ip.line_sz = (int)line; 95 interface_ip.assoc = (int)assoc; 96 interface_ip.nbanks = (int)banks; 97 interface_ip.specific_tag = tag > 0; 98 interface_ip.tag_w = tag; 99 100 if (cache_params.cache_level == L1) { 101 interface_ip.out_w = interface_ip.line_sz * BITS_PER_BYTE; 102 } else { 103 interface_ip.out_w = interface_ip.line_sz * BITS_PER_BYTE / 2; 104 } 105 106 interface_ip.access_mode = cache_params.cache_access_mode; 107 interface_ip.throughput= cache_params.throughput; 108 interface_ip.latency = cache_params.latency; 109 interface_ip.obj_func_dyn_energy = 0; 110 interface_ip.obj_func_dyn_power = 0; 111 interface_ip.obj_func_leak_power = 0; 112 interface_ip.obj_func_cycle_t = 1; 113 interface_ip.is_cache = is_cache; 114 interface_ip.pure_ram = cache_params.pure_ram; 115 interface_ip.pure_cam = pure_cam; 116 interface_ip.num_rw_ports = cache_params.cache_rw_ports; 117 interface_ip.num_rd_ports = cache_params.cache_rd_ports; 118 interface_ip.num_wr_ports = cache_params.cache_wr_ports; 119 interface_ip.num_se_rd_ports = cache_params.cache_se_rd_ports; 120 interface_ip.num_search_ports = cache_params.cache_search_ports; 121 122 arrayPtr = new CacheArray(xml_data, &interface_ip, "Data and Tag Arrays", 123 cache_params.device_ty, clockRate, opt_local, 124 cache_params.core_ty); 125 children.push_back(arrayPtr); 126 127 // This is for calculating TDP, which depends on the number of 128 // available ports 129 int num_tdp_ports = arrayPtr->l_ip.num_rw_ports + 130 arrayPtr->l_ip.num_rd_ports + arrayPtr->l_ip.num_wr_ports; 131 132 // Set new array stats for calculating TDP and runtime power 133 arrayPtr->tdp_stats.reset(); 134 arrayPtr->tdp_stats.readAc.access = cache_stats.tdp_read_access_scalar * 135 num_tdp_ports * cache_stats.duty_cycle * 136 cache_stats.homenode_access_scalar; 137 arrayPtr->tdp_stats.readAc.miss = 0; 138 arrayPtr->tdp_stats.readAc.hit = arrayPtr->tdp_stats.readAc.access - 139 arrayPtr->tdp_stats.readAc.miss; 140 arrayPtr->tdp_stats.writeAc.access = cache_stats.tdp_write_access_scalar * 141 num_tdp_ports * cache_stats.duty_cycle * 142 cache_stats.homenode_access_scalar; 143 arrayPtr->tdp_stats.writeAc.miss = 0; 144 arrayPtr->tdp_stats.writeAc.hit = arrayPtr->tdp_stats.writeAc.access - 145 arrayPtr->tdp_stats.writeAc.miss; 146 arrayPtr->tdp_stats.searchAc.access = 0; 147 arrayPtr->tdp_stats.searchAc.miss = 0; 148 arrayPtr->tdp_stats.searchAc.hit = 0; 149 150 arrayPtr->rtp_stats.reset(); 151 if (cache_stats.use_detailed_stats) { 152 arrayPtr->rtp_stats.dataReadAc.access = 153 cache_stats.num_data_array_reads; 154 arrayPtr->rtp_stats.dataWriteAc.access = 155 cache_stats.num_data_array_writes; 156 arrayPtr->rtp_stats.tagReadAc.access = 157 cache_stats.num_tag_array_reads; 158 arrayPtr->rtp_stats.tagWriteAc.access = 159 cache_stats.num_tag_array_writes; 160 } else { 161 // This code makes assumptions. For instance, it assumes that 162 // tag and data arrays are accessed in parallel on a read request and 163 // this is a write-allocate cache. It also ignores any coherence 164 // requests. Using detailed stats as above can avoid the ambiguity 165 // that is introduced here 166 arrayPtr->rtp_stats.dataReadAc.access = 167 cache_stats.read_accesses + cache_stats.write_misses; 168 arrayPtr->rtp_stats.dataWriteAc.access = 169 cache_stats.write_accesses + cache_stats.read_misses; 170 arrayPtr->rtp_stats.tagReadAc.access = 171 cache_stats.read_accesses + cache_stats.write_accesses; 172 arrayPtr->rtp_stats.tagWriteAc.access = 173 cache_stats.read_misses + cache_stats.write_misses; 174 } 175 176 // Set SBT stats if this is an SBT directory type 177 if (dir_overhead > 0) { 178 arrayPtr->setSBTDirOverhead(dir_overhead); 179 180 // TDP stats 181 arrayPtr->sbt_tdp_stats.readAc.access = 182 cache_stats.tdp_read_access_scalar * 183 num_tdp_ports * cache_stats.dir_duty_cycle * 184 (1 - cache_stats.homenode_access_scalar); 185 arrayPtr->sbt_tdp_stats.readAc.miss = 0; 186 arrayPtr->sbt_tdp_stats.readAc.hit = 187 arrayPtr->sbt_tdp_stats.readAc.access - 188 arrayPtr->sbt_tdp_stats.readAc.miss; 189 arrayPtr->sbt_tdp_stats.writeAc.access = 190 cache_stats.tdp_sbt_write_access_scalar * 191 num_tdp_ports * cache_stats.dir_duty_cycle * 192 (1 - cache_stats.homenode_access_scalar); 193 arrayPtr->sbt_tdp_stats.writeAc.miss = 0; 194 arrayPtr->sbt_tdp_stats.writeAc.hit = 195 arrayPtr->sbt_tdp_stats.writeAc.access - 196 arrayPtr->sbt_tdp_stats.writeAc.miss; 197 198 // Runtime power stats 199 arrayPtr->sbt_rtp_stats.readAc.access = 200 cache_stats.homenode_read_accesses; 201 arrayPtr->sbt_rtp_stats.readAc.miss = 202 cache_stats.homenode_read_misses; 203 arrayPtr->sbt_rtp_stats.readAc.access = 204 cache_stats.homenode_read_accesses - 205 cache_stats.homenode_read_misses; 206 arrayPtr->sbt_rtp_stats.writeAc.access = 207 cache_stats.homenode_write_accesses; 208 arrayPtr->sbt_rtp_stats.writeAc.miss = 209 cache_stats.homenode_write_misses; 210 arrayPtr->sbt_rtp_stats.writeAc.hit = 211 cache_stats.homenode_write_accesses - 212 cache_stats.homenode_write_misses; 213 } 214 215 interface_ip.force_cache_config = force_cache_config; 216 if (!((cache_params.dir_ty == ST && 217 cache_params.cache_level == L1Directory) || 218 (cache_params.dir_ty == ST && 219 cache_params.cache_level== L2Directory))) { 220 // Miss Buffer 221 tag = physical_address_width + EXTRA_TAG_BITS; 222 data = (physical_address_width) + 223 int(ceil(log2(size / cache_params.blockW))) + 224 (cache_params.blockW * BITS_PER_BYTE); 225 line = int(ceil(data / BITS_PER_BYTE)); 226 size = cache_params.missb_size * line; 227 228 interface_ip.cache_sz = size; 229 interface_ip.line_sz = line; 230 interface_ip.assoc = cache_params.missb_assoc; 231 interface_ip.nbanks = cache_params.missb_banks; 232 interface_ip.specific_tag = tag > 0; 233 interface_ip.tag_w = tag; 234 235 if (cache_params.cache_level == L1) { 236 interface_ip.out_w = line * BITS_PER_BYTE; 237 } else { 238 interface_ip.out_w = line * BITS_PER_BYTE / 2; 239 } 240 241 interface_ip.access_mode = cache_params.miss_buff_access_mode; 242 interface_ip.obj_func_dyn_energy = 0; 243 interface_ip.obj_func_dyn_power = 0; 244 interface_ip.obj_func_leak_power = 0; 245 interface_ip.obj_func_cycle_t = 1; 246 interface_ip.is_cache = is_cache; 247 interface_ip.pure_ram = cache_params.pure_ram; 248 interface_ip.pure_cam = pure_cam; 249 interface_ip.throughput = cache_params.throughput; 250 interface_ip.latency = cache_params.latency; 251 interface_ip.num_rw_ports = cache_params.miss_buff_rw_ports; 252 interface_ip.num_rd_ports = cache_params.miss_buff_rd_ports; 253 interface_ip.num_wr_ports = cache_params.miss_buff_wr_ports; 254 interface_ip.num_se_rd_ports = cache_params.miss_buff_se_rd_ports; 255 interface_ip.num_search_ports = cache_params.miss_buff_search_ports; 256 257 arrayPtr = new CacheArray(xml_data, &interface_ip, "Miss Buffer", 258 cache_params.device_ty, clockRate, opt_local, 259 cache_params.core_ty); 260 children.push_back(arrayPtr); 261 262 arrayPtr->tdp_stats.reset(); 263 arrayPtr->tdp_stats.readAc.access = 0; 264 arrayPtr->tdp_stats.writeAc.access = arrayPtr->l_ip.num_search_ports; 265 arrayPtr->tdp_stats.searchAc.access = arrayPtr->l_ip.num_search_ports; 266 267 arrayPtr->rtp_stats.reset(); 268 arrayPtr->rtp_stats.readAc.access = 269 cache_stats.read_misses + cache_stats.write_misses; 270 arrayPtr->rtp_stats.writeAc.access = 271 cache_stats.read_misses + cache_stats.write_misses; 272 arrayPtr->rtp_stats.searchAc.access = 0; 273 274 if (cache_params.dir_ty == SBT) { 275 arrayPtr->rtp_stats.readAc.access += 276 cache_stats.homenode_write_misses; 277 arrayPtr->rtp_stats.writeAc.access += 278 cache_stats.homenode_write_misses; 279 } 280 281 // Fill Buffer 282 tag = physical_address_width + EXTRA_TAG_BITS; 283 data = cache_params.blockW; 284 285 interface_ip.cache_sz = data * cache_params.fu_size; 286 interface_ip.line_sz = data; 287 interface_ip.assoc = cache_params.fu_assoc; 288 interface_ip.nbanks = cache_params.fu_banks; 289 interface_ip.specific_tag = tag > 0; 290 interface_ip.tag_w = tag; 291 292 if (cache_params.cache_level == L1) { 293 interface_ip.out_w = interface_ip.line_sz * BITS_PER_BYTE; 294 } else { 295 interface_ip.out_w = interface_ip.line_sz * BITS_PER_BYTE / 2; 296 } 297 298 interface_ip.access_mode = cache_params.fetch_buff_access_mode; 299 interface_ip.obj_func_dyn_energy = 0; 300 interface_ip.obj_func_dyn_power = 0; 301 interface_ip.obj_func_leak_power = 0; 302 interface_ip.obj_func_cycle_t = 1; 303 interface_ip.is_cache = is_cache; 304 interface_ip.pure_cam = pure_cam; 305 interface_ip.throughput = cache_params.throughput; 306 interface_ip.latency = cache_params.latency; 307 interface_ip.num_rw_ports = cache_params.fetch_buff_rw_ports; 308 interface_ip.num_rd_ports = cache_params.fetch_buff_rd_ports; 309 interface_ip.num_wr_ports = cache_params.fetch_buff_wr_ports; 310 interface_ip.num_se_rd_ports = cache_params.fetch_buff_se_rd_ports; 311 interface_ip.num_search_ports = cache_params.fetch_buff_search_ports; 312 arrayPtr = new CacheArray(xml_data, &interface_ip, "Fill Buffer", 313 cache_params.device_ty, clockRate, opt_local, 314 cache_params.core_ty); 315 children.push_back(arrayPtr); 316 317 arrayPtr->tdp_stats.reset(); 318 arrayPtr->tdp_stats.readAc.access = 0; 319 arrayPtr->tdp_stats.writeAc.access = arrayPtr->l_ip.num_search_ports; 320 arrayPtr->tdp_stats.searchAc.access = arrayPtr->l_ip.num_search_ports; 321 322 arrayPtr->rtp_stats.reset(); 323 arrayPtr->rtp_stats.readAc.access = 324 cache_stats.read_misses + cache_stats.write_misses; 325 arrayPtr->rtp_stats.writeAc.access = 326 cache_stats.read_misses + cache_stats.write_misses; 327 arrayPtr->rtp_stats.searchAc.access = 0; 328 329 if (cache_params.dir_ty == SBT) { 330 arrayPtr->rtp_stats.readAc.access += 331 cache_stats.homenode_write_misses; 332 arrayPtr->rtp_stats.writeAc.access += 333 cache_stats.homenode_write_misses; 334 } 335 336 // Prefetch Buffer 337 tag = physical_address_width + EXTRA_TAG_BITS; 338 line = cache_params.blockW; 339 340 interface_ip.cache_sz = cache_params.prefetchb_size * line; 341 interface_ip.line_sz = line; 342 interface_ip.assoc = cache_params.prefetchb_assoc; 343 interface_ip.nbanks = cache_params.prefetchb_banks; 344 interface_ip.specific_tag = tag > 0; 345 interface_ip.tag_w = tag; 346 347 if (cache_params.cache_level == L1) { 348 interface_ip.out_w = interface_ip.line_sz * BITS_PER_BYTE; 349 } else { 350 interface_ip.out_w = interface_ip.line_sz * BITS_PER_BYTE / 2; 351 } 352 353 interface_ip.access_mode = cache_params.prefetch_buff_access_mode; 354 interface_ip.obj_func_dyn_energy = 0; 355 interface_ip.obj_func_dyn_power = 0; 356 interface_ip.obj_func_leak_power = 0; 357 interface_ip.obj_func_cycle_t = 1; 358 interface_ip.is_cache = is_cache; 359 interface_ip.pure_ram = cache_params.pure_ram; 360 interface_ip.pure_cam = pure_cam; 361 interface_ip.throughput = cache_params.throughput; 362 interface_ip.latency = cache_params.latency; 363 interface_ip.num_rw_ports = cache_params.pf_buff_rw_ports; 364 interface_ip.num_rd_ports = cache_params.pf_buff_rd_ports; 365 interface_ip.num_wr_ports = cache_params.pf_buff_wr_ports; 366 interface_ip.num_se_rd_ports = cache_params.pf_buff_se_rd_ports; 367 interface_ip.num_search_ports = cache_params.pf_buff_search_ports; 368 arrayPtr = new CacheArray(xml_data, &interface_ip, "Prefetch Buffer", 369 cache_params.device_ty, clockRate, opt_local, 370 cache_params.core_ty); 371 children.push_back(arrayPtr); 372 373 arrayPtr->tdp_stats.reset(); 374 arrayPtr->tdp_stats.readAc.access = 0; 375 arrayPtr->tdp_stats.writeAc.access = arrayPtr->l_ip.num_search_ports; 376 arrayPtr->tdp_stats.searchAc.access = arrayPtr->l_ip.num_search_ports; 377 378 arrayPtr->rtp_stats.reset(); 379 arrayPtr->rtp_stats.readAc.access = cache_stats.read_misses; 380 arrayPtr->rtp_stats.writeAc.access = cache_stats.read_misses; 381 arrayPtr->rtp_stats.searchAc.access = 0; 382 383 if (cache_params.dir_ty == SBT) { 384 arrayPtr->rtp_stats.readAc.access += 385 cache_stats.homenode_write_misses; 386 arrayPtr->rtp_stats.writeAc.access += 387 cache_stats.homenode_write_misses; 388 } 389 390 // Writeback Buffer 391 if (cache_params.wbb_size > 0) { 392 tag = physical_address_width + EXTRA_TAG_BITS; 393 line = cache_params.blockW; 394 395 interface_ip.cache_sz = cache_params.wbb_size * line; 396 interface_ip.line_sz = line; 397 interface_ip.assoc = cache_params.wbb_assoc; 398 interface_ip.nbanks = cache_params.wbb_banks; 399 interface_ip.specific_tag = tag > 0; 400 interface_ip.tag_w = tag; 401 402 if (cache_params.cache_level == L1) { 403 interface_ip.out_w = interface_ip.line_sz * BITS_PER_BYTE; 404 } else { 405 interface_ip.out_w = interface_ip.line_sz * BITS_PER_BYTE / 2; 406 } 407 408 interface_ip.access_mode = cache_params.writeback_buff_access_mode; 409 interface_ip.obj_func_dyn_energy = 0; 410 interface_ip.obj_func_dyn_power = 0; 411 interface_ip.obj_func_leak_power = 0; 412 interface_ip.obj_func_cycle_t = 1; 413 interface_ip.is_cache = is_cache; 414 interface_ip.pure_ram = cache_params.pure_ram; 415 interface_ip.pure_cam = pure_cam; 416 interface_ip.throughput = cache_params.throughput; 417 interface_ip.latency = cache_params.latency; 418 interface_ip.num_rw_ports = cache_params.wb_buff_rw_ports; 419 interface_ip.num_rd_ports = cache_params.wb_buff_rd_ports; 420 interface_ip.num_wr_ports = cache_params.wb_buff_wr_ports; 421 interface_ip.num_se_rd_ports = cache_params.wb_buff_se_rd_ports; 422 interface_ip.num_search_ports = cache_params.wb_buff_search_ports; 423 arrayPtr = new CacheArray(xml_data, &interface_ip, 424 "Writeback Buffer", 425 cache_params.device_ty, clockRate, 426 opt_local, cache_params.core_ty); 427 children.push_back(arrayPtr); 428 429 arrayPtr->tdp_stats.reset(); 430 arrayPtr->tdp_stats.readAc.access = 0; 431 arrayPtr->tdp_stats.writeAc.access = 432 arrayPtr->l_ip.num_search_ports; 433 arrayPtr->tdp_stats.searchAc.access = 434 arrayPtr->l_ip.num_search_ports; 435 436 arrayPtr->rtp_stats.reset(); 437 arrayPtr->rtp_stats.readAc.access = cache_stats.write_misses; 438 arrayPtr->rtp_stats.writeAc.access = cache_stats.write_misses; 439 arrayPtr->rtp_stats.searchAc.access = 0; 440 441 if (cache_params.dir_ty == SBT) { 442 arrayPtr->rtp_stats.readAc.access += 443 cache_stats.homenode_write_misses; 444 arrayPtr->rtp_stats.writeAc.access += 445 cache_stats.homenode_write_misses; 446 } 447 } 448 } 449} 450 451void CacheUnit::computeEnergy() { 452 McPATComponent::computeEnergy(); 453} 454 455void CacheUnit::set_cache_param_from_xml_data() { 456 int level, type; 457 458 // Initialization... move this? 459 memset(&cache_params, 0, sizeof(CacheParameters)); 460 memset(&cache_stats, 0, sizeof(CacheStatistics)); 461 462 // By default, use the core clock frequency. This can be changed by 463 // setting the clockrate param in the XML definition of the CacheUnit 464 clockRate = target_core_clockrate; 465 XMLCSTR comp_name = xml_data->getAttribute("name"); 466 if (comp_name) { 467 name = comp_name; 468 } 469 470 int num_children = xml_data->nChildNode("param"); 471 int i; 472 int tech_type; 473 int mat_type; 474 for (i = 0; i < num_children; i++) { 475 XMLNode* paramNode = xml_data->getChildNodePtr("param", &i); 476 XMLCSTR node_name = paramNode->getAttribute("name"); 477 XMLCSTR value = paramNode->getAttribute("value"); 478 479 if (!node_name) 480 warnMissingParamName(paramNode->getAttribute("id")); 481 482 ASSIGN_INT_IF("level", level); 483 ASSIGN_FP_IF("size", cache_params.capacity); 484 ASSIGN_FP_IF("block_size", cache_params.blockW); 485 ASSIGN_FP_IF("assoc", cache_params.assoc); 486 ASSIGN_FP_IF("num_banks", cache_params.nbanks); 487 ASSIGN_FP_IF("latency", cache_params.latency); 488 ASSIGN_FP_IF("throughput", cache_params.throughput); 489 ASSIGN_INT_IF("miss_buffer_size", cache_params.missb_size); 490 ASSIGN_INT_IF("fetch_buffer_size", cache_params.fu_size); 491 ASSIGN_INT_IF("prefetch_buffer_size", cache_params.prefetchb_size); 492 ASSIGN_INT_IF("writeback_buffer_size", cache_params.wbb_size); 493 ASSIGN_INT_IF("miss_buffer_assoc", cache_params.missb_assoc); 494 ASSIGN_INT_IF("fetch_buffer_assoc", cache_params.fu_assoc); 495 ASSIGN_INT_IF("prefetch_buffer_assoc", cache_params.prefetchb_assoc); 496 ASSIGN_INT_IF("writeback_buffer_assoc", cache_params.wbb_assoc); 497 ASSIGN_INT_IF("miss_buffer_banks", cache_params.missb_banks); 498 ASSIGN_INT_IF("fetch_buffer_banks", cache_params.fu_banks); 499 ASSIGN_INT_IF("prefetch_buffer_banks", cache_params.prefetchb_banks); 500 ASSIGN_INT_IF("writeback_buffer_banks", cache_params.wbb_banks); 501 ASSIGN_ENUM_IF("cache_access_mode", 502 cache_params.cache_access_mode, Access_mode); 503 ASSIGN_ENUM_IF("miss_buff_access_mode", 504 cache_params.miss_buff_access_mode, Access_mode); 505 ASSIGN_ENUM_IF("fetch_buff_access_mode", 506 cache_params.fetch_buff_access_mode, Access_mode); 507 ASSIGN_ENUM_IF("prefetch_buff_access_mode", 508 cache_params.prefetch_buff_access_mode, Access_mode); 509 ASSIGN_ENUM_IF("writeback_buff_access_mode", 510 cache_params.writeback_buff_access_mode, Access_mode); 511 ASSIGN_INT_IF("cache_rw_ports", cache_params.cache_rw_ports); 512 ASSIGN_INT_IF("cache_rd_ports", cache_params.cache_rd_ports); 513 ASSIGN_INT_IF("cache_wr_ports", cache_params.cache_wr_ports); 514 ASSIGN_INT_IF("cache_se_rd_ports", cache_params.cache_se_rd_ports); 515 ASSIGN_INT_IF("cache_search_ports", cache_params.cache_search_ports); 516 ASSIGN_INT_IF("miss_buff_rw_ports", cache_params.miss_buff_rw_ports); 517 ASSIGN_INT_IF("miss_buff_rd_ports", cache_params.miss_buff_rd_ports); 518 ASSIGN_INT_IF("miss_buff_wr_ports", cache_params.miss_buff_wr_ports); 519 ASSIGN_INT_IF("miss_buff_se_rd_ports" , 520 cache_params.miss_buff_se_rd_ports); 521 ASSIGN_INT_IF("miss_buff_search_ports", 522 cache_params.miss_buff_search_ports); 523 ASSIGN_INT_IF("fetch_buff_rw_ports", cache_params.fetch_buff_rw_ports); 524 ASSIGN_INT_IF("fetch_buff_rd_ports", cache_params.fetch_buff_rd_ports); 525 ASSIGN_INT_IF("fetch_buff_wr_ports", cache_params.fetch_buff_wr_ports); 526 ASSIGN_INT_IF("fetch_buff_se_rd_ports", 527 cache_params.fetch_buff_se_rd_ports); 528 ASSIGN_INT_IF("fetch_buff_search_ports", 529 cache_params.fetch_buff_search_ports); 530 ASSIGN_INT_IF("pf_buff_rw_ports", cache_params.pf_buff_rw_ports); 531 ASSIGN_INT_IF("pf_buff_rd_ports", cache_params.pf_buff_rd_ports); 532 ASSIGN_INT_IF("pf_buff_wr_ports", cache_params.pf_buff_wr_ports); 533 ASSIGN_INT_IF("pf_buff_se_rd_ports", cache_params.pf_buff_se_rd_ports); 534 ASSIGN_INT_IF("pf_buff_search_ports", 535 cache_params.pf_buff_search_ports); 536 ASSIGN_INT_IF("wb_buff_rw_ports", cache_params.wb_buff_rw_ports); 537 ASSIGN_INT_IF("wb_buff_rd_ports", cache_params.wb_buff_rd_ports); 538 ASSIGN_INT_IF("wb_buff_wr_ports", cache_params.wb_buff_wr_ports); 539 ASSIGN_INT_IF("wb_buff_se_rd_ports", cache_params.wb_buff_se_rd_ports); 540 ASSIGN_INT_IF("wb_buff_search_ports", 541 cache_params.wb_buff_search_ports); 542 ASSIGN_FP_IF("clockrate", cache_params.clockRate); 543 ASSIGN_INT_IF("pure_ram", cache_params.pure_ram); 544 ASSIGN_INT_IF("tech_type", tech_type); 545 ASSIGN_ENUM_IF("Directory_type", cache_params.dir_ty, Dir_type); 546 ASSIGN_ENUM_IF("device_type", cache_params.device_ty, Device_ty); 547 ASSIGN_ENUM_IF("core_type", cache_params.core_ty, Core_type); 548 ASSIGN_INT_IF("num_cores", cache_params.num_cores); 549 ASSIGN_INT_IF("wire_mat_type", mat_type); 550 ASSIGN_ENUM_IF("wire_type", interface_ip.wt, Wire_type); 551 552 else { 553 warnUnrecognizedParam(node_name); 554 } 555 } 556 557 // Change from MHz to Hz 558 cache_params.clockRate *= 1e6; 559 if (cache_params.clockRate > 0) { 560 clockRate = cache_params.clockRate; 561 } 562 563 interface_ip.data_arr_ram_cell_tech_type = tech_type; 564 interface_ip.data_arr_peri_global_tech_type = tech_type; 565 interface_ip.tag_arr_ram_cell_tech_type = tech_type; 566 interface_ip.tag_arr_peri_global_tech_type = tech_type; 567 568 interface_ip.wire_is_mat_type = mat_type; 569 interface_ip.wire_os_mat_type = mat_type; 570 571 switch(level) { 572 case 1: 573 cache_params.cache_level = L1; 574 break; 575 case 2: 576 cache_params.cache_level = L2; 577 break; 578 case 3: 579 cache_params.cache_level = L3; 580 break; 581 case 4: 582 cache_params.cache_level = L1Directory; 583 break; 584 case 5: 585 cache_params.cache_level = L2Directory; 586 break; 587 588 default: 589 fprintf(stderr, "ERROR: Unrecognized cache level in %s: %d\n", 590 name.c_str(), level); 591 exit(1); 592 } 593 594 cache_stats.use_detailed_stats = false; 595 596 num_children = xml_data->nChildNode("stat"); 597 for (i = 0; i < num_children; i++) { 598 XMLNode* statNode = xml_data->getChildNodePtr("stat", &i); 599 XMLCSTR node_name = statNode->getAttribute("name"); 600 XMLCSTR value = statNode->getAttribute("value"); 601 602 if (!node_name) 603 warnMissingStatName(statNode->getAttribute("id")); 604 605 ASSIGN_FP_IF("num_data_array_reads", cache_stats.num_data_array_reads); 606 ASSIGN_FP_IF("num_data_array_writes", 607 cache_stats.num_data_array_writes); 608 ASSIGN_FP_IF("num_tag_array_reads", cache_stats.num_tag_array_reads); 609 ASSIGN_FP_IF("num_tag_array_writes", cache_stats.num_tag_array_writes); 610 ASSIGN_FP_IF("duty_cycle", cache_stats.duty_cycle); 611 ASSIGN_FP_IF("read_accesses", cache_stats.read_accesses); 612 ASSIGN_FP_IF("write_accesses", cache_stats.write_accesses); 613 ASSIGN_FP_IF("read_misses", cache_stats.read_misses); 614 ASSIGN_FP_IF("write_misses", cache_stats.write_misses); 615 ASSIGN_FP_IF("conflicts", cache_stats.conflicts); 616 ASSIGN_INT_IF("homenode_read_accesses", 617 cache_stats.homenode_read_accesses); 618 ASSIGN_INT_IF("homenode_write_accesses", 619 cache_stats.homenode_write_accesses); 620 ASSIGN_INT_IF("homenode_read_misses", 621 cache_stats.homenode_read_misses); 622 ASSIGN_INT_IF("homenode_write_misses", 623 cache_stats.homenode_write_misses); 624 ASSIGN_FP_IF("homenode_access_scalar", 625 cache_stats.homenode_access_scalar); 626 ASSIGN_FP_IF("tdp_read_access_scalar", 627 cache_stats.tdp_read_access_scalar); 628 ASSIGN_FP_IF("tdp_write_access_scalar", 629 cache_stats.tdp_write_access_scalar); 630 ASSIGN_FP_IF("tdp_sbt_write_access_scalar", 631 cache_stats.tdp_sbt_write_access_scalar); 632 ASSIGN_FP_IF("dir_duty_cycle", 633 cache_stats.dir_duty_cycle); 634 635 else { 636 warnUnrecognizedStat(node_name); 637 } 638 } 639 640 if (cache_stats.num_data_array_reads > 0 || 641 cache_stats.num_data_array_writes > 0 || 642 cache_stats.num_tag_array_reads > 0 || 643 cache_stats.num_tag_array_writes > 0) { 644 cache_stats.use_detailed_stats = true; 645 calculate_runtime_data_and_tag = true; 646 } 647} 648