1/* 2 * Copyright (c) 2019 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Copyright (c) 1999-2013 Mark D. Hill and David A. Wood 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions are 19 * met: redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer; 21 * redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution; 24 * neither the name of the copyright holders nor the names of its 25 * contributors may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 */ 40 41machine(MachineType:L2Cache, "Token protocol") 42: CacheMemory * L2cache; 43 Cycles response_latency := 1; 44 Cycles request_latency := 1; 45 46 // L2 BANK QUEUES 47 // From local bank of L2 cache TO the network 48 MessageBuffer * L1RequestFromL2Cache, network="To", virtual_network="0", 49 vnet_type="request"; // this L2 bank -> a local L1 50 MessageBuffer * GlobalRequestFromL2Cache, network="To", virtual_network="1", 51 vnet_type="request"; // this L2 bank -> mod-directory 52 MessageBuffer * responseFromL2Cache, network="To", virtual_network="2", 53 vnet_type="response"; // this L2 bank -> a local L1 || mod-directory 54 55 // FROM the network to this local bank of L2 cache 56 MessageBuffer * L1RequestToL2Cache, network="From", virtual_network="0", 57 vnet_type="request"; // a local L1 -> this L2 bank, Lets try this??? 58 MessageBuffer * GlobalRequestToL2Cache, network="From", virtual_network="1", 59 vnet_type="request"; // mod-directory -> this L2 bank 60 MessageBuffer * responseToL2Cache, network="From", virtual_network="2", 61 vnet_type="response"; // a local L1 || mod-directory -> this L2 bank 62 63 MessageBuffer * triggerQueue; 64{ 65 // STATES 66 state_declaration(State, desc="L2 Cache states", default="L2Cache_State_I") { 67 68 // Stable states 69 NP, AccessPermission:Invalid, desc="Not Present"; 70 I, AccessPermission:Invalid, desc="Invalid"; 71 ILS, AccessPermission:Invalid, desc="Idle/NP, but local sharers exist"; 72 ILX, AccessPermission:Invalid, desc="Idle/NP, but local exclusive exists"; 73 ILO, AccessPermission:Invalid, desc="Idle/NP, but local owner exists"; 74 ILOX, AccessPermission:Invalid, desc="Idle/NP, but local owner exists and chip is exclusive"; 75 ILOS, AccessPermission:Invalid, desc="Idle/NP, but local owner exists and local sharers as well"; 76 ILOSX, AccessPermission:Invalid, desc="Idle/NP, but local owner exists, local sharers exist, chip is exclusive "; 77 S, AccessPermission:Read_Only, desc="Shared, no local sharers"; 78 O, AccessPermission:Read_Only, desc="Owned, no local sharers"; 79 OLS, AccessPermission:Read_Only, desc="Owned with local sharers"; 80 OLSX, AccessPermission:Read_Only, desc="Owned with local sharers, chip is exclusive"; 81 SLS, AccessPermission:Read_Only, desc="Shared with local sharers"; 82 M, AccessPermission:Read_Write, desc="Modified"; 83 84 // Transient States 85 86 IFGX, AccessPermission:Busy, desc="Blocked, forwarded global GETX to local owner/exclusive. No other on-chip invs needed"; 87 IFGS, AccessPermission:Busy, desc="Blocked, forwarded global GETS to local owner"; 88 ISFGS, AccessPermission:Busy, desc="Blocked, forwarded global GETS to local owner, local sharers exist"; 89 IFGXX, AccessPermission:Busy, desc="Blocked, forwarded global GETX to local owner but may need acks from other sharers"; 90 OLSF, AccessPermission:Busy, desc="Blocked, got Fwd_GETX with local sharers, waiting for local inv acks"; 91 92 // writebacks 93 ILOW, AccessPermission:Busy, desc="local WB request, was ILO"; 94 ILOXW, AccessPermission:Busy, desc="local WB request, was ILOX"; 95 ILOSW, AccessPermission:Busy, desc="local WB request, was ILOS"; 96 ILOSXW, AccessPermission:Busy, desc="local WB request, was ILOSX"; 97 SLSW, AccessPermission:Busy, desc="local WB request, was SLS"; 98 OLSW, AccessPermission:Busy, desc="local WB request, was OLS"; 99 ILSW, AccessPermission:Busy, desc="local WB request, was ILS"; 100 IW, AccessPermission:Busy, desc="local WB request from only sharer, was ILS"; 101 OW, AccessPermission:Busy, desc="local WB request from only sharer, was OLS"; 102 SW, AccessPermission:Busy, desc="local WB request from only sharer, was SLS"; 103 OXW, AccessPermission:Busy, desc="local WB request from only sharer, was OLSX"; 104 OLSXW, AccessPermission:Busy, desc="local WB request from sharer, was OLSX"; 105 ILXW, AccessPermission:Busy, desc="local WB request, was ILX"; 106 107 IFLS, AccessPermission:Busy, desc="Blocked, forwarded local GETS to _some_ local sharer"; 108 IFLO, AccessPermission:Busy, desc="Blocked, forwarded local GETS to local owner"; 109 IFLOX, AccessPermission:Busy, desc="Blocked, forwarded local GETS to local owner but chip is exclusive"; 110 IFLOXX, AccessPermission:Busy, desc="Blocked, forwarded local GETX to local owner/exclusive, chip is exclusive"; 111 IFLOSX, AccessPermission:Busy, desc="Blocked, forwarded local GETS to local owner w/ other sharers, chip is exclusive"; 112 IFLXO, AccessPermission:Busy, desc="Blocked, forwarded local GETX to local owner with other sharers, chip is exclusive"; 113 114 IGS, AccessPermission:Busy, desc="Semi-blocked, issued local GETS to directory"; 115 IGM, AccessPermission:Busy, desc="Blocked, issued local GETX to directory. Need global acks and data"; 116 IGMLS, AccessPermission:Busy, desc="Blocked, issued local GETX to directory but may need to INV local sharers"; 117 IGMO, AccessPermission:Busy, desc="Blocked, have data for local GETX but need all acks"; 118 IGMIO, AccessPermission:Busy, desc="Blocked, issued local GETX, local owner with possible local sharer, may need to INV"; 119 OGMIO, AccessPermission:Busy, desc="Blocked, issued local GETX, was owner, may need to INV"; 120 IGMIOF, AccessPermission:Busy, desc="Blocked, issued local GETX, local owner, waiting for global acks, got Fwd_GETX"; 121 IGMIOFS, AccessPermission:Busy, desc="Blocked, issued local GETX, local owner, waiting for global acks, got Fwd_GETS"; 122 OGMIOF, AccessPermission:Busy, desc="Blocked, issued local GETX, was owner, waiting for global acks, got Fwd_GETX"; 123 124 II, AccessPermission:Busy, desc="Blocked, handling invalidations"; 125 MM, AccessPermission:Busy, desc="Blocked, was M satisfying local GETX"; 126 SS, AccessPermission:Busy, desc="Blocked, was S satisfying local GETS"; 127 OO, AccessPermission:Busy, desc="Blocked, was O satisfying local GETS"; 128 OLSS, AccessPermission:Busy, desc="Blocked, satisfying local GETS"; 129 OLSXS, AccessPermission:Busy, desc="Blocked, satisfying local GETS"; 130 SLSS, AccessPermission:Busy, desc="Blocked, satisfying local GETS"; 131 132 OI, AccessPermission:Busy, desc="Blocked, doing writeback, was O"; 133 MI, AccessPermission:Busy, desc="Blocked, doing writeback, was M"; 134 MII, AccessPermission:Busy, desc="Blocked, doing writeback, was M, got Fwd_GETX"; 135 OLSI, AccessPermission:Busy, desc="Blocked, doing writeback, was OLS"; 136 ILSI, AccessPermission:Busy, desc="Blocked, doing writeback, was OLS got Fwd_GETX"; 137 138 // DMA blocking states 139 ILOSD, AccessPermission:Busy, desc="Blocked, waiting for DMA ack"; 140 ILOSXD, AccessPermission:Busy, desc="Blocked, waiting for DMA ack"; 141 ILOD, AccessPermission:Busy, desc="Blocked, waiting for DMA ack"; 142 ILXD, AccessPermission:Busy, desc="Blocked, waiting for DMA ack"; 143 ILOXD, AccessPermission:Busy, desc="Blocked, waiting for DMA ack"; 144 } 145 146 // EVENTS 147 enumeration(Event, desc="Cache events") { 148 149 // Requests 150 L1_GETS, desc="local L1 GETS request"; 151 L1_GETX, desc="local L1 GETX request"; 152 L1_PUTO, desc="local owner wants to writeback"; 153 L1_PUTX, desc="local exclusive wants to writeback"; 154 L1_PUTS_only, desc="only local sharer wants to writeback"; 155 L1_PUTS, desc="local sharer wants to writeback"; 156 Fwd_GETX, desc="A GetX from another processor"; 157 Fwd_GETS, desc="A GetS from another processor"; 158 Fwd_DMA, desc="A request from DMA"; 159 Own_GETX, desc="A GetX from this node"; 160 Inv, desc="Invalidations from the directory"; 161 162 // Responses 163 IntAck, desc="Received an ack message"; 164 ExtAck, desc="Received an ack message"; 165 All_Acks, desc="Received all ack messages"; 166 Data, desc="Received a data message, responder has a shared copy"; 167 Data_Exclusive, desc="Received a data message"; 168 L1_WBCLEANDATA, desc="Writeback from L1, with data"; 169 L1_WBDIRTYDATA, desc="Writeback from L1, with data"; 170 171 Writeback_Ack, desc="Writeback O.K. from directory"; 172 Writeback_Nack, desc="Writeback not O.K. from directory"; 173 174 Unblock, desc="Local L1 is telling L2 dir to unblock"; 175 Exclusive_Unblock, desc="Local L1 is telling L2 dir to unblock"; 176 177 DmaAck, desc="DMA ack from local L1"; 178 // events initiated by this L2 179 L2_Replacement, desc="L2 Replacement", format="!r"; 180 181 } 182 183 // TYPES 184 185 // CacheEntry 186 structure(Entry, desc="...", interface="AbstractCacheEntry") { 187 State CacheState, desc="cache state"; 188 NetDest Sharers, desc="Set of the internal processors that want the block in shared state"; 189 MachineID Owner, desc="ID of the L1 cache to forward the block to once we get a response"; 190 bool OwnerValid, default="false", desc="true if Owner means something"; 191 bool Dirty, desc="Is the data dirty (different than memory)?"; 192 DataBlock DataBlk, desc="data for the block"; 193 } 194 195 196 structure(DirEntry, desc="...", interface="AbstractEntry") { 197 NetDest Sharers, desc="Set of the internal processors that want the block in shared state"; 198 MachineID Owner, desc="ID of the L1 cache to forward the block to once we get a response"; 199 bool OwnerValid, default="false", desc="true if Owner means something"; 200 State DirState, desc="directory state"; 201 } 202 203 // TBE fields 204 structure(TBE, desc="...") { 205 Addr addr, desc="Physical address for this TBE"; 206 State TBEState, desc="Transient state"; 207 Addr PC, desc="Program counter of request"; 208 DataBlock DataBlk, desc="Buffer for the data block"; 209 bool Dirty, desc="Is the data dirty (different than memory)?"; 210 211 int NumExtPendingAcks, default="0", desc="Number of global acks/data messages waiting for"; 212 int NumIntPendingAcks, default="0", desc="Number of global acks/data messages waiting for"; 213 int Fwd_GETX_ExtAcks, default="0", desc="Number of acks that requestor will need"; 214 int Local_GETX_IntAcks, default="0", desc="Number of acks that requestor will need"; 215 216 NetDest L1_GetS_IDs, desc="Set of the internal processors that want the block in shared state"; 217 MachineID L1_GetX_ID, desc="ID of the L1 cache to forward the block to once we get a response"; 218 NetDest Fwd_GetS_IDs, desc="Set of the internal processors that want the block in shared state"; 219 MachineID Fwd_GetX_ID, desc="ID of the L1 cache to forward the block to once we get a response"; 220 } 221 222 structure(TBETable, external = "yes") { 223 TBE lookup(Addr); 224 void allocate(Addr); 225 void deallocate(Addr); 226 bool isPresent(Addr); 227 } 228 229 structure(PerfectCacheMemory, external = "yes") { 230 void allocate(Addr); 231 void deallocate(Addr); 232 DirEntry lookup(Addr); 233 bool isTagPresent(Addr); 234 } 235 236 TBETable TBEs, template="<L2Cache_TBE>", constructor="m_number_of_TBEs"; 237 PerfectCacheMemory localDirectory, template="<L2Cache_DirEntry>"; 238 239 Tick clockEdge(); 240 Tick cyclesToTicks(Cycles c); 241 void set_cache_entry(AbstractCacheEntry b); 242 void unset_cache_entry(); 243 void set_tbe(TBE b); 244 void unset_tbe(); 245 MachineID mapAddressToMachine(Addr addr, MachineType mtype); 246 void wakeUpAllBuffers(Addr a); 247 248 // Latency for responses that fetch data from cache 249 Cycles cacheResponseLatency() { 250 if (L2cache.getTagLatency() > response_latency) { 251 return L2cache.getTagLatency(); 252 } 253 else { 254 return response_latency; 255 } 256 } 257 258 Entry getCacheEntry(Addr address), return_by_pointer="yes" { 259 return static_cast(Entry, "pointer", L2cache[address]); 260 } 261 262 bool isDirTagPresent(Addr addr) { 263 return (localDirectory.isTagPresent(addr) ); 264 } 265 266 DirEntry getDirEntry(Addr address), return_by_pointer="yes" { 267 return localDirectory.lookup(address); 268 } 269 270 bool isOnlySharer(Entry cache_entry, Addr addr, MachineID shar_id) { 271 if (is_valid(cache_entry)) { 272 assert (localDirectory.isTagPresent(addr) == false); 273 if (cache_entry.Sharers.count() > 1) { 274 return false; 275 } 276 else if (cache_entry.Sharers.count() == 1) { 277 if (cache_entry.Sharers.isElement(shar_id)) { 278 return true; 279 } 280 else { 281 return false; // something happened which should cause this PUTS to be nacked 282 } 283 return true; 284 } 285 else { 286 return false; 287 } 288 } 289 else if (localDirectory.isTagPresent(addr)){ 290 DirEntry dir_entry := getDirEntry(addr); 291 if (dir_entry.Sharers.count() > 1) { 292 return false; 293 } 294 else if (dir_entry.Sharers.count() == 1) { 295 if (dir_entry.Sharers.isElement(shar_id)) { 296 return true; 297 } 298 else { 299 return false; // something happened which should cause this PUTS to be nacked 300 } 301 } 302 else { 303 return false; 304 } 305 } 306 else { 307 // shouldn't happen unless L1 issues PUTS before unblock received 308 return false; 309 } 310 } 311 312 void copyCacheStateToDir(Entry cache_entry, Addr addr) { 313 assert(localDirectory.isTagPresent(addr) == false); 314 assert(is_valid(cache_entry)); 315 localDirectory.allocate(addr); 316 DirEntry dir_entry := getDirEntry(addr); 317 dir_entry.DirState := cache_entry.CacheState; 318 dir_entry.Sharers := cache_entry.Sharers; 319 dir_entry.Owner := cache_entry.Owner; 320 dir_entry.OwnerValid := cache_entry.OwnerValid; 321 322 } 323 324 void copyDirToCache(Entry cache_entry, Addr addr) { 325 assert(is_valid(cache_entry)); 326 DirEntry dir_entry := getDirEntry(addr); 327 cache_entry.Sharers := dir_entry.Sharers; 328 cache_entry.Owner := dir_entry.Owner; 329 cache_entry.OwnerValid := dir_entry.OwnerValid; 330 } 331 332 333 void recordLocalSharerInDir(Entry cache_entry, Addr addr, MachineID shar_id) { 334 if (is_valid(cache_entry)) { 335 assert (localDirectory.isTagPresent(addr) == false); 336 cache_entry.Sharers.add(shar_id); 337 } 338 else { 339 if (localDirectory.isTagPresent(addr) == false) { 340 localDirectory.allocate(addr); 341 DirEntry dir_entry := getDirEntry(addr); 342 dir_entry.Sharers.clear(); 343 dir_entry.OwnerValid := false; 344 } 345 DirEntry dir_entry := getDirEntry(addr); 346 dir_entry.Sharers.add(shar_id); 347 } 348 } 349 350 void recordNewLocalExclusiveInDir(Entry cache_entry, Addr addr, MachineID exc_id) { 351 352 if (is_valid(cache_entry)) { 353 assert (localDirectory.isTagPresent(addr) == false); 354 cache_entry.Sharers.clear(); 355 cache_entry.OwnerValid := true; 356 cache_entry.Owner := exc_id; 357 } 358 else { 359 if (localDirectory.isTagPresent(addr) == false) { 360 localDirectory.allocate(addr); 361 } 362 DirEntry dir_entry := getDirEntry(addr); 363 dir_entry.Sharers.clear(); 364 dir_entry.OwnerValid := true; 365 dir_entry.Owner := exc_id; 366 } 367 } 368 369 void removeAllLocalSharersFromDir(Entry cache_entry, Addr addr) { 370 if (is_valid(cache_entry)) { 371 assert (localDirectory.isTagPresent(addr) == false); 372 cache_entry.Sharers.clear(); 373 cache_entry.OwnerValid := false; 374 } 375 else { 376 DirEntry dir_entry := getDirEntry(addr); 377 dir_entry.Sharers.clear(); 378 dir_entry.OwnerValid := false; 379 } 380 } 381 382 void removeSharerFromDir(Entry cache_entry, Addr addr, MachineID sender) { 383 if (is_valid(cache_entry)) { 384 assert (localDirectory.isTagPresent(addr) == false); 385 cache_entry.Sharers.remove(sender); 386 } 387 else { 388 DirEntry dir_entry := getDirEntry(addr); 389 dir_entry.Sharers.remove(sender); 390 } 391 } 392 393 void removeOwnerFromDir(Entry cache_entry, Addr addr, MachineID sender) { 394 if (is_valid(cache_entry)) { 395 assert (localDirectory.isTagPresent(addr) == false); 396 cache_entry.OwnerValid := false; 397 } 398 else { 399 DirEntry dir_entry := getDirEntry(addr); 400 dir_entry.OwnerValid := false; 401 } 402 } 403 404 bool isLocalSharer(Entry cache_entry, Addr addr, MachineID shar_id) { 405 if (is_valid(cache_entry)) { 406 assert (localDirectory.isTagPresent(addr) == false); 407 return cache_entry.Sharers.isElement(shar_id); 408 } 409 else { 410 DirEntry dir_entry := getDirEntry(addr); 411 return dir_entry.Sharers.isElement(shar_id); 412 } 413 } 414 415 NetDest getLocalSharers(Entry cache_entry, Addr addr) { 416 if (is_valid(cache_entry)) { 417 assert (localDirectory.isTagPresent(addr) == false); 418 return cache_entry.Sharers; 419 } 420 else { 421 DirEntry dir_entry := getDirEntry(addr); 422 return dir_entry.Sharers; 423 } 424 } 425 426 MachineID getLocalOwner(Entry cache_entry, Addr addr) { 427 if (is_valid(cache_entry)) { 428 assert (localDirectory.isTagPresent(addr) == false); 429 return cache_entry.Owner; 430 } 431 else { 432 DirEntry dir_entry := getDirEntry(addr); 433 return dir_entry.Owner; 434 } 435 } 436 437 int countLocalSharers(Entry cache_entry, Addr addr) { 438 if (is_valid(cache_entry)) { 439 assert (localDirectory.isTagPresent(addr) == false); 440 return cache_entry.Sharers.count(); 441 } 442 else { 443 DirEntry dir_entry := getDirEntry(addr); 444 return dir_entry.Sharers.count(); 445 } 446 } 447 448 bool isLocalOwnerValid(Entry cache_entry, Addr addr) { 449 if (is_valid(cache_entry)) { 450 assert (localDirectory.isTagPresent(addr) == false); 451 return cache_entry.OwnerValid; 452 } 453 else { 454 DirEntry dir_entry := getDirEntry(addr); 455 return dir_entry.OwnerValid; 456 } 457 } 458 459 int countLocalSharersExceptRequestor(Entry cache_entry, Addr addr, MachineID requestor) { 460 if (is_valid(cache_entry)) { 461 assert (localDirectory.isTagPresent(addr) == false); 462 if (cache_entry.Sharers.isElement(requestor)) { 463 return ( cache_entry.Sharers.count() - 1 ); 464 } 465 else { 466 return cache_entry.Sharers.count(); 467 } 468 } 469 else { 470 DirEntry dir_entry := getDirEntry(addr); 471 if (dir_entry.Sharers.isElement(requestor)) { 472 return ( dir_entry.Sharers.count() - 1 ); 473 } 474 else { 475 return dir_entry.Sharers.count(); 476 } 477 } 478 } 479 480 State getState(TBE tbe, Entry cache_entry, Addr addr) { 481 482 if (is_valid(tbe)) { 483 return tbe.TBEState; 484 } else if (is_valid(cache_entry)) { 485 return cache_entry.CacheState; 486 } else if (isDirTagPresent(addr)) { 487 DirEntry dir_entry := getDirEntry(addr); 488 return dir_entry.DirState; 489 } else { 490 return State:NP; 491 } 492 } 493 494 std::string getCoherenceRequestTypeStr(CoherenceRequestType type) { 495 return CoherenceRequestType_to_string(type); 496 } 497 498 void setState(TBE tbe, Entry cache_entry, Addr addr, State state) { 499 assert((localDirectory.isTagPresent(addr) && L2cache.isTagPresent(addr)) == false); 500 501 if (is_valid(tbe)) { 502 tbe.TBEState := state; 503 } 504 505 if ( 506 (state == State:M) || 507 (state == State:O) || 508 (state == State:S) || 509 (state == State:OLS) || 510 (state == State:SLS) || 511 (state == State:OLSX) || 512 (state == State:SLS) 513 ) { 514 assert(is_valid(cache_entry)); 515 } 516 else if ( 517 (state == State:ILS) || 518 (state == State:ILX) || 519 (state == State:ILO) || 520 (state == State:ILOX) || 521 (state == State:ILOS) || 522 (state == State:ILOSX) 523 ) { 524 // assert(isCacheTagPresent(addr) == false); 525 } 526 527 if (is_valid(cache_entry)) { 528 if ( ((cache_entry.CacheState != State:M) && (state == State:M)) || 529 ((cache_entry.CacheState != State:S) && (state == State:S)) || 530 ((cache_entry.CacheState != State:O) && (state == State:O)) ) { 531 cache_entry.CacheState := state; 532 // disable Coherence Checker for now 533 // sequencer.checkCoherence(addr); 534 } 535 else { 536 cache_entry.CacheState := state; 537 } 538 } 539 else if (localDirectory.isTagPresent(addr)) { 540 DirEntry dir_entry := getDirEntry(addr); 541 dir_entry.DirState := state; 542 } 543 } 544 545 AccessPermission getAccessPermission(Addr addr) { 546 TBE tbe := TBEs[addr]; 547 if(is_valid(tbe)) { 548 DPRINTF(RubySlicc, "%s\n", L2Cache_State_to_permission(tbe.TBEState)); 549 return L2Cache_State_to_permission(tbe.TBEState); 550 } 551 552 Entry cache_entry := getCacheEntry(addr); 553 if(is_valid(cache_entry)) { 554 DPRINTF(RubySlicc, "%s\n", L2Cache_State_to_permission(cache_entry.CacheState)); 555 return L2Cache_State_to_permission(cache_entry.CacheState); 556 } 557 558 DPRINTF(RubySlicc, "AccessPermission_NotPresent\n"); 559 return AccessPermission:NotPresent; 560 } 561 562 void setAccessPermission(Entry cache_entry, Addr addr, State state) { 563 if (is_valid(cache_entry)) { 564 cache_entry.changePermission(L2Cache_State_to_permission(state)); 565 } 566 } 567 568 void functionalRead(Addr addr, Packet *pkt) { 569 TBE tbe := TBEs[addr]; 570 if(is_valid(tbe)) { 571 testAndRead(addr, tbe.DataBlk, pkt); 572 } else { 573 testAndRead(addr, getCacheEntry(addr).DataBlk, pkt); 574 } 575 } 576 577 int functionalWrite(Addr addr, Packet *pkt) { 578 int num_functional_writes := 0; 579 580 TBE tbe := TBEs[addr]; 581 if(is_valid(tbe)) { 582 num_functional_writes := num_functional_writes + 583 testAndWrite(addr, tbe.DataBlk, pkt); 584 return num_functional_writes; 585 } 586 587 num_functional_writes := num_functional_writes + 588 testAndWrite(addr, getCacheEntry(addr).DataBlk, pkt); 589 return num_functional_writes; 590 } 591 592 out_port(globalRequestNetwork_out, RequestMsg, GlobalRequestFromL2Cache); 593 out_port(localRequestNetwork_out, RequestMsg, L1RequestFromL2Cache); 594 out_port(responseNetwork_out, ResponseMsg, responseFromL2Cache); 595 596 out_port(triggerQueue_out, TriggerMsg, triggerQueue); 597 598 599 // ** IN_PORTS ** 600 601 // Trigger Queue 602 in_port(triggerQueue_in, TriggerMsg, triggerQueue, rank=3) { 603 if (triggerQueue_in.isReady(clockEdge())) { 604 peek(triggerQueue_in, TriggerMsg) { 605 if (in_msg.Type == TriggerType:ALL_ACKS) { 606 trigger(Event:All_Acks, in_msg.addr, 607 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 608 } else { 609 error("Unexpected message"); 610 } 611 } 612 } 613 } 614 615 // Response Network 616 in_port(responseNetwork_in, ResponseMsg, responseToL2Cache, rank=2) { 617 if (responseNetwork_in.isReady(clockEdge())) { 618 peek(responseNetwork_in, ResponseMsg) { 619 assert(in_msg.Destination.isElement(machineID)); 620 if (in_msg.Type == CoherenceResponseType:ACK) { 621 if (in_msg.SenderMachine == MachineType:L2Cache) { 622 trigger(Event:ExtAck, in_msg.addr, 623 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 624 } 625 else { 626 trigger(Event:IntAck, in_msg.addr, 627 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 628 } 629 } else if (in_msg.Type == CoherenceResponseType:DATA) { 630 trigger(Event:Data, in_msg.addr, 631 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 632 } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) { 633 trigger(Event:Data_Exclusive, in_msg.addr, 634 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 635 } else if (in_msg.Type == CoherenceResponseType:UNBLOCK) { 636 DPRINTF(RubySlicc, "Received Unblock from L1 addr: %x\n", in_msg.addr); 637 trigger(Event:Unblock, in_msg.addr, 638 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 639 } else if (in_msg.Type == CoherenceResponseType:UNBLOCK_EXCLUSIVE) { 640 trigger(Event:Exclusive_Unblock, in_msg.addr, 641 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 642 } else if (in_msg.Type == CoherenceResponseType:WB_ACK) { 643 trigger(Event:Writeback_Ack, in_msg.addr, 644 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 645 } else if (in_msg.Type == CoherenceResponseType:WB_NACK) { 646 trigger(Event:Writeback_Nack, in_msg.addr, 647 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 648 } else if (in_msg.Type == CoherenceResponseType:DMA_ACK) { 649 trigger(Event:DmaAck, in_msg.addr, 650 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 651 } else { 652 error("Unexpected message"); 653 } 654 } 655 } 656 } 657 658 659 // Request Network 660 in_port(requestNetwork_in, RequestMsg, GlobalRequestToL2Cache, rank=1) { 661 if (requestNetwork_in.isReady(clockEdge())) { 662 peek(requestNetwork_in, RequestMsg) { 663 if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestType:DMA_WRITE) { 664 if (in_msg.Requestor == machineID) { 665 trigger(Event:Own_GETX, in_msg.addr, 666 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 667 } else { 668 trigger(Event:Fwd_GETX, in_msg.addr, 669 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 670 } 671 } else if (in_msg.Type == CoherenceRequestType:GETS) { 672 trigger(Event:Fwd_GETS, in_msg.addr, 673 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 674 } else if(in_msg.Type == CoherenceRequestType:DMA_READ) { 675 trigger(Event:Fwd_DMA, in_msg.addr, 676 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 677 } else if (in_msg.Type == CoherenceRequestType:INV) { 678 trigger(Event:Inv, in_msg.addr, 679 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 680 } else { 681 error("Unexpected message"); 682 } 683 } 684 } 685 } 686 687 in_port(L1requestNetwork_in, RequestMsg, L1RequestToL2Cache, rank=0) { 688 if (L1requestNetwork_in.isReady(clockEdge())) { 689 peek(L1requestNetwork_in, RequestMsg) { 690 assert(in_msg.Destination.isElement(machineID)); 691 if (in_msg.Type == CoherenceRequestType:GETX) { 692 trigger(Event:L1_GETX, in_msg.addr, 693 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 694 } else if (in_msg.Type == CoherenceRequestType:GETS) { 695 trigger(Event:L1_GETS, in_msg.addr, 696 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 697 } else if (in_msg.Type == CoherenceRequestType:PUTO) { 698 trigger(Event:L1_PUTO, in_msg.addr, 699 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 700 } else if (in_msg.Type == CoherenceRequestType:PUTX) { 701 trigger(Event:L1_PUTX, in_msg.addr, 702 getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); 703 } else if (in_msg.Type == CoherenceRequestType:PUTS) { 704 Entry cache_entry := getCacheEntry(in_msg.addr); 705 if (isOnlySharer(cache_entry, in_msg.addr, in_msg.Requestor)) { 706 trigger(Event:L1_PUTS_only, in_msg.addr, 707 cache_entry, TBEs[in_msg.addr]); 708 } 709 else { 710 trigger(Event:L1_PUTS, in_msg.addr, 711 cache_entry, TBEs[in_msg.addr]); 712 } 713 } else if (in_msg.Type == CoherenceRequestType:WRITEBACK_DIRTY_DATA) { 714 Entry cache_entry := getCacheEntry(in_msg.addr); 715 if (is_invalid(cache_entry) && 716 L2cache.cacheAvail(in_msg.addr) == false) { 717 Addr victim := L2cache.cacheProbe(in_msg.addr); 718 trigger(Event:L2_Replacement, 719 victim, getCacheEntry(victim), TBEs[victim]); 720 } 721 else { 722 trigger(Event:L1_WBDIRTYDATA, in_msg.addr, 723 cache_entry, TBEs[in_msg.addr]); 724 } 725 } else if (in_msg.Type == CoherenceRequestType:WRITEBACK_CLEAN_DATA) { 726 Entry cache_entry := getCacheEntry(in_msg.addr); 727 if (is_invalid(cache_entry) && 728 L2cache.cacheAvail(in_msg.addr) == false) { 729 Addr victim := L2cache.cacheProbe(in_msg.addr); 730 trigger(Event:L2_Replacement, 731 victim, getCacheEntry(victim), TBEs[victim]); 732 } 733 else { 734 trigger(Event:L1_WBCLEANDATA, in_msg.addr, 735 cache_entry, TBEs[in_msg.addr]); 736 } 737 } else { 738 error("Unexpected message"); 739 } 740 } 741 } 742 } 743 744 745 // ACTIONS 746 747 action(a_issueGETS, "a", desc="issue local request globally") { 748 peek(L1requestNetwork_in, RequestMsg) { 749 enqueue(globalRequestNetwork_out, RequestMsg, request_latency) { 750 out_msg.addr := address; 751 out_msg.Type := CoherenceRequestType:GETS; 752 out_msg.RequestorMachine := MachineType:L2Cache; 753 out_msg.Requestor := machineID; 754 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 755 out_msg.MessageSize := MessageSizeType:Request_Control; 756 } 757 } 758 } 759 760 action(a_issueGETX, "\a", desc="issue local request globally") { 761 peek(L1requestNetwork_in, RequestMsg) { 762 enqueue(globalRequestNetwork_out, RequestMsg, request_latency) { 763 out_msg.addr := address; 764 out_msg.Type := CoherenceRequestType:GETX; 765 out_msg.RequestorMachine := MachineType:L2Cache; 766 out_msg.Requestor := machineID; 767 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 768 out_msg.MessageSize := MessageSizeType:Request_Control; 769 } 770 } 771 } 772 773 action(b_issuePUTX, "b", desc="Issue PUTX") { 774 enqueue(globalRequestNetwork_out, RequestMsg, request_latency) { 775 out_msg.addr := address; 776 out_msg.Type := CoherenceRequestType:PUTX; 777 out_msg.RequestorMachine := MachineType:L2Cache; 778 out_msg.Requestor := machineID; 779 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 780 out_msg.MessageSize := MessageSizeType:Writeback_Control; 781 } 782 } 783 784 action(b_issuePUTO, "\b", desc="Issue PUTO") { 785 enqueue(globalRequestNetwork_out, RequestMsg, request_latency) { 786 out_msg.addr := address; 787 out_msg.Type := CoherenceRequestType:PUTO; 788 out_msg.Requestor := machineID; 789 out_msg.RequestorMachine := MachineType:L2Cache; 790 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 791 out_msg.MessageSize := MessageSizeType:Writeback_Control; 792 } 793 } 794 795 /* PUTO, but local sharers exist */ 796 action(b_issuePUTO_ls, "\bb", desc="Issue PUTO") { 797 enqueue(globalRequestNetwork_out, RequestMsg, request_latency) { 798 out_msg.addr := address; 799 out_msg.Type := CoherenceRequestType:PUTO_SHARERS; 800 out_msg.Requestor := machineID; 801 out_msg.RequestorMachine := MachineType:L2Cache; 802 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 803 out_msg.MessageSize := MessageSizeType:Writeback_Control; 804 } 805 } 806 807 action(c_sendDataFromTBEToL1GETS, "c", desc="Send data from TBE to L1 requestors in TBE") { 808 assert(is_valid(tbe)); 809 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 810 out_msg.addr := address; 811 out_msg.Type := CoherenceResponseType:DATA; 812 out_msg.Sender := machineID; 813 out_msg.SenderMachine := MachineType:L2Cache; 814 out_msg.Destination.addNetDest(tbe.L1_GetS_IDs); 815 out_msg.DataBlk := tbe.DataBlk; 816 // out_msg.Dirty := tbe.Dirty; 817 // shared data should be clean 818 out_msg.Dirty := false; 819 out_msg.MessageSize := MessageSizeType:Response_Data; 820 } 821 DPRINTF(RubySlicc, "Address: %#x, Data Block: %s\n", 822 address, tbe.DataBlk); 823 } 824 825 action(c_sendDataFromTBEToL1GETX, "\c", desc="Send data from TBE to L1 requestors in TBE") { 826 assert(is_valid(tbe)); 827 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 828 out_msg.addr := address; 829 out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE; 830 out_msg.Sender := machineID; 831 out_msg.SenderMachine := MachineType:L2Cache; 832 out_msg.Destination.add(tbe.L1_GetX_ID); 833 out_msg.DataBlk := tbe.DataBlk; 834 out_msg.Dirty := tbe.Dirty; 835 out_msg.Acks := tbe.Local_GETX_IntAcks; 836 out_msg.MessageSize := MessageSizeType:Response_Data; 837 } 838 DPRINTF(RubySlicc, "Address: %#x, Data Block: %s\n", 839 address, tbe.DataBlk); 840 } 841 842 action(c_sendExclusiveDataFromTBEToL1GETS, "\cc", desc="Send data from TBE to L1 requestors in TBE") { 843 assert(is_valid(tbe)); 844 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 845 out_msg.addr := address; 846 out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE; 847 out_msg.Sender := machineID; 848 out_msg.SenderMachine := MachineType:L2Cache; 849 out_msg.Destination.addNetDest(tbe.L1_GetS_IDs); 850 out_msg.DataBlk := tbe.DataBlk; 851 out_msg.Dirty := tbe.Dirty; 852 out_msg.MessageSize := MessageSizeType:Response_Data; 853 } 854 } 855 856 action(c_sendDataFromTBEToFwdGETX, "cc", desc="Send data from TBE to external GETX") { 857 assert(is_valid(tbe)); 858 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 859 out_msg.addr := address; 860 out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE; 861 out_msg.Sender := machineID; 862 out_msg.SenderMachine := MachineType:L2Cache; 863 out_msg.Destination.add(tbe.Fwd_GetX_ID); 864 out_msg.DataBlk := tbe.DataBlk; 865 out_msg.Dirty := tbe.Dirty; 866 out_msg.Acks := tbe.Fwd_GETX_ExtAcks; 867 out_msg.MessageSize := MessageSizeType:Response_Data; 868 } 869 } 870 871 action(cd_sendDataFromTBEToFwdDma, "cd", desc="Send data from TBE to external GETX") { 872 assert(is_valid(tbe)); 873 peek(requestNetwork_in, RequestMsg) { 874 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 875 out_msg.addr := address; 876 out_msg.Type := CoherenceResponseType:DATA; 877 out_msg.Sender := machineID; 878 out_msg.SenderMachine := MachineType:L2Cache; 879 out_msg.Destination.add(in_msg.Requestor); 880 out_msg.DataBlk := tbe.DataBlk; 881 // out_msg.Dirty := tbe.Dirty; 882 // shared data should be clean 883 out_msg.Dirty := false; 884 out_msg.Acks := tbe.Fwd_GETX_ExtAcks; 885 out_msg.MessageSize := MessageSizeType:Response_Data; 886 } 887 } 888 DPRINTF(RubySlicc, "Address: %#x, Data Block: %s\n", 889 address, tbe.DataBlk); 890 } 891 892 action(c_sendDataFromTBEToFwdGETS, "ccc", desc="Send data from TBE to external GETX") { 893 assert(is_valid(tbe)); 894 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 895 out_msg.addr := address; 896 out_msg.Type := CoherenceResponseType:DATA; 897 out_msg.Sender := machineID; 898 out_msg.SenderMachine := MachineType:L2Cache; 899 out_msg.Destination.addNetDest(tbe.Fwd_GetS_IDs); 900 out_msg.DataBlk := tbe.DataBlk; 901 // out_msg.Dirty := tbe.Dirty; 902 // shared data should be clean 903 out_msg.Dirty := false; 904 out_msg.Acks := tbe.Fwd_GETX_ExtAcks; 905 out_msg.MessageSize := MessageSizeType:Response_Data; 906 } 907 DPRINTF(RubySlicc, "Address: %#x, Data Block: %s\n", 908 address, tbe.DataBlk); 909 } 910 911 action(c_sendExclusiveDataFromTBEToFwdGETS, "\ccc", desc="Send data from TBE to external GETX") { 912 assert(is_valid(tbe)); 913 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 914 out_msg.addr := address; 915 out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE; 916 out_msg.Sender := machineID; 917 out_msg.SenderMachine := MachineType:L2Cache; 918 out_msg.Destination.addNetDest(tbe.Fwd_GetS_IDs); 919 out_msg.DataBlk := tbe.DataBlk; 920 out_msg.Dirty := tbe.Dirty; 921 out_msg.Acks := tbe.Fwd_GETX_ExtAcks; 922 out_msg.MessageSize := MessageSizeType:Response_Data; 923 } 924 DPRINTF(RubySlicc, "Address: %#x, Data Block: %s\n", 925 address, tbe.DataBlk); 926 } 927 928 action(d_sendDataToL1GETS, "d", desc="Send data directly to L1 requestor") { 929 assert(is_valid(cache_entry)); 930 peek(L1requestNetwork_in, RequestMsg) { 931 enqueue(responseNetwork_out, ResponseMsg, cacheResponseLatency()) { 932 out_msg.addr := address; 933 out_msg.Type := CoherenceResponseType:DATA; 934 out_msg.Sender := machineID; 935 out_msg.SenderMachine := MachineType:L2Cache; 936 out_msg.Destination.add(in_msg.Requestor); 937 out_msg.DataBlk := cache_entry.DataBlk; 938 // out_msg.Dirty := cache_entry.Dirty; 939 // shared data should be clean 940 out_msg.Dirty := false; 941 out_msg.MessageSize := MessageSizeType:ResponseL2hit_Data; 942 } 943 } 944 DPRINTF(RubySlicc, "Address: %#x, Data Block: %s\n", 945 address, cache_entry.DataBlk); 946 } 947 948 action(d_sendDataToL1GETX, "\d", desc="Send data and a token from TBE to L1 requestor") { 949 assert(is_valid(cache_entry)); 950 peek(L1requestNetwork_in, RequestMsg) { 951 enqueue(responseNetwork_out, ResponseMsg, cacheResponseLatency()) { 952 assert(is_valid(tbe)); 953 out_msg.addr := address; 954 out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE; 955 out_msg.Sender := machineID; 956 out_msg.SenderMachine := MachineType:L2Cache; 957 out_msg.Destination.add(in_msg.Requestor); 958 out_msg.DataBlk := cache_entry.DataBlk; 959 out_msg.Dirty := cache_entry.Dirty; 960 out_msg.MessageSize := MessageSizeType:ResponseL2hit_Data; 961 out_msg.Acks := tbe.Local_GETX_IntAcks; 962 } 963 } 964 DPRINTF(RubySlicc, "Address: %#x, Data Block: %s\n", 965 address, cache_entry.DataBlk); 966 } 967 968 action(dd_sendDataToFwdGETX, "dd", desc="send data") { 969 assert(is_valid(cache_entry)); 970 peek(requestNetwork_in, RequestMsg) { 971 enqueue(responseNetwork_out, ResponseMsg, cacheResponseLatency()) { 972 out_msg.addr := address; 973 out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE; 974 out_msg.Sender := machineID; 975 out_msg.SenderMachine := MachineType:L2Cache; 976 out_msg.Destination.add(in_msg.Requestor); 977 out_msg.DataBlk := cache_entry.DataBlk; 978 out_msg.Dirty := cache_entry.Dirty; 979 out_msg.MessageSize := MessageSizeType:Response_Data; 980 out_msg.Acks := in_msg.Acks; 981 } 982 } 983 DPRINTF(RubySlicc, "Address: %#x, Data Block: %s\n", 984 address, cache_entry.DataBlk); 985 } 986 987 988 action(dd_sendDataToFwdGETS, "\dd", desc="send data") { 989 assert(is_valid(cache_entry)); 990 peek(requestNetwork_in, RequestMsg) { 991 enqueue(responseNetwork_out, ResponseMsg, cacheResponseLatency()) { 992 out_msg.addr := address; 993 out_msg.Type := CoherenceResponseType:DATA; 994 out_msg.Sender := machineID; 995 out_msg.SenderMachine := MachineType:L2Cache; 996 out_msg.Destination.add(in_msg.Requestor); 997 out_msg.DataBlk := cache_entry.DataBlk; 998 // out_msg.Dirty := cache_entry.Dirty; 999 // shared data should be clean 1000 out_msg.Dirty := false; 1001 out_msg.MessageSize := MessageSizeType:Response_Data; 1002 } 1003 } 1004 DPRINTF(RubySlicc, "Address: %#x, Data Block: %s\n", 1005 address, cache_entry.DataBlk); 1006 } 1007 1008 action(dd_sendExclusiveDataToFwdGETS, "\d\d", desc="send data") { 1009 assert(is_valid(cache_entry)); 1010 peek(requestNetwork_in, RequestMsg) { 1011 enqueue(responseNetwork_out, ResponseMsg, cacheResponseLatency()) { 1012 out_msg.addr := address; 1013 out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE; 1014 out_msg.Sender := machineID; 1015 out_msg.SenderMachine := MachineType:L2Cache; 1016 out_msg.Destination.add(in_msg.Requestor); 1017 out_msg.DataBlk := cache_entry.DataBlk; 1018 out_msg.Dirty := cache_entry.Dirty; 1019 out_msg.MessageSize := MessageSizeType:Response_Data; 1020 } 1021 } 1022 } 1023 1024 action(e_sendAck, "e", desc="Send ack with the tokens we've collected thus far.") { 1025 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 1026 assert(is_valid(tbe)); 1027 out_msg.addr := address; 1028 out_msg.Type := CoherenceResponseType:ACK; 1029 out_msg.Sender := machineID; 1030 out_msg.SenderMachine := MachineType:L2Cache; 1031 1032 out_msg.Destination.add( tbe.Fwd_GetX_ID); 1033 out_msg.Acks := 0 - 1; 1034 out_msg.MessageSize := MessageSizeType:Response_Control; 1035 } 1036 } 1037 1038 action(e_sendAckToL1Requestor, "\e", desc="Send ack with the tokens we've collected thus far.") { 1039 peek(L1requestNetwork_in, RequestMsg) { 1040 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 1041 out_msg.addr := address; 1042 out_msg.Type := CoherenceResponseType:ACK; 1043 out_msg.Sender := machineID; 1044 out_msg.SenderMachine := MachineType:L2Cache; 1045 out_msg.Destination.add(in_msg.Requestor); 1046 out_msg.Acks := 0 - 1; 1047 out_msg.MessageSize := MessageSizeType:Response_Control; 1048 } 1049 } 1050 } 1051 1052 action(e_sendAckToL1RequestorFromTBE, "eee", desc="Send ack with the tokens we've collected thus far.") { 1053 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 1054 assert(is_valid(tbe)); 1055 out_msg.addr := address; 1056 out_msg.Type := CoherenceResponseType:ACK; 1057 out_msg.Sender := machineID; 1058 out_msg.SenderMachine := MachineType:L2Cache; 1059 out_msg.Destination.add(tbe.L1_GetX_ID); 1060 out_msg.Acks := 0 - 1; 1061 out_msg.MessageSize := MessageSizeType:Response_Control; 1062 } 1063 } 1064 1065 action(ee_sendLocalInv, "\ee", desc="Send local invalidates") { 1066 assert(is_valid(tbe)); 1067 tbe.NumIntPendingAcks := countLocalSharers(cache_entry, address); 1068 DPRINTF(RubySlicc, "Address: %#x, Local Sharers: %s, Pending Acks: %d\n", 1069 address, getLocalSharers(cache_entry, address), 1070 tbe.NumIntPendingAcks); 1071 if (isLocalOwnerValid(cache_entry, address)) { 1072 tbe.NumIntPendingAcks := tbe.NumIntPendingAcks + 1; 1073 DPRINTF(RubySlicc, "%s\n", getLocalOwner(cache_entry, address)); 1074 } 1075 1076 enqueue( localRequestNetwork_out, RequestMsg, response_latency ) { 1077 out_msg.addr := address; 1078 out_msg.Type := CoherenceRequestType:INV; 1079 out_msg.Requestor := machineID; 1080 out_msg.RequestorMachine := MachineType:L2Cache; 1081 out_msg.Destination.addNetDest(getLocalSharers(cache_entry, address)); 1082 if (isLocalOwnerValid(cache_entry, address)) 1083 { 1084 out_msg.Destination.add(getLocalOwner(cache_entry, address)); 1085 } 1086 out_msg.MessageSize := MessageSizeType:Invalidate_Control; 1087 } 1088 } 1089 1090 action(ee_sendLocalInvSharersOnly, "\eee", desc="Send local invalidates to sharers if they exist") { 1091 1092 // assert(countLocalSharers(address) > 0); 1093 assert(is_valid(tbe)); 1094 tbe.NumIntPendingAcks := countLocalSharers(cache_entry, address); 1095 1096 if (countLocalSharers(cache_entry, address) > 0) { 1097 enqueue( localRequestNetwork_out, RequestMsg, response_latency ) { 1098 out_msg.addr := address; 1099 out_msg.Type := CoherenceRequestType:INV; 1100 out_msg.Requestor := machineID; 1101 out_msg.RequestorMachine := MachineType:L2Cache; 1102 out_msg.Destination.addNetDest(getLocalSharers(cache_entry, address)); 1103 out_msg.MessageSize := MessageSizeType:Invalidate_Control; 1104 } 1105 } 1106 } 1107 1108 action(ee_addLocalIntAck, "e\ee", desc="add a local ack to wait for") { 1109 assert(is_valid(tbe)); 1110 tbe.NumIntPendingAcks := tbe.NumIntPendingAcks + 1; 1111 } 1112 1113 action(ee_issueLocalInvExceptL1Requestor, "\eeee", desc="Send local invalidates to sharers if they exist") { 1114 peek(L1requestNetwork_in, RequestMsg) { 1115 1116// assert(countLocalSharers(address) > 0); 1117 if (countLocalSharers(cache_entry, address) == 0) { 1118 tbe.NumIntPendingAcks := 0; 1119 } 1120 else { 1121 1122 if (isLocalSharer(cache_entry, address, in_msg.Requestor)) { 1123 tbe.NumIntPendingAcks := countLocalSharers(cache_entry, address) - 1; 1124 } 1125 else { 1126 tbe.NumIntPendingAcks := countLocalSharers(cache_entry, address); 1127 } 1128 1129 enqueue( localRequestNetwork_out, RequestMsg, response_latency ) { 1130 out_msg.addr := address; 1131 out_msg.Type := CoherenceRequestType:INV; 1132 out_msg.Requestor := in_msg.Requestor; 1133 out_msg.RequestorMachine := MachineType:L1Cache; 1134 out_msg.Destination.addNetDest(getLocalSharers(cache_entry, address)); 1135 out_msg.Destination.remove(in_msg.Requestor); 1136 out_msg.MessageSize := MessageSizeType:Invalidate_Control; 1137 } 1138 } 1139 } 1140 } 1141 1142 action(ee_issueLocalInvExceptL1RequestorInTBE, "\eeeeee", desc="Send local invalidates to sharers if they exist") { 1143 assert(is_valid(tbe)); 1144 if (countLocalSharers(cache_entry, address) == 0) { 1145 tbe.NumIntPendingAcks := 0; 1146 } 1147 else { 1148 if (isLocalSharer(cache_entry, address, tbe.L1_GetX_ID)) { 1149 tbe.NumIntPendingAcks := countLocalSharers(cache_entry, address) - 1; 1150 } 1151 else { 1152 tbe.NumIntPendingAcks := countLocalSharers(cache_entry, address); 1153 } 1154 } 1155 enqueue( localRequestNetwork_out, RequestMsg, response_latency ) { 1156 out_msg.addr := address; 1157 out_msg.Type := CoherenceRequestType:INV; 1158 out_msg.Requestor := tbe.L1_GetX_ID; 1159 out_msg.RequestorMachine := MachineType:L1Cache; 1160 out_msg.Destination.addNetDest(getLocalSharers(cache_entry, address)); 1161 out_msg.Destination.remove(tbe.L1_GetX_ID); 1162 out_msg.MessageSize := MessageSizeType:Invalidate_Control; 1163 } 1164 } 1165 1166 1167 action(f_sendUnblock, "f", desc="Send unblock to global directory") { 1168 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 1169 out_msg.addr := address; 1170 out_msg.Type := CoherenceResponseType:UNBLOCK; 1171 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 1172 out_msg.Sender := machineID; 1173 out_msg.SenderMachine := MachineType:L2Cache; 1174 out_msg.MessageSize := MessageSizeType:Unblock_Control; 1175 } 1176 } 1177 1178 1179 action(f_sendExclusiveUnblock, "\f", desc="Send unblock to global directory") { 1180 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 1181 out_msg.addr := address; 1182 out_msg.Type := CoherenceResponseType:UNBLOCK_EXCLUSIVE; 1183 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 1184 out_msg.Sender := machineID; 1185 out_msg.SenderMachine := MachineType:L2Cache; 1186 out_msg.MessageSize := MessageSizeType:Unblock_Control; 1187 } 1188 } 1189 1190 1191 action(g_recordLocalSharer, "g", desc="Record new local sharer from unblock message") { 1192 peek(responseNetwork_in, ResponseMsg) { 1193 recordLocalSharerInDir(cache_entry, in_msg.addr, in_msg.Sender); 1194 } 1195 } 1196 1197 action(g_recordLocalExclusive, "\g", desc="Record new local exclusive sharer from unblock message") { 1198 peek(responseNetwork_in, ResponseMsg) { 1199 recordNewLocalExclusiveInDir(cache_entry, address, in_msg.Sender); 1200 } 1201 } 1202 1203 action(gg_clearLocalSharers, "gg", desc="Clear local sharers") { 1204 removeAllLocalSharersFromDir(cache_entry, address); 1205 } 1206 1207 action(gg_clearSharerFromL1Response, "\gg", desc="Clear sharer from L1 response queue") { 1208 peek(responseNetwork_in, ResponseMsg) { 1209 removeSharerFromDir(cache_entry, in_msg.addr, in_msg.Sender); 1210 } 1211 } 1212 1213 action(gg_clearSharerFromL1Request, "clsl1r", desc="Clear sharer from L1 request queue") { 1214 peek(L1requestNetwork_in, RequestMsg) { 1215 removeSharerFromDir(cache_entry, in_msg.addr, in_msg.Requestor); 1216 } 1217 } 1218 1219 action(gg_clearOwnerFromL1Request, "clol1r", desc="Clear owner from L1 request queue") { 1220 peek(L1requestNetwork_in, RequestMsg) { 1221 removeOwnerFromDir(cache_entry, in_msg.addr, in_msg.Requestor); 1222 } 1223 } 1224 1225 action(h_countLocalSharersExceptRequestor, "h", desc="counts number of acks needed for L1 GETX") { 1226 peek(L1requestNetwork_in, RequestMsg) { 1227 assert(is_valid(tbe)); 1228 tbe.Local_GETX_IntAcks := countLocalSharersExceptRequestor(cache_entry, address, in_msg.Requestor); 1229 } 1230 } 1231 1232 action(h_clearIntAcks, "\h", desc="clear IntAcks") { 1233 assert(is_valid(tbe)); 1234 tbe.Local_GETX_IntAcks := 0; 1235 } 1236 1237 action(hh_countLocalSharersExceptL1GETXRequestorInTBE, "hh", desc="counts number of acks needed for L1 GETX") { 1238 assert(is_valid(tbe)); 1239 tbe.Local_GETX_IntAcks := countLocalSharersExceptRequestor(cache_entry, address, tbe.L1_GetX_ID); 1240 } 1241 1242 action(i_copyDataToTBE, "\i", desc="Copy data from response queue to TBE") { 1243 peek(responseNetwork_in, ResponseMsg) { 1244 assert(is_valid(tbe)); 1245 tbe.DataBlk := in_msg.DataBlk; 1246 tbe.Dirty := in_msg.Dirty; 1247 APPEND_TRANSITION_COMMENT(in_msg.Sender); 1248 } 1249 } 1250 1251 action(i_allocateTBE, "i", desc="Allocate TBE for internal/external request(isPrefetch=0, number of invalidates=0)") { 1252 check_allocate(TBEs); 1253 TBEs.allocate(address); 1254 set_tbe(TBEs[address]); 1255 if(is_valid(cache_entry)) { 1256 tbe.DataBlk := cache_entry.DataBlk; 1257 tbe.Dirty := cache_entry.Dirty; 1258 } 1259 tbe.NumIntPendingAcks := 0; // default value 1260 tbe.NumExtPendingAcks := 0; // default value 1261 tbe.Fwd_GetS_IDs.clear(); 1262 tbe.L1_GetS_IDs.clear(); 1263 } 1264 1265 1266 1267 action(j_forwardGlobalRequestToLocalOwner, "j", desc="Forward external request to local owner") { 1268 peek(requestNetwork_in, RequestMsg) { 1269 enqueue( localRequestNetwork_out, RequestMsg, response_latency ) { 1270 out_msg.addr := in_msg.addr; 1271 out_msg.Type := in_msg.Type; 1272 out_msg.Requestor := machineID; 1273 out_msg.RequestorMachine := MachineType:L2Cache; 1274 out_msg.Destination.add(getLocalOwner(cache_entry, in_msg.addr)); 1275 out_msg.Type := in_msg.Type; 1276 out_msg.MessageSize := MessageSizeType:Forwarded_Control; 1277 out_msg.Acks := 0 - 1; 1278 } 1279 } 1280 } 1281 1282 action(jd_forwardDmaRequestToLocalOwner, "jd", desc="Forward dma request to local owner") { 1283 peek(requestNetwork_in, RequestMsg) { 1284 enqueue( localRequestNetwork_out, RequestMsg, response_latency ) { 1285 out_msg.addr := in_msg.addr; 1286 out_msg.Type := in_msg.Type; 1287 out_msg.Requestor := in_msg.Requestor; 1288 out_msg.RequestorMachine := in_msg.RequestorMachine; 1289 out_msg.Destination.add(getLocalOwner(cache_entry, in_msg.addr)); 1290 out_msg.Type := in_msg.Type; 1291 out_msg.MessageSize := MessageSizeType:Forwarded_Control; 1292 out_msg.Acks := 0 - 1; 1293 } 1294 } 1295 } 1296 1297 1298 action(k_forwardLocalGETSToLocalSharer, "k", desc="Forward local request to local sharer/owner") { 1299 peek(L1requestNetwork_in, RequestMsg) { 1300 enqueue( localRequestNetwork_out, RequestMsg, response_latency ) { 1301 out_msg.addr := in_msg.addr; 1302 out_msg.Type := CoherenceRequestType:GETS; 1303 out_msg.Requestor := in_msg.Requestor; 1304 out_msg.RequestorMachine := MachineType:L1Cache; 1305 // should randomize this so one node doesn't get abused more than others 1306 DirEntry dir_entry := getDirEntry(in_msg.addr); 1307 out_msg.Destination.add(dir_entry.Sharers.smallestElement(MachineType:L1Cache)); 1308 out_msg.MessageSize := MessageSizeType:Forwarded_Control; 1309 } 1310 } 1311 } 1312 1313 action(k_forwardLocalGETXToLocalOwner, "\k", desc="Forward local request to local owner") { 1314 enqueue( localRequestNetwork_out, RequestMsg, response_latency ) { 1315 assert(is_valid(tbe)); 1316 out_msg.addr := address; 1317 out_msg.Type := CoherenceRequestType:GETX; 1318 out_msg.Requestor := tbe.L1_GetX_ID; 1319 out_msg.RequestorMachine := MachineType:L1Cache; 1320 DirEntry dir_entry := getDirEntry(address); 1321 out_msg.Destination.add(dir_entry.Owner); 1322 out_msg.MessageSize := MessageSizeType:Forwarded_Control; 1323 out_msg.Acks := 1 + tbe.Local_GETX_IntAcks; 1324 } 1325 } 1326 1327 // same as previous except that it assumes to TBE is present to get number of acks 1328 action(kk_forwardLocalGETXToLocalExclusive, "kk", desc="Forward local request to local owner") { 1329 peek(L1requestNetwork_in, RequestMsg) { 1330 enqueue( localRequestNetwork_out, RequestMsg, response_latency ) { 1331 out_msg.addr := in_msg.addr; 1332 out_msg.Type := CoherenceRequestType:GETX; 1333 out_msg.Requestor := in_msg.Requestor; 1334 out_msg.RequestorMachine := MachineType:L1Cache; 1335 out_msg.Destination.add(getLocalOwner(cache_entry, in_msg.addr)); 1336 out_msg.MessageSize := MessageSizeType:Forwarded_Control; 1337 out_msg.Acks := 1; 1338 } 1339 } 1340 } 1341 1342 action(kk_forwardLocalGETSToLocalOwner, "\kk", desc="Forward local request to local owner") { 1343 peek(L1requestNetwork_in, RequestMsg) { 1344 enqueue( localRequestNetwork_out, RequestMsg, response_latency ) { 1345 out_msg.addr := in_msg.addr; 1346 out_msg.Type := CoherenceRequestType:GETS; 1347 out_msg.Requestor := in_msg.Requestor; 1348 out_msg.RequestorMachine := MachineType:L1Cache; 1349 out_msg.Destination.add(getLocalOwner(cache_entry, in_msg.addr)); 1350 out_msg.MessageSize := MessageSizeType:Forwarded_Control; 1351 } 1352 } 1353 } 1354 1355 1356 action(l_writebackAckNeedData, "l", desc="Send writeback ack to L1 requesting data") { 1357 peek(L1requestNetwork_in, RequestMsg) { 1358 enqueue( responseNetwork_out, ResponseMsg, response_latency ) { 1359 out_msg.addr := in_msg.addr; 1360 out_msg.Type := CoherenceResponseType:WB_ACK_DATA; 1361 out_msg.Sender := machineID; 1362 out_msg.SenderMachine := MachineType:L2Cache; 1363 out_msg.Destination.add(in_msg.Requestor); 1364 out_msg.MessageSize := MessageSizeType:Writeback_Control; 1365 } 1366 } 1367 } 1368 1369 action(l_writebackAckDropData, "\l", desc="Send writeback ack to L1 indicating to drop data") { 1370 peek(L1requestNetwork_in, RequestMsg) { 1371 enqueue( responseNetwork_out, ResponseMsg, response_latency ) { 1372 out_msg.addr := in_msg.addr; 1373 out_msg.Type := CoherenceResponseType:WB_ACK; 1374 out_msg.Sender := machineID; 1375 out_msg.SenderMachine := MachineType:L2Cache; 1376 out_msg.Destination.add(in_msg.Requestor); 1377 out_msg.MessageSize := MessageSizeType:Writeback_Control; 1378 } 1379 } 1380 } 1381 1382 action(ll_writebackNack, "\ll", desc="Send writeback nack to L1") { 1383 peek(L1requestNetwork_in, RequestMsg) { 1384 enqueue( responseNetwork_out, ResponseMsg, response_latency ) { 1385 out_msg.addr := in_msg.addr; 1386 out_msg.Type := CoherenceResponseType:WB_NACK; 1387 out_msg.Sender := machineID; 1388 out_msg.SenderMachine := MachineType:L2Cache; 1389 out_msg.Destination.add(in_msg.Requestor); 1390 out_msg.MessageSize := MessageSizeType:Writeback_Control; 1391 } 1392 } 1393 } 1394 1395 action(m_popRequestQueue, "m", desc="Pop request queue.") { 1396 requestNetwork_in.dequeue(clockEdge()); 1397 } 1398 1399 action(m_decrementNumberOfMessagesInt, "\m", desc="Decrement the number of messages for which we're waiting") { 1400 peek(responseNetwork_in, ResponseMsg) { 1401 assert(is_valid(tbe)); 1402 tbe.NumIntPendingAcks := tbe.NumIntPendingAcks + in_msg.Acks; 1403 } 1404 } 1405 1406 action(m_decrementNumberOfMessagesExt, "\mmm", desc="Decrement the number of messages for which we're waiting") { 1407 peek(responseNetwork_in, ResponseMsg) { 1408 assert(is_valid(tbe)); 1409 tbe.NumExtPendingAcks := tbe.NumExtPendingAcks - in_msg.Acks; 1410 } 1411 } 1412 1413 action(mm_decrementNumberOfMessagesExt, "\mm", desc="Decrement the number of messages for which we're waiting") { 1414 peek(requestNetwork_in, RequestMsg) { 1415 assert(is_valid(tbe)); 1416 tbe.NumExtPendingAcks := tbe.NumExtPendingAcks - in_msg.Acks; 1417 } 1418 } 1419 1420 action(n_popResponseQueue, "n", desc="Pop response queue") { 1421 responseNetwork_in.dequeue(clockEdge()); 1422 } 1423 1424 action(n_popTriggerQueue, "\n", desc="Pop trigger queue.") { 1425 triggerQueue_in.dequeue(clockEdge()); 1426 } 1427 1428 action(o_popL1RequestQueue, "o", desc="Pop L1 request queue.") { 1429 L1requestNetwork_in.dequeue(clockEdge()); 1430 } 1431 1432 1433 action(o_checkForIntCompletion, "\o", desc="Check if we have received all the messages required for completion") { 1434 assert(is_valid(tbe)); 1435 if (tbe.NumIntPendingAcks == 0) { 1436 enqueue(triggerQueue_out, TriggerMsg) { 1437 out_msg.addr := address; 1438 out_msg.Type := TriggerType:ALL_ACKS; 1439 } 1440 } 1441 } 1442 1443 action(o_checkForExtCompletion, "\oo", desc="Check if we have received all the messages required for completion") { 1444 assert(is_valid(tbe)); 1445 if (tbe.NumExtPendingAcks == 0) { 1446 enqueue(triggerQueue_out, TriggerMsg) { 1447 out_msg.addr := address; 1448 out_msg.Type := TriggerType:ALL_ACKS; 1449 } 1450 } 1451 } 1452 1453 1454 action( qq_sendDataFromTBEToMemory, "qq", desc="Send data from TBE to directory") { 1455 enqueue(globalRequestNetwork_out, RequestMsg, response_latency) { 1456 assert(is_valid(tbe)); 1457 out_msg.addr := address; 1458 out_msg.Requestor := machineID; 1459 out_msg.RequestorMachine := MachineType:L2Cache; 1460 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 1461 if (tbe.Dirty) { 1462 out_msg.Type := CoherenceRequestType:WRITEBACK_DIRTY_DATA; 1463 out_msg.DataBlk := tbe.DataBlk; 1464 out_msg.MessageSize := MessageSizeType:Writeback_Data; 1465 } else { 1466 out_msg.Type := CoherenceRequestType:WRITEBACK_CLEAN_ACK; 1467 // NOTE: in a real system this would not send data. We send 1468 // data here only so we can check it at the memory 1469 out_msg.DataBlk := tbe.DataBlk; 1470 out_msg.MessageSize := MessageSizeType:Writeback_Control; 1471 } 1472 } 1473 } 1474 1475 action( r_setMRU, "\rrr", desc="manually set the MRU bit for cache line" ) { 1476 if(is_valid(cache_entry)) { 1477 L2cache.setMRU(address); 1478 } 1479 } 1480 1481 action( s_recordGetXL1ID, "ss", desc="record local GETX requestor") { 1482 peek(L1requestNetwork_in, RequestMsg) { 1483 assert(is_valid(tbe)); 1484 tbe.L1_GetX_ID := in_msg.Requestor; 1485 } 1486 } 1487 1488 action(s_deallocateTBE, "s", desc="Deallocate external TBE") { 1489 TBEs.deallocate(address); 1490 unset_tbe(); 1491 } 1492 1493 action( s_recordGetSL1ID, "\ss", desc="record local GETS requestor") { 1494 peek(L1requestNetwork_in, RequestMsg) { 1495 assert(is_valid(tbe)); 1496 tbe.L1_GetS_IDs.add(in_msg.Requestor); 1497 } 1498 } 1499 1500 action(t_recordFwdXID, "t", desc="record global GETX requestor") { 1501 peek(requestNetwork_in, RequestMsg) { 1502 assert(is_valid(tbe)); 1503 tbe.Fwd_GetX_ID := in_msg.Requestor; 1504 tbe.Fwd_GETX_ExtAcks := in_msg.Acks; 1505 } 1506 } 1507 1508 action(t_recordFwdSID, "\t", desc="record global GETS requestor") { 1509 peek(requestNetwork_in, RequestMsg) { 1510 assert(is_valid(tbe)); 1511 tbe.Fwd_GetS_IDs.clear(); 1512 tbe.Fwd_GetS_IDs.add(in_msg.Requestor); 1513 } 1514 } 1515 1516 1517 action(u_writeCleanDataToCache, "wCd", desc="Write clean data to cache") { 1518 peek(L1requestNetwork_in, RequestMsg) { 1519 assert(is_valid(cache_entry)); 1520 cache_entry.DataBlk := in_msg.DataBlk; 1521 DPRINTF(RubySlicc, "Address: %#x, Data Block: %s\n", 1522 address, cache_entry.DataBlk); 1523 assert(cache_entry.Dirty == false); 1524 } 1525 } 1526 1527 action(u_writeDirtyDataToCache, "wDd", desc="Write dirty data to cache") { 1528 peek(L1requestNetwork_in, RequestMsg) { 1529 assert(is_valid(cache_entry)); 1530 cache_entry.DataBlk := in_msg.DataBlk; 1531 DPRINTF(RubySlicc, "Address: %#x, Data Block: %s\n", 1532 address, cache_entry.DataBlk); 1533 cache_entry.Dirty := true; 1534 } 1535 } 1536 1537 action(vv_allocateL2CacheBlock, "\v", desc="Set L2 cache tag equal to tag of block B.") { 1538 set_cache_entry(L2cache.allocate(address, new Entry)); 1539 } 1540 1541 action(rr_deallocateL2CacheBlock, "\r", desc="Deallocate L2 cache block. Sets the cache to not present, allowing a replacement in parallel with a fetch.") { 1542 L2cache.deallocate(address); 1543 unset_cache_entry(); 1544 } 1545 1546 action(uu_profileMiss, "\um", desc="Profile the demand miss") { 1547 ++L2cache.demand_misses; 1548 } 1549 1550 action(uu_profileHit, "\uh", desc="Profile the demand hit") { 1551 ++L2cache.demand_hits; 1552 } 1553 1554 action(y_copyCacheStateToDir, "y", desc="Copy cache state to directory state") { 1555 copyCacheStateToDir(cache_entry, address); 1556 } 1557 1558 action(y_copyDirToCacheAndRemove, "/y", desc="Copy dir state to cache and remove") { 1559 copyDirToCache(cache_entry, address); 1560 localDirectory.deallocate(address); 1561 } 1562 1563 action(zz_recycleGlobalRequestQueue, "\zglb", desc="Send the head of the mandatory queue to the back of the queue.") { 1564 peek(requestNetwork_in, RequestMsg) { 1565 APPEND_TRANSITION_COMMENT(in_msg.Requestor); 1566 } 1567 requestNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency)); 1568 } 1569 1570 action(zz_recycleL1RequestQueue, "\zl1", desc="Send the head of the mandatory queue to the back of the queue.") { 1571 peek(L1requestNetwork_in, RequestMsg) { 1572 APPEND_TRANSITION_COMMENT(in_msg.Requestor); 1573 } 1574 L1requestNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency)); 1575 } 1576 1577 action(st_stallAndWaitL1RequestQueue, "st", desc="Stall and wait on the address") { 1578 stall_and_wait(L1requestNetwork_in, address); 1579 } 1580 1581 action(wa_wakeUpDependents, "wa", desc="Wake up any requests waiting for this address") { 1582 wakeUpAllBuffers(address); 1583 } 1584 1585 action(da_sendDmaAckUnblock, "da", desc="Send dma ack to global directory") { 1586 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 1587 out_msg.addr := address; 1588 out_msg.Type := CoherenceResponseType:DMA_ACK; 1589 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 1590 out_msg.Sender := machineID; 1591 out_msg.SenderMachine := MachineType:L2Cache; 1592 out_msg.MessageSize := MessageSizeType:Unblock_Control; 1593 } 1594 } 1595 1596 1597 1598 //***************************************************** 1599 // TRANSITIONS 1600 //***************************************************** 1601 1602 transition({II, IFGX, IFGS, ISFGS, IFGXX, IFLXO, ILOW, ILOXW, ILOSW, ILOSXW, SLSW, OLSW, ILSW, IW, OW, SW, OXW, OLSXW, ILXW, IFLS, IFLO, IFLOX, IFLOXX, IFLOSX, OLSXS, IGS, IGM, IGMLS, IGMO, IGMIO, OGMIO, IGMIOF, OGMIOF, MM, SS, OO, OI, MI, MII, OLSI, ILSI, SLSS, OLSS, OLSF, IGMIOFS, ILOSD, ILOSXD, ILOD, ILXD, ILOXD}, {L1_PUTO, L1_PUTS, L1_PUTS_only, L1_PUTX}) { 1603 st_stallAndWaitL1RequestQueue; 1604 } 1605 1606 transition({II, IFGX, IFGS, ISFGS, IFGXX, IFLXO, ILOW, ILOXW, ILOSW, ILOSXW, SLSW, OLSW, ILSW, IW, OW, SW, OXW, OLSXW, ILXW, IFLS, IFLO, IFLOX, IFLOXX, IFLOSX, OLSXS, IGS, IGM, IGMLS, IGMO, IGMIO, OGMIO, IGMIOF, OGMIOF, MM, SS, OO, OI, MI, MII, OLSI, ILSI, SLSS, OLSS, OLSF, IGMIOFS, ILOSD, ILOSXD, ILOD, ILXD, ILOXD}, {L1_GETX, L1_GETS}) { 1607 st_stallAndWaitL1RequestQueue; 1608 } 1609 1610 transition({IFGX, IFGS, ISFGS, IFGXX, IFLXO, ILOW, ILOXW, ILOSW, ILOSXW, SLSW, OLSW, ILSW, IW, ILXW, OW, SW, OXW, OLSXW, IFLS, IFLO, IFLOX, IFLOXX, IFLOSX,OLSXS, IGS, IGM, IGMLS, IGMO, MM, SS, OO, OI, MI, MII, OLSI, ILSI, SLSS, OLSS, OLSF, IGMIOFS, ILOSD, ILOSXD, ILOD, ILXD, ILOXD}, L2_Replacement) { 1611 zz_recycleL1RequestQueue; 1612 } 1613 1614 transition({IFGX, IFGS, ISFGS, IFGXX, IFLXO, ILOW, ILOXW, ILOSW, ILOSXW, SLSW, OLSW, ILSW, IW, OW, SW, OXW, OLSXW, ILXW, IFLS, IFLO, IFLOX, IFLOXX, IFLOSX,OLSXS, IGS, IGM, MM, SS, OO, SLSS, OLSS, OLSF, IGMIOFS, ILOSD, ILOSXD, ILOD, ILXD, ILOXD}, {Fwd_GETX, Fwd_GETS, Fwd_DMA}) { 1615 zz_recycleGlobalRequestQueue; 1616 } 1617 1618 transition({OGMIO, IGMIO, IGMO}, Fwd_DMA) { 1619 zz_recycleGlobalRequestQueue; 1620 } 1621 1622 transition({IFGX, IFGS, ISFGS, IFGXX, IFLXO, ILOW, ILOXW, ILOSW, ILOSXW, SLSW, OLSW, ILSW, IW, OW, SW, OXW, OLSXW, ILXW, IFLS, IFLO, IFLOX, IFLOXX, IFLOSX,OLSXS, MM, SS, OO, SLSS, OLSS, OLSF, IGMIOFS, ILOSD, ILOSXD, ILOD, ILXD, ILOXD}, {Inv}) { 1623 zz_recycleGlobalRequestQueue; 1624 } 1625 1626 transition({IGM, IGS, ILOSD, ILOSXD, ILOD, ILXD, ILOXD}, {Own_GETX}) { 1627 zz_recycleGlobalRequestQueue; 1628 } 1629 1630 // must happened because we forwarded GETX to local exclusive trying to do wb 1631 transition({I, M, O, ILS, ILOX, OLS, OLSX, SLS, S}, L1_PUTX) { 1632 ll_writebackNack; 1633 o_popL1RequestQueue; 1634 } 1635 1636 transition({M}, {L1_PUTS, L1_PUTO} ) { 1637 ll_writebackNack; 1638 o_popL1RequestQueue; 1639 } 1640 1641 transition({ILS, OLSX}, L1_PUTO){ 1642 ll_writebackNack; 1643 o_popL1RequestQueue; 1644 } 1645 1646// happened if we forwarded GETS to exclusive who tried to do writeback 1647// ?? should we just Nack these instead? Could be a bugs here 1648 transition(ILO, L1_PUTX, ILOW) { 1649 l_writebackAckNeedData; 1650 o_popL1RequestQueue; 1651 } 1652 1653 // this can happen if we forwarded a L1_GETX to exclusiver after it issued a PUTX 1654 transition(ILOS, L1_PUTX, ILOSW) { 1655 l_writebackAckNeedData; 1656 o_popL1RequestQueue; 1657 } 1658 1659 transition(ILOSX, L1_PUTX, ILOSXW) { 1660 l_writebackAckNeedData; 1661 o_popL1RequestQueue; 1662 } 1663 1664 // must happened because we got Inv when L1 attempted PUTS 1665 transition(I, L1_PUTS) { 1666 ll_writebackNack; 1667 o_popL1RequestQueue; 1668 } 1669 1670 transition(I, L1_PUTO) { 1671 ll_writebackNack; 1672 o_popL1RequestQueue; 1673 } 1674 1675 // FORWARDED REQUESTS 1676 1677 transition({ILO, ILX, ILOX}, Fwd_GETS, IFGS) { 1678 i_allocateTBE; 1679 t_recordFwdSID; 1680 j_forwardGlobalRequestToLocalOwner; 1681 m_popRequestQueue; 1682 } 1683 1684 transition({ILOS, ILOSX}, Fwd_GETS, ISFGS) { 1685 i_allocateTBE; 1686 t_recordFwdSID; 1687 j_forwardGlobalRequestToLocalOwner; 1688 m_popRequestQueue; 1689 } 1690 1691 transition(ILOS, Fwd_DMA, ILOSD) { 1692 i_allocateTBE; 1693 jd_forwardDmaRequestToLocalOwner; 1694 m_popRequestQueue; 1695 } 1696 1697 transition(ILOSD, DmaAck, ILOS) { 1698 s_deallocateTBE; 1699 da_sendDmaAckUnblock; 1700 n_popResponseQueue; 1701 wa_wakeUpDependents; 1702 } 1703 1704 transition(ILOSX, Fwd_DMA, ILOSXD) { 1705 i_allocateTBE; 1706 t_recordFwdSID; 1707 jd_forwardDmaRequestToLocalOwner; 1708 m_popRequestQueue; 1709 } 1710 1711 transition(ILOSXD, DmaAck, ILOSX) { 1712 s_deallocateTBE; 1713 da_sendDmaAckUnblock; 1714 n_popResponseQueue; 1715 wa_wakeUpDependents; 1716 } 1717 1718 transition(ILO, Fwd_DMA, ILOD) { 1719 i_allocateTBE; 1720 t_recordFwdSID; 1721 jd_forwardDmaRequestToLocalOwner; 1722 m_popRequestQueue; 1723 } 1724 1725 transition(ILOD, DmaAck, ILO) { 1726 s_deallocateTBE; 1727 da_sendDmaAckUnblock; 1728 n_popResponseQueue; 1729 wa_wakeUpDependents; 1730 } 1731 1732 transition(ILX, Fwd_DMA, ILXD) { 1733 i_allocateTBE; 1734 t_recordFwdSID; 1735 jd_forwardDmaRequestToLocalOwner; 1736 m_popRequestQueue; 1737 } 1738 1739 transition(ILXD, DmaAck, ILX) { 1740 s_deallocateTBE; 1741 da_sendDmaAckUnblock; 1742 n_popResponseQueue; 1743 wa_wakeUpDependents; 1744 } 1745 1746 transition(ILOX, Fwd_DMA, ILOXD) { 1747 i_allocateTBE; 1748 t_recordFwdSID; 1749 jd_forwardDmaRequestToLocalOwner; 1750 m_popRequestQueue; 1751 } 1752 1753 transition(ILOXD, DmaAck, ILOX) { 1754 s_deallocateTBE; 1755 da_sendDmaAckUnblock; 1756 n_popResponseQueue; 1757 wa_wakeUpDependents; 1758 } 1759 1760 transition({ILOS, ILOSX, ILO, ILX, ILOX, ILXW}, Data) { 1761 i_copyDataToTBE; 1762 c_sendDataFromTBEToFwdGETS; 1763 s_deallocateTBE; 1764 n_popResponseQueue; 1765 } 1766 1767 transition(IFGS, Data, ILO) { 1768 i_copyDataToTBE; 1769 c_sendDataFromTBEToFwdGETS; 1770 s_deallocateTBE; 1771 n_popResponseQueue; 1772 wa_wakeUpDependents; 1773 } 1774 1775 transition(ISFGS, Data, ILOS) { 1776 i_copyDataToTBE; 1777 c_sendDataFromTBEToFwdGETS; 1778 s_deallocateTBE; 1779 n_popResponseQueue; 1780 wa_wakeUpDependents; 1781 } 1782 1783 transition(IFGS, Data_Exclusive, I) { 1784 i_copyDataToTBE; 1785 c_sendExclusiveDataFromTBEToFwdGETS; 1786 gg_clearLocalSharers; 1787 s_deallocateTBE; 1788 n_popResponseQueue; 1789 wa_wakeUpDependents; 1790 } 1791 1792 1793 transition({ILX, ILO, ILOX}, Fwd_GETX, IFGX) { 1794 i_allocateTBE; 1795 t_recordFwdXID; 1796 j_forwardGlobalRequestToLocalOwner; 1797 m_popRequestQueue; 1798 } 1799 1800 transition(IFGX, {Data_Exclusive, Data}, I) { 1801 i_copyDataToTBE; 1802 c_sendDataFromTBEToFwdGETX; 1803 gg_clearLocalSharers; 1804 s_deallocateTBE; 1805 n_popResponseQueue; 1806 wa_wakeUpDependents; 1807 } 1808 1809 transition({ILOSX, ILOS}, Fwd_GETX, IFGXX) { 1810 i_allocateTBE; 1811 t_recordFwdXID; 1812 j_forwardGlobalRequestToLocalOwner; 1813 ee_sendLocalInvSharersOnly; 1814 ee_addLocalIntAck; 1815 m_popRequestQueue; 1816 } 1817 1818 1819 transition(IFGXX, IntAck) { 1820 m_decrementNumberOfMessagesInt; 1821 o_checkForIntCompletion; 1822 n_popResponseQueue; 1823 } 1824 1825 transition(IFGXX, Data_Exclusive) { 1826 i_copyDataToTBE; 1827 m_decrementNumberOfMessagesInt; 1828 o_checkForIntCompletion; 1829 n_popResponseQueue; 1830 } 1831 1832 transition(IFGXX, All_Acks, I) { 1833 c_sendDataFromTBEToFwdGETX; 1834 gg_clearLocalSharers; 1835 s_deallocateTBE; 1836 n_popTriggerQueue; 1837 wa_wakeUpDependents; 1838 } 1839 1840 1841 // transition({O, OX}, Fwd_GETX, I) { 1842 transition(O, Fwd_GETX, I) { 1843 dd_sendDataToFwdGETX; 1844 y_copyCacheStateToDir; 1845 rr_deallocateL2CacheBlock; 1846 m_popRequestQueue; 1847 } 1848 1849 transition({O, OLS}, Fwd_GETS) { 1850 dd_sendDataToFwdGETS; 1851 m_popRequestQueue; 1852 } 1853 1854 transition({O, OLS}, Fwd_DMA) { 1855 dd_sendDataToFwdGETS; 1856 da_sendDmaAckUnblock; 1857 m_popRequestQueue; 1858 } 1859 1860 // transition({OLSX, OX}, Fwd_GETS, O) { 1861 transition(OLSX, Fwd_GETS, OLS) { 1862 dd_sendDataToFwdGETS; 1863 m_popRequestQueue; 1864 } 1865 1866 transition(OLSX, Fwd_DMA) { 1867 dd_sendDataToFwdGETS; 1868 da_sendDmaAckUnblock; 1869 m_popRequestQueue; 1870 } 1871 1872 transition(M, Fwd_GETX, I) { 1873 dd_sendDataToFwdGETX; 1874 rr_deallocateL2CacheBlock; 1875 m_popRequestQueue; 1876 } 1877 1878 // MAKE THIS THE SAME POLICY FOR NOW 1879 1880 // transition(M, Fwd_GETS, O) { 1881 // dd_sendDataToFwdGETS; 1882 // m_popRequestQueue; 1883 // } 1884 1885 transition(M, Fwd_GETS, I) { 1886 dd_sendExclusiveDataToFwdGETS; 1887 rr_deallocateL2CacheBlock; 1888 m_popRequestQueue; 1889 } 1890 1891 transition(M, Fwd_DMA) { 1892 dd_sendExclusiveDataToFwdGETS; 1893 da_sendDmaAckUnblock; 1894 m_popRequestQueue; 1895 } 1896 1897 transition({OLS, OLSX}, Fwd_GETX, OLSF) { 1898 i_allocateTBE; 1899 t_recordFwdXID; 1900 ee_sendLocalInv; 1901 m_popRequestQueue; 1902 } 1903 1904 transition(OLSF, IntAck) { 1905 m_decrementNumberOfMessagesInt; 1906 o_checkForIntCompletion; 1907 n_popResponseQueue; 1908 } 1909 1910 transition(OLSF, All_Acks, I) { 1911 c_sendDataFromTBEToFwdGETX; 1912 gg_clearLocalSharers; 1913 s_deallocateTBE; 1914 rr_deallocateL2CacheBlock; 1915 n_popTriggerQueue; 1916 wa_wakeUpDependents; 1917 } 1918 1919 1920 1921 // INVALIDATIONS FROM GLOBAL DIRECTORY 1922 1923 transition({IGM, IGS}, Inv) { 1924 t_recordFwdXID; 1925 e_sendAck; 1926 m_popRequestQueue; 1927 } 1928 1929 transition({I,NP}, Inv) { 1930 i_allocateTBE; 1931 t_recordFwdXID; 1932 e_sendAck; 1933 s_deallocateTBE; 1934 m_popRequestQueue; 1935 } 1936 1937 // NEED INV for S state 1938 1939 transition({ILS, ILO, ILX}, Inv, II) { 1940 i_allocateTBE; 1941 t_recordFwdXID; 1942 ee_sendLocalInv; 1943 gg_clearLocalSharers; 1944 m_popRequestQueue; 1945 } 1946 1947 transition(SLS, Inv, II) { 1948 i_allocateTBE; 1949 t_recordFwdXID; 1950 ee_sendLocalInv; 1951 rr_deallocateL2CacheBlock; 1952 m_popRequestQueue; 1953 } 1954 1955 transition(II, IntAck) { 1956 m_decrementNumberOfMessagesInt; 1957 o_checkForIntCompletion; 1958 n_popResponseQueue; 1959 } 1960 1961 transition(II, All_Acks, I) { 1962 e_sendAck; 1963 s_deallocateTBE; 1964 n_popTriggerQueue; 1965 wa_wakeUpDependents; 1966 } 1967 1968 transition(S, Inv, I) { 1969 i_allocateTBE; 1970 t_recordFwdXID; 1971 e_sendAck; 1972 s_deallocateTBE; 1973 rr_deallocateL2CacheBlock; 1974 m_popRequestQueue; 1975 } 1976 1977 1978 // LOCAL REQUESTS SATISFIED LOCALLY 1979 1980 transition(OLSX, L1_GETX, IFLOX) { 1981 i_allocateTBE; 1982 s_recordGetXL1ID; 1983 // count number of INVs needed that doesn't include requestor 1984 h_countLocalSharersExceptRequestor; 1985 // issue INVs to everyone except requestor 1986 ee_issueLocalInvExceptL1Requestor; 1987 d_sendDataToL1GETX 1988 y_copyCacheStateToDir; 1989 r_setMRU; 1990 rr_deallocateL2CacheBlock; 1991 uu_profileHit; 1992 o_popL1RequestQueue; 1993 } 1994 1995 transition(IFLOX, Exclusive_Unblock, ILX) { 1996 g_recordLocalExclusive; 1997 s_deallocateTBE; 1998 n_popResponseQueue; 1999 wa_wakeUpDependents; 2000 } 2001 2002 transition(OLSX, L1_GETS, OLSXS) { 2003 d_sendDataToL1GETS; 2004 r_setMRU; 2005 uu_profileHit; 2006 o_popL1RequestQueue; 2007 } 2008 2009 transition(OLSXS, Unblock, OLSX) { 2010 g_recordLocalSharer; 2011 n_popResponseQueue; 2012 wa_wakeUpDependents; 2013 } 2014 2015 // after this, can't get Fwd_GETX 2016 transition(IGMO, Own_GETX) { 2017 mm_decrementNumberOfMessagesExt; 2018 o_checkForExtCompletion; 2019 m_popRequestQueue; 2020 2021 } 2022 2023 2024 transition(ILX, L1_GETS, IFLOXX) { 2025 kk_forwardLocalGETSToLocalOwner; 2026 uu_profileMiss; 2027 o_popL1RequestQueue; 2028 } 2029 2030 transition(ILOSX, L1_GETS, IFLOSX) { 2031 kk_forwardLocalGETSToLocalOwner; 2032 uu_profileMiss; 2033 o_popL1RequestQueue; 2034 } 2035 2036 transition({ILOS, ILO}, L1_GETS, IFLO) { 2037 kk_forwardLocalGETSToLocalOwner; 2038 uu_profileMiss; 2039 o_popL1RequestQueue; 2040 } 2041 2042 transition(ILS, L1_GETS, IFLS) { 2043 k_forwardLocalGETSToLocalSharer; 2044 uu_profileMiss; 2045 o_popL1RequestQueue; 2046 } 2047 2048 transition({ILX, ILOX}, L1_GETX, IFLOXX) { 2049 kk_forwardLocalGETXToLocalExclusive; 2050 e_sendAckToL1Requestor; 2051 uu_profileMiss; 2052 o_popL1RequestQueue; 2053 } 2054 2055 transition(ILOX, L1_GETS, IFLOX) { 2056 kk_forwardLocalGETSToLocalOwner; 2057 uu_profileMiss; 2058 o_popL1RequestQueue; 2059 } 2060 2061 transition(IFLOX, Unblock, ILOSX) { 2062 g_recordLocalSharer; 2063 n_popResponseQueue; 2064 wa_wakeUpDependents; 2065 } 2066 2067 transition(IFLS, Unblock, ILS) { 2068 g_recordLocalSharer; 2069 n_popResponseQueue; 2070 wa_wakeUpDependents; 2071 } 2072 2073 transition(IFLOXX, Unblock, ILOSX) { 2074 g_recordLocalSharer; 2075 n_popResponseQueue; 2076 wa_wakeUpDependents; 2077 } 2078 2079 transition(IFLOSX, Unblock, ILOSX) { 2080 g_recordLocalSharer; 2081 n_popResponseQueue; 2082 wa_wakeUpDependents; 2083 } 2084 2085 transition({IFLOSX, IFLOXX}, Exclusive_Unblock, ILX) { 2086 g_recordLocalExclusive; 2087 n_popResponseQueue; 2088 wa_wakeUpDependents; 2089 } 2090 2091 transition(IFLO, Unblock, ILOS) { 2092 g_recordLocalSharer; 2093 n_popResponseQueue; 2094 wa_wakeUpDependents; 2095 } 2096 2097 2098 transition(ILOSX, L1_GETX, IFLXO) { 2099 i_allocateTBE; 2100 s_recordGetXL1ID; 2101 h_countLocalSharersExceptRequestor; 2102 ee_issueLocalInvExceptL1Requestor; 2103 k_forwardLocalGETXToLocalOwner; 2104 e_sendAckToL1RequestorFromTBE; 2105 uu_profileMiss; 2106 o_popL1RequestQueue; 2107 } 2108 2109 transition(IFLXO, Exclusive_Unblock, ILX) { 2110 g_recordLocalExclusive; 2111 s_deallocateTBE; 2112 n_popResponseQueue; 2113 wa_wakeUpDependents; 2114 } 2115 2116 // LOCAL REQUESTS THAT MUST ISSUE 2117 2118 transition(NP, {L1_PUTS, L1_PUTX, L1_PUTO}) { 2119 ll_writebackNack; 2120 o_popL1RequestQueue; 2121 } 2122 2123 transition({NP, I}, L1_GETS, IGS) { 2124 i_allocateTBE; 2125 s_recordGetSL1ID; 2126 a_issueGETS; 2127 uu_profileMiss; 2128 o_popL1RequestQueue; 2129 } 2130 2131 transition({NP, I}, L1_GETX, IGM) { 2132 i_allocateTBE; 2133 s_recordGetXL1ID; 2134 a_issueGETX; 2135 uu_profileMiss; 2136 o_popL1RequestQueue; 2137 } 2138 2139 transition(S, L1_GETX, IGM) { 2140 i_allocateTBE; 2141 s_recordGetXL1ID; 2142 a_issueGETX; 2143 y_copyCacheStateToDir; 2144 r_setMRU; 2145 rr_deallocateL2CacheBlock; 2146 uu_profileMiss; 2147 o_popL1RequestQueue; 2148 } 2149 2150 transition(ILS, L1_GETX, IGMLS) { 2151 i_allocateTBE; 2152 s_recordGetXL1ID; 2153 a_issueGETX; 2154 // count number of INVs (just sharers?) needed that doesn't include requestor 2155 h_countLocalSharersExceptRequestor; 2156 uu_profileMiss; 2157 o_popL1RequestQueue; 2158 } 2159 2160 transition(IGMLS, Inv) { 2161 t_recordFwdXID; 2162 ee_sendLocalInv; 2163 m_popRequestQueue; 2164 } 2165 2166 transition(IGMLS, IntAck) { 2167 m_decrementNumberOfMessagesInt; 2168 o_checkForIntCompletion; 2169 n_popResponseQueue; 2170 } 2171 2172 transition(IGMLS, All_Acks, IGM) { 2173 gg_clearLocalSharers; 2174 h_clearIntAcks; 2175 e_sendAck; 2176 n_popTriggerQueue; 2177 } 2178 2179 // transition(IGMLS, ExtAck, IGMO) { 2180 transition(IGMLS, ExtAck) { 2181 m_decrementNumberOfMessagesExt; 2182 o_checkForExtCompletion; 2183 n_popResponseQueue; 2184 } 2185 2186 transition(IGMLS, {Data, Data_Exclusive}, IGMO) { 2187 ee_issueLocalInvExceptL1RequestorInTBE; 2188 i_copyDataToTBE; 2189 m_decrementNumberOfMessagesExt; 2190 o_checkForExtCompletion; 2191 n_popResponseQueue; 2192 } 2193 2194 2195 transition(ILOS, L1_GETX, IGMIO) { 2196 i_allocateTBE; 2197 s_recordGetXL1ID; 2198 a_issueGETX; 2199 uu_profileMiss; 2200 o_popL1RequestQueue; 2201 } 2202 2203 // new exclusive happened while sharer attempted writeback 2204 transition(ILX, {L1_PUTS, L1_PUTS_only, L1_PUTO}) { 2205 ll_writebackNack; 2206 o_popL1RequestQueue; 2207 } 2208 2209 transition(S, L1_PUTS) { 2210 ll_writebackNack; 2211 o_popL1RequestQueue; 2212 } 2213 2214 transition(OLS, L1_GETX, OGMIO) { 2215 i_allocateTBE; 2216 s_recordGetXL1ID; 2217 a_issueGETX; 2218 h_countLocalSharersExceptRequestor; 2219 // COPY DATA FROM CACHE TO TBE (happens during i_allocateTBE) 2220 y_copyCacheStateToDir; 2221 rr_deallocateL2CacheBlock; 2222 uu_profileMiss; 2223 o_popL1RequestQueue; 2224 } 2225 2226 transition(OGMIO, Fwd_GETS) { 2227 t_recordFwdSID; 2228 c_sendDataFromTBEToFwdGETS; 2229 m_popRequestQueue; 2230 } 2231 2232 transition(ILO, L1_GETX, IGMIO) { 2233 i_allocateTBE; 2234 s_recordGetXL1ID; 2235 a_issueGETX; 2236 // the following, of course, returns 0 sharers but do anyways for consistency 2237 h_countLocalSharersExceptRequestor; 2238 uu_profileMiss; 2239 o_popL1RequestQueue; 2240 } 2241 2242 transition({ILO, ILOX}, L1_PUTS) { 2243 ll_writebackNack; 2244 o_popL1RequestQueue; 2245 } 2246 2247 transition(IGMIO, Fwd_GETX, IGMIOF) { 2248 t_recordFwdXID; 2249 j_forwardGlobalRequestToLocalOwner; 2250 ee_sendLocalInvSharersOnly; 2251 ee_addLocalIntAck; 2252 m_popRequestQueue; 2253 } 2254 2255 transition(IGMIO, Fwd_GETS, IGMIOFS) { 2256 t_recordFwdSID; 2257 j_forwardGlobalRequestToLocalOwner; 2258 m_popRequestQueue; 2259 } 2260 2261 transition(IGMIOFS, Data, IGMIO) { 2262 i_copyDataToTBE; 2263 c_sendDataFromTBEToFwdGETS; 2264 n_popResponseQueue; 2265 } 2266 2267 transition(OGMIO, Fwd_GETX, OGMIOF) { 2268 t_recordFwdXID; 2269 ee_sendLocalInvSharersOnly; 2270 m_popRequestQueue; 2271 } 2272 2273 transition(OGMIOF, IntAck) { 2274 m_decrementNumberOfMessagesInt; 2275 o_checkForIntCompletion; 2276 n_popResponseQueue; 2277 } 2278 2279 transition(OGMIOF, All_Acks, IGM) { 2280 gg_clearLocalSharers; 2281 hh_countLocalSharersExceptL1GETXRequestorInTBE; 2282 c_sendDataFromTBEToFwdGETX; 2283 n_popTriggerQueue; 2284 } 2285 2286 transition(IGMIOF, IntAck) { 2287 m_decrementNumberOfMessagesInt; 2288 o_checkForIntCompletion; 2289 n_popResponseQueue; 2290 } 2291 2292 transition(IGMIOF, Data_Exclusive) { 2293 i_copyDataToTBE; 2294 m_decrementNumberOfMessagesInt; 2295 o_checkForIntCompletion; 2296 n_popResponseQueue; 2297 } 2298 2299 transition(IGMIOF, All_Acks, IGM) { 2300 gg_clearLocalSharers; 2301 c_sendDataFromTBEToFwdGETX; 2302 n_popTriggerQueue; 2303 } 2304 2305 transition(IGMIO, All_Acks, IGMO) { 2306 hh_countLocalSharersExceptL1GETXRequestorInTBE; 2307 ee_issueLocalInvExceptL1RequestorInTBE; 2308 k_forwardLocalGETXToLocalOwner; 2309 e_sendAckToL1RequestorFromTBE; 2310 n_popTriggerQueue; 2311 } 2312 2313 transition(OGMIO, All_Acks, IGMO) { 2314 ee_issueLocalInvExceptL1RequestorInTBE; 2315 c_sendDataFromTBEToL1GETX; 2316 n_popTriggerQueue; 2317 } 2318 2319 transition({IGMIO, OGMIO}, Own_GETX) { 2320 mm_decrementNumberOfMessagesExt; 2321 o_checkForExtCompletion; 2322 m_popRequestQueue; 2323 2324 } 2325 2326 transition(IGM, {Data, Data_Exclusive}, IGMO) { 2327 i_copyDataToTBE; 2328 m_decrementNumberOfMessagesExt; 2329 o_checkForExtCompletion; 2330 n_popResponseQueue; 2331 } 2332 2333 transition({IGM, IGMIO, OGMIO}, ExtAck) { 2334 m_decrementNumberOfMessagesExt; 2335 o_checkForExtCompletion; 2336 n_popResponseQueue; 2337 } 2338 2339 transition(IGMO, ExtAck) { 2340 m_decrementNumberOfMessagesExt; 2341 o_checkForExtCompletion; 2342 n_popResponseQueue; 2343 } 2344 2345 transition(IGS, Data) { 2346 i_copyDataToTBE; 2347 m_decrementNumberOfMessagesExt; 2348 c_sendDataFromTBEToL1GETS; 2349 n_popResponseQueue; 2350 } 2351 2352 transition(IGS, Data_Exclusive) { 2353 i_copyDataToTBE; 2354 m_decrementNumberOfMessagesExt; 2355 c_sendExclusiveDataFromTBEToL1GETS; 2356 n_popResponseQueue; 2357 } 2358 2359 transition(IGS, Unblock, ILS) { 2360 g_recordLocalSharer; 2361 f_sendUnblock; 2362 s_deallocateTBE; 2363 n_popResponseQueue; 2364 wa_wakeUpDependents; 2365 } 2366 2367 transition(IGS, Exclusive_Unblock, ILX) { 2368 g_recordLocalExclusive; 2369 f_sendExclusiveUnblock; 2370 s_deallocateTBE; 2371 n_popResponseQueue; 2372 wa_wakeUpDependents; 2373 } 2374 2375 transition(IGMO, All_Acks) { 2376 c_sendDataFromTBEToL1GETX; 2377 n_popTriggerQueue; 2378 } 2379 2380 transition(IGMO, Exclusive_Unblock, ILX) { 2381 g_recordLocalExclusive; 2382 f_sendExclusiveUnblock; 2383 s_deallocateTBE; 2384 n_popResponseQueue; 2385 wa_wakeUpDependents; 2386 } 2387 2388 2389 transition(SLS, L1_GETX, IGMLS) { 2390 i_allocateTBE; 2391 s_recordGetXL1ID; 2392 a_issueGETX; 2393 // count number of INVs needed that doesn't include requestor 2394 h_countLocalSharersExceptRequestor; 2395 // issue INVs to everyone except requestor 2396 y_copyCacheStateToDir; 2397 rr_deallocateL2CacheBlock; 2398 uu_profileMiss; 2399 o_popL1RequestQueue; 2400 2401 } 2402 2403 transition(SLS, L1_GETS, SLSS ) { 2404 d_sendDataToL1GETS; 2405 r_setMRU; 2406 uu_profileHit; 2407 o_popL1RequestQueue; 2408 } 2409 2410 transition(SLSS, Unblock, SLS) { 2411 g_recordLocalSharer; 2412 n_popResponseQueue; 2413 wa_wakeUpDependents; 2414 } 2415 2416 2417 transition(O, L1_GETX, IGMO) { 2418 i_allocateTBE; 2419 s_recordGetXL1ID; 2420 a_issueGETX; 2421 y_copyCacheStateToDir; 2422 rr_deallocateL2CacheBlock; 2423 uu_profileMiss; 2424 o_popL1RequestQueue; 2425 } 2426 2427 transition(OLS, L1_GETS, OLSS) { 2428 d_sendDataToL1GETS; 2429 r_setMRU; 2430 uu_profileHit; 2431 o_popL1RequestQueue; 2432 } 2433 2434 transition(OLSS, Unblock, OLS) { 2435 g_recordLocalSharer; 2436 n_popResponseQueue; 2437 wa_wakeUpDependents; 2438 } 2439 2440 transition(IGMO, Fwd_GETX, IGM) { 2441 t_recordFwdXID; 2442 c_sendDataFromTBEToFwdGETX; 2443 m_popRequestQueue; 2444 2445 } 2446 2447 transition(IGMO, Fwd_GETS) { 2448 t_recordFwdSID; 2449 c_sendDataFromTBEToFwdGETS; 2450 m_popRequestQueue; 2451 } 2452 2453 2454 // LOCAL REQUESTS SATISFIED DIRECTLY BY L2 2455 2456 transition(M, L1_GETX, MM) { 2457 i_allocateTBE; 2458 // should count 0 of course 2459 h_countLocalSharersExceptRequestor; 2460 d_sendDataToL1GETX; 2461 y_copyCacheStateToDir; 2462 rr_deallocateL2CacheBlock; 2463 s_deallocateTBE; 2464 uu_profileHit; 2465 o_popL1RequestQueue; 2466 } 2467 2468 transition(MM, Exclusive_Unblock, ILX) { 2469 g_recordLocalExclusive; 2470 n_popResponseQueue; 2471 wa_wakeUpDependents; 2472 } 2473 2474 transition(M, L1_GETS, OO) { 2475 i_allocateTBE; 2476 // should count 0 of course 2477 h_countLocalSharersExceptRequestor; 2478 d_sendDataToL1GETX; 2479 r_setMRU; 2480 s_deallocateTBE; 2481 uu_profileHit; 2482 o_popL1RequestQueue; 2483 } 2484 2485 transition(S, L1_GETS, SS) { 2486 d_sendDataToL1GETS; 2487 r_setMRU; 2488 uu_profileHit; 2489 o_popL1RequestQueue; 2490 } 2491 2492 transition(SS, Unblock, SLS) { 2493 g_recordLocalSharer; 2494 n_popResponseQueue; 2495 wa_wakeUpDependents; 2496 } 2497 2498 transition(O, L1_GETS, OO) { 2499 d_sendDataToL1GETS; 2500 r_setMRU; 2501 uu_profileHit; 2502 o_popL1RequestQueue; 2503 } 2504 2505 transition(OO, Unblock, OLS) { 2506 g_recordLocalSharer; 2507 n_popResponseQueue; 2508 wa_wakeUpDependents; 2509 } 2510 2511 transition(OO, Exclusive_Unblock, ILX) { 2512 g_recordLocalExclusive 2513 y_copyCacheStateToDir; 2514 rr_deallocateL2CacheBlock; 2515 n_popResponseQueue; 2516 wa_wakeUpDependents; 2517 } 2518 2519 2520 // L1 WRITEBACKS 2521 transition(ILO, L1_PUTO, ILOW) { 2522 l_writebackAckNeedData; 2523 o_popL1RequestQueue; 2524 } 2525 2526 transition(ILOX, L1_PUTO, ILOXW) { 2527 l_writebackAckNeedData; 2528 o_popL1RequestQueue; 2529 } 2530 2531 2532 transition(ILOS, L1_PUTO, ILOSW) { 2533 l_writebackAckNeedData; 2534 o_popL1RequestQueue; 2535 } 2536 2537 transition(ILOSX, L1_PUTO, ILOSXW) { 2538 l_writebackAckNeedData; 2539 o_popL1RequestQueue; 2540 } 2541 2542 2543 // hmmm...keep data or drop. Just drop for now 2544 transition(ILOS, L1_PUTS_only, ILOW) { 2545 l_writebackAckDropData; 2546 o_popL1RequestQueue; 2547 } 2548 2549 transition(ILSW, Unblock, ILS) { 2550 gg_clearSharerFromL1Response; 2551 n_popResponseQueue; 2552 wa_wakeUpDependents; 2553 } 2554 2555 transition(ILOW, Unblock, ILO) { 2556 gg_clearSharerFromL1Response; 2557 n_popResponseQueue; 2558 wa_wakeUpDependents; 2559 } 2560 2561 transition(ILOSX, L1_PUTS_only, ILOXW) { 2562 l_writebackAckDropData; 2563 o_popL1RequestQueue; 2564 } 2565 2566 transition(ILOXW, Unblock, ILOX) { 2567 gg_clearSharerFromL1Response; 2568 n_popResponseQueue; 2569 wa_wakeUpDependents; 2570 } 2571 2572 // hmmm...keep data or drop. Just drop for now 2573 transition(ILOS, L1_PUTS, ILOSW) { 2574 l_writebackAckDropData; 2575 o_popL1RequestQueue; 2576 } 2577 2578 transition(ILOSX, L1_PUTS, ILOSXW) { 2579 l_writebackAckDropData; 2580 o_popL1RequestQueue; 2581 } 2582 2583 transition(ILOSW, Unblock, ILOS) { 2584 gg_clearSharerFromL1Response; 2585 n_popResponseQueue; 2586 wa_wakeUpDependents; 2587 } 2588 2589 transition(ILOSXW, Unblock, ILOSX) { 2590 gg_clearSharerFromL1Response; 2591 n_popResponseQueue; 2592 wa_wakeUpDependents; 2593 } 2594 2595 transition(SLS, L1_PUTS, SLSW) { 2596 l_writebackAckDropData; 2597 o_popL1RequestQueue; 2598 } 2599 2600 transition(SLS, L1_PUTS_only, SW) { 2601 l_writebackAckDropData; 2602 o_popL1RequestQueue; 2603 } 2604 2605 transition(SW, {Unblock}, S) { 2606 gg_clearSharerFromL1Response; 2607 n_popResponseQueue; 2608 wa_wakeUpDependents; 2609 } 2610 2611 transition(OLS, L1_PUTS, OLSW) { 2612 l_writebackAckDropData; 2613 o_popL1RequestQueue; 2614 } 2615 2616 transition(ILS, L1_PUTS, ILSW) { 2617 l_writebackAckNeedData; 2618 o_popL1RequestQueue; 2619 } 2620 2621 transition(ILS, L1_PUTS_only, IW) { 2622 l_writebackAckNeedData; 2623 o_popL1RequestQueue; 2624 } 2625 2626 transition(OLS, L1_PUTS_only, OW) { 2627 l_writebackAckDropData; 2628 o_popL1RequestQueue; 2629 } 2630 2631 transition(OLSX, L1_PUTS_only, OXW) { 2632 l_writebackAckDropData; 2633 o_popL1RequestQueue; 2634 } 2635 2636 transition(OLSX, L1_PUTS, OLSXW) { 2637 l_writebackAckDropData; 2638 o_popL1RequestQueue; 2639 } 2640 2641 transition(OLSXW, {Unblock}, OLSX) { 2642 gg_clearSharerFromL1Response; 2643 n_popResponseQueue; 2644 wa_wakeUpDependents; 2645 } 2646 2647 transition(OW, {Unblock}, O) { 2648 gg_clearSharerFromL1Response; 2649 n_popResponseQueue; 2650 wa_wakeUpDependents; 2651 } 2652 2653 transition(OXW, {Unblock}, M) { 2654 gg_clearSharerFromL1Response; 2655 n_popResponseQueue; 2656 wa_wakeUpDependents; 2657 } 2658 2659 transition(ILX, L1_PUTX, ILXW ) { 2660 l_writebackAckNeedData; 2661 o_popL1RequestQueue; 2662 } 2663 2664 transition(ILXW, L1_WBDIRTYDATA, M) { 2665 gg_clearLocalSharers; 2666 vv_allocateL2CacheBlock; 2667 y_copyDirToCacheAndRemove; 2668 u_writeDirtyDataToCache; 2669 o_popL1RequestQueue; 2670 wa_wakeUpDependents; 2671 } 2672 2673 // clean writeback 2674 transition(ILXW, L1_WBCLEANDATA, M) { 2675 gg_clearLocalSharers; 2676 vv_allocateL2CacheBlock; 2677 y_copyDirToCacheAndRemove; 2678 u_writeCleanDataToCache; 2679 o_popL1RequestQueue; 2680 wa_wakeUpDependents; 2681 } 2682 2683 transition(ILXW, Unblock, ILX) { 2684 // writeback canceled because L1 invalidated 2685 n_popResponseQueue; 2686 wa_wakeUpDependents; 2687 } 2688 2689 transition(ILSW, L1_WBCLEANDATA, SLS) { 2690 vv_allocateL2CacheBlock; 2691 y_copyDirToCacheAndRemove; 2692 u_writeCleanDataToCache; 2693 gg_clearSharerFromL1Request; 2694 o_popL1RequestQueue; 2695 wa_wakeUpDependents; 2696 } 2697 2698 transition(IW, L1_WBCLEANDATA, S) { 2699 vv_allocateL2CacheBlock; 2700 y_copyDirToCacheAndRemove; 2701 u_writeCleanDataToCache; 2702 gg_clearSharerFromL1Request; 2703 o_popL1RequestQueue; 2704 wa_wakeUpDependents; 2705 } 2706 2707 // Owner can have dirty data 2708 transition(ILOW, L1_WBDIRTYDATA, O) { 2709 vv_allocateL2CacheBlock; 2710 y_copyDirToCacheAndRemove; 2711 gg_clearOwnerFromL1Request; 2712 u_writeDirtyDataToCache; 2713 o_popL1RequestQueue; 2714 wa_wakeUpDependents; 2715 } 2716 2717 transition(ILOW, L1_WBCLEANDATA, O) { 2718 vv_allocateL2CacheBlock; 2719 y_copyDirToCacheAndRemove; 2720 gg_clearOwnerFromL1Request; 2721 u_writeCleanDataToCache; 2722 o_popL1RequestQueue; 2723 wa_wakeUpDependents; 2724 } 2725 2726 transition(ILOXW, L1_WBDIRTYDATA, M) { 2727 vv_allocateL2CacheBlock; 2728 y_copyDirToCacheAndRemove; 2729 gg_clearOwnerFromL1Request; 2730 u_writeDirtyDataToCache; 2731 o_popL1RequestQueue; 2732 wa_wakeUpDependents; 2733 } 2734 2735 transition(ILOXW, L1_WBCLEANDATA, M) { 2736 vv_allocateL2CacheBlock; 2737 y_copyDirToCacheAndRemove; 2738 gg_clearOwnerFromL1Request; 2739 u_writeCleanDataToCache; 2740 o_popL1RequestQueue; 2741 wa_wakeUpDependents; 2742 } 2743 2744 transition(ILOSW, L1_WBDIRTYDATA, OLS) { 2745 vv_allocateL2CacheBlock; 2746 y_copyDirToCacheAndRemove; 2747 gg_clearOwnerFromL1Request; 2748 u_writeDirtyDataToCache; 2749 o_popL1RequestQueue; 2750 wa_wakeUpDependents; 2751 } 2752 2753 transition(ILOSW, L1_WBCLEANDATA, OLS) { 2754 vv_allocateL2CacheBlock; 2755 y_copyDirToCacheAndRemove; 2756 gg_clearOwnerFromL1Request; 2757 u_writeCleanDataToCache; 2758 o_popL1RequestQueue; 2759 wa_wakeUpDependents; 2760 } 2761 2762 transition(ILOSXW, L1_WBDIRTYDATA, OLSX) { 2763 vv_allocateL2CacheBlock; 2764 y_copyDirToCacheAndRemove; 2765 gg_clearOwnerFromL1Request; 2766 u_writeDirtyDataToCache; 2767 o_popL1RequestQueue; 2768 wa_wakeUpDependents; 2769 } 2770 2771 transition(ILOSXW, L1_WBCLEANDATA, OLSX) { 2772 vv_allocateL2CacheBlock; 2773 y_copyDirToCacheAndRemove; 2774 gg_clearOwnerFromL1Request; 2775 u_writeCleanDataToCache; 2776 o_popL1RequestQueue; 2777 wa_wakeUpDependents; 2778 } 2779 2780 transition(SLSW, {Unblock}, SLS) { 2781 gg_clearSharerFromL1Response; 2782 n_popResponseQueue; 2783 wa_wakeUpDependents; 2784 } 2785 2786 transition(OLSW, {Unblock}, OLS) { 2787 gg_clearSharerFromL1Response; 2788 n_popResponseQueue; 2789 wa_wakeUpDependents; 2790 } 2791 2792 2793 // L2 WRITEBACKS 2794 transition({I, S}, L2_Replacement, I) { 2795 rr_deallocateL2CacheBlock; 2796 } 2797 2798 transition(ILS, L2_Replacement) { 2799 y_copyCacheStateToDir; 2800 rr_deallocateL2CacheBlock; 2801 } 2802 2803 transition(ILX, L2_Replacement ) { 2804 y_copyCacheStateToDir; 2805 rr_deallocateL2CacheBlock; 2806 } 2807 2808 transition({ILO, ILOS}, L2_Replacement ) { 2809 y_copyCacheStateToDir; 2810 rr_deallocateL2CacheBlock; 2811 } 2812 2813 transition(SLS, L2_Replacement, ILS) { 2814 y_copyCacheStateToDir; 2815 rr_deallocateL2CacheBlock; 2816 } 2817 2818 transition({OLS, OLSX}, L2_Replacement, OLSI) { 2819 y_copyCacheStateToDir; 2820 b_issuePUTO_ls; 2821 i_allocateTBE; 2822 rr_deallocateL2CacheBlock; 2823 } 2824 2825 2826 transition(O, L2_Replacement, OI) { 2827 b_issuePUTO; 2828 i_allocateTBE; 2829 rr_deallocateL2CacheBlock; 2830 } 2831 2832 transition(M, L2_Replacement, MI) { 2833 b_issuePUTX; 2834 i_allocateTBE; 2835 rr_deallocateL2CacheBlock; 2836 } 2837 2838 transition(OLSI, Fwd_GETX, ILSI) { 2839 t_recordFwdXID; 2840 ee_sendLocalInv; 2841 m_popRequestQueue; 2842 } 2843 2844 transition(ILSI, IntAck) { 2845 m_decrementNumberOfMessagesInt; 2846 o_checkForIntCompletion; 2847 n_popResponseQueue; 2848 } 2849 2850 transition(ILSI, All_Acks, MII) { 2851 gg_clearLocalSharers; 2852 c_sendDataFromTBEToFwdGETX; 2853 n_popTriggerQueue; 2854 } 2855 2856 transition(OLSI, Fwd_GETS) { 2857 t_recordFwdSID; 2858 c_sendDataFromTBEToFwdGETS; 2859 m_popRequestQueue; 2860 } 2861 2862 transition({MI, OI}, Fwd_GETS, OI) { 2863 t_recordFwdSID; 2864 c_sendDataFromTBEToFwdGETS; 2865 m_popRequestQueue; 2866 } 2867 2868 transition({MI, OI}, Fwd_DMA, OI) { 2869 cd_sendDataFromTBEToFwdDma; 2870 da_sendDmaAckUnblock; 2871 m_popRequestQueue; 2872 } 2873 2874 transition(OLSI, Fwd_DMA) { 2875 cd_sendDataFromTBEToFwdDma; 2876 da_sendDmaAckUnblock; 2877 m_popRequestQueue; 2878 } 2879 2880 transition({MI, OI}, Fwd_GETX, MII) { 2881 t_recordFwdXID; 2882 c_sendDataFromTBEToFwdGETX; 2883 m_popRequestQueue; 2884 } 2885 2886 transition({MI, OI}, Writeback_Ack, I) { 2887 qq_sendDataFromTBEToMemory; 2888 s_deallocateTBE; 2889 n_popResponseQueue; 2890 wa_wakeUpDependents; 2891 } 2892 2893 transition(MII, Writeback_Nack, I) { 2894 s_deallocateTBE; 2895 n_popResponseQueue; 2896 wa_wakeUpDependents; 2897 } 2898 2899 transition(OI, Writeback_Nack) { 2900 b_issuePUTO; 2901 n_popResponseQueue; 2902 } 2903 2904 transition(OLSI, Writeback_Ack, ILS) { 2905 qq_sendDataFromTBEToMemory; 2906 s_deallocateTBE; 2907 n_popResponseQueue; 2908 wa_wakeUpDependents; 2909 } 2910 2911 transition(MII, Writeback_Ack, I) { 2912 f_sendUnblock; 2913 s_deallocateTBE; 2914 n_popResponseQueue; 2915 wa_wakeUpDependents; 2916 } 2917 2918 transition(ILSI, Writeback_Ack, ILS) { 2919 f_sendUnblock; 2920 s_deallocateTBE; 2921 n_popResponseQueue; 2922 wa_wakeUpDependents; 2923 } 2924} 2925