1/* 2 * Copyright (c) 2012-2015 Advanced Micro Devices, Inc. 3 * All rights reserved. 4 * 5 * For use for simulation and test purposes only 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright notice, 14 * this list of conditions and the following disclaimer in the documentation 15 * and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the copyright holder nor the names of its 18 * contributors may be used to endorse or promote products derived from this 19 * software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 * 33 * Authors: Mithuna Thottethodi 34 */ 35 36machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L2)") 37: CacheMemory * directory; 38 // Convention: wire buffers are prefixed with "w_" for clarity 39 WireBuffer * w_reqToTCCDir; 40 WireBuffer * w_respToTCCDir; 41 WireBuffer * w_TCCUnblockToTCCDir; 42 WireBuffer * w_reqToTCC; 43 WireBuffer * w_probeToTCC; 44 WireBuffer * w_respToTCC; 45 int TCC_select_num_bits; 46 Cycles response_latency := 5; 47 Cycles directory_latency := 6; 48 Cycles issue_latency := 120; 49 50 // From the TCPs or SQCs 51 MessageBuffer * requestFromTCP, network="From", virtual_network="1", vnet_type="request"; 52 MessageBuffer * responseFromTCP, network="From", virtual_network="3", vnet_type="response"; 53 MessageBuffer * unblockFromTCP, network="From", virtual_network="5", vnet_type="unblock"; 54 55 // To the Cores. TCC deals only with TCPs/SQCs. CP cores do not communicate directly with TCC. 56 MessageBuffer * probeToCore, network="To", virtual_network="1", vnet_type="request"; 57 MessageBuffer * responseToCore, network="To", virtual_network="3", vnet_type="response"; 58 59 // From the NB 60 MessageBuffer * probeFromNB, network="From", virtual_network="0", vnet_type="request"; 61 MessageBuffer * responseFromNB, network="From", virtual_network="2", vnet_type="response"; 62 // To the NB 63 MessageBuffer * requestToNB, network="To", virtual_network="0", vnet_type="request"; 64 MessageBuffer * responseToNB, network="To", virtual_network="2", vnet_type="response"; 65 MessageBuffer * unblockToNB, network="To", virtual_network="4", vnet_type="unblock"; 66 67 MessageBuffer * triggerQueue, random="false"; 68{ 69 // STATES 70 state_declaration(State, desc="Directory states", default="TCCdir_State_I") { 71 // Base states 72 I, AccessPermission:Invalid, desc="Invalid"; 73 S, AccessPermission:Invalid, desc="Shared"; 74 E, AccessPermission:Invalid, desc="Shared"; 75 O, AccessPermission:Invalid, desc="Owner"; 76 M, AccessPermission:Invalid, desc="Modified"; 77 78 CP_I, AccessPermission:Invalid, desc="Blocked, must send data after acks are in, going to invalid"; 79 B_I, AccessPermission:Invalid, desc="Blocked, need not send data after acks are in, going to invalid"; 80 CP_O, AccessPermission:Invalid, desc="Blocked, must send data after acks are in, going to owned"; 81 CP_S, AccessPermission:Invalid, desc="Blocked, must send data after acks are in, going to shared"; 82 CP_OM, AccessPermission:Invalid, desc="Blocked, must send data after acks are in, going to O_M"; 83 CP_SM, AccessPermission:Invalid, desc="Blocked, must send data after acks are in, going to S_M"; 84 CP_ISM, AccessPermission:Invalid, desc="Blocked, must send data after acks are in, going to I_M"; 85 CP_IOM, AccessPermission:Invalid, desc="Blocked, must send data after acks are in, going to I_M"; 86 CP_OSIW, AccessPermission:Invalid, desc="Blocked, must send data after acks+CancelWB are in, going to I_C"; 87 88 89 // Transient states and busy states used for handling side (TCC-facing) interactions 90 BW_S, AccessPermission:Invalid, desc="Blocked, Awaiting TCC unblock"; 91 BW_E, AccessPermission:Invalid, desc="Blocked, Awaiting TCC unblock"; 92 BW_O, AccessPermission:Invalid, desc="Blocked, Awaiting TCC unblock"; 93 BW_M, AccessPermission:Invalid, desc="Blocked, Awaiting TCC unblock"; 94 95 // Transient states and busy states used for handling upward (TCP-facing) interactions 96 I_M, AccessPermission:Invalid, desc="Invalid, issued RdBlkM, have not seen response yet"; 97 I_ES, AccessPermission:Invalid, desc="Invalid, issued RdBlk, have not seen response yet"; 98 I_S, AccessPermission:Invalid, desc="Invalid, issued RdBlkS, have not seen response yet"; 99 BBS_S, AccessPermission:Invalid, desc="Blocked, going from S to S"; 100 BBO_O, AccessPermission:Invalid, desc="Blocked, going from O to O"; 101 BBM_M, AccessPermission:Invalid, desc="Blocked, going from M to M, waiting for data to forward"; 102 BBM_O, AccessPermission:Invalid, desc="Blocked, going from M to O, waiting for data to forward"; 103 BB_M, AccessPermission:Invalid, desc="Blocked, going from M to M, waiting for unblock"; 104 BB_O, AccessPermission:Invalid, desc="Blocked, going from M to O, waiting for unblock"; 105 BB_OO, AccessPermission:Invalid, desc="Blocked, going from O to O (adding sharers), waiting for unblock"; 106 BB_S, AccessPermission:Invalid, desc="Blocked, going to S, waiting for (possible multiple) unblock(s)"; 107 BBS_M, AccessPermission:Invalid, desc="Blocked, going from S or O to M"; 108 BBO_M, AccessPermission:Invalid, desc="Blocked, going from S or O to M"; 109 BBS_UM, AccessPermission:Invalid, desc="Blocked, going from S or O to M via upgrade"; 110 BBO_UM, AccessPermission:Invalid, desc="Blocked, going from S or O to M via upgrade"; 111 S_M, AccessPermission:Invalid, desc="Shared, issued CtoD, have not seen response yet"; 112 O_M, AccessPermission:Invalid, desc="Shared, issued CtoD, have not seen response yet"; 113 114 // 115 BBB_S, AccessPermission:Invalid, desc="Blocked, going to S after core unblock"; 116 BBB_M, AccessPermission:Invalid, desc="Blocked, going to M after core unblock"; 117 BBB_E, AccessPermission:Invalid, desc="Blocked, going to E after core unblock"; 118 119 VES_I, AccessPermission:Invalid, desc="TCC replacement, waiting for clean WB ack"; 120 VM_I, AccessPermission:Invalid, desc="TCC replacement, waiting for dirty WB ack"; 121 VO_I, AccessPermission:Invalid, desc="TCC replacement, waiting for dirty WB ack"; 122 VO_S, AccessPermission:Invalid, desc="TCC owner replacement, waiting for dirty WB ack"; 123 124 ES_I, AccessPermission:Invalid, desc="L1 replacement, waiting for clean WB ack"; 125 MO_I, AccessPermission:Invalid, desc="L1 replacement, waiting for dirty WB ack"; 126 127 I_C, AccessPermission:Invalid, desc="Invalid, waiting for WBAck from NB for canceled WB"; 128 I_W, AccessPermission:Invalid, desc="Invalid, waiting for WBAck from NB; canceled WB raced with directory invalidation"; 129 130 // Recall States 131 BRWD_I, AccessPermission:Invalid, desc="Recalling, waiting for WBAck and Probe Data responses"; 132 BRW_I, AccessPermission:Read_Write, desc="Recalling, waiting for WBAck"; 133 BRD_I, AccessPermission:Invalid, desc="Recalling, waiting for Probe Data responses"; 134 135 } 136 137 enumeration(RequestType, desc="To communicate stats from transitions to recordStats") { 138 DataArrayRead, desc="Read the data array"; 139 DataArrayWrite, desc="Write the data array"; 140 TagArrayRead, desc="Read the data array"; 141 TagArrayWrite, desc="Write the data array"; 142 } 143 144 145 146 // EVENTS 147 enumeration(Event, desc="TCC Directory Events") { 148 // Upward facing events (TCCdir w.r.t. TCP/SQC and TCC behaves like NBdir behaves with TCP/SQC and L3 149 150 // Directory Recall 151 Recall, desc="directory cache is full"; 152 // CPU requests 153 CPUWrite, desc="Initial req from core, sent to TCC"; 154 NoCPUWrite, desc="Initial req from core, but non-exclusive clean data; can be discarded"; 155 CPUWriteCancel, desc="Initial req from core, sent to TCC"; 156 157 // Requests from the TCPs 158 RdBlk, desc="RdBlk event"; 159 RdBlkM, desc="RdBlkM event"; 160 RdBlkS, desc="RdBlkS event"; 161 CtoD, desc="Change to Dirty request"; 162 163 // TCC writebacks 164 VicDirty, desc="..."; 165 VicDirtyLast, desc="..."; 166 VicClean, desc="..."; 167 NoVic, desc="..."; 168 StaleVic, desc="..."; 169 CancelWB, desc="TCC got invalidating probe, canceled WB"; 170 171 // Probe Responses from TCP/SQCs 172 CPUPrbResp, desc="Probe response from TCP/SQC"; 173 TCCPrbResp, desc="Probe response from TCC"; 174 175 ProbeAcksComplete, desc="All acks received"; 176 ProbeAcksCompleteReissue, desc="All acks received, changing CtoD to reissue"; 177 178 CoreUnblock, desc="unblock from TCP/SQC"; 179 LastCoreUnblock, desc="Last unblock from TCP/SQC"; 180 TCCUnblock, desc="unblock from TCC (current owner)"; 181 TCCUnblock_Sharer, desc="unblock from TCC (a sharer, not owner)"; 182 TCCUnblock_NotValid,desc="unblock from TCC (not valid...caused by stale writebacks)"; 183 184 // Downward facing events 185 186 // NB initiated 187 NB_AckS, desc="NB Ack to TCC Request"; 188 NB_AckE, desc="NB Ack to TCC Request"; 189 NB_AckM, desc="NB Ack to TCC Request"; 190 NB_AckCtoD, desc="NB Ack to TCC Request"; 191 NB_AckWB, desc="NB Ack for clean WB"; 192 193 194 // Incoming Probes from NB 195 PrbInvData, desc="Invalidating probe, return dirty data"; 196 PrbInv, desc="Invalidating probe, no need to return data"; 197 PrbShrData, desc="Downgrading probe, return data"; 198 } 199 200 201 // TYPES 202 203 // Entry for directory 204 structure(Entry, desc="...", interface='AbstractCacheEntry') { 205 State CacheState, desc="Cache state (Cache of directory entries)"; 206 DataBlock DataBlk, desc="data for the block"; 207 NetDest Sharers, desc="Sharers for this block"; 208 NetDest Owner, desc="Owner of this block"; 209 NetDest MergedSharers, desc="Read sharers who are merged on a request"; 210 int WaitingUnblocks, desc="Number of acks we're waiting for"; 211 } 212 213 structure(TBE, desc="...") { 214 State TBEState, desc="Transient state"; 215 DataBlock DataBlk, desc="DataBlk"; 216 bool Dirty, desc="Is the data dirty?"; 217 MachineID Requestor, desc="requestor"; 218 int NumPendingAcks, desc="num acks expected"; 219 MachineID OriginalRequestor, desc="Original Requestor"; 220 MachineID UntransferredOwner, desc = "Untransferred owner for an upgrade transaction"; 221 bool UntransferredOwnerExists, desc = "1 if Untransferred owner exists for an upgrade transaction"; 222 bool Cached, desc="data hit in Cache"; 223 bool Shared, desc="victim hit by shared probe"; 224 bool Upgrade, desc="An upgrade request in progress"; 225 bool CtoD, desc="Saved sysack info"; 226 CoherenceState CohState, desc="Saved sysack info"; 227 MessageSizeType MessageSize, desc="Saved sysack info"; 228 MachineID Sender, desc="sender"; 229 } 230 231 structure(TBETable, external = "yes") { 232 TBE lookup(Addr); 233 void allocate(Addr); 234 void deallocate(Addr); 235 bool isPresent(Addr); 236 } 237 238 // ** OBJECTS ** 239 TBETable TBEs, template="<TCCdir_TBE>", constructor="m_number_of_TBEs"; 240 int TCC_select_low_bit, default="RubySystem::getBlockSizeBits()"; 241 NetDest TCC_dir_subtree; 242 NetDest temp; 243 244 Tick clockEdge(); 245 Tick cyclesToTicks(Cycles c); 246 247 void set_cache_entry(AbstractCacheEntry b); 248 void unset_cache_entry(); 249 void set_tbe(TBE b); 250 void unset_tbe(); 251 MachineID mapAddressToMachine(Addr addr, MachineType mtype); 252 253 bool presentOrAvail(Addr addr) { 254 return directory.isTagPresent(addr) || directory.cacheAvail(addr); 255 } 256 257 Entry getCacheEntry(Addr addr), return_by_pointer="yes" { 258 return static_cast(Entry, "pointer", directory.lookup(addr)); 259 } 260 261 DataBlock getDataBlock(Addr addr), return_by_ref="yes" { 262 TBE tbe := TBEs.lookup(addr); 263 if(is_valid(tbe)) { 264 return tbe.DataBlk; 265 } else { 266 assert(false); 267 return getCacheEntry(addr).DataBlk; 268 } 269 } 270 271 State getState(TBE tbe, Entry cache_entry, Addr addr) { 272 if(is_valid(tbe)) { 273 return tbe.TBEState; 274 } else if (is_valid(cache_entry)) { 275 return cache_entry.CacheState; 276 } 277 return State:I; 278 } 279 280 void setAccessPermission(Entry cache_entry, Addr addr, State state) { 281 if (is_valid(cache_entry)) { 282 cache_entry.changePermission(TCCdir_State_to_permission(state)); 283 } 284 } 285 286 AccessPermission getAccessPermission(Addr addr) { 287 TBE tbe := TBEs.lookup(addr); 288 if(is_valid(tbe)) { 289 return TCCdir_State_to_permission(tbe.TBEState); 290 } 291 292 Entry cache_entry := getCacheEntry(addr); 293 if(is_valid(cache_entry)) { 294 return TCCdir_State_to_permission(cache_entry.CacheState); 295 } 296 297 return AccessPermission:NotPresent; 298 } 299 300 void functionalRead(Addr addr, Packet *pkt) { 301 TBE tbe := TBEs.lookup(addr); 302 if(is_valid(tbe)) { 303 testAndRead(addr, tbe.DataBlk, pkt); 304 } else { 305 functionalMemoryRead(pkt); 306 } 307 } 308 309 int functionalWrite(Addr addr, Packet *pkt) { 310 int num_functional_writes := 0; 311 312 TBE tbe := TBEs.lookup(addr); 313 if(is_valid(tbe)) { 314 num_functional_writes := num_functional_writes + 315 testAndWrite(addr, tbe.DataBlk, pkt); 316 } 317 318 num_functional_writes := num_functional_writes + functionalMemoryWrite(pkt); 319 return num_functional_writes; 320 } 321 322 void setState(TBE tbe, Entry cache_entry, Addr addr, State state) { 323 if (is_valid(tbe)) { 324 tbe.TBEState := state; 325 } 326 327 if (is_valid(cache_entry)) { 328 cache_entry.CacheState := state; 329 330 if (state == State:S) { 331 assert(cache_entry.Owner.count() == 0); 332 } 333 334 if (state == State:O) { 335 assert(cache_entry.Owner.count() == 1); 336 assert(cache_entry.Sharers.isSuperset(cache_entry.Owner) == false); 337 } 338 339 if (state == State:M) { 340 assert(cache_entry.Owner.count() == 1); 341 assert(cache_entry.Sharers.count() == 0); 342 } 343 344 if (state == State:E) { 345 assert(cache_entry.Owner.count() == 0); 346 assert(cache_entry.Sharers.count() == 1); 347 } 348 } 349 } 350 351 352 353 void recordRequestType(RequestType request_type, Addr addr) { 354 if (request_type == RequestType:DataArrayRead) { 355 directory.recordRequestType(CacheRequestType:DataArrayRead, addr); 356 } else if (request_type == RequestType:DataArrayWrite) { 357 directory.recordRequestType(CacheRequestType:DataArrayWrite, addr); 358 } else if (request_type == RequestType:TagArrayRead) { 359 directory.recordRequestType(CacheRequestType:TagArrayRead, addr); 360 } else if (request_type == RequestType:TagArrayWrite) { 361 directory.recordRequestType(CacheRequestType:TagArrayWrite, addr); 362 } 363 } 364 365 bool checkResourceAvailable(RequestType request_type, Addr addr) { 366 if (request_type == RequestType:DataArrayRead) { 367 return directory.checkResourceAvailable(CacheResourceType:DataArray, addr); 368 } else if (request_type == RequestType:DataArrayWrite) { 369 return directory.checkResourceAvailable(CacheResourceType:DataArray, addr); 370 } else if (request_type == RequestType:TagArrayRead) { 371 return directory.checkResourceAvailable(CacheResourceType:TagArray, addr); 372 } else if (request_type == RequestType:TagArrayWrite) { 373 return directory.checkResourceAvailable(CacheResourceType:TagArray, addr); 374 } else { 375 error("Invalid RequestType type in checkResourceAvailable"); 376 return true; 377 } 378 } 379 380 // ** OUT_PORTS ** 381 382 // Three classes of ports 383 // Class 1: downward facing network links to NB 384 out_port(requestToNB_out, CPURequestMsg, requestToNB); 385 out_port(responseToNB_out, ResponseMsg, responseToNB); 386 out_port(unblockToNB_out, UnblockMsg, unblockToNB); 387 388 389 // Class 2: upward facing ports to GPU cores 390 out_port(probeToCore_out, TDProbeRequestMsg, probeToCore); 391 out_port(responseToCore_out, ResponseMsg, responseToCore); 392 393 // Class 3: sideward facing ports (on "wirebuffer" links) to TCC 394 out_port(w_requestTCC_out, CPURequestMsg, w_reqToTCC); 395 out_port(w_probeTCC_out, NBProbeRequestMsg, w_probeToTCC); 396 out_port(w_respTCC_out, ResponseMsg, w_respToTCC); 397 398 399 // local trigger port 400 out_port(triggerQueue_out, TriggerMsg, triggerQueue); 401 402 // 403 // request queue going to NB 404 // 405 406 // ** IN_PORTS ** 407 408 // Trigger Queue 409 in_port(triggerQueue_in, TriggerMsg, triggerQueue, rank=8) { 410 if (triggerQueue_in.isReady(clockEdge())) { 411 peek(triggerQueue_in, TriggerMsg) { 412 TBE tbe := TBEs.lookup(in_msg.addr); 413 assert(is_valid(tbe)); 414 Entry cache_entry := getCacheEntry(in_msg.addr); 415 if ((in_msg.Type == TriggerType:AcksComplete) && (tbe.Upgrade == false)) { 416 trigger(Event:ProbeAcksComplete, in_msg.addr, cache_entry, tbe); 417 } else if ((in_msg.Type == TriggerType:AcksComplete) && (tbe.Upgrade == true)) { 418 trigger(Event:ProbeAcksCompleteReissue, in_msg.addr, cache_entry, tbe); 419 } 420 } 421 } 422 } 423 424 // Unblock Networks (TCCdir can receive unblocks from TCC, TCPs) 425 // Port on first (of three) wire buffers from TCC 426 in_port(w_TCCUnblock_in, UnblockMsg, w_TCCUnblockToTCCDir, rank=7) { 427 if (w_TCCUnblock_in.isReady(clockEdge())) { 428 peek(w_TCCUnblock_in, UnblockMsg) { 429 TBE tbe := TBEs.lookup(in_msg.addr); 430 Entry cache_entry := getCacheEntry(in_msg.addr); 431 if (in_msg.currentOwner) { 432 trigger(Event:TCCUnblock, in_msg.addr, cache_entry, tbe); 433 } else if (in_msg.valid) { 434 trigger(Event:TCCUnblock_Sharer, in_msg.addr, cache_entry, tbe); 435 } else { 436 trigger(Event:TCCUnblock_NotValid, in_msg.addr, cache_entry, tbe); 437 } 438 } 439 } 440 } 441 442 in_port(unblockNetwork_in, UnblockMsg, unblockFromTCP, rank=6) { 443 if (unblockNetwork_in.isReady(clockEdge())) { 444 peek(unblockNetwork_in, UnblockMsg) { 445 TBE tbe := TBEs.lookup(in_msg.addr); 446 Entry cache_entry := getCacheEntry(in_msg.addr); 447 if(cache_entry.WaitingUnblocks == 1) { 448 trigger(Event:LastCoreUnblock, in_msg.addr, cache_entry, tbe); 449 } 450 else { 451 trigger(Event:CoreUnblock, in_msg.addr, cache_entry, tbe); 452 } 453 } 454 } 455 } 456 457 458 //Responses from TCC, and Cores 459 // Port on second (of three) wire buffers from TCC 460 in_port(w_TCCResponse_in, ResponseMsg, w_respToTCCDir, rank=5) { 461 if (w_TCCResponse_in.isReady(clockEdge())) { 462 peek(w_TCCResponse_in, ResponseMsg) { 463 TBE tbe := TBEs.lookup(in_msg.addr); 464 Entry cache_entry := getCacheEntry(in_msg.addr); 465 if (in_msg.Type == CoherenceResponseType:CPUPrbResp) { 466 trigger(Event:TCCPrbResp, in_msg.addr, cache_entry, tbe); 467 } 468 } 469 } 470 } 471 472 in_port(responseNetwork_in, ResponseMsg, responseFromTCP, rank=4) { 473 if (responseNetwork_in.isReady(clockEdge())) { 474 peek(responseNetwork_in, ResponseMsg) { 475 TBE tbe := TBEs.lookup(in_msg.addr); 476 Entry cache_entry := getCacheEntry(in_msg.addr); 477 if (in_msg.Type == CoherenceResponseType:CPUPrbResp) { 478 trigger(Event:CPUPrbResp, in_msg.addr, cache_entry, tbe); 479 } 480 } 481 } 482 } 483 484 485 // Port on third (of three) wire buffers from TCC 486 in_port(w_TCCRequest_in, CPURequestMsg, w_reqToTCCDir, rank=3) { 487 if(w_TCCRequest_in.isReady(clockEdge())) { 488 peek(w_TCCRequest_in, CPURequestMsg) { 489 TBE tbe := TBEs.lookup(in_msg.addr); 490 Entry cache_entry := getCacheEntry(in_msg.addr); 491 if (in_msg.Type == CoherenceRequestType:WrCancel) { 492 trigger(Event:CancelWB, in_msg.addr, cache_entry, tbe); 493 } else if (in_msg.Type == CoherenceRequestType:VicDirty) { 494 if (is_valid(cache_entry) && cache_entry.Owner.isElement(in_msg.Requestor)) { 495 // if modified, or owner with no other sharers 496 if ((cache_entry.CacheState == State:M) || (cache_entry.Sharers.count() == 0)) { 497 assert(cache_entry.Owner.count()==1); 498 trigger(Event:VicDirtyLast, in_msg.addr, cache_entry, tbe); 499 } else { 500 trigger(Event:VicDirty, in_msg.addr, cache_entry, tbe); 501 } 502 } else { 503 trigger(Event:StaleVic, in_msg.addr, cache_entry, tbe); 504 } 505 } else { 506 if (in_msg.Type == CoherenceRequestType:VicClean) { 507 if (is_valid(cache_entry) && cache_entry.Sharers.isElement(in_msg.Requestor)) { 508 if (cache_entry.Sharers.count() == 1) { 509 // Last copy, victimize to L3 510 trigger(Event:VicClean, in_msg.addr, cache_entry, tbe); 511 } else { 512 // Either not the last copy or stall. No need to victimmize 513 // remove sharer from sharer list 514 assert(cache_entry.Sharers.count() > 1); 515 trigger(Event:NoVic, in_msg.addr, cache_entry, tbe); 516 } 517 } else { 518 trigger(Event:StaleVic, in_msg.addr, cache_entry, tbe); 519 } 520 } 521 } 522 } 523 } 524 } 525 526 in_port(responseFromNB_in, ResponseMsg, responseFromNB, rank=2) { 527 if (responseFromNB_in.isReady(clockEdge())) { 528 peek(responseFromNB_in, ResponseMsg, block_on="addr") { 529 530 TBE tbe := TBEs.lookup(in_msg.addr); 531 Entry cache_entry := getCacheEntry(in_msg.addr); 532 if (in_msg.Type == CoherenceResponseType:NBSysResp) { 533 if (in_msg.State == CoherenceState:Modified) { 534 if (in_msg.CtoD) { 535 trigger(Event:NB_AckCtoD, in_msg.addr, cache_entry, tbe); 536 } else { 537 trigger(Event:NB_AckM, in_msg.addr, cache_entry, tbe); 538 } 539 } else if (in_msg.State == CoherenceState:Shared) { 540 trigger(Event:NB_AckS, in_msg.addr, cache_entry, tbe); 541 } else if (in_msg.State == CoherenceState:Exclusive) { 542 trigger(Event:NB_AckE, in_msg.addr, cache_entry, tbe); 543 } 544 } else if (in_msg.Type == CoherenceResponseType:NBSysWBAck) { 545 trigger(Event:NB_AckWB, in_msg.addr, cache_entry, tbe); 546 } else { 547 error("Unexpected Response Message to Core"); 548 } 549 } 550 } 551 } 552 553 // Finally handling incoming requests (from TCP) and probes (from NB). 554 555 in_port(probeNetwork_in, NBProbeRequestMsg, probeFromNB, rank=1) { 556 if (probeNetwork_in.isReady(clockEdge())) { 557 peek(probeNetwork_in, NBProbeRequestMsg) { 558 DPRINTF(RubySlicc, "%s\n", in_msg); 559 DPRINTF(RubySlicc, "machineID: %s\n", machineID); 560 Entry cache_entry := getCacheEntry(in_msg.addr); 561 TBE tbe := TBEs.lookup(in_msg.addr); 562 563 if (in_msg.Type == ProbeRequestType:PrbInv) { 564 if (in_msg.ReturnData) { 565 trigger(Event:PrbInvData, in_msg.addr, cache_entry, tbe); 566 } else { 567 trigger(Event:PrbInv, in_msg.addr, cache_entry, tbe); 568 } 569 } else if (in_msg.Type == ProbeRequestType:PrbDowngrade) { 570 assert(in_msg.ReturnData); 571 trigger(Event:PrbShrData, in_msg.addr, cache_entry, tbe); 572 } 573 } 574 } 575 } 576 577 578 in_port(coreRequestNetwork_in, CPURequestMsg, requestFromTCP, rank=0) { 579 if (coreRequestNetwork_in.isReady(clockEdge())) { 580 peek(coreRequestNetwork_in, CPURequestMsg) { 581 TBE tbe := TBEs.lookup(in_msg.addr); 582 Entry cache_entry := getCacheEntry(in_msg.addr); 583 if (presentOrAvail(in_msg.addr)) { 584 if (in_msg.Type == CoherenceRequestType:VicDirty) { 585 trigger(Event:CPUWrite, in_msg.addr, cache_entry, tbe); 586 } else if (in_msg.Type == CoherenceRequestType:VicClean) { 587 if (is_valid(cache_entry) && cache_entry.Owner.isElement(in_msg.Requestor)) { 588 trigger(Event:CPUWrite, in_msg.addr, cache_entry, tbe); 589 } else if(is_valid(cache_entry) && (cache_entry.Sharers.count() + cache_entry.Owner.count() ) >1) { 590 trigger(Event:NoCPUWrite, in_msg.addr, cache_entry, tbe); 591 } else { 592 trigger(Event:CPUWrite, in_msg.addr, cache_entry, tbe); 593 } 594 } else if (in_msg.Type == CoherenceRequestType:RdBlk) { 595 trigger(Event:RdBlk, in_msg.addr, cache_entry, tbe); 596 } else if (in_msg.Type == CoherenceRequestType:RdBlkS) { 597 trigger(Event:RdBlkS, in_msg.addr, cache_entry, tbe); 598 } else if (in_msg.Type == CoherenceRequestType:RdBlkM) { 599 trigger(Event:RdBlkM, in_msg.addr, cache_entry, tbe); 600 } else if (in_msg.Type == CoherenceRequestType:WrCancel) { 601 trigger(Event:CPUWriteCancel, in_msg.addr, cache_entry, tbe); 602 } 603 } else { 604 // All requests require a directory entry 605 Addr victim := directory.cacheProbe(in_msg.addr); 606 trigger(Event:Recall, victim, getCacheEntry(victim), TBEs.lookup(victim)); 607 } 608 } 609 } 610 } 611 612 613 614 615 // Actions 616 617 //Downward facing actions 618 619 action(c_clearOwner, "c", desc="Clear the owner field") { 620 cache_entry.Owner.clear(); 621 } 622 623 action(rS_removeRequesterFromSharers, "rS", desc="Remove unblocker from sharer list") { 624 peek(unblockNetwork_in, UnblockMsg) { 625 cache_entry.Sharers.remove(in_msg.Sender); 626 } 627 } 628 629 action(rT_removeTCCFromSharers, "rT", desc="Remove TCC from sharer list") { 630 peek(w_TCCRequest_in, CPURequestMsg) { 631 cache_entry.Sharers.remove(in_msg.Requestor); 632 } 633 } 634 635 action(rO_removeOriginalRequestorFromSharers, "rO", desc="Remove replacing core from sharer list") { 636 peek(coreRequestNetwork_in, CPURequestMsg) { 637 cache_entry.Sharers.remove(in_msg.Requestor); 638 } 639 } 640 641 action(rC_removeCoreFromSharers, "rC", desc="Remove replacing core from sharer list") { 642 peek(coreRequestNetwork_in, CPURequestMsg) { 643 cache_entry.Sharers.remove(in_msg.Requestor); 644 } 645 } 646 647 action(rCo_removeCoreFromOwner, "rCo", desc="Remove replacing core from sharer list") { 648 // Note that under some cases this action will try to remove a stale owner 649 peek(coreRequestNetwork_in, CPURequestMsg) { 650 cache_entry.Owner.remove(in_msg.Requestor); 651 } 652 } 653 654 action(rR_removeResponderFromSharers, "rR", desc="Remove responder from sharer list") { 655 peek(responseNetwork_in, ResponseMsg) { 656 cache_entry.Sharers.remove(in_msg.Sender); 657 } 658 } 659 660 action(nC_sendNullWBAckToCore, "nC", desc = "send a null WB Ack to release core") { 661 peek(coreRequestNetwork_in, CPURequestMsg) { 662 enqueue(responseToCore_out, ResponseMsg, 1) { 663 out_msg.addr := address; 664 out_msg.Type := CoherenceResponseType:TDSysWBNack; 665 out_msg.Sender := machineID; 666 out_msg.Destination.add(in_msg.Requestor); 667 out_msg.MessageSize := in_msg.MessageSize; 668 } 669 } 670 } 671 672 action(nT_sendNullWBAckToTCC, "nT", desc = "send a null WB Ack to release TCC") { 673 peek(w_TCCRequest_in, CPURequestMsg) { 674 enqueue(w_respTCC_out, ResponseMsg, 1) { 675 out_msg.addr := address; 676 out_msg.Type := CoherenceResponseType:TDSysWBAck; 677 out_msg.Sender := machineID; 678 out_msg.Destination.add(in_msg.Requestor); 679 out_msg.MessageSize := in_msg.MessageSize; 680 } 681 } 682 } 683 684 action(eto_moveExSharerToOwner, "eto", desc="move the current exclusive sharer to owner") { 685 assert(cache_entry.Sharers.count() == 1); 686 assert(cache_entry.Owner.count() == 0); 687 cache_entry.Owner := cache_entry.Sharers; 688 cache_entry.Sharers.clear(); 689 APPEND_TRANSITION_COMMENT(" new owner "); 690 APPEND_TRANSITION_COMMENT(cache_entry.Owner); 691 } 692 693 action(aT_addTCCToSharers, "aT", desc="Add TCC to sharer list") { 694 peek(w_TCCUnblock_in, UnblockMsg) { 695 cache_entry.Sharers.add(in_msg.Sender); 696 } 697 } 698 699 action(as_addToSharers, "as", desc="Add unblocker to sharer list") { 700 peek(unblockNetwork_in, UnblockMsg) { 701 cache_entry.Sharers.add(in_msg.Sender); 702 } 703 } 704 705 action(c_moveOwnerToSharer, "cc", desc="Move owner to sharers") { 706 cache_entry.Sharers.addNetDest(cache_entry.Owner); 707 cache_entry.Owner.clear(); 708 } 709 710 action(cc_clearSharers, "\c", desc="Clear the sharers field") { 711 cache_entry.Sharers.clear(); 712 } 713 714 action(e_ownerIsUnblocker, "e", desc="The owner is now the unblocker") { 715 peek(unblockNetwork_in, UnblockMsg) { 716 cache_entry.Owner.clear(); 717 cache_entry.Owner.add(in_msg.Sender); 718 APPEND_TRANSITION_COMMENT(" tcp_ub owner "); 719 APPEND_TRANSITION_COMMENT(cache_entry.Owner); 720 } 721 } 722 723 action(eT_ownerIsUnblocker, "eT", desc="TCC (unblocker) is now owner") { 724 peek(w_TCCUnblock_in, UnblockMsg) { 725 cache_entry.Owner.clear(); 726 cache_entry.Owner.add(in_msg.Sender); 727 APPEND_TRANSITION_COMMENT(" tcc_ub owner "); 728 APPEND_TRANSITION_COMMENT(cache_entry.Owner); 729 } 730 } 731 732 action(ctr_copyTCCResponseToTBE, "ctr", desc="Copy TCC probe response data to TBE") { 733 peek(w_TCCResponse_in, ResponseMsg) { 734 // Overwrite data if tbe does not hold dirty data. Stop once it is dirty. 735 if(tbe.Dirty == false) { 736 tbe.DataBlk := in_msg.DataBlk; 737 tbe.Dirty := in_msg.Dirty; 738 tbe.Sender := in_msg.Sender; 739 } 740 DPRINTF(RubySlicc, "%s\n", (tbe.DataBlk)); 741 } 742 } 743 744 action(ccr_copyCoreResponseToTBE, "ccr", desc="Copy core probe response data to TBE") { 745 peek(responseNetwork_in, ResponseMsg) { 746 // Overwrite data if tbe does not hold dirty data. Stop once it is dirty. 747 if(tbe.Dirty == false) { 748 tbe.DataBlk := in_msg.DataBlk; 749 tbe.Dirty := in_msg.Dirty; 750 751 if(tbe.Sender == machineID) { 752 tbe.Sender := in_msg.Sender; 753 } 754 } 755 DPRINTF(RubySlicc, "%s\n", (tbe.DataBlk)); 756 } 757 } 758 759 action(cd_clearDirtyBitTBE, "cd", desc="Clear Dirty bit in TBE") { 760 tbe.Dirty := false; 761 } 762 763 action(n_issueRdBlk, "n-", desc="Issue RdBlk") { 764 enqueue(requestToNB_out, CPURequestMsg, issue_latency) { 765 out_msg.addr := address; 766 out_msg.Type := CoherenceRequestType:RdBlk; 767 out_msg.Requestor := machineID; 768 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 769 out_msg.MessageSize := MessageSizeType:Request_Control; 770 } 771 } 772 773 action(nS_issueRdBlkS, "nS", desc="Issue RdBlkS") { 774 enqueue(requestToNB_out, CPURequestMsg, issue_latency) { 775 out_msg.addr := address; 776 out_msg.Type := CoherenceRequestType:RdBlkS; 777 out_msg.Requestor := machineID; 778 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 779 out_msg.MessageSize := MessageSizeType:Request_Control; 780 } 781 } 782 783 action(nM_issueRdBlkM, "nM", desc="Issue RdBlkM") { 784 enqueue(requestToNB_out, CPURequestMsg, issue_latency) { 785 out_msg.addr := address; 786 out_msg.Type := CoherenceRequestType:RdBlkM; 787 out_msg.Requestor := machineID; 788 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 789 out_msg.MessageSize := MessageSizeType:Request_Control; 790 } 791 } 792 793 action(rU_rememberUpgrade, "rU", desc="Remember that this was an upgrade") { 794 tbe.Upgrade := true; 795 } 796 797 action(ruo_rememberUntransferredOwner, "ruo", desc="Remember the untransferred owner") { 798 peek(responseNetwork_in, ResponseMsg) { 799 if(in_msg.UntransferredOwner == true) { 800 tbe.UntransferredOwner := in_msg.Sender; 801 tbe.UntransferredOwnerExists := true; 802 } 803 DPRINTF(RubySlicc, "%s\n", (in_msg)); 804 } 805 } 806 807 action(ruoT_rememberUntransferredOwnerTCC, "ruoT", desc="Remember the untransferred owner") { 808 peek(w_TCCResponse_in, ResponseMsg) { 809 if(in_msg.UntransferredOwner == true) { 810 tbe.UntransferredOwner := in_msg.Sender; 811 tbe.UntransferredOwnerExists := true; 812 } 813 DPRINTF(RubySlicc, "%s\n", (in_msg)); 814 } 815 } 816 817 action(vd_victim, "vd", desc="Victimize M/O Data") { 818 enqueue(requestToNB_out, CPURequestMsg, issue_latency) { 819 out_msg.addr := address; 820 out_msg.Requestor := machineID; 821 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 822 out_msg.MessageSize := MessageSizeType:Request_Control; 823 out_msg.Type := CoherenceRequestType:VicDirty; 824 if (cache_entry.CacheState == State:O) { 825 out_msg.Shared := true; 826 } else { 827 out_msg.Shared := false; 828 } 829 out_msg.Dirty := true; 830 } 831 } 832 833 action(vc_victim, "vc", desc="Victimize E/S Data") { 834 enqueue(requestToNB_out, CPURequestMsg, issue_latency) { 835 out_msg.addr := address; 836 out_msg.Requestor := machineID; 837 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 838 out_msg.MessageSize := MessageSizeType:Request_Control; 839 out_msg.Type := CoherenceRequestType:VicClean; 840 if (cache_entry.CacheState == State:S) { 841 out_msg.Shared := true; 842 } else { 843 out_msg.Shared := false; 844 } 845 out_msg.Dirty := false; 846 } 847 } 848 849 850 action(sT_sendRequestToTCC, "sT", desc="send request to TCC") { 851 peek(coreRequestNetwork_in, CPURequestMsg) { 852 enqueue(w_requestTCC_out, CPURequestMsg, 1) { 853 out_msg.addr := address; 854 out_msg.Type := in_msg.Type; 855 out_msg.Requestor := in_msg.Requestor; 856 out_msg.DataBlk := in_msg.DataBlk; 857 out_msg.Destination.add(mapAddressToRange(address,MachineType:TCC, 858 TCC_select_low_bit, TCC_select_num_bits)); 859 out_msg.Shared := in_msg.Shared; 860 out_msg.MessageSize := in_msg.MessageSize; 861 } 862 APPEND_TRANSITION_COMMENT(" requestor "); 863 APPEND_TRANSITION_COMMENT(in_msg.Requestor); 864 865 } 866 } 867 868 869 action(sc_probeShrCoreData, "sc", desc="probe shared cores, return data") { 870 MachineID tcc := mapAddressToRange(address,MachineType:TCC, 871 TCC_select_low_bit, TCC_select_num_bits); 872 873 temp := cache_entry.Sharers; 874 temp.addNetDest(cache_entry.Owner); 875 if (temp.isElement(tcc)) { 876 temp.remove(tcc); 877 } 878 if (temp.count() > 0) { 879 enqueue(probeToCore_out, TDProbeRequestMsg, response_latency) { 880 out_msg.addr := address; 881 out_msg.Type := ProbeRequestType:PrbDowngrade; 882 out_msg.ReturnData := true; 883 out_msg.MessageSize := MessageSizeType:Control; 884 out_msg.Destination := temp; 885 tbe.NumPendingAcks := temp.count(); 886 if(cache_entry.CacheState == State:M) { 887 assert(tbe.NumPendingAcks == 1); 888 } 889 DPRINTF(RubySlicc, "%s\n", (out_msg)); 890 } 891 } 892 } 893 894 action(ls2_probeShrL2Data, "ls2", desc="local probe downgrade L2, return data") { 895 MachineID tcc := mapAddressToRange(address,MachineType:TCC, 896 TCC_select_low_bit, TCC_select_num_bits); 897 if ((cache_entry.Sharers.isElement(tcc)) || (cache_entry.Owner.isElement(tcc))) { 898 enqueue(w_probeTCC_out, TDProbeRequestMsg, 1) { 899 out_msg.addr := address; 900 out_msg.Type := ProbeRequestType:PrbDowngrade; 901 out_msg.ReturnData := true; 902 out_msg.MessageSize := MessageSizeType:Control; 903 out_msg.Destination.add(tcc); 904 tbe.NumPendingAcks := tbe.NumPendingAcks + 1; 905 DPRINTF(RubySlicc, "%s\n", out_msg); 906 907 } 908 } 909 } 910 911 action(s2_probeShrL2Data, "s2", desc="probe shared L2, return data") { 912 MachineID tcc := mapAddressToRange(address,MachineType:TCC, 913 TCC_select_low_bit, TCC_select_num_bits); 914 if ((cache_entry.Sharers.isElement(tcc)) || (cache_entry.Owner.isElement(tcc))) { 915 enqueue(w_probeTCC_out, TDProbeRequestMsg, 1) { 916 out_msg.addr := address; 917 out_msg.Type := ProbeRequestType:PrbDowngrade; 918 out_msg.ReturnData := true; 919 out_msg.MessageSize := MessageSizeType:Control; 920 out_msg.Destination.add(tcc); 921 tbe.NumPendingAcks := tbe.NumPendingAcks + 1; 922 DPRINTF(RubySlicc, "%s\n", out_msg); 923 924 } 925 } 926 } 927 928 action(ldc_probeInvCoreData, "ldc", desc="local probe to inv cores, return data") { 929 MachineID tcc := mapAddressToRange(address,MachineType:TCC, 930 TCC_select_low_bit, TCC_select_num_bits); 931 peek(coreRequestNetwork_in, CPURequestMsg) { 932 NetDest dest:= cache_entry.Sharers; 933 dest.addNetDest(cache_entry.Owner); 934 if(dest.isElement(tcc)){ 935 dest.remove(tcc); 936 } 937 dest.remove(in_msg.Requestor); 938 tbe.NumPendingAcks := dest.count(); 939 if (dest.count()>0){ 940 enqueue(probeToCore_out, TDProbeRequestMsg, response_latency) { 941 out_msg.addr := address; 942 out_msg.Type := ProbeRequestType:PrbInv; 943 out_msg.ReturnData := true; 944 out_msg.MessageSize := MessageSizeType:Control; 945 946 out_msg.Destination.addNetDest(dest); 947 if(cache_entry.CacheState == State:M) { 948 assert(tbe.NumPendingAcks == 1); 949 } 950 951 DPRINTF(RubySlicc, "%s\n", (out_msg)); 952 } 953 } 954 } 955 } 956 957 action(ld2_probeInvL2Data, "ld2", desc="local probe inv L2, return data") { 958 MachineID tcc := mapAddressToRange(address,MachineType:TCC, 959 TCC_select_low_bit, TCC_select_num_bits); 960 if ((cache_entry.Sharers.isElement(tcc)) || (cache_entry.Owner.isElement(tcc))) { 961 enqueue(w_probeTCC_out, TDProbeRequestMsg, 1) { 962 out_msg.addr := address; 963 out_msg.Type := ProbeRequestType:PrbInv; 964 out_msg.ReturnData := true; 965 out_msg.MessageSize := MessageSizeType:Control; 966 out_msg.Destination.add(tcc); 967 tbe.NumPendingAcks := tbe.NumPendingAcks + 1; 968 DPRINTF(RubySlicc, "%s\n", out_msg); 969 970 } 971 } 972 } 973 974 action(dc_probeInvCoreData, "dc", desc="probe inv cores + TCC, return data") { 975 MachineID tcc := mapAddressToRange(address,MachineType:TCC, 976 TCC_select_low_bit, TCC_select_num_bits); 977 enqueue(probeToCore_out, TDProbeRequestMsg, response_latency) { 978 out_msg.addr := address; 979 out_msg.Type := ProbeRequestType:PrbInv; 980 out_msg.ReturnData := true; 981 out_msg.MessageSize := MessageSizeType:Control; 982 983 out_msg.Destination.addNetDest(cache_entry.Sharers); 984 out_msg.Destination.addNetDest(cache_entry.Owner); 985 tbe.NumPendingAcks := cache_entry.Sharers.count() + cache_entry.Owner.count(); 986 if(cache_entry.CacheState == State:M) { 987 assert(tbe.NumPendingAcks == 1); 988 } 989 if (out_msg.Destination.isElement(tcc)) { 990 out_msg.Destination.remove(tcc); 991 tbe.NumPendingAcks := tbe.NumPendingAcks - 1; 992 } 993 994 DPRINTF(RubySlicc, "%s\n", (out_msg)); 995 } 996 } 997 998 action(d2_probeInvL2Data, "d2", desc="probe inv L2, return data") { 999 MachineID tcc := mapAddressToRange(address,MachineType:TCC, 1000 TCC_select_low_bit, TCC_select_num_bits); 1001 if ((cache_entry.Sharers.isElement(tcc)) || (cache_entry.Owner.isElement(tcc))) { 1002 enqueue(w_probeTCC_out, TDProbeRequestMsg, 1) { 1003 out_msg.addr := address; 1004 out_msg.Type := ProbeRequestType:PrbInv; 1005 out_msg.ReturnData := true; 1006 out_msg.MessageSize := MessageSizeType:Control; 1007 out_msg.Destination.add(tcc); 1008 tbe.NumPendingAcks := tbe.NumPendingAcks + 1; 1009 DPRINTF(RubySlicc, "%s\n", out_msg); 1010 1011 } 1012 } 1013 } 1014 1015 action(lpc_probeInvCore, "lpc", desc="local probe inv cores, no data") { 1016 peek(coreRequestNetwork_in, CPURequestMsg) { 1017 TCC_dir_subtree.broadcast(MachineType:TCP); 1018 TCC_dir_subtree.broadcast(MachineType:SQC); 1019 1020 temp := cache_entry.Sharers; 1021 temp := temp.OR(cache_entry.Owner); 1022 TCC_dir_subtree := TCC_dir_subtree.AND(temp); 1023 tbe.NumPendingAcks := TCC_dir_subtree.count(); 1024 if(cache_entry.CacheState == State:M) { 1025 assert(tbe.NumPendingAcks == 1); 1026 } 1027 if(TCC_dir_subtree.isElement(in_msg.Requestor)) { 1028 TCC_dir_subtree.remove(in_msg.Requestor); 1029 tbe.NumPendingAcks := tbe.NumPendingAcks - 1; 1030 } 1031 1032 if(TCC_dir_subtree.count() > 0) { 1033 enqueue(probeToCore_out, TDProbeRequestMsg, response_latency) { 1034 out_msg.addr := address; 1035 out_msg.Type := ProbeRequestType:PrbInv; 1036 out_msg.ReturnData := false; 1037 out_msg.MessageSize := MessageSizeType:Control; 1038 out_msg.localCtoD := true; 1039 1040 out_msg.Destination.addNetDest(TCC_dir_subtree); 1041 1042 DPRINTF(RubySlicc, "%s\n", (out_msg)); 1043 } 1044 } 1045 } 1046 } 1047 1048 action(ipc_probeInvCore, "ipc", desc="probe inv cores, no data") { 1049 TCC_dir_subtree.broadcast(MachineType:TCP); 1050 TCC_dir_subtree.broadcast(MachineType:SQC); 1051 1052 temp := cache_entry.Sharers; 1053 temp := temp.OR(cache_entry.Owner); 1054 TCC_dir_subtree := TCC_dir_subtree.AND(temp); 1055 tbe.NumPendingAcks := TCC_dir_subtree.count(); 1056 if(TCC_dir_subtree.count() > 0) { 1057 1058 enqueue(probeToCore_out, TDProbeRequestMsg, response_latency) { 1059 out_msg.addr := address; 1060 out_msg.Type := ProbeRequestType:PrbInv; 1061 out_msg.ReturnData := false; 1062 out_msg.MessageSize := MessageSizeType:Control; 1063 1064 out_msg.Destination.addNetDest(TCC_dir_subtree); 1065 if(cache_entry.CacheState == State:M) { 1066 assert(tbe.NumPendingAcks == 1); 1067 } 1068 1069 DPRINTF(RubySlicc, "%s\n", (out_msg)); 1070 } 1071 } 1072 } 1073 1074 action(i2_probeInvL2, "i2", desc="probe inv L2, no data") { 1075 MachineID tcc := mapAddressToRange(address,MachineType:TCC, 1076 TCC_select_low_bit, TCC_select_num_bits); 1077 if ((cache_entry.Sharers.isElement(tcc)) || (cache_entry.Owner.isElement(tcc))) { 1078 enqueue(w_probeTCC_out, TDProbeRequestMsg, 1) { 1079 tbe.NumPendingAcks := tbe.NumPendingAcks + 1; 1080 out_msg.addr := address; 1081 out_msg.Type := ProbeRequestType:PrbInv; 1082 out_msg.ReturnData := false; 1083 out_msg.MessageSize := MessageSizeType:Control; 1084 out_msg.Destination.add(tcc); 1085 DPRINTF(RubySlicc, "%s\n", out_msg); 1086 1087 } 1088 } 1089 } 1090 1091 action(pi_sendProbeResponseInv, "pi", desc="send probe ack inv, no data") { 1092 enqueue(responseToNB_out, ResponseMsg, issue_latency) { 1093 out_msg.addr := address; 1094 out_msg.Type := CoherenceResponseType:CPUPrbResp; // TCC, L3 respond in same way to probes 1095 out_msg.Sender := machineID; 1096 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 1097 out_msg.Dirty := false; 1098 out_msg.Hit := false; 1099 out_msg.Ntsl := true; 1100 out_msg.State := CoherenceState:NA; 1101 out_msg.MessageSize := MessageSizeType:Response_Control; 1102 } 1103 } 1104 1105 action(pim_sendProbeResponseInvMs, "pim", desc="send probe ack inv, no data") { 1106 enqueue(responseToNB_out, ResponseMsg, issue_latency) { 1107 out_msg.addr := address; 1108 out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and TCC respond in same way to probes 1109 out_msg.Sender := machineID; 1110 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 1111 out_msg.Dirty := false; 1112 out_msg.Ntsl := true; 1113 out_msg.Hit := false; 1114 out_msg.State := CoherenceState:NA; 1115 out_msg.MessageSize := MessageSizeType:Response_Control; 1116 } 1117 } 1118 1119 action(prm_sendProbeResponseMiss, "prm", desc="send probe ack PrbShrData, no data") { 1120 enqueue(responseToNB_out, ResponseMsg, issue_latency) { 1121 out_msg.addr := address; 1122 out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and TCC respond in same way to probes 1123 out_msg.Sender := machineID; 1124 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 1125 out_msg.Dirty := false; // only true if sending back data i think 1126 out_msg.Hit := false; 1127 out_msg.Ntsl := false; 1128 out_msg.State := CoherenceState:NA; 1129 out_msg.MessageSize := MessageSizeType:Response_Control; 1130 } 1131 } 1132 1133 1134 1135 action(pd_sendProbeResponseData, "pd", desc="send probe ack, with data") { 1136 enqueue(responseToNB_out, ResponseMsg, issue_latency) { 1137 assert(is_valid(cache_entry) || is_valid(tbe)); 1138 out_msg.addr := address; 1139 out_msg.Type := CoherenceResponseType:CPUPrbResp; 1140 out_msg.Sender := machineID; 1141 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 1142 out_msg.DataBlk := getDataBlock(address); 1143 if (is_valid(tbe)) { 1144 out_msg.Dirty := tbe.Dirty; 1145 } 1146 out_msg.Hit := true; 1147 out_msg.State := CoherenceState:NA; 1148 out_msg.MessageSize := MessageSizeType:Response_Data; 1149 } 1150 } 1151 1152 1153 action(pdm_sendProbeResponseDataMs, "pdm", desc="send probe ack, with data") { 1154 enqueue(responseToNB_out, ResponseMsg, issue_latency) { 1155 assert(is_valid(cache_entry) || is_valid(tbe)); 1156 assert(is_valid(cache_entry)); 1157 out_msg.addr := address; 1158 out_msg.Type := CoherenceResponseType:CPUPrbResp; 1159 out_msg.Sender := machineID; 1160 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 1161 out_msg.DataBlk := getDataBlock(address); 1162 if (is_valid(tbe)) { 1163 out_msg.Dirty := tbe.Dirty; 1164 } 1165 out_msg.Hit := true; 1166 out_msg.State := CoherenceState:NA; 1167 out_msg.MessageSize := MessageSizeType:Response_Data; 1168 } 1169 } 1170 1171 action(mc_cancelWB, "mc", desc="send writeback cancel to NB directory") { 1172 enqueue(requestToNB_out, CPURequestMsg, issue_latency) { 1173 out_msg.addr := address; 1174 out_msg.Type := CoherenceRequestType:WrCancel; 1175 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 1176 out_msg.Requestor := machineID; 1177 out_msg.MessageSize := MessageSizeType:Request_Control; 1178 } 1179 } 1180 1181 action(sCS_sendCollectiveResponseS, "sCS", desc="send shared response to all merged TCP/SQC") { 1182 enqueue(responseToCore_out, ResponseMsg, 1) { 1183 out_msg.addr := address; 1184 out_msg.Type := CoherenceResponseType:TDSysResp; 1185 out_msg.Sender := tbe.Sender; 1186 out_msg.DataBlk := tbe.DataBlk; 1187 out_msg.MessageSize := MessageSizeType:Response_Data; 1188 out_msg.CtoD := false; 1189 out_msg.State := CoherenceState:Shared; 1190 out_msg.Destination.addNetDest(cache_entry.MergedSharers); 1191 out_msg.Shared := tbe.Shared; 1192 out_msg.Dirty := tbe.Dirty; 1193 DPRINTF(RubySlicc, "%s\n", out_msg); 1194 } 1195 } 1196 1197 action(sS_sendResponseS, "sS", desc="send shared response to TCP/SQC") { 1198 enqueue(responseToCore_out, ResponseMsg, 1) { 1199 out_msg.addr := address; 1200 out_msg.Type := CoherenceResponseType:TDSysResp; 1201 out_msg.Sender := tbe.Sender; 1202 out_msg.DataBlk := tbe.DataBlk; 1203 out_msg.MessageSize := MessageSizeType:Response_Data; 1204 out_msg.CtoD := false; 1205 out_msg.State := CoherenceState:Shared; 1206 out_msg.Destination.add(tbe.OriginalRequestor); 1207 out_msg.Shared := tbe.Shared; 1208 out_msg.Dirty := tbe.Dirty; 1209 DPRINTF(RubySlicc, "%s\n", out_msg); 1210 } 1211 } 1212 1213 action(sM_sendResponseM, "sM", desc="send response to TCP/SQC") { 1214 enqueue(responseToCore_out, ResponseMsg, 1) { 1215 out_msg.addr := address; 1216 out_msg.Type := CoherenceResponseType:TDSysResp; 1217 out_msg.Sender := tbe.Sender; 1218 out_msg.DataBlk := tbe.DataBlk; 1219 out_msg.MessageSize := MessageSizeType:Response_Data; 1220 out_msg.CtoD := false; 1221 out_msg.State := CoherenceState:Modified; 1222 out_msg.Destination.add(tbe.OriginalRequestor); 1223 out_msg.Shared := tbe.Shared; 1224 out_msg.Dirty := tbe.Dirty; 1225 DPRINTF(RubySlicc, "%s\n", out_msg); 1226 } 1227 } 1228 1229 1230 1231 action(fw2_forwardWBAck, "fw2", desc="forward WBAck to TCC") { 1232 peek(responseFromNB_in, ResponseMsg) { 1233 if(tbe.OriginalRequestor != machineID) { 1234 enqueue(w_respTCC_out, ResponseMsg, 1) { 1235 out_msg.addr := address; 1236 out_msg.Type := CoherenceResponseType:TDSysWBAck; 1237 out_msg.Sender := machineID; 1238 //out_msg.DataBlk := tbe.DataBlk; 1239 out_msg.Destination.add(tbe.OriginalRequestor); 1240 out_msg.MessageSize := in_msg.MessageSize; 1241 } 1242 } 1243 } 1244 } 1245 1246 action(sa_saveSysAck, "sa", desc="Save SysAck ") { 1247 peek(responseFromNB_in, ResponseMsg) { 1248 tbe.Dirty := in_msg.Dirty; 1249 if (tbe.Dirty == false) { 1250 tbe.DataBlk := in_msg.DataBlk; 1251 } 1252 else { 1253 tbe.DataBlk := tbe.DataBlk; 1254 } 1255 tbe.CtoD := in_msg.CtoD; 1256 tbe.CohState := in_msg.State; 1257 tbe.Shared := in_msg.Shared; 1258 tbe.MessageSize := in_msg.MessageSize; 1259 } 1260 } 1261 1262 action(fsa_forwardSavedAck, "fsa", desc="forward saved SysAck to TCP or SQC") { 1263 enqueue(responseToCore_out, ResponseMsg, 1) { 1264 out_msg.addr := address; 1265 out_msg.Type := CoherenceResponseType:TDSysResp; 1266 out_msg.Sender := machineID; 1267 if (tbe.Dirty == false) { 1268 out_msg.DataBlk := tbe.DataBlk; 1269 } 1270 else { 1271 out_msg.DataBlk := tbe.DataBlk; 1272 } 1273 out_msg.CtoD := tbe.CtoD; 1274 out_msg.State := tbe.CohState; 1275 out_msg.Destination.add(tbe.OriginalRequestor); 1276 out_msg.Shared := tbe.Shared; 1277 out_msg.MessageSize := tbe.MessageSize; 1278 out_msg.Dirty := tbe.Dirty; 1279 out_msg.Sender := tbe.Sender; 1280 } 1281 } 1282 1283 action(fa_forwardSysAck, "fa", desc="forward SysAck to TCP or SQC") { 1284 peek(responseFromNB_in, ResponseMsg) { 1285 enqueue(responseToCore_out, ResponseMsg, 1) { 1286 out_msg.addr := address; 1287 out_msg.Type := CoherenceResponseType:TDSysResp; 1288 out_msg.Sender := machineID; 1289 if (tbe.Dirty == false) { 1290 out_msg.DataBlk := in_msg.DataBlk; 1291 tbe.Sender := machineID; 1292 } 1293 else { 1294 out_msg.DataBlk := tbe.DataBlk; 1295 } 1296 out_msg.CtoD := in_msg.CtoD; 1297 out_msg.State := in_msg.State; 1298 out_msg.Destination.add(tbe.OriginalRequestor); 1299 out_msg.Shared := in_msg.Shared; 1300 out_msg.MessageSize := in_msg.MessageSize; 1301 out_msg.Dirty := in_msg.Dirty; 1302 out_msg.Sender := tbe.Sender; 1303 DPRINTF(RubySlicc, "%s\n", (out_msg.DataBlk)); 1304 } 1305 } 1306 } 1307 1308 action(pso_probeSharedDataOwner, "pso", desc="probe shared data at owner") { 1309 MachineID tcc := mapAddressToRange(address,MachineType:TCC, 1310 TCC_select_low_bit, TCC_select_num_bits); 1311 if (cache_entry.Owner.isElement(tcc)) { 1312 enqueue(w_probeTCC_out, TDProbeRequestMsg, 1) { 1313 out_msg.addr := address; 1314 out_msg.Type := ProbeRequestType:PrbDowngrade; 1315 out_msg.ReturnData := true; 1316 out_msg.MessageSize := MessageSizeType:Control; 1317 out_msg.Destination.add(tcc); 1318 DPRINTF(RubySlicc, "%s\n", out_msg); 1319 } 1320 } 1321 else { // i.e., owner is a core 1322 enqueue(probeToCore_out, TDProbeRequestMsg, response_latency) { 1323 out_msg.addr := address; 1324 out_msg.Type := ProbeRequestType:PrbDowngrade; 1325 out_msg.ReturnData := true; 1326 out_msg.MessageSize := MessageSizeType:Control; 1327 out_msg.Destination.addNetDest(cache_entry.Owner); 1328 DPRINTF(RubySlicc, "%s\n", out_msg); 1329 } 1330 } 1331 tbe.NumPendingAcks := 1; 1332 } 1333 1334 action(i_popIncomingRequestQueue, "i", desc="Pop incoming request queue") { 1335 coreRequestNetwork_in.dequeue(clockEdge()); 1336 } 1337 1338 action(j_popIncomingUnblockQueue, "j", desc="Pop incoming unblock queue") { 1339 unblockNetwork_in.dequeue(clockEdge()); 1340 } 1341 1342 action(pk_popResponseQueue, "pk", desc="Pop response queue") { 1343 responseNetwork_in.dequeue(clockEdge()); 1344 } 1345 1346 action(pp_popProbeQueue, "pp", desc="Pop incoming probe queue") { 1347 probeNetwork_in.dequeue(clockEdge()); 1348 } 1349 1350 action(pR_popResponseFromNBQueue, "pR", desc="Pop incoming Response queue From NB") { 1351 responseFromNB_in.dequeue(clockEdge()); 1352 } 1353 1354 action(pt_popTriggerQueue, "pt", desc="pop trigger queue") { 1355 triggerQueue_in.dequeue(clockEdge()); 1356 } 1357 1358 action(pl_popTCCRequestQueue, "pl", desc="pop TCC request queue") { 1359 w_TCCRequest_in.dequeue(clockEdge()); 1360 } 1361 1362 action(plr_popTCCResponseQueue, "plr", desc="pop TCC response queue") { 1363 w_TCCResponse_in.dequeue(clockEdge()); 1364 } 1365 1366 action(plu_popTCCUnblockQueue, "plu", desc="pop TCC unblock queue") { 1367 w_TCCUnblock_in.dequeue(clockEdge()); 1368 } 1369 1370 1371 action(m_addUnlockerToSharers, "m", desc="Add the unlocker to the sharer list") { 1372 peek(unblockNetwork_in, UnblockMsg) { 1373 cache_entry.Sharers.add(in_msg.Sender); 1374 cache_entry.MergedSharers.remove(in_msg.Sender); 1375 assert(cache_entry.WaitingUnblocks >= 0); 1376 cache_entry.WaitingUnblocks := cache_entry.WaitingUnblocks - 1; 1377 } 1378 } 1379 1380 action(q_addOutstandingMergedSharer, "q", desc="Increment outstanding requests") { 1381 peek(coreRequestNetwork_in, CPURequestMsg) { 1382 cache_entry.MergedSharers.add(in_msg.Requestor); 1383 cache_entry.WaitingUnblocks := cache_entry.WaitingUnblocks + 1; 1384 } 1385 } 1386 1387 action(uu_sendUnblock, "uu", desc="state changed, unblock") { 1388 enqueue(unblockToNB_out, UnblockMsg, issue_latency) { 1389 out_msg.addr := address; 1390 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 1391 out_msg.MessageSize := MessageSizeType:Unblock_Control; 1392 DPRINTF(RubySlicc, "%s\n", out_msg); 1393 } 1394 } 1395 1396 action(zz_recycleRequest, "\z", desc="Recycle the request queue") { 1397 coreRequestNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency)); 1398 } 1399 1400 action(yy_recycleTCCRequestQueue, "yy", desc="recycle yy request queue") { 1401 w_TCCRequest_in.recycle(clockEdge(), cyclesToTicks(recycle_latency)); 1402 } 1403 1404 action(xz_recycleResponseQueue, "xz", desc="recycle response queue") { 1405 responseNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency)); 1406 } 1407 1408 action(xx_recycleTCCResponseQueue, "xx", desc="recycle TCC response queue") { 1409 w_TCCResponse_in.recycle(clockEdge(), cyclesToTicks(recycle_latency)); 1410 } 1411 1412 action(vv_recycleTCCUnblockQueue, "vv", desc="Recycle the probe request queue") { 1413 w_TCCUnblock_in.recycle(clockEdge(), cyclesToTicks(recycle_latency)); 1414 } 1415 1416 action(xy_recycleUnblockQueue, "xy", desc="Recycle the probe request queue") { 1417 w_TCCUnblock_in.recycle(clockEdge(), cyclesToTicks(recycle_latency)); 1418 } 1419 1420 action(ww_recycleProbeRequest, "ww", desc="Recycle the probe request queue") { 1421 probeNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency)); 1422 } 1423 1424 action(x_decrementAcks, "x", desc="decrement Acks pending") { 1425 tbe.NumPendingAcks := tbe.NumPendingAcks - 1; 1426 } 1427 1428 action(o_checkForAckCompletion, "o", desc="check for ack completion") { 1429 if (tbe.NumPendingAcks == 0) { 1430 enqueue(triggerQueue_out, TriggerMsg, 1) { 1431 out_msg.addr := address; 1432 out_msg.Type := TriggerType:AcksComplete; 1433 } 1434 } 1435 APPEND_TRANSITION_COMMENT(" tbe acks "); 1436 APPEND_TRANSITION_COMMENT(tbe.NumPendingAcks); 1437 } 1438 1439 action(tp_allocateTBE, "tp", desc="allocate TBE Entry for upward transactions") { 1440 check_allocate(TBEs); 1441 peek(probeNetwork_in, NBProbeRequestMsg) { 1442 TBEs.allocate(address); 1443 set_tbe(TBEs.lookup(address)); 1444 tbe.Dirty := false; 1445 tbe.NumPendingAcks := 0; 1446 tbe.UntransferredOwnerExists := false; 1447 } 1448 } 1449 1450 action(tv_allocateTBE, "tv", desc="allocate TBE Entry for TCC transactions") { 1451 check_allocate(TBEs); 1452 peek(w_TCCRequest_in, CPURequestMsg) { 1453 TBEs.allocate(address); 1454 set_tbe(TBEs.lookup(address)); 1455 tbe.DataBlk := in_msg.DataBlk; // Data only for WBs 1456 tbe.Dirty := false; 1457 tbe.OriginalRequestor := in_msg.Requestor; 1458 tbe.NumPendingAcks := 0; 1459 tbe.UntransferredOwnerExists := false; 1460 } 1461 } 1462 1463 action(t_allocateTBE, "t", desc="allocate TBE Entry") { 1464 check_allocate(TBEs);//check whether resources are full 1465 peek(coreRequestNetwork_in, CPURequestMsg) { 1466 TBEs.allocate(address); 1467 set_tbe(TBEs.lookup(address)); 1468 tbe.DataBlk := cache_entry.DataBlk; // Data only for WBs 1469 tbe.Dirty := false; 1470 tbe.Upgrade := false; 1471 tbe.OriginalRequestor := in_msg.Requestor; 1472 tbe.NumPendingAcks := 0; 1473 tbe.UntransferredOwnerExists := false; 1474 tbe.Sender := machineID; 1475 } 1476 } 1477 1478 action(tr_allocateTBE, "tr", desc="allocate TBE Entry for recall") { 1479 check_allocate(TBEs);//check whether resources are full 1480 TBEs.allocate(address); 1481 set_tbe(TBEs.lookup(address)); 1482 tbe.DataBlk := cache_entry.DataBlk; // Data only for WBs 1483 tbe.Dirty := false; 1484 tbe.Upgrade := false; 1485 tbe.OriginalRequestor := machineID; //Recall request, Self initiated 1486 tbe.NumPendingAcks := 0; 1487 tbe.UntransferredOwnerExists := false; 1488 } 1489 1490 action(dt_deallocateTBE, "dt", desc="Deallocate TBE entry") { 1491 TBEs.deallocate(address); 1492 unset_tbe(); 1493 } 1494 1495 1496 action(d_allocateDir, "d", desc="allocate Directory Cache") { 1497 if (is_invalid(cache_entry)) { 1498 set_cache_entry(directory.allocate(address, new Entry)); 1499 } 1500 } 1501 1502 action(dd_deallocateDir, "dd", desc="deallocate Directory Cache") { 1503 if (is_valid(cache_entry)) { 1504 directory.deallocate(address); 1505 } 1506 unset_cache_entry(); 1507 } 1508 1509 action(ss_sendStaleNotification, "ss", desc="stale data; nothing to writeback") { 1510 enqueue(responseToNB_out, ResponseMsg, issue_latency) { 1511 out_msg.addr := address; 1512 out_msg.Type := CoherenceResponseType:StaleNotif; 1513 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 1514 out_msg.Sender := machineID; 1515 out_msg.MessageSize := MessageSizeType:Response_Control; 1516 } 1517 } 1518 1519 action(wb_data, "wb", desc="write back data") { 1520 enqueue(responseToNB_out, ResponseMsg, issue_latency) { 1521 out_msg.addr := address; 1522 out_msg.Type := CoherenceResponseType:CPUData; 1523 out_msg.Sender := machineID; 1524 out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); 1525 out_msg.DataBlk := tbe.DataBlk; 1526 out_msg.Dirty := tbe.Dirty; 1527 if (tbe.Shared) { 1528 out_msg.NbReqShared := true; 1529 } else { 1530 out_msg.NbReqShared := false; 1531 } 1532 out_msg.State := CoherenceState:Shared; // faux info 1533 out_msg.MessageSize := MessageSizeType:Writeback_Data; 1534 DPRINTF(RubySlicc, "%s\n", out_msg); 1535 } 1536 } 1537 1538 action(sf_setSharedFlip, "sf", desc="hit by shared probe, status may be different") { 1539 assert(is_valid(tbe)); 1540 tbe.Shared := true; 1541 } 1542 1543 action(y_writeDataToTBE, "y", desc="write Probe Data to TBE") { 1544 peek(responseNetwork_in, ResponseMsg) { 1545 if (!tbe.Dirty || in_msg.Dirty) { 1546 tbe.DataBlk := in_msg.DataBlk; 1547 tbe.Dirty := in_msg.Dirty; 1548 } 1549 if (in_msg.Hit) { 1550 tbe.Cached := true; 1551 } 1552 } 1553 } 1554 1555 action(ty_writeTCCDataToTBE, "ty", desc="write TCC Probe Data to TBE") { 1556 peek(w_TCCResponse_in, ResponseMsg) { 1557 if (!tbe.Dirty || in_msg.Dirty) { 1558 tbe.DataBlk := in_msg.DataBlk; 1559 tbe.Dirty := in_msg.Dirty; 1560 } 1561 if (in_msg.Hit) { 1562 tbe.Cached := true; 1563 } 1564 } 1565 } 1566 1567 1568 action(ut_updateTag, "ut", desc="update Tag (i.e. set MRU)") { 1569 directory.setMRU(address); 1570 } 1571 1572 // TRANSITIONS 1573 1574 // Handling TCP/SQC requests (similar to how NB dir handles TCC events with some changes to account for stateful directory). 1575 1576 1577 // transitions from base 1578 transition(I, RdBlk, I_ES){TagArrayRead} { 1579 d_allocateDir; 1580 t_allocateTBE; 1581 n_issueRdBlk; 1582 i_popIncomingRequestQueue; 1583 } 1584 1585 transition(I, RdBlkS, I_S){TagArrayRead} { 1586 d_allocateDir; 1587 t_allocateTBE; 1588 nS_issueRdBlkS; 1589 i_popIncomingRequestQueue; 1590 } 1591 1592 1593 transition(I_S, NB_AckS, BBB_S) { 1594 fa_forwardSysAck; 1595 pR_popResponseFromNBQueue; 1596 } 1597 1598 transition(I_ES, NB_AckS, BBB_S) { 1599 fa_forwardSysAck; 1600 pR_popResponseFromNBQueue; 1601 } 1602 1603 transition(I_ES, NB_AckE, BBB_E) { 1604 fa_forwardSysAck; 1605 pR_popResponseFromNBQueue; 1606 } 1607 1608 transition({S_M, O_M}, {NB_AckCtoD,NB_AckM}, BBB_M) { 1609 fa_forwardSysAck; 1610 pR_popResponseFromNBQueue; 1611 } 1612 1613 transition(I_M, NB_AckM, BBB_M) { 1614 fa_forwardSysAck; 1615 pR_popResponseFromNBQueue; 1616 } 1617 1618 transition(BBB_M, CoreUnblock, M){TagArrayWrite} { 1619 c_clearOwner; 1620 cc_clearSharers; 1621 e_ownerIsUnblocker; 1622 uu_sendUnblock; 1623 dt_deallocateTBE; 1624 j_popIncomingUnblockQueue; 1625 } 1626 1627 transition(BBB_S, CoreUnblock, S){TagArrayWrite} { 1628 as_addToSharers; 1629 uu_sendUnblock; 1630 dt_deallocateTBE; 1631 j_popIncomingUnblockQueue; 1632 } 1633 1634 transition(BBB_E, CoreUnblock, E){TagArrayWrite} { 1635 as_addToSharers; 1636 uu_sendUnblock; 1637 dt_deallocateTBE; 1638 j_popIncomingUnblockQueue; 1639 } 1640 1641 1642 transition(I, RdBlkM, I_M){TagArrayRead} { 1643 d_allocateDir; 1644 t_allocateTBE; 1645 nM_issueRdBlkM; 1646 i_popIncomingRequestQueue; 1647 } 1648 1649 // 1650 transition(S, {RdBlk, RdBlkS}, BBS_S){TagArrayRead} { 1651 t_allocateTBE; 1652 sc_probeShrCoreData; 1653 s2_probeShrL2Data; 1654 q_addOutstandingMergedSharer; 1655 i_popIncomingRequestQueue; 1656 } 1657 // Merging of read sharing into a single request 1658 transition(BBS_S, {RdBlk, RdBlkS}) { 1659 q_addOutstandingMergedSharer; 1660 i_popIncomingRequestQueue; 1661 } 1662 // Wait for probe acks to be complete 1663 transition(BBS_S, CPUPrbResp) { 1664 ccr_copyCoreResponseToTBE; 1665 x_decrementAcks; 1666 o_checkForAckCompletion; 1667 pk_popResponseQueue; 1668 } 1669 1670 transition(BBS_S, TCCPrbResp) { 1671 ctr_copyTCCResponseToTBE; 1672 x_decrementAcks; 1673 o_checkForAckCompletion; 1674 plr_popTCCResponseQueue; 1675 } 1676 1677 // Window for merging complete with this transition 1678 // Send responses to all outstanding 1679 transition(BBS_S, ProbeAcksComplete, BB_S) { 1680 sCS_sendCollectiveResponseS; 1681 pt_popTriggerQueue; 1682 } 1683 1684 transition(BB_S, CoreUnblock, BB_S) { 1685 m_addUnlockerToSharers; 1686 j_popIncomingUnblockQueue; 1687 } 1688 1689 transition(BB_S, LastCoreUnblock, S) { 1690 m_addUnlockerToSharers; 1691 dt_deallocateTBE; 1692 j_popIncomingUnblockQueue; 1693 } 1694 1695 transition(O, {RdBlk, RdBlkS}, BBO_O){TagArrayRead} { 1696 t_allocateTBE; 1697 pso_probeSharedDataOwner; 1698 q_addOutstandingMergedSharer; 1699 i_popIncomingRequestQueue; 1700 } 1701 // Merging of read sharing into a single request 1702 transition(BBO_O, {RdBlk, RdBlkS}) { 1703 q_addOutstandingMergedSharer; 1704 i_popIncomingRequestQueue; 1705 } 1706 1707 // Wait for probe acks to be complete 1708 transition(BBO_O, CPUPrbResp) { 1709 ccr_copyCoreResponseToTBE; 1710 x_decrementAcks; 1711 o_checkForAckCompletion; 1712 pk_popResponseQueue; 1713 } 1714 1715 transition(BBO_O, TCCPrbResp) { 1716 ctr_copyTCCResponseToTBE; 1717 x_decrementAcks; 1718 o_checkForAckCompletion; 1719 plr_popTCCResponseQueue; 1720 } 1721 1722 // Window for merging complete with this transition 1723 // Send responses to all outstanding 1724 transition(BBO_O, ProbeAcksComplete, BB_OO) { 1725 sCS_sendCollectiveResponseS; 1726 pt_popTriggerQueue; 1727 } 1728 1729 transition(BB_OO, CoreUnblock) { 1730 m_addUnlockerToSharers; 1731 j_popIncomingUnblockQueue; 1732 } 1733 1734 transition(BB_OO, LastCoreUnblock, O){TagArrayWrite} { 1735 m_addUnlockerToSharers; 1736 dt_deallocateTBE; 1737 j_popIncomingUnblockQueue; 1738 } 1739 1740 transition(S, CPUWrite, BW_S){TagArrayRead} { 1741 t_allocateTBE; 1742 rC_removeCoreFromSharers; 1743 sT_sendRequestToTCC; 1744 i_popIncomingRequestQueue; 1745 } 1746 1747 transition(E, CPUWrite, BW_E){TagArrayRead} { 1748 t_allocateTBE; 1749 rC_removeCoreFromSharers; 1750 sT_sendRequestToTCC; 1751 i_popIncomingRequestQueue; 1752 } 1753 1754 transition(O, CPUWrite, BW_O){TagArrayRead} { 1755 t_allocateTBE; 1756 rCo_removeCoreFromOwner; 1757 rC_removeCoreFromSharers; 1758 sT_sendRequestToTCC; 1759 i_popIncomingRequestQueue; 1760 } 1761 1762 transition(M, CPUWrite, BW_M){TagArrayRead} { 1763 t_allocateTBE; 1764 rCo_removeCoreFromOwner; 1765 rC_removeCoreFromSharers; 1766 sT_sendRequestToTCC; 1767 i_popIncomingRequestQueue; 1768 } 1769 1770 transition(BW_S, TCCUnblock_Sharer, S){TagArrayWrite} { 1771 aT_addTCCToSharers; 1772 dt_deallocateTBE; 1773 plu_popTCCUnblockQueue; 1774 } 1775 1776 transition(BW_S, TCCUnblock_NotValid, S){TagArrayWrite} { 1777 dt_deallocateTBE; 1778 plu_popTCCUnblockQueue; 1779 } 1780 1781 transition(BW_E, TCCUnblock, E){TagArrayWrite} { 1782 cc_clearSharers; 1783 aT_addTCCToSharers; 1784 dt_deallocateTBE; 1785 plu_popTCCUnblockQueue; 1786 } 1787 1788 transition(BW_E, TCCUnblock_NotValid, E) { 1789 dt_deallocateTBE; 1790 plu_popTCCUnblockQueue; 1791 } 1792 1793 transition(BW_M, TCCUnblock, M) { 1794 c_clearOwner; 1795 cc_clearSharers; 1796 eT_ownerIsUnblocker; 1797 dt_deallocateTBE; 1798 plu_popTCCUnblockQueue; 1799 } 1800 1801 transition(BW_M, TCCUnblock_NotValid, M) { 1802 // Note this transition should only be executed if we received a stale wb 1803 dt_deallocateTBE; 1804 plu_popTCCUnblockQueue; 1805 } 1806 1807 transition(BW_O, TCCUnblock, O) { 1808 c_clearOwner; 1809 eT_ownerIsUnblocker; 1810 dt_deallocateTBE; 1811 plu_popTCCUnblockQueue; 1812 } 1813 1814 transition(BW_O, TCCUnblock_NotValid, O) { 1815 // Note this transition should only be executed if we received a stale wb 1816 dt_deallocateTBE; 1817 plu_popTCCUnblockQueue; 1818 } 1819 1820 // We lost the owner likely do to an invalidation racing with a 'O' wb 1821 transition(BW_O, TCCUnblock_Sharer, S) { 1822 c_clearOwner; 1823 aT_addTCCToSharers; 1824 dt_deallocateTBE; 1825 plu_popTCCUnblockQueue; 1826 } 1827 1828 transition({BW_M, BW_S, BW_E, BW_O}, {PrbInv,PrbInvData,PrbShrData}) { 1829 ww_recycleProbeRequest; 1830 } 1831 1832 transition(BRWD_I, {PrbInvData, PrbInv, PrbShrData}) { 1833 ww_recycleProbeRequest; 1834 } 1835 1836 // Three step process: locally invalidate others, issue CtoD, wait for NB_AckCtoD 1837 transition(S, CtoD, BBS_UM) {TagArrayRead} { 1838 t_allocateTBE; 1839 lpc_probeInvCore; 1840 i2_probeInvL2; 1841 o_checkForAckCompletion; 1842 i_popIncomingRequestQueue; 1843 } 1844 1845 transition(BBS_UM, CPUPrbResp, BBS_UM) { 1846 x_decrementAcks; 1847 o_checkForAckCompletion; 1848 pk_popResponseQueue; 1849 } 1850 1851 transition(BBS_UM, TCCPrbResp) { 1852 x_decrementAcks; 1853 o_checkForAckCompletion; 1854 plr_popTCCResponseQueue; 1855 } 1856 1857 transition(BBS_UM, ProbeAcksComplete, S_M) { 1858 rU_rememberUpgrade; 1859 nM_issueRdBlkM; 1860 pt_popTriggerQueue; 1861 } 1862 1863 // Three step process: locally invalidate others, issue CtoD, wait for NB_AckCtoD 1864 transition(O, CtoD, BBO_UM){TagArrayRead} { 1865 t_allocateTBE; 1866 lpc_probeInvCore; 1867 i2_probeInvL2; 1868 o_checkForAckCompletion; 1869 i_popIncomingRequestQueue; 1870 } 1871 1872 transition(BBO_UM, CPUPrbResp, BBO_UM) { 1873 ruo_rememberUntransferredOwner; 1874 x_decrementAcks; 1875 o_checkForAckCompletion; 1876 pk_popResponseQueue; 1877 } 1878 1879 transition(BBO_UM, TCCPrbResp) { 1880 ruoT_rememberUntransferredOwnerTCC; 1881 x_decrementAcks; 1882 o_checkForAckCompletion; 1883 plr_popTCCResponseQueue; 1884 } 1885 1886 transition(BBO_UM, ProbeAcksComplete, O_M) { 1887 rU_rememberUpgrade; 1888 nM_issueRdBlkM; 1889 pt_popTriggerQueue; 1890 } 1891 1892 transition({S,E}, RdBlkM, BBS_M){TagArrayWrite} { 1893 t_allocateTBE; 1894 ldc_probeInvCoreData; 1895 ld2_probeInvL2Data; 1896 o_checkForAckCompletion; 1897 i_popIncomingRequestQueue; 1898 } 1899 1900 transition(BBS_M, CPUPrbResp) { 1901 ccr_copyCoreResponseToTBE; 1902 rR_removeResponderFromSharers; 1903 x_decrementAcks; 1904 o_checkForAckCompletion; 1905 pk_popResponseQueue; 1906 } 1907 1908 transition(BBS_M, TCCPrbResp) { 1909 ctr_copyTCCResponseToTBE; 1910 x_decrementAcks; 1911 o_checkForAckCompletion; 1912 plr_popTCCResponseQueue; 1913 } 1914 1915 transition(BBS_M, ProbeAcksComplete, S_M) { 1916 nM_issueRdBlkM; 1917 pt_popTriggerQueue; 1918 } 1919 1920 transition(O, RdBlkM, BBO_M){TagArrayRead} { 1921 t_allocateTBE; 1922 ldc_probeInvCoreData; 1923 ld2_probeInvL2Data; 1924 o_checkForAckCompletion; 1925 i_popIncomingRequestQueue; 1926 } 1927 1928 transition(BBO_M, CPUPrbResp) { 1929 ccr_copyCoreResponseToTBE; 1930 rR_removeResponderFromSharers; 1931 x_decrementAcks; 1932 o_checkForAckCompletion; 1933 pk_popResponseQueue; 1934 } 1935 1936 transition(BBO_M, TCCPrbResp) { 1937 ctr_copyTCCResponseToTBE; 1938 x_decrementAcks; 1939 o_checkForAckCompletion; 1940 plr_popTCCResponseQueue; 1941 } 1942 1943 transition(BBO_M, ProbeAcksComplete, O_M) { 1944 nM_issueRdBlkM; 1945 pt_popTriggerQueue; 1946 } 1947 1948 // 1949 transition(M, RdBlkM, BBM_M){TagArrayRead} { 1950 t_allocateTBE; 1951 ldc_probeInvCoreData; 1952 ld2_probeInvL2Data; 1953 i_popIncomingRequestQueue; 1954 } 1955 1956 transition(BBM_M, CPUPrbResp) { 1957 ccr_copyCoreResponseToTBE; 1958 x_decrementAcks; 1959 o_checkForAckCompletion; 1960 pk_popResponseQueue; 1961 } 1962 1963 // TCP recalled block before receiving probe 1964 transition({BBM_M, BBS_M, BBO_M}, {CPUWrite,NoCPUWrite}) { 1965 zz_recycleRequest; 1966 } 1967 1968 transition(BBM_M, TCCPrbResp) { 1969 ctr_copyTCCResponseToTBE; 1970 x_decrementAcks; 1971 o_checkForAckCompletion; 1972 plr_popTCCResponseQueue; 1973 } 1974 1975 transition(BBM_M, ProbeAcksComplete, BB_M) { 1976 sM_sendResponseM; 1977 pt_popTriggerQueue; 1978 } 1979 1980 transition(BB_M, CoreUnblock, M){TagArrayWrite} { 1981 e_ownerIsUnblocker; 1982 dt_deallocateTBE; 1983 j_popIncomingUnblockQueue; 1984 } 1985 1986 transition(M, {RdBlkS, RdBlk}, BBM_O){TagArrayRead} { 1987 t_allocateTBE; 1988 sc_probeShrCoreData; 1989 s2_probeShrL2Data; 1990 i_popIncomingRequestQueue; 1991 } 1992 1993 transition(E, {RdBlkS, RdBlk}, BBM_O){TagArrayRead} { 1994 t_allocateTBE; 1995 eto_moveExSharerToOwner; 1996 sc_probeShrCoreData; 1997 s2_probeShrL2Data; 1998 i_popIncomingRequestQueue; 1999 } 2000 2001 transition(BBM_O, CPUPrbResp) { 2002 ccr_copyCoreResponseToTBE; 2003 x_decrementAcks; 2004 o_checkForAckCompletion; 2005 pk_popResponseQueue; 2006 } 2007 transition(BBM_O, TCCPrbResp) { 2008 ctr_copyTCCResponseToTBE; 2009 x_decrementAcks; 2010 o_checkForAckCompletion; 2011 plr_popTCCResponseQueue; 2012 } 2013 transition(BBM_O, ProbeAcksComplete, BB_O) { 2014 sS_sendResponseS; 2015 pt_popTriggerQueue; 2016 } 2017 2018 transition(BB_O, CoreUnblock, O){TagArrayWrite} { 2019 as_addToSharers; 2020 dt_deallocateTBE; 2021 j_popIncomingUnblockQueue; 2022 } 2023 2024 transition({BBO_O, BBM_M, BBS_S, BBM_O, BB_M, BB_O, BB_S, BBO_UM, BBS_UM, BBS_M, BBO_M, BB_OO}, {PrbInvData, PrbInv,PrbShrData}) { 2025 ww_recycleProbeRequest; 2026 } 2027 2028 transition({BBM_O, BBS_S, CP_S, CP_O, CP_SM, CP_OM, BBO_O}, {CPUWrite,NoCPUWrite}) { 2029 zz_recycleRequest; 2030 } 2031 2032 // stale CtoD raced with external invalidation 2033 transition({I, CP_I, B_I, CP_IOM, CP_ISM, CP_OSIW, BRWD_I, BRW_I, BRD_I}, CtoD) { 2034 i_popIncomingRequestQueue; 2035 } 2036 2037 // stale CtoD raced with internal RdBlkM 2038 transition({BBM_M, BBS_M, BBO_M, BBB_M, BBS_UM, BBO_UM}, CtoD) { 2039 i_popIncomingRequestQueue; 2040 } 2041 2042 transition({E, M}, CtoD) { 2043 i_popIncomingRequestQueue; 2044 } 2045 2046 2047 // TCC-directory has sent out (And potentially received acks for) probes. 2048 // TCP/SQC replacement (known to be stale subsequent) are popped off. 2049 transition({BBO_UM, BBS_UM}, {CPUWrite,NoCPUWrite}) { 2050 nC_sendNullWBAckToCore; 2051 i_popIncomingRequestQueue; 2052 } 2053 2054 transition(S_M, {NoCPUWrite, CPUWrite}) { 2055 zz_recycleRequest; 2056 } 2057 2058 transition(O_M, {NoCPUWrite, CPUWrite}) { 2059 zz_recycleRequest; 2060 } 2061 2062 2063 transition({BBM_M, BBS_M, BBO_M, BBO_UM, BBS_UM}, {VicDirty, VicClean, VicDirtyLast, NoVic}) { 2064 nT_sendNullWBAckToTCC; 2065 pl_popTCCRequestQueue; 2066 } 2067 2068 transition({CP_S, CP_O, CP_OM, CP_SM}, {VicDirty, VicClean, VicDirtyLast, CancelWB, NoVic}) { 2069 yy_recycleTCCRequestQueue; 2070 } 2071 2072 // However, when TCCdir has sent out PrbSharedData, one cannot ignore. 2073 transition({BBS_S, BBO_O, BBM_O, S_M, O_M, BBB_M, BBB_S, BBB_E}, {VicDirty, VicClean, VicDirtyLast,CancelWB}) { 2074 yy_recycleTCCRequestQueue; 2075 } 2076 2077 transition({BW_S,BW_E,BW_O, BW_M}, {VicDirty, VicClean, VicDirtyLast, NoVic}) { 2078 yy_recycleTCCRequestQueue; 2079 } 2080 2081 transition({BW_S,BW_E,BW_O, BW_M}, CancelWB) { 2082 nT_sendNullWBAckToTCC; 2083 pl_popTCCRequestQueue; 2084 } 2085 2086 2087 /// recycle if waiting for unblocks. 2088 transition({BB_M,BB_O,BB_S,BB_OO}, {VicDirty, VicClean, VicDirtyLast,NoVic,CancelWB}) { 2089 yy_recycleTCCRequestQueue; 2090 } 2091 2092 transition({BBS_S, BBO_O}, NoVic) { 2093 rT_removeTCCFromSharers; 2094 nT_sendNullWBAckToTCC; 2095 pl_popTCCRequestQueue; 2096 } 2097 2098 // stale. Pop message and send dummy ack. 2099 transition({I_S, I_ES, I_M}, {VicDirty, VicClean, VicDirtyLast, NoVic}) { 2100 nT_sendNullWBAckToTCC; 2101 pl_popTCCRequestQueue; 2102 } 2103 2104 transition(M, VicDirtyLast, VM_I){TagArrayRead} { 2105 tv_allocateTBE; 2106 vd_victim; 2107 pl_popTCCRequestQueue; 2108 } 2109 2110 transition(E, VicDirty, VM_I){TagArrayRead} { 2111 tv_allocateTBE; 2112 vd_victim; 2113 pl_popTCCRequestQueue; 2114 } 2115 2116 transition(O, VicDirty, VO_S){TagArrayRead} { 2117 tv_allocateTBE; 2118 vd_victim; 2119 pl_popTCCRequestQueue; 2120 } 2121 2122 transition(O, {VicDirtyLast, VicClean}, VO_I){TagArrayRead} { 2123 tv_allocateTBE; 2124 vd_victim; 2125 pl_popTCCRequestQueue; 2126 } 2127 2128 transition({E, S}, VicClean, VES_I){TagArrayRead} { 2129 tv_allocateTBE; 2130 vc_victim; 2131 pl_popTCCRequestQueue; 2132 } 2133 2134 transition({O, S}, NoVic){TagArrayRead} { 2135 rT_removeTCCFromSharers; 2136 nT_sendNullWBAckToTCC; 2137 pl_popTCCRequestQueue; 2138 } 2139 2140 transition({O,S}, NoCPUWrite){TagArrayRead} { 2141 rC_removeCoreFromSharers; 2142 nC_sendNullWBAckToCore; 2143 i_popIncomingRequestQueue; 2144 } 2145 2146 transition({M,E}, NoCPUWrite){TagArrayRead} { 2147 rC_removeCoreFromSharers; 2148 nC_sendNullWBAckToCore; 2149 i_popIncomingRequestQueue; 2150 } 2151 2152 // This can only happen if it is race. (TCCdir sent out probes which caused this cancel in the first place.) 2153 transition({VM_I, VES_I, VO_I}, CancelWB) { 2154 pl_popTCCRequestQueue; 2155 } 2156 2157 transition({VM_I, VES_I, VO_I}, NB_AckWB, I){TagArrayWrite} { 2158 c_clearOwner; 2159 cc_clearSharers; 2160 wb_data; 2161 fw2_forwardWBAck; 2162 dt_deallocateTBE; 2163 dd_deallocateDir; 2164 pR_popResponseFromNBQueue; 2165 } 2166 2167 transition(VO_S, NB_AckWB, S){TagArrayWrite} { 2168 c_clearOwner; 2169 wb_data; 2170 fw2_forwardWBAck; 2171 dt_deallocateTBE; 2172 pR_popResponseFromNBQueue; 2173 } 2174 2175 transition(I_C, NB_AckWB, I){TagArrayWrite} { 2176 c_clearOwner; 2177 cc_clearSharers; 2178 ss_sendStaleNotification; 2179 fw2_forwardWBAck; 2180 dt_deallocateTBE; 2181 dd_deallocateDir; 2182 pR_popResponseFromNBQueue; 2183 } 2184 2185 transition(I_W, NB_AckWB, I) { 2186 ss_sendStaleNotification; 2187 dt_deallocateTBE; 2188 dd_deallocateDir; 2189 pR_popResponseFromNBQueue; 2190 } 2191 2192 2193 2194 // Do not handle replacements, reads of any kind or writebacks from transients; recycle 2195 transition({I_M, I_ES, I_S, MO_I, ES_I, S_M, O_M, VES_I, VO_I, VO_S, VM_I, I_C, I_W}, {RdBlkS,RdBlkM,RdBlk,CtoD}) { 2196 zz_recycleRequest; 2197 } 2198 2199 transition( VO_S, NoCPUWrite) { 2200 zz_recycleRequest; 2201 } 2202 2203 transition({BW_M, BW_S, BW_O, BW_E}, {RdBlkS,RdBlkM,RdBlk,CtoD,NoCPUWrite, CPUWrite}) { 2204 zz_recycleRequest; 2205 } 2206 2207 transition({BBB_M, BBB_S, BBB_E, BB_O, BB_M, BB_S, BB_OO}, { RdBlk, RdBlkS, RdBlkM, CPUWrite, NoCPUWrite}) { 2208 zz_recycleRequest; 2209 } 2210 2211 transition({BBB_S, BBB_E, BB_O, BB_S, BB_OO}, { CtoD}) { 2212 zz_recycleRequest; 2213 } 2214 2215 transition({BBS_UM, BBO_UM, BBM_M, BBM_O, BBS_M, BBO_M}, { RdBlk, RdBlkS, RdBlkM}) { 2216 zz_recycleRequest; 2217 } 2218 2219 transition(BBM_O, CtoD) { 2220 zz_recycleRequest; 2221 } 2222 2223 transition({BBS_S, BBO_O}, {RdBlkM, CtoD}) { 2224 zz_recycleRequest; 2225 } 2226 2227 transition({B_I, CP_I, CP_S, CP_O, CP_OM, CP_SM, CP_IOM, CP_ISM, CP_OSIW, BRWD_I, BRW_I, BRD_I}, {RdBlk, RdBlkS, RdBlkM}) { 2228 zz_recycleRequest; 2229 } 2230 2231 transition({CP_O, CP_S, CP_OM}, CtoD) { 2232 zz_recycleRequest; 2233 } 2234 2235 // Ignore replacement related messages after probe got in. 2236 transition({CP_I, B_I, CP_IOM, CP_ISM, CP_OSIW, BRWD_I, BRW_I, BRD_I}, {CPUWrite, NoCPUWrite}) { 2237 zz_recycleRequest; 2238 } 2239 2240 // Ignore replacement related messages after probes processed 2241 transition({I, I_S, I_ES, I_M, I_C, I_W}, {CPUWrite,NoCPUWrite}) { 2242 nC_sendNullWBAckToCore; 2243 i_popIncomingRequestQueue; 2244 } 2245 // cannot ignore cancel... otherwise TCP/SQC will be stuck in I_C 2246 transition({I, I_S, I_ES, I_M, I_C, I_W, S_M, M, O, E, S}, CPUWriteCancel){TagArrayRead} { 2247 nC_sendNullWBAckToCore; 2248 i_popIncomingRequestQueue; 2249 } 2250 2251 transition({CP_I, B_I, CP_IOM, CP_ISM, BRWD_I, BRW_I, BRD_I}, {NoVic, VicClean, VicDirty, VicDirtyLast}){ 2252 nT_sendNullWBAckToTCC; 2253 pl_popTCCRequestQueue; 2254 } 2255 2256 // Handling Probes from NB (General process: (1) propagate up, go to blocking state (2) process acks (3) on last ack downward.) 2257 2258 // step 1 2259 transition({M, O, E, S}, PrbInvData, CP_I){TagArrayRead} { 2260 tp_allocateTBE; 2261 dc_probeInvCoreData; 2262 d2_probeInvL2Data; 2263 pp_popProbeQueue; 2264 } 2265 // step 2a 2266 transition(CP_I, CPUPrbResp) { 2267 y_writeDataToTBE; 2268 x_decrementAcks; 2269 o_checkForAckCompletion; 2270 pk_popResponseQueue; 2271 } 2272 // step 2b 2273 transition(CP_I, TCCPrbResp) { 2274 ty_writeTCCDataToTBE; 2275 x_decrementAcks; 2276 o_checkForAckCompletion; 2277 plr_popTCCResponseQueue; 2278 } 2279 // step 3 2280 transition(CP_I, ProbeAcksComplete, I){TagArrayWrite} { 2281 pd_sendProbeResponseData; 2282 c_clearOwner; 2283 cc_clearSharers; 2284 dt_deallocateTBE; 2285 dd_deallocateDir; 2286 pt_popTriggerQueue; 2287 } 2288 2289 // step 1 2290 transition({M, O, E, S}, PrbInv, B_I){TagArrayWrite} { 2291 tp_allocateTBE; 2292 ipc_probeInvCore; 2293 i2_probeInvL2; 2294 pp_popProbeQueue; 2295 } 2296 // step 2 2297 transition(B_I, CPUPrbResp) { 2298 x_decrementAcks; 2299 o_checkForAckCompletion; 2300 pk_popResponseQueue; 2301 } 2302 // step 2b 2303 transition(B_I, TCCPrbResp) { 2304 x_decrementAcks; 2305 o_checkForAckCompletion; 2306 plr_popTCCResponseQueue; 2307 } 2308 // step 3 2309 transition(B_I, ProbeAcksComplete, I){TagArrayWrite} { 2310 // send response down to NB 2311 pi_sendProbeResponseInv; 2312 c_clearOwner; 2313 cc_clearSharers; 2314 dt_deallocateTBE; 2315 dd_deallocateDir; 2316 pt_popTriggerQueue; 2317 } 2318 2319 2320 // step 1 2321 transition({M, O}, PrbShrData, CP_O){TagArrayRead} { 2322 tp_allocateTBE; 2323 sc_probeShrCoreData; 2324 s2_probeShrL2Data; 2325 pp_popProbeQueue; 2326 } 2327 2328 transition(E, PrbShrData, CP_O){TagArrayRead} { 2329 tp_allocateTBE; 2330 eto_moveExSharerToOwner; 2331 sc_probeShrCoreData; 2332 s2_probeShrL2Data; 2333 pp_popProbeQueue; 2334 } 2335 // step 2 2336 transition(CP_O, CPUPrbResp) { 2337 y_writeDataToTBE; 2338 x_decrementAcks; 2339 o_checkForAckCompletion; 2340 pk_popResponseQueue; 2341 } 2342 // step 2b 2343 transition(CP_O, TCCPrbResp) { 2344 ty_writeTCCDataToTBE; 2345 x_decrementAcks; 2346 o_checkForAckCompletion; 2347 plr_popTCCResponseQueue; 2348 } 2349 // step 3 2350 transition(CP_O, ProbeAcksComplete, O){TagArrayWrite} { 2351 // send response down to NB 2352 pd_sendProbeResponseData; 2353 dt_deallocateTBE; 2354 pt_popTriggerQueue; 2355 } 2356 2357 //step 1 2358 transition(S, PrbShrData, CP_S) { 2359 tp_allocateTBE; 2360 sc_probeShrCoreData; 2361 s2_probeShrL2Data; 2362 pp_popProbeQueue; 2363 } 2364 // step 2 2365 transition(CP_S, CPUPrbResp) { 2366 y_writeDataToTBE; 2367 x_decrementAcks; 2368 o_checkForAckCompletion; 2369 pk_popResponseQueue; 2370 } 2371 // step 2b 2372 transition(CP_S, TCCPrbResp) { 2373 ty_writeTCCDataToTBE; 2374 x_decrementAcks; 2375 o_checkForAckCompletion; 2376 plr_popTCCResponseQueue; 2377 } 2378 // step 3 2379 transition(CP_S, ProbeAcksComplete, S) { 2380 // send response down to NB 2381 pd_sendProbeResponseData; 2382 dt_deallocateTBE; 2383 pt_popTriggerQueue; 2384 } 2385 2386 // step 1 2387 transition(O_M, PrbInvData, CP_IOM) { 2388 dc_probeInvCoreData; 2389 d2_probeInvL2Data; 2390 pp_popProbeQueue; 2391 } 2392 // step 2a 2393 transition(CP_IOM, CPUPrbResp) { 2394 y_writeDataToTBE; 2395 x_decrementAcks; 2396 o_checkForAckCompletion; 2397 pk_popResponseQueue; 2398 } 2399 // step 2b 2400 transition(CP_IOM, TCCPrbResp) { 2401 ty_writeTCCDataToTBE; 2402 x_decrementAcks; 2403 o_checkForAckCompletion; 2404 plr_popTCCResponseQueue; 2405 } 2406 // step 3 2407 transition(CP_IOM, ProbeAcksComplete, I_M) { 2408 pdm_sendProbeResponseDataMs; 2409 c_clearOwner; 2410 cc_clearSharers; 2411 cd_clearDirtyBitTBE; 2412 pt_popTriggerQueue; 2413 } 2414 2415 transition(CP_IOM, ProbeAcksCompleteReissue, I){TagArrayWrite} { 2416 pdm_sendProbeResponseDataMs; 2417 c_clearOwner; 2418 cc_clearSharers; 2419 dt_deallocateTBE; 2420 dd_deallocateDir; 2421 pt_popTriggerQueue; 2422 } 2423 2424 // step 1 2425 transition(S_M, PrbInvData, CP_ISM) { 2426 dc_probeInvCoreData; 2427 d2_probeInvL2Data; 2428 o_checkForAckCompletion; 2429 pp_popProbeQueue; 2430 } 2431 // step 2a 2432 transition(CP_ISM, CPUPrbResp) { 2433 y_writeDataToTBE; 2434 x_decrementAcks; 2435 o_checkForAckCompletion; 2436 pk_popResponseQueue; 2437 } 2438 // step 2b 2439 transition(CP_ISM, TCCPrbResp) { 2440 ty_writeTCCDataToTBE; 2441 x_decrementAcks; 2442 o_checkForAckCompletion; 2443 plr_popTCCResponseQueue; 2444 } 2445 // step 3 2446 transition(CP_ISM, ProbeAcksComplete, I_M) { 2447 pdm_sendProbeResponseDataMs; 2448 c_clearOwner; 2449 cc_clearSharers; 2450 cd_clearDirtyBitTBE; 2451 2452 //dt_deallocateTBE; 2453 pt_popTriggerQueue; 2454 } 2455 transition(CP_ISM, ProbeAcksCompleteReissue, I){TagArrayWrite} { 2456 pim_sendProbeResponseInvMs; 2457 c_clearOwner; 2458 cc_clearSharers; 2459 dt_deallocateTBE; 2460 dd_deallocateDir; 2461 pt_popTriggerQueue; 2462 } 2463 2464 // step 1 2465 transition({S_M, O_M}, {PrbInv}, CP_ISM) { 2466 dc_probeInvCoreData; 2467 d2_probeInvL2Data; 2468 pp_popProbeQueue; 2469 } 2470 // next steps inherited from BS_ISM 2471 2472 // Simpler cases 2473 2474 transition({I_C, I_W}, {PrbInvData, PrbInv, PrbShrData}) { 2475 pi_sendProbeResponseInv; 2476 pp_popProbeQueue; 2477 } 2478 2479 //If the directory is certain that the block is not present, one can send an acknowledgement right away. 2480 // No need for three step process. 2481 transition(I, {PrbInv,PrbShrData,PrbInvData}){TagArrayRead} { 2482 pi_sendProbeResponseInv; 2483 pp_popProbeQueue; 2484 } 2485 2486 transition({I_M, I_ES, I_S}, {PrbInv, PrbInvData}) { 2487 pi_sendProbeResponseInv; 2488 pp_popProbeQueue; 2489 } 2490 2491 transition({I_M, I_ES, I_S}, PrbShrData) { 2492 prm_sendProbeResponseMiss; 2493 pp_popProbeQueue; 2494 } 2495 2496 //step 1 2497 transition(S_M, PrbShrData, CP_SM) { 2498 sc_probeShrCoreData; 2499 s2_probeShrL2Data; 2500 o_checkForAckCompletion; 2501 pp_popProbeQueue; 2502 } 2503 // step 2 2504 transition(CP_SM, CPUPrbResp) { 2505 y_writeDataToTBE; 2506 x_decrementAcks; 2507 o_checkForAckCompletion; 2508 pk_popResponseQueue; 2509 } 2510 // step 2b 2511 transition(CP_SM, TCCPrbResp) { 2512 ty_writeTCCDataToTBE; 2513 x_decrementAcks; 2514 o_checkForAckCompletion; 2515 plr_popTCCResponseQueue; 2516 } 2517 // step 3 2518 transition(CP_SM, {ProbeAcksComplete,ProbeAcksCompleteReissue}, S_M){DataArrayRead} { 2519 // send response down to NB 2520 pd_sendProbeResponseData; 2521 pt_popTriggerQueue; 2522 } 2523 2524 //step 1 2525 transition(O_M, PrbShrData, CP_OM) { 2526 sc_probeShrCoreData; 2527 s2_probeShrL2Data; 2528 pp_popProbeQueue; 2529 } 2530 // step 2 2531 transition(CP_OM, CPUPrbResp) { 2532 y_writeDataToTBE; 2533 x_decrementAcks; 2534 o_checkForAckCompletion; 2535 pk_popResponseQueue; 2536 } 2537 // step 2b 2538 transition(CP_OM, TCCPrbResp) { 2539 ty_writeTCCDataToTBE; 2540 x_decrementAcks; 2541 o_checkForAckCompletion; 2542 plr_popTCCResponseQueue; 2543 } 2544 // step 3 2545 transition(CP_OM, {ProbeAcksComplete,ProbeAcksCompleteReissue}, O_M) { 2546 // send response down to NB 2547 pd_sendProbeResponseData; 2548 pt_popTriggerQueue; 2549 } 2550 2551 transition(BRW_I, PrbInvData, I_W) { 2552 pd_sendProbeResponseData; 2553 pp_popProbeQueue; 2554 } 2555 2556 transition({VM_I,VO_I}, PrbInvData, I_C) { 2557 pd_sendProbeResponseData; 2558 pp_popProbeQueue; 2559 } 2560 2561 transition(VES_I, {PrbInvData,PrbInv}, I_C) { 2562 pi_sendProbeResponseInv; 2563 pp_popProbeQueue; 2564 } 2565 2566 transition({VM_I, VO_I, BRW_I}, PrbInv, I_W) { 2567 pi_sendProbeResponseInv; 2568 pp_popProbeQueue; 2569 } 2570 2571 transition({VM_I, VO_I, VO_S, VES_I, BRW_I}, PrbShrData) { 2572 pd_sendProbeResponseData; 2573 sf_setSharedFlip; 2574 pp_popProbeQueue; 2575 } 2576 2577 transition(VO_S, PrbInvData, CP_OSIW) { 2578 dc_probeInvCoreData; 2579 d2_probeInvL2Data; 2580 pp_popProbeQueue; 2581 } 2582 2583 transition(CP_OSIW, TCCPrbResp) { 2584 x_decrementAcks; 2585 o_checkForAckCompletion; 2586 plr_popTCCResponseQueue; 2587 } 2588 transition(CP_OSIW, CPUPrbResp) { 2589 x_decrementAcks; 2590 o_checkForAckCompletion; 2591 pk_popResponseQueue; 2592 } 2593 2594 transition(CP_OSIW, ProbeAcksComplete, I_C) { 2595 pd_sendProbeResponseData; 2596 cd_clearDirtyBitTBE; 2597 pt_popTriggerQueue; 2598 } 2599 2600 transition({I, S, E, O, M, CP_O, CP_S, CP_OM, CP_SM, CP_OSIW, BW_S, BW_E, BW_O, BW_M, I_M, I_ES, I_S, BBS_S, BBO_O, BBM_M, BBM_O, BB_M, BB_O, BB_OO, BB_S, BBS_M, BBO_M, BBO_UM, BBS_UM, S_M, O_M, BBB_S, BBB_M, BBB_E, VES_I, VM_I, VO_I, VO_S, ES_I, MO_I, I_C, I_W}, StaleVic) { 2601 nT_sendNullWBAckToTCC; 2602 pl_popTCCRequestQueue; 2603 } 2604 2605 transition({CP_I, B_I, CP_IOM, CP_ISM, BRWD_I, BRW_I, BRD_I}, StaleVic) { 2606 nT_sendNullWBAckToTCC; 2607 pl_popTCCRequestQueue; 2608 } 2609 2610 // Recall Transistions 2611 // transient states still require the directory state 2612 transition({M, O}, Recall, BRWD_I) { 2613 tr_allocateTBE; 2614 vd_victim; 2615 dc_probeInvCoreData; 2616 d2_probeInvL2Data; 2617 } 2618 2619 transition({E, S}, Recall, BRWD_I) { 2620 tr_allocateTBE; 2621 vc_victim; 2622 dc_probeInvCoreData; 2623 d2_probeInvL2Data; 2624 } 2625 2626 transition(I, Recall) { 2627 dd_deallocateDir; 2628 } 2629 2630 transition({BRWD_I, BRD_I}, CPUPrbResp) { 2631 y_writeDataToTBE; 2632 x_decrementAcks; 2633 o_checkForAckCompletion; 2634 pk_popResponseQueue; 2635 } 2636 2637 transition({BRWD_I, BRD_I}, TCCPrbResp) { 2638 ty_writeTCCDataToTBE; 2639 x_decrementAcks; 2640 o_checkForAckCompletion; 2641 plr_popTCCResponseQueue; 2642 } 2643 2644 transition(BRWD_I, NB_AckWB, BRD_I) { 2645 pR_popResponseFromNBQueue; 2646 } 2647 2648 transition(BRWD_I, ProbeAcksComplete, BRW_I) { 2649 pt_popTriggerQueue; 2650 } 2651 2652 transition(BRW_I, NB_AckWB, I) { 2653 wb_data; 2654 dt_deallocateTBE; 2655 dd_deallocateDir; 2656 pR_popResponseFromNBQueue; 2657 } 2658 2659 transition(BRD_I, ProbeAcksComplete, I) { 2660 wb_data; 2661 dt_deallocateTBE; 2662 dd_deallocateDir; 2663 pt_popTriggerQueue; 2664 } 2665 2666 // wait for stable state for Recall 2667 transition({BRWD_I,BRD_I,BRW_I,CP_O, CP_S, CP_OM, CP_SM, CP_OSIW, BW_S, BW_E, BW_O, BW_M, I_M, I_ES, I_S, BBS_S, BBO_O, BBM_M, BBM_O, BB_M, BB_O, BB_OO, BB_S, BBS_M, BBO_M, BBO_UM, BBS_UM, S_M, O_M, BBB_S, BBB_M, BBB_E, VES_I, VM_I, VO_I, VO_S, ES_I, MO_I, I_C, I_W, CP_I}, Recall) { 2668 zz_recycleRequest; // stall and wait would be for the wrong address 2669 ut_updateTag; // try to find an easier recall 2670 } 2671 2672} 2673