RubySlicc_ComponentMapping.hh revision 6154
1 2/* 3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer; 10 * redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution; 13 * neither the name of the copyright holders nor the names of its 14 * contributors may be used to endorse or promote products derived from 15 * this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30/* 31 * $Id$ 32 */ 33 34#ifndef COMPONENTMAPPINGFNS_H 35#define COMPONENTMAPPINGFNS_H 36 37#include "mem/ruby/common/Global.hh" 38#include "mem/ruby/config/RubyConfig.hh" 39#include "mem/ruby/system/NodeID.hh" 40#include "mem/ruby/system/MachineID.hh" 41#include "mem/ruby/common/Address.hh" 42#include "mem/ruby/common/Set.hh" 43#include "mem/ruby/common/NetDest.hh" 44#include "mem/protocol/GenericMachineType.hh" 45 46#ifdef MACHINETYPE_L1Cache 47#define MACHINETYPE_L1CACHE_ENUM MachineType_L1Cache 48#else 49#define MACHINETYPE_L1CACHE_ENUM MachineType_NUM 50#endif 51 52#ifdef MACHINETYPE_L2Cache 53#define MACHINETYPE_L2CACHE_ENUM MachineType_L2Cache 54#else 55#define MACHINETYPE_L2CACHE_ENUM MachineType_NUM 56#endif 57 58#ifdef MACHINETYPE_L3Cache 59#define MACHINETYPE_L3CACHE_ENUM MachineType_L3Cache 60#else 61#define MACHINETYPE_L3CACHE_ENUM MachineType_NUM 62#endif 63 64#ifdef MACHINETYPE_PersistentArbiter 65#define MACHINETYPE_PERSISTENTARBITER_ENUM MachineType_PersistentArbiter 66#else 67#define MACHINETYPE_PERSISTENTARBITER_ENUM MachineType_NUM 68#endif 69 70#ifdef MACHINETYPE_Collector 71#define MACHINETYPE_COLLECTOR_ENUM MachineType_Collector 72#else 73#define MACHINETYPE_COLLECTOR_ENUM MachineType_NUM 74#endif 75 76 77// used to determine the correct L1 set 78// input parameters are the address and number of set bits for the L1 cache 79// returns a value between 0 and the total number of L1 cache sets 80inline 81int map_address_to_L1CacheSet(const Address& addr, int cache_num_set_bits) 82{ 83 return addr.bitSelect(RubyConfig::dataBlockBits(), 84 RubyConfig::dataBlockBits()+cache_num_set_bits-1); 85} 86 87// used to determine the correct L2 set 88// input parameters are the address and number of set bits for the L2 cache 89// returns a value between 0 and the total number of L2 cache sets 90inline 91int map_address_to_L2CacheSet(const Address& addr, int cache_num_set_bits) 92{ 93 assert(cache_num_set_bits == L2_CACHE_NUM_SETS_BITS); // ensure the l2 bank mapping functions agree with l2 set bits 94 95 if (MAP_L2BANKS_TO_LOWEST_BITS) { 96 return addr.bitSelect(RubyConfig::dataBlockBits()+RubyConfig::L2CachePerChipBits(), 97 RubyConfig::dataBlockBits()+RubyConfig::L2CachePerChipBits()+cache_num_set_bits-1); 98 } else { 99 return addr.bitSelect(RubyConfig::dataBlockBits(), 100 RubyConfig::dataBlockBits()+cache_num_set_bits-1); 101 } 102} 103 104// input parameter is the base ruby node of the L1 cache 105// returns a value between 0 and total_L2_Caches_within_the_system 106inline 107MachineID map_L1CacheMachId_to_L2Cache(const Address& addr, MachineID L1CacheMachId) 108{ 109 int L2bank = 0; 110 MachineID mach = {MACHINETYPE_L2CACHE_ENUM, 0}; 111 112 if (RubyConfig::L2CachePerChipBits() > 0) { 113 if (MAP_L2BANKS_TO_LOWEST_BITS) { 114 L2bank = addr.bitSelect(RubyConfig::dataBlockBits(), 115 RubyConfig::dataBlockBits()+RubyConfig::L2CachePerChipBits()-1); 116 } else { 117 L2bank = addr.bitSelect(RubyConfig::dataBlockBits()+L2_CACHE_NUM_SETS_BITS, 118 RubyConfig::dataBlockBits()+L2_CACHE_NUM_SETS_BITS+RubyConfig::L2CachePerChipBits()-1); 119 } 120 } 121 122 assert(L2bank < RubyConfig::numberOfL2CachePerChip()); 123 assert(L2bank >= 0); 124 125 mach.num = RubyConfig::L1CacheNumToL2Base(L1CacheMachId.num)*RubyConfig::numberOfL2CachePerChip() // base # 126 + L2bank; // bank # 127 assert(mach.num < RubyConfig::numberOfL2Cache()); 128 return mach; 129} 130 131// used to determine the correct L2 bank 132// input parameter is the base ruby node of the L2 cache 133// returns a value between 0 and total_L2_Caches_within_the_system 134inline 135MachineID map_L2ChipId_to_L2Cache(const Address& addr, NodeID L2ChipId) 136{ 137 assert(L2ChipId < RubyConfig::numberOfChips()); 138 139 int L2bank = 0; 140 MachineID mach = {MACHINETYPE_L2CACHE_ENUM, 0}; 141 142 if (RubyConfig::L2CachePerChipBits() > 0) { 143 if (MAP_L2BANKS_TO_LOWEST_BITS) { 144 L2bank = addr.bitSelect(RubyConfig::dataBlockBits(), 145 RubyConfig::dataBlockBits()+RubyConfig::L2CachePerChipBits()-1); 146 } else { 147 L2bank = addr.bitSelect(RubyConfig::dataBlockBits()+L2_CACHE_NUM_SETS_BITS, 148 RubyConfig::dataBlockBits()+L2_CACHE_NUM_SETS_BITS+RubyConfig::L2CachePerChipBits()-1); 149 } 150 } 151 152 assert(L2bank < RubyConfig::numberOfL2CachePerChip()); 153 assert(L2bank >= 0); 154 155 mach.num = L2ChipId*RubyConfig::numberOfL2CachePerChip() // base # 156 + L2bank; // bank # 157 assert(mach.num < RubyConfig::numberOfL2Cache()); 158 return mach; 159} 160 161// used to determine the home directory 162// returns a value between 0 and total_directories_within_the_system 163inline 164NodeID map_Address_to_DirectoryNode(const Address& addr) 165{ 166 NodeID dirNode = 0; 167 168 if (RubyConfig::memoryBits() > 0) { 169 dirNode = addr.bitSelect(RubyConfig::dataBlockBits(), 170 RubyConfig::dataBlockBits()+RubyConfig::memoryBits()-1); 171 } 172 173 // Index indexHighPortion = address.bitSelect(MEMORY_SIZE_BITS-1, PAGE_SIZE_BITS+NUMBER_OF_MEMORY_MODULE_BITS); 174 // Index indexLowPortion = address.bitSelect(DATA_BLOCK_BITS, PAGE_SIZE_BITS-1); 175 176 //Index index = indexLowPortion | (indexHighPortion << (PAGE_SIZE_BITS - DATA_BLOCK_BITS)); 177 178/* 179 180ADDRESS_WIDTH MEMORY_SIZE_BITS PAGE_SIZE_BITS DATA_BLOCK_BITS 181 | | | | 182 \ / \ / \ / \ / 0 183 ----------------------------------------------------------------------- 184 | unused |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| | 185 | |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| | 186 ----------------------------------------------------------------------- 187 indexHighPortion indexLowPortion 188 <-------> 189 NUMBER_OF_MEMORY_MODULE_BITS 190 */ 191 192 assert(dirNode < RubyConfig::numberOfMemories()); 193 assert(dirNode >= 0); 194 return dirNode; 195} 196 197// used to determine the home directory 198// returns a value between 0 and total_directories_within_the_system 199inline 200MachineID map_Address_to_Directory(const Address &addr) 201{ 202 MachineID mach = {MachineType_Directory, map_Address_to_DirectoryNode(addr)}; 203 return mach; 204} 205 206inline 207MachineID map_Address_to_CentralArbiterNode(const Address& addr) 208{ 209 MachineType t = MACHINETYPE_PERSISTENTARBITER_ENUM; 210 MachineID mach = {t, map_Address_to_DirectoryNode(addr)}; 211 212 assert(mach.num < RubyConfig::numberOfMemories()); 213 assert(mach.num >= 0); 214 return mach; 215} 216 217inline 218NetDest getMultiStaticL2BankNetDest(const Address& addr, const Set& sharers) // set of L2RubyNodes 219{ 220 NetDest dest; 221 222 for (int i = 0; i < sharers.getSize(); i++) { 223 if (sharers.isElement(i)) { 224 dest.add(map_L2ChipId_to_L2Cache(addr,i)); 225 } 226 } 227 return dest; 228} 229 230inline 231NetDest getOtherLocalL1IDs(MachineID L1) 232{ 233 int start = (L1.num / RubyConfig::numberOfProcsPerChip()) * RubyConfig::numberOfProcsPerChip(); 234 NetDest ret; 235 236 assert(MACHINETYPE_L1CACHE_ENUM != MachineType_NUM); 237 238 for (int i = start; i < (start + RubyConfig::numberOfProcsPerChip()); i++) { 239 if (i != L1.num) { 240 MachineID mach = { MACHINETYPE_L1CACHE_ENUM, i }; 241 ret.add( mach ); 242 } 243 } 244 245 return ret; 246} 247 248inline 249NetDest getLocalL1IDs(MachineID mach) 250{ 251 assert(MACHINETYPE_L1CACHE_ENUM != MachineType_NUM); 252 253 NetDest ret; 254 255 if (mach.type == MACHINETYPE_L1CACHE_ENUM) { 256 257 int start = (mach.num / RubyConfig::numberOfL1CachePerChip()) * RubyConfig::numberOfProcsPerChip(); 258 259 for (int i = start; i < (start + RubyConfig::numberOfProcsPerChip()); i++) { 260 MachineID mach = { MACHINETYPE_L1CACHE_ENUM, i }; 261 ret.add( mach ); 262 } 263 } 264 else if (mach.type == MACHINETYPE_L2CACHE_ENUM) { 265 266 int chip = mach.num/RubyConfig::numberOfL2CachePerChip(); 267 int start = ( chip*RubyConfig::numberOfL1CachePerChip()); 268 for (int i = start; i < (start + RubyConfig::numberOfL1CachePerChip()); i++) { 269 MachineID mach = { MACHINETYPE_L1CACHE_ENUM, i }; 270 ret.add( mach ); 271 } 272 } 273 274 return ret; 275} 276 277inline 278NetDest getExternalL1IDs(MachineID L1) 279{ 280 NetDest ret; 281 282 assert(MACHINETYPE_L1CACHE_ENUM != MachineType_NUM); 283 284 for (int i = 0; i < RubyConfig::numberOfProcessors(); i++) { 285 // ret.add( (NodeID) i); 286 MachineID mach = { MACHINETYPE_L1CACHE_ENUM, i }; 287 ret.add( mach ); 288 } 289 290 ret.removeNetDest(getLocalL1IDs(L1)); 291 292 return ret; 293} 294 295inline 296bool isLocalProcessor(MachineID thisId, MachineID tarID) 297{ 298 int start = (thisId.num / RubyConfig::numberOfProcsPerChip()) * RubyConfig::numberOfProcsPerChip(); 299 300 for (int i = start; i < (start + RubyConfig::numberOfProcsPerChip()); i++) { 301 if (i == tarID.num) { 302 return true; 303 } 304 } 305 return false; 306} 307 308 309inline 310NetDest getAllPertinentL2Banks(const Address& addr) // set of L2RubyNodes 311{ 312 NetDest dest; 313 314 for (int i = 0; i < RubyConfig::numberOfChips(); i++) { 315 dest.add(map_L2ChipId_to_L2Cache(addr,i)); 316 } 317 return dest; 318} 319 320inline 321bool isL1OnChip(MachineID L1machID, NodeID L2NodeID) 322{ 323 if (L1machID.type == MACHINETYPE_L1CACHE_ENUM) { 324 return (L1machID.num == L2NodeID); 325 } else { 326 return false; 327 } 328} 329 330inline 331bool isL2OnChip(MachineID L2machID, NodeID L2NodeID) 332{ 333 if (L2machID.type == MACHINETYPE_L2CACHE_ENUM) { 334 return (L2machID.num == L2NodeID); 335 } else { 336 return false; 337 } 338} 339 340inline 341NodeID closest_clockwise_distance(NodeID this_node, NodeID next_node) 342{ 343 if (this_node <= next_node) { 344 return (next_node - this_node); 345 } else { 346 return (next_node - this_node + RubyConfig::numberOfChips()); 347 } 348} 349 350inline 351bool closer_clockwise_processor(NodeID this_node, NodeID newer, NodeID older) 352{ 353 return (closest_clockwise_distance(this_node, newer) < closest_clockwise_distance(this_node, older)); 354} 355 356extern inline NodeID getChipID(MachineID L2machID) 357{ 358 return (L2machID.num%RubyConfig::numberOfChips())/RubyConfig::numberOfProcsPerChip(); 359} 360 361extern inline NodeID machineIDToNodeID(MachineID machID) 362{ 363 // return machID.num%RubyConfig::numberOfChips(); 364 return machID.num; 365} 366 367extern inline NodeID machineIDToVersion(MachineID machID) 368{ 369 return machID.num/RubyConfig::numberOfChips(); 370} 371 372extern inline MachineType machineIDToMachineType(MachineID machID) 373{ 374 return machID.type; 375} 376 377extern inline NodeID L1CacheMachIDToProcessorNum(MachineID machID) 378{ 379 assert(machID.type == MachineType_L1Cache); 380 return machID.num; 381} 382 383extern inline NodeID L2CacheMachIDToChipID(MachineID machID) 384{ 385 assert(machID.type == MACHINETYPE_L2CACHE_ENUM); 386 return machID.num/RubyConfig::numberOfL2CachePerChip(); 387} 388 389extern inline MachineID getCollectorDest(MachineID L1MachID) 390{ 391 MachineID mach = {MACHINETYPE_COLLECTOR_ENUM, L1MachID.num}; 392 return mach; 393} 394 395extern inline MachineID getCollectorL1Cache(MachineID colID) 396{ 397 MachineID mach = {MACHINETYPE_L1CACHE_ENUM, colID.num}; 398 return mach; 399} 400 401extern inline MachineID getL1MachineID(NodeID L1RubyNode) 402{ 403 MachineID mach = {MACHINETYPE_L1CACHE_ENUM, L1RubyNode}; 404 return mach; 405} 406 407extern inline GenericMachineType ConvertMachToGenericMach(MachineType machType) { 408 if (machType == MACHINETYPE_L1CACHE_ENUM) { 409 return GenericMachineType_L1Cache; 410 } else if (machType == MACHINETYPE_L2CACHE_ENUM) { 411 return GenericMachineType_L2Cache; 412 } else if (machType == MACHINETYPE_L3CACHE_ENUM) { 413 return GenericMachineType_L3Cache; 414 } else if (machType == MachineType_Directory) { 415 return GenericMachineType_Directory; 416 } else if (machType == MACHINETYPE_COLLECTOR_ENUM) { 417 return GenericMachineType_Collector; 418 } else { 419 ERROR_MSG("cannot convert to a GenericMachineType"); 420 return GenericMachineType_NULL; 421 } 422} 423 424 425#endif // COMPONENTMAPPINGFNS_H 426