1/* 2 * Copyright (c) 2010-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: Lisa Hsu 34 */ 35 36machine(MachineType:Directory, "AMD_Base-like protocol") 37: DirectoryMemory * directory; 38 CacheMemory * L3CacheMemory; 39 Cycles response_latency := 5; 40 Cycles response_latency_regionDir := 1; 41 Cycles l3_hit_latency := 30; 42 bool useL3OnWT := "False"; 43 Cycles to_memory_controller_latency := 1; 44 45 // From the Cores 46 MessageBuffer * requestFromCores, network="From", virtual_network="0", vnet_type="request"; 47 MessageBuffer * responseFromCores, network="From", virtual_network="2", vnet_type="response"; 48 MessageBuffer * unblockFromCores, network="From", virtual_network="4", vnet_type="unblock"; 49 50 // To the Cores 51 MessageBuffer * probeToCore, network="To", virtual_network="0", vnet_type="request"; 52 MessageBuffer * responseToCore, network="To", virtual_network="2", vnet_type="response"; 53 54 // From region buffer 55 MessageBuffer * reqFromRegBuf, network="From", virtual_network="7", vnet_type="request"; 56 57 // To Region directory 58 MessageBuffer * reqToRegDir, network="To", virtual_network="5", vnet_type="request"; 59 MessageBuffer * reqFromRegDir, network="From", virtual_network="5", vnet_type="request"; 60 MessageBuffer * unblockToRegDir, network="To", virtual_network="4", vnet_type="unblock"; 61 62 MessageBuffer * triggerQueue; 63 MessageBuffer * L3triggerQueue; 64 MessageBuffer * responseFromMemory; 65{ 66 // STATES 67 state_declaration(State, desc="Directory states", default="Directory_State_U") { 68 U, AccessPermission:Backing_Store, desc="unblocked"; 69 BR, AccessPermission:Backing_Store, desc="got CPU read request, blocked while sent to L3"; 70 BW, AccessPermission:Backing_Store, desc="got CPU write request, blocked while sent to L3"; 71 BL, AccessPermission:Busy, desc="got L3 WB request"; 72 // BL is Busy because it's possible for the data only to be in the network 73 // in the WB, L3 has sent it and gone on with its business in possibly I 74 // state. 75 BI, AccessPermission:Backing_Store, desc="Blocked waiting for inv ack from core"; 76 BS_M, AccessPermission:Backing_Store, desc="blocked waiting for memory"; 77 BM_M, AccessPermission:Backing_Store, desc="blocked waiting for memory"; 78 B_M, AccessPermission:Backing_Store, desc="blocked waiting for memory"; 79 BP, AccessPermission:Backing_Store, desc="blocked waiting for probes, no need for memory"; 80 BS_PM, AccessPermission:Backing_Store, desc="blocked waiting for probes and Memory"; 81 BM_PM, AccessPermission:Backing_Store, desc="blocked waiting for probes and Memory"; 82 B_PM, AccessPermission:Backing_Store, desc="blocked waiting for probes and Memory"; 83 BS_Pm, AccessPermission:Backing_Store, desc="blocked waiting for probes, already got memory"; 84 BM_Pm, AccessPermission:Backing_Store, desc="blocked waiting for probes, already got memory"; 85 B_Pm, AccessPermission:Backing_Store, desc="blocked waiting for probes, already got memory"; 86 B, AccessPermission:Backing_Store, desc="sent response, Blocked til ack"; 87 88 // These are needed for when a private requests was issued before an inv was received 89 // for writebacks 90 BS_Pm_BL, AccessPermission:Backing_Store, desc="blocked waiting for probes, already got memory"; 91 BM_Pm_BL, AccessPermission:Backing_Store, desc="blocked waiting for probes, already got memory"; 92 B_Pm_BL, AccessPermission:Backing_Store, desc="blocked waiting for probes, already got memory"; 93 BP_BL, AccessPermission:Backing_Store, desc="blocked waiting for probes, no need for memory"; 94 // for reads 95 BS_Pm_B, AccessPermission:Backing_Store, desc="blocked waiting for probes, already got memory"; 96 BM_Pm_B, AccessPermission:Backing_Store, desc="blocked waiting for probes, already got memory"; 97 B_Pm_B, AccessPermission:Backing_Store, desc="blocked waiting for probes, already got memory"; 98 BP_B, AccessPermission:Backing_Store, desc="blocked waiting for probes, no need for memory"; 99 } 100 101 // Events 102 enumeration(Event, desc="Directory events") { 103 // CPU requests 104 RdBlkS, desc="..."; 105 RdBlkM, desc="..."; 106 RdBlk, desc="..."; 107 WriteThrough, desc="WriteThrough Message"; 108 Atomic, desc="Atomic Message"; 109 110 RdBlkSP, desc="..."; 111 RdBlkMP, desc="..."; 112 RdBlkP, desc="..."; 113 VicDirtyP, desc="..."; 114 VicCleanP, desc="..."; 115 WriteThroughP, desc="WriteThrough Message"; 116 AtomicP, desc="Atomic Message"; 117 118 // writebacks 119 VicDirty, desc="..."; 120 VicClean, desc="..."; 121 CPUData, desc="WB data from CPU"; 122 StaleWB, desc="WB response for a no longer valid request"; 123 124 // probe responses 125 CPUPrbResp, desc="Probe Response Msg"; 126 LastCPUPrbResp, desc="Last Probe Response Msg"; 127 128 ProbeAcksComplete, desc="Probe Acks Complete"; 129 130 L3Hit, desc="Hit in L3 return data to core"; 131 132 // Memory Controller 133 MemData, desc="Fetched data from memory arrives"; 134 WBAck, desc="Writeback Ack from memory arrives"; 135 136 CoreUnblock, desc="Core received data, unblock"; 137 UnblockWriteThrough, desc="unblock, self triggered"; 138 139 StaleVicDirty, desc="Core invalidated before VicDirty processed"; 140 StaleVicDirtyP, desc="Core invalidated before VicDirty processed"; 141 142 // For region protocol 143 CPUReq, desc="Generic CPU request"; 144 Inv, desc="Region dir needs a block invalidated"; 145 Downgrade, desc="Region dir needs a block downgraded"; 146 147 // For private accesses (bypassed reg-dir) 148 CPUReadP, desc="Initial req from core, sent to L3"; 149 CPUWriteP, desc="Initial req from core, sent to L3"; 150 } 151 152 enumeration(RequestType, desc="To communicate stats from transitions to recordStats") { 153 L3DataArrayRead, desc="Read the data array"; 154 L3DataArrayWrite, desc="Write the data array"; 155 L3TagArrayRead, desc="Read the data array"; 156 L3TagArrayWrite, desc="Write the data array"; 157 } 158 159 // TYPES 160 161 // DirectoryEntry 162 structure(Entry, desc="...", interface="AbstractEntry") { 163 State DirectoryState, desc="Directory state"; 164 DataBlock DataBlk, desc="data for the block"; 165 NetDest VicDirtyIgnore, desc="VicDirty coming from whom to ignore"; 166 } 167 168 structure(CacheEntry, desc="...", interface="AbstractCacheEntry") { 169 DataBlock DataBlk, desc="data for the block"; 170 MachineID LastSender, desc="Mach which this block came from"; 171 } 172 173 structure(TBE, desc="...") { 174 State TBEState, desc="Transient state"; 175 DataBlock DataBlk, desc="data for the block"; 176 DataBlock DataBlkAux, desc="Auxiliary data for the block"; 177 bool Dirty, desc="Is the data dirty?"; 178 int NumPendingAcks, desc="num acks expected"; 179 MachineID OriginalRequestor, desc="Original Requestor"; 180 MachineID WTRequestor, desc="WT Requestor"; 181 bool Cached, desc="data hit in Cache"; 182 bool MemData, desc="Got MemData?",default="false"; 183 bool wtData, desc="Got write through data?",default="false"; 184 bool atomicData, desc="Got Atomic op?",default="false"; 185 Cycles InitialRequestTime, desc="..."; 186 Cycles ForwardRequestTime, desc="..."; 187 Cycles ProbeRequestStartTime, desc="..."; 188 bool DemandRequest, desc="for profiling"; 189 MachineID LastSender, desc="Mach which this block came from"; 190 bool L3Hit, default="false", desc="Was this an L3 hit?"; 191 bool TriggeredAcksComplete, default="false", desc="True if already triggered acks complete"; 192 WriteMask writeMask, desc="outstanding write through mask"; 193 } 194 195 structure(TBETable, external="yes") { 196 TBE lookup(Addr); 197 void allocate(Addr); 198 void deallocate(Addr); 199 bool isPresent(Addr); 200 } 201 202 TBETable TBEs, template="<Directory_TBE>", constructor="m_number_of_TBEs"; 203 204 Tick clockEdge(); 205 Tick cyclesToTicks(Cycles c); 206 207 void set_tbe(TBE a); 208 void unset_tbe(); 209 void wakeUpAllBuffers(); 210 void wakeUpBuffers(Addr a); 211 Cycles curCycle(); 212 213 MachineID mapAddressToMachine(Addr addr, MachineType mtype); 214 215 Entry getDirectoryEntry(Addr addr), return_by_pointer="yes" { 216 Entry dir_entry := static_cast(Entry, "pointer", directory.lookup(addr)); 217 218 if (is_valid(dir_entry)) { 219 //DPRINTF(RubySlicc, "Getting entry %s: %s\n", addr, dir_entry.DataBlk); 220 return dir_entry; 221 } 222 223 dir_entry := static_cast(Entry, "pointer", 224 directory.allocate(addr, new Entry)); 225 return dir_entry; 226 } 227 228 DataBlock getDataBlock(Addr addr), return_by_ref="yes" { 229 TBE tbe := TBEs.lookup(addr); 230 if (is_valid(tbe) && tbe.MemData) { 231 DPRINTF(RubySlicc, "Returning DataBlk from TBE %s:%s\n", addr, tbe); 232 return tbe.DataBlk; 233 } 234 DPRINTF(RubySlicc, "Returning DataBlk from Dir %s:%s\n", addr, getDirectoryEntry(addr)); 235 return getDirectoryEntry(addr).DataBlk; 236 } 237 238 State getState(TBE tbe, CacheEntry entry, Addr addr) { 239 return getDirectoryEntry(addr).DirectoryState; 240 } 241 242 State getStateFromAddr(Addr addr) { 243 return getDirectoryEntry(addr).DirectoryState; 244 } 245 246 void setState(TBE tbe, CacheEntry entry, Addr addr, State state) { 247 getDirectoryEntry(addr).DirectoryState := state; 248 } 249 250 AccessPermission getAccessPermission(Addr addr) { 251 // For this Directory, all permissions are just tracked in Directory, since 252 // it's not possible to have something in TBE but not Dir, just keep track 253 // of state all in one place. 254 if(directory.isPresent(addr)) { 255 return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState); 256 } 257 258 return AccessPermission:NotPresent; 259 } 260 261 void functionalRead(Addr addr, Packet *pkt) { 262 TBE tbe := TBEs.lookup(addr); 263 if(is_valid(tbe)) { 264 testAndRead(addr, tbe.DataBlk, pkt); 265 } else { 266 functionalMemoryRead(pkt); 267 } 268 } 269 270 int functionalWrite(Addr addr, Packet *pkt) { 271 int num_functional_writes := 0; 272 273 TBE tbe := TBEs.lookup(addr); 274 if(is_valid(tbe)) { 275 num_functional_writes := num_functional_writes + 276 testAndWrite(addr, tbe.DataBlk, pkt); 277 } 278 279 num_functional_writes := num_functional_writes + functionalMemoryWrite(pkt); 280 return num_functional_writes; 281 } 282 283 void setAccessPermission(CacheEntry entry, Addr addr, State state) { 284 getDirectoryEntry(addr).changePermission(Directory_State_to_permission(state)); 285 } 286 287 void recordRequestType(RequestType request_type, Addr addr) { 288 if (request_type == RequestType:L3DataArrayRead) { 289 L3CacheMemory.recordRequestType(CacheRequestType:DataArrayRead, addr); 290 } else if (request_type == RequestType:L3DataArrayWrite) { 291 L3CacheMemory.recordRequestType(CacheRequestType:DataArrayWrite, addr); 292 } else if (request_type == RequestType:L3TagArrayRead) { 293 L3CacheMemory.recordRequestType(CacheRequestType:TagArrayRead, addr); 294 } else if (request_type == RequestType:L3TagArrayWrite) { 295 L3CacheMemory.recordRequestType(CacheRequestType:TagArrayWrite, addr); 296 } 297 } 298 299 bool checkResourceAvailable(RequestType request_type, Addr addr) { 300 if (request_type == RequestType:L3DataArrayRead) { 301 return L3CacheMemory.checkResourceAvailable(CacheResourceType:DataArray, addr); 302 } else if (request_type == RequestType:L3DataArrayWrite) { 303 return L3CacheMemory.checkResourceAvailable(CacheResourceType:DataArray, addr); 304 } else if (request_type == RequestType:L3TagArrayRead) { 305 return L3CacheMemory.checkResourceAvailable(CacheResourceType:TagArray, addr); 306 } else if (request_type == RequestType:L3TagArrayWrite) { 307 return L3CacheMemory.checkResourceAvailable(CacheResourceType:TagArray, addr); 308 } else { 309 error("Invalid RequestType type in checkResourceAvailable"); 310 return true; 311 } 312 } 313 314 // ** OUT_PORTS ** 315 out_port(probeNetwork_out, NBProbeRequestMsg, probeToCore); 316 out_port(responseNetwork_out, ResponseMsg, responseToCore); 317 318 out_port(requestNetworkReg_out, CPURequestMsg, reqToRegDir); 319 out_port(regAckNetwork_out, UnblockMsg, unblockToRegDir); 320 321 out_port(triggerQueue_out, TriggerMsg, triggerQueue); 322 out_port(L3TriggerQueue_out, TriggerMsg, L3triggerQueue); 323 324 // ** IN_PORTS ** 325 326 // Trigger Queue 327 in_port(triggerQueue_in, TriggerMsg, triggerQueue, rank=7) { 328 if (triggerQueue_in.isReady(clockEdge())) { 329 peek(triggerQueue_in, TriggerMsg) { 330 TBE tbe := TBEs.lookup(in_msg.addr); 331 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(in_msg.addr)); 332 if (in_msg.Type == TriggerType:AcksComplete) { 333 trigger(Event:ProbeAcksComplete, in_msg.addr, entry, tbe); 334 } else if (in_msg.Type == TriggerType:UnblockWriteThrough) { 335 trigger(Event:UnblockWriteThrough, in_msg.addr, entry, tbe); 336 } else { 337 error("Unknown trigger msg"); 338 } 339 } 340 } 341 } 342 343 in_port(L3TriggerQueue_in, TriggerMsg, L3triggerQueue, rank=6) { 344 if (L3TriggerQueue_in.isReady(clockEdge())) { 345 peek(L3TriggerQueue_in, TriggerMsg) { 346 TBE tbe := TBEs.lookup(in_msg.addr); 347 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(in_msg.addr)); 348 if (in_msg.Type == TriggerType:L3Hit) { 349 trigger(Event:L3Hit, in_msg.addr, entry, tbe); 350 } else { 351 error("Unknown trigger msg"); 352 } 353 } 354 } 355 } 356 357 // Unblock Network 358 in_port(unblockNetwork_in, UnblockMsg, unblockFromCores, rank=5) { 359 if (unblockNetwork_in.isReady(clockEdge())) { 360 peek(unblockNetwork_in, UnblockMsg) { 361 TBE tbe := TBEs.lookup(in_msg.addr); 362 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(in_msg.addr)); 363 trigger(Event:CoreUnblock, in_msg.addr, entry, tbe); 364 } 365 } 366 } 367 368 // Core response network 369 in_port(responseNetwork_in, ResponseMsg, responseFromCores, rank=4) { 370 if (responseNetwork_in.isReady(clockEdge())) { 371 peek(responseNetwork_in, ResponseMsg) { 372 DPRINTF(RubySlicc, "core responses %s\n", in_msg); 373 TBE tbe := TBEs.lookup(in_msg.addr); 374 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(in_msg.addr)); 375 if (in_msg.Type == CoherenceResponseType:CPUPrbResp) { 376 if (is_valid(tbe) && tbe.NumPendingAcks == 1 377 && tbe.TriggeredAcksComplete == false) { 378 trigger(Event:LastCPUPrbResp, in_msg.addr, entry, tbe); 379 } else { 380 trigger(Event:CPUPrbResp, in_msg.addr, entry, tbe); 381 } 382 } else if (in_msg.Type == CoherenceResponseType:CPUData) { 383 trigger(Event:CPUData, in_msg.addr, entry, tbe); 384 } else if (in_msg.Type == CoherenceResponseType:StaleNotif) { 385 trigger(Event:StaleWB, in_msg.addr, entry, tbe); 386 } else { 387 error("Unexpected response type"); 388 } 389 } 390 } 391 } 392 393 // off-chip memory request/response is done 394 in_port(memQueue_in, MemoryMsg, responseFromMemory, rank=3) { 395 if (memQueue_in.isReady(clockEdge())) { 396 peek(memQueue_in, MemoryMsg) { 397 TBE tbe := TBEs.lookup(in_msg.addr); 398 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(in_msg.addr)); 399 if (in_msg.Type == MemoryRequestType:MEMORY_READ) { 400 trigger(Event:MemData, in_msg.addr, entry, tbe); 401 DPRINTF(RubySlicc, "%s\n", in_msg); 402 } else if (in_msg.Type == MemoryRequestType:MEMORY_WB) { 403 trigger(Event:WBAck, in_msg.addr, entry, tbe); // ignore WBAcks, don't care about them. 404 } else { 405 DPRINTF(RubySlicc, "%s\n", in_msg.Type); 406 error("Invalid message"); 407 } 408 } 409 } 410 } 411 412 in_port(regBuf_in, CPURequestMsg, reqFromRegBuf, rank=2) { 413 if (regBuf_in.isReady(clockEdge())) { 414 peek(regBuf_in, CPURequestMsg) { 415 TBE tbe := TBEs.lookup(in_msg.addr); 416 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(in_msg.addr)); 417 if (in_msg.Type == CoherenceRequestType:ForceInv) { 418 trigger(Event:Inv, in_msg.addr, entry, tbe); 419 } else if (in_msg.Type == CoherenceRequestType:ForceDowngrade) { 420 trigger(Event:Downgrade, in_msg.addr, entry, tbe); 421 } else { 422 error("Bad request from region buffer"); 423 } 424 } 425 } 426 } 427 428 in_port(regDir_in, CPURequestMsg, reqFromRegDir, rank=1) { 429 if (regDir_in.isReady(clockEdge())) { 430 peek(regDir_in, CPURequestMsg) { 431 TBE tbe := TBEs.lookup(in_msg.addr); 432 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(in_msg.addr)); 433 if (in_msg.Type == CoherenceRequestType:RdBlk) { 434 trigger(Event:RdBlk, in_msg.addr, entry, tbe); 435 } else if (in_msg.Type == CoherenceRequestType:RdBlkS) { 436 trigger(Event:RdBlkS, in_msg.addr, entry, tbe); 437 } else if (in_msg.Type == CoherenceRequestType:RdBlkM) { 438 trigger(Event:RdBlkM, in_msg.addr, entry, tbe); 439 } else if (in_msg.Type == CoherenceRequestType:Atomic) { 440 trigger(Event:Atomic, in_msg.addr, entry, tbe); 441 } else if (in_msg.Type == CoherenceRequestType:WriteThrough) { 442 trigger(Event:WriteThrough, in_msg.addr, entry, tbe); 443 } else if (in_msg.Type == CoherenceRequestType:VicDirty) { 444 if (getDirectoryEntry(in_msg.addr).VicDirtyIgnore.isElement(in_msg.Requestor)) { 445 DPRINTF(RubySlicc, "Dropping VicDirty for address %s\n", in_msg.addr); 446 trigger(Event:StaleVicDirty, in_msg.addr, entry, tbe); 447 } else { 448 trigger(Event:VicDirty, in_msg.addr, entry, tbe); 449 } 450 } else if (in_msg.Type == CoherenceRequestType:VicClean) { 451 if (getDirectoryEntry(in_msg.addr).VicDirtyIgnore.isElement(in_msg.Requestor)) { 452 DPRINTF(RubySlicc, "Dropping VicClean for address %s\n", in_msg.addr); 453 trigger(Event:StaleVicDirty, in_msg.addr, entry, tbe); 454 } else { 455 trigger(Event:VicClean, in_msg.addr, entry, tbe); 456 } 457 } else { 458 error("Bad message type fwded from Region Dir"); 459 } 460 } 461 } 462 } 463 464 in_port(requestNetwork_in, CPURequestMsg, requestFromCores, rank=0) { 465 if (requestNetwork_in.isReady(clockEdge())) { 466 peek(requestNetwork_in, CPURequestMsg) { 467 TBE tbe := TBEs.lookup(in_msg.addr); 468 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(in_msg.addr)); 469 if (in_msg.Private) { 470 // Bypass the region dir 471 if (in_msg.Type == CoherenceRequestType:RdBlk) { 472 trigger(Event:RdBlkP, in_msg.addr, entry, tbe); 473 } else if (in_msg.Type == CoherenceRequestType:RdBlkS) { 474 trigger(Event:RdBlkSP, in_msg.addr, entry, tbe); 475 } else if (in_msg.Type == CoherenceRequestType:RdBlkM) { 476 trigger(Event:RdBlkMP, in_msg.addr, entry, tbe); 477 } else if (in_msg.Type == CoherenceRequestType:Atomic) { 478 trigger(Event:AtomicP, in_msg.addr, entry, tbe); 479 } else if (in_msg.Type == CoherenceRequestType:WriteThrough) { 480 trigger(Event:WriteThroughP, in_msg.addr, entry, tbe); 481 } else if (in_msg.Type == CoherenceRequestType:VicDirty) { 482 if (getDirectoryEntry(in_msg.addr).VicDirtyIgnore.isElement(in_msg.Requestor)) { 483 DPRINTF(RubySlicc, "Dropping VicDirtyP for address %s\n", in_msg.addr); 484 trigger(Event:StaleVicDirtyP, in_msg.addr, entry, tbe); 485 } else { 486 DPRINTF(RubySlicc, "Got VicDirty from %s on %s\n", in_msg.Requestor, in_msg.addr); 487 trigger(Event:VicDirtyP, in_msg.addr, entry, tbe); 488 } 489 } else if (in_msg.Type == CoherenceRequestType:VicClean) { 490 if (getDirectoryEntry(in_msg.addr).VicDirtyIgnore.isElement(in_msg.Requestor)) { 491 DPRINTF(RubySlicc, "Dropping VicCleanP for address %s\n", in_msg.addr); 492 trigger(Event:StaleVicDirtyP, in_msg.addr, entry, tbe); 493 } else { 494 DPRINTF(RubySlicc, "Got VicClean from %s on %s\n", in_msg.Requestor, in_msg.addr); 495 trigger(Event:VicCleanP, in_msg.addr, entry, tbe); 496 } 497 } else { 498 error("Bad message type for private access"); 499 } 500 } else { 501 trigger(Event:CPUReq, in_msg.addr, entry, tbe); 502 } 503 } 504 } 505 } 506 507 // Actions 508 action(s_sendResponseS, "s", desc="send Shared response") { 509 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 510 out_msg.addr := address; 511 out_msg.Type := CoherenceResponseType:NBSysResp; 512 if (tbe.L3Hit) { 513 out_msg.Sender := createMachineID(MachineType:L3Cache, intToID(0)); 514 } else { 515 out_msg.Sender := machineID; 516 } 517 out_msg.Destination.add(tbe.OriginalRequestor); 518 out_msg.DataBlk := tbe.DataBlk; 519 out_msg.MessageSize := MessageSizeType:Response_Data; 520 out_msg.Dirty := false; 521 out_msg.State := CoherenceState:Shared; 522 out_msg.InitialRequestTime := tbe.InitialRequestTime; 523 out_msg.ForwardRequestTime := tbe.ForwardRequestTime; 524 out_msg.ProbeRequestStartTime := tbe.ProbeRequestStartTime; 525 out_msg.OriginalResponder := tbe.LastSender; 526 out_msg.DemandRequest := tbe.DemandRequest; 527 out_msg.L3Hit := tbe.L3Hit; 528 DPRINTF(RubySlicc, "%s\n", out_msg); 529 } 530 } 531 532 action(es_sendResponseES, "es", desc="send Exclusive or Shared response") { 533 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 534 out_msg.addr := address; 535 out_msg.Type := CoherenceResponseType:NBSysResp; 536 if (tbe.L3Hit) { 537 out_msg.Sender := createMachineID(MachineType:L3Cache, intToID(0)); 538 } else { 539 out_msg.Sender := machineID; 540 } 541 out_msg.Destination.add(tbe.OriginalRequestor); 542 out_msg.DataBlk := tbe.DataBlk; 543 out_msg.MessageSize := MessageSizeType:Response_Data; 544 out_msg.Dirty := tbe.Dirty; 545 if (tbe.Cached) { 546 out_msg.State := CoherenceState:Shared; 547 } else { 548 out_msg.State := CoherenceState:Exclusive; 549 } 550 out_msg.InitialRequestTime := tbe.InitialRequestTime; 551 out_msg.ForwardRequestTime := tbe.ForwardRequestTime; 552 out_msg.ProbeRequestStartTime := tbe.ProbeRequestStartTime; 553 out_msg.OriginalResponder := tbe.LastSender; 554 out_msg.DemandRequest := tbe.DemandRequest; 555 out_msg.L3Hit := tbe.L3Hit; 556 DPRINTF(RubySlicc, "%s\n", out_msg); 557 } 558 } 559 560 action(m_sendResponseM, "m", desc="send Modified response") { 561 if (tbe.wtData) { 562 enqueue(triggerQueue_out, TriggerMsg, 1) { 563 out_msg.addr := address; 564 out_msg.Type := TriggerType:UnblockWriteThrough; 565 } 566 } else { 567 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 568 out_msg.addr := address; 569 out_msg.Type := CoherenceResponseType:NBSysResp; 570 if (tbe.L3Hit) { 571 out_msg.Sender := createMachineID(MachineType:L3Cache, intToID(0)); 572 } else { 573 out_msg.Sender := machineID; 574 } 575 out_msg.Destination.add(tbe.OriginalRequestor); 576 out_msg.DataBlk := tbe.DataBlk; 577 out_msg.MessageSize := MessageSizeType:Response_Data; 578 out_msg.Dirty := tbe.Dirty; 579 out_msg.State := CoherenceState:Modified; 580 out_msg.CtoD := false; 581 out_msg.InitialRequestTime := tbe.InitialRequestTime; 582 out_msg.ForwardRequestTime := tbe.ForwardRequestTime; 583 out_msg.ProbeRequestStartTime := tbe.ProbeRequestStartTime; 584 out_msg.OriginalResponder := tbe.LastSender; 585 out_msg.DemandRequest := tbe.DemandRequest; 586 out_msg.L3Hit := tbe.L3Hit; 587 if (tbe.atomicData) { 588 out_msg.WTRequestor := tbe.WTRequestor; 589 } 590 DPRINTF(RubySlicc, "%s\n", out_msg); 591 } 592 if (tbe.atomicData) { 593 enqueue(triggerQueue_out, TriggerMsg, 1) { 594 out_msg.addr := address; 595 out_msg.Type := TriggerType:UnblockWriteThrough; 596 } 597 } 598 } 599 } 600 601 action(sb_sendResponseSBypass, "sb", desc="send Shared response") { 602 peek(requestNetwork_in, CPURequestMsg) { 603 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 604 out_msg.addr := address; 605 out_msg.Type := CoherenceResponseType:NBSysResp; 606 if (tbe.L3Hit) { 607 out_msg.Sender := createMachineID(MachineType:L3Cache, intToID(0)); 608 } else { 609 out_msg.Sender := machineID; 610 } 611 out_msg.Destination.add(in_msg.Requestor); 612 out_msg.DataBlk := tbe.DataBlk; 613 out_msg.MessageSize := MessageSizeType:Response_Data; 614 out_msg.Dirty := false; 615 out_msg.State := CoherenceState:Shared; 616 out_msg.InitialRequestTime := in_msg.InitialRequestTime; 617 out_msg.ForwardRequestTime := curCycle(); 618 out_msg.ProbeRequestStartTime := in_msg.ProbeRequestStartTime; 619 out_msg.OriginalResponder := tbe.LastSender; 620 out_msg.DemandRequest := false; 621 out_msg.L3Hit := tbe.L3Hit; 622 DPRINTF(RubySlicc, "%s\n", out_msg); 623 } 624 } 625 } 626 627 action(esb_sendResponseESBypass, "esb", desc="send Exclusive or Shared response") { 628 peek(requestNetwork_in, CPURequestMsg) { 629 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 630 out_msg.addr := address; 631 out_msg.Type := CoherenceResponseType:NBSysResp; 632 if (tbe.L3Hit) { 633 out_msg.Sender := createMachineID(MachineType:L3Cache, intToID(0)); 634 } else { 635 out_msg.Sender := machineID; 636 } 637 out_msg.Destination.add(in_msg.Requestor); 638 out_msg.DataBlk := tbe.DataBlk; 639 out_msg.MessageSize := MessageSizeType:Response_Data; 640 out_msg.Dirty := tbe.Dirty; 641 if (tbe.Cached || in_msg.ForceShared) { 642 out_msg.State := CoherenceState:Shared; 643 } else { 644 out_msg.State := CoherenceState:Exclusive; 645 } 646 out_msg.InitialRequestTime := in_msg.InitialRequestTime; 647 out_msg.ForwardRequestTime := curCycle(); 648 out_msg.ProbeRequestStartTime := in_msg.ProbeRequestStartTime; 649 out_msg.OriginalResponder := tbe.LastSender; 650 out_msg.DemandRequest := false; 651 out_msg.L3Hit := tbe.L3Hit; 652 DPRINTF(RubySlicc, "%s\n", out_msg); 653 } 654 } 655 } 656 657 action(mbwt_sendResponseWriteThroughBypass, "mbwt", desc="send write through response") { 658 peek(requestNetwork_in, CPURequestMsg) { 659 if (in_msg.Type == CoherenceRequestType:WriteThrough) { 660 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 661 out_msg.addr := address; 662 out_msg.Type := CoherenceResponseType:NBSysWBAck; 663 out_msg.Destination.add(in_msg.Requestor); 664 out_msg.WTRequestor := in_msg.WTRequestor; 665 out_msg.Sender := machineID; 666 out_msg.MessageSize := MessageSizeType:Writeback_Control; 667 out_msg.InitialRequestTime := in_msg.InitialRequestTime; 668 out_msg.ForwardRequestTime := curCycle(); 669 out_msg.ProbeRequestStartTime := in_msg.ProbeRequestStartTime; 670 out_msg.DemandRequest := false; 671 } 672 } else { 673 assert(in_msg.Type == CoherenceRequestType:Atomic); 674 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 675 out_msg.addr := address; 676 out_msg.Type := CoherenceResponseType:NBSysResp; 677 if (tbe.L3Hit) { 678 out_msg.Sender := createMachineID(MachineType:L3Cache, intToID(0)); 679 } else { 680 out_msg.Sender := machineID; 681 } 682 out_msg.Destination.add(in_msg.Requestor); 683 out_msg.DataBlk := getDirectoryEntry(address).DataBlk; 684 out_msg.MessageSize := MessageSizeType:Response_Data; 685 out_msg.Dirty := in_msg.Dirty; 686 out_msg.State := CoherenceState:Modified; 687 out_msg.CtoD := false; 688 out_msg.InitialRequestTime := in_msg.InitialRequestTime; 689 out_msg.ForwardRequestTime := curCycle(); 690 out_msg.ProbeRequestStartTime := in_msg.ProbeRequestStartTime; 691 out_msg.OriginalResponder := tbe.LastSender; 692 out_msg.DemandRequest := false; 693 out_msg.L3Hit := tbe.L3Hit; 694 out_msg.WTRequestor := in_msg.WTRequestor; 695 DPRINTF(RubySlicc, "%s\n", out_msg); 696 } 697 } 698 enqueue(triggerQueue_out, TriggerMsg, 1) { 699 out_msg.addr := address; 700 out_msg.Type := TriggerType:UnblockWriteThrough; 701 } 702 } 703 } 704 705 action(mb_sendResponseMBypass, "mb", desc="send Modified response") { 706 peek(requestNetwork_in, CPURequestMsg) { 707 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 708 out_msg.addr := address; 709 out_msg.Type := CoherenceResponseType:NBSysResp; 710 if (tbe.L3Hit) { 711 out_msg.Sender := createMachineID(MachineType:L3Cache, intToID(0)); 712 } else { 713 out_msg.Sender := machineID; 714 } 715 out_msg.Destination.add(in_msg.Requestor); 716 out_msg.DataBlk := tbe.DataBlk; 717 out_msg.MessageSize := MessageSizeType:Response_Data; 718 out_msg.Dirty := tbe.Dirty; 719 out_msg.State := CoherenceState:Modified; 720 out_msg.CtoD := false; 721 out_msg.InitialRequestTime := in_msg.InitialRequestTime; 722 out_msg.ForwardRequestTime := curCycle(); 723 out_msg.ProbeRequestStartTime := in_msg.ProbeRequestStartTime; 724 out_msg.OriginalResponder := tbe.LastSender; 725 out_msg.DemandRequest := false; 726 out_msg.L3Hit := tbe.L3Hit; 727 DPRINTF(RubySlicc, "%s\n", out_msg); 728 } 729 } 730 } 731 732 action(c_sendResponseCtoD, "c", desc="send CtoD Ack") { 733 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 734 out_msg.addr := address; 735 out_msg.Type := CoherenceResponseType:NBSysResp; 736 out_msg.Sender := machineID; 737 out_msg.Destination.add(tbe.OriginalRequestor); 738 out_msg.MessageSize := MessageSizeType:Response_Control; 739 out_msg.Dirty := false; 740 out_msg.State := CoherenceState:Modified; 741 out_msg.CtoD := true; 742 out_msg.InitialRequestTime := tbe.InitialRequestTime; 743 out_msg.ForwardRequestTime := curCycle(); 744 out_msg.ProbeRequestStartTime := tbe.ProbeRequestStartTime; 745 out_msg.DemandRequest := tbe.DemandRequest; 746 DPRINTF(RubySlicc, "%s\n", out_msg); 747 } 748 } 749 750 action(cp_sendResponseCtoDP, "cp", desc="send CtoD Ack") { 751 peek(requestNetwork_in, CPURequestMsg) { 752 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 753 out_msg.addr := address; 754 out_msg.Type := CoherenceResponseType:NBSysResp; 755 out_msg.Sender := machineID; 756 out_msg.Destination.add(in_msg.Requestor); 757 out_msg.MessageSize := MessageSizeType:Response_Control; 758 out_msg.Dirty := false; 759 out_msg.State := CoherenceState:Modified; 760 out_msg.CtoD := true; 761 out_msg.InitialRequestTime := in_msg.InitialRequestTime; 762 out_msg.ForwardRequestTime := curCycle(); 763 out_msg.ProbeRequestStartTime := in_msg.ProbeRequestStartTime; 764 out_msg.DemandRequest := false; 765 DPRINTF(RubySlicc, "%s\n", out_msg); 766 } 767 } 768 } 769 770 action(w_sendResponseWBAck, "w", desc="send WB Ack") { 771 peek(regDir_in, CPURequestMsg) { 772 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 773 out_msg.addr := address; 774 out_msg.Type := CoherenceResponseType:NBSysWBAck; 775 out_msg.Destination.add(in_msg.Requestor); 776 out_msg.WTRequestor := in_msg.WTRequestor; 777 out_msg.Sender := machineID; 778 out_msg.MessageSize := MessageSizeType:Writeback_Control; 779 out_msg.InitialRequestTime := in_msg.InitialRequestTime; 780 out_msg.ForwardRequestTime := in_msg.ForwardRequestTime; 781 out_msg.ProbeRequestStartTime := in_msg.ProbeRequestStartTime; 782 out_msg.DemandRequest := false; 783 } 784 } 785 } 786 787 action(wp_sendResponseWBAckP, "wp", desc="send WB Ack") { 788 peek(requestNetwork_in, CPURequestMsg) { 789 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 790 out_msg.addr := address; 791 out_msg.Type := CoherenceResponseType:NBSysWBAck; 792 out_msg.Destination.add(in_msg.Requestor); 793 out_msg.WTRequestor := in_msg.WTRequestor; 794 out_msg.Sender := machineID; 795 out_msg.MessageSize := MessageSizeType:Writeback_Control; 796 out_msg.InitialRequestTime := in_msg.InitialRequestTime; 797 out_msg.ForwardRequestTime := curCycle(); 798 out_msg.ProbeRequestStartTime := in_msg.ProbeRequestStartTime; 799 out_msg.DemandRequest := false; 800 } 801 } 802 } 803 804 action(wc_sendResponseWBAck, "wc", desc="send WB Ack for cancel") { 805 peek(responseNetwork_in, ResponseMsg) { 806 enqueue(responseNetwork_out, ResponseMsg, response_latency) { 807 out_msg.addr := address; 808 out_msg.Type := CoherenceResponseType:NBSysWBAck; 809 out_msg.Destination.add(in_msg.Sender); 810 out_msg.Sender := machineID; 811 out_msg.MessageSize := MessageSizeType:Writeback_Control; 812 } 813 } 814 } 815 816 action(ra_ackRegionDir, "ra", desc="Ack region dir") { 817 peek(regDir_in, CPURequestMsg) { 818 if (in_msg.NoAckNeeded == false) { 819 enqueue(responseNetwork_out, ResponseMsg, response_latency_regionDir) { 820 out_msg.addr := address; 821 out_msg.Type := CoherenceResponseType:DirReadyAck; 822 out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir)); 823 out_msg.Sender := machineID; 824 out_msg.MessageSize := MessageSizeType:Writeback_Control; 825 } 826 } 827 } 828 } 829 830 action(l_queueMemRdReq, "lr", desc="Read data from memory") { 831 peek(regDir_in, CPURequestMsg) { 832 if (L3CacheMemory.isTagPresent(address)) { 833 enqueue(L3TriggerQueue_out, TriggerMsg, l3_hit_latency) { 834 out_msg.addr := address; 835 out_msg.Type := TriggerType:L3Hit; 836 DPRINTF(RubySlicc, "%s\n", out_msg); 837 } 838 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(address)); 839 tbe.DataBlk := entry.DataBlk; 840 tbe.LastSender := entry.LastSender; 841 tbe.L3Hit := true; 842 tbe.MemData := true; 843 DPRINTF(RubySlicc, "L3 data is %s\n", entry.DataBlk); 844 L3CacheMemory.deallocate(address); 845 } else { 846 queueMemoryRead(machineID, address, to_memory_controller_latency); 847 } 848 } 849 } 850 851 action(lrp_queueMemRdReqP, "lrp", desc="Read data from memory") { 852 peek(requestNetwork_in, CPURequestMsg) { 853 if (L3CacheMemory.isTagPresent(address)) { 854 enqueue(L3TriggerQueue_out, TriggerMsg, l3_hit_latency) { 855 out_msg.addr := address; 856 out_msg.Type := TriggerType:L3Hit; 857 DPRINTF(RubySlicc, "%s\n", out_msg); 858 } 859 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(address)); 860 tbe.DataBlk := entry.DataBlk; 861 tbe.LastSender := entry.LastSender; 862 tbe.L3Hit := true; 863 tbe.MemData := true; 864 DPRINTF(RubySlicc, "L3 data is %s\n", entry.DataBlk); 865 L3CacheMemory.deallocate(address); 866 } else { 867 queueMemoryRead(machineID, address, to_memory_controller_latency); 868 } 869 } 870 } 871 872 action(dcr_probeInvCoreData, "dcr", desc="probe inv cores, return data") { 873 peek(regBuf_in, CPURequestMsg) { 874 enqueue(probeNetwork_out, NBProbeRequestMsg, response_latency) { 875 out_msg.addr := address; 876 out_msg.Type := ProbeRequestType:PrbInv; 877 out_msg.ReturnData := true; 878 out_msg.MessageSize := MessageSizeType:Control; 879 out_msg.Destination := in_msg.Sharers; 880 tbe.NumPendingAcks := tbe.NumPendingAcks + in_msg.Sharers.count(); 881 DPRINTF(RubySlicc, "%s\n", out_msg); 882 APPEND_TRANSITION_COMMENT(" dcr: Acks remaining: "); 883 APPEND_TRANSITION_COMMENT(tbe.NumPendingAcks); 884 tbe.ProbeRequestStartTime := curCycle(); 885 } 886 } 887 } 888 889 action(ddr_probeDownCoreData, "ddr", desc="probe inv cores, return data") { 890 peek(regBuf_in, CPURequestMsg) { 891 enqueue(probeNetwork_out, NBProbeRequestMsg, response_latency) { 892 out_msg.addr := address; 893 out_msg.Type := ProbeRequestType:PrbDowngrade; 894 out_msg.ReturnData := true; 895 out_msg.MessageSize := MessageSizeType:Control; 896 out_msg.Destination := in_msg.Sharers; 897 tbe.NumPendingAcks := tbe.NumPendingAcks + in_msg.Sharers.count(); 898 DPRINTF(RubySlicc, "%s\n", out_msg); 899 APPEND_TRANSITION_COMMENT(" dcr: Acks remaining: "); 900 APPEND_TRANSITION_COMMENT(tbe.NumPendingAcks); 901 tbe.ProbeRequestStartTime := curCycle(); 902 } 903 } 904 } 905 906 action(sc_probeShrCoreData, "sc", desc="probe shared cores, return data") { 907 peek(requestNetwork_in, CPURequestMsg) { // not the right network? 908 enqueue(probeNetwork_out, NBProbeRequestMsg, response_latency) { 909 out_msg.addr := address; 910 out_msg.Type := ProbeRequestType:PrbDowngrade; 911 out_msg.ReturnData := true; 912 out_msg.MessageSize := MessageSizeType:Control; 913 out_msg.Destination.broadcast(MachineType:CorePair); // won't be realistic for multisocket 914 tbe.NumPendingAcks := tbe.NumPendingAcks +machineCount(MachineType:CorePair) - 1; 915 out_msg.Destination.broadcast(MachineType:TCP); 916 tbe.NumPendingAcks := tbe.NumPendingAcks + machineCount(MachineType:TCP); 917 out_msg.Destination.broadcast(MachineType:SQC); 918 tbe.NumPendingAcks := tbe.NumPendingAcks + machineCount(MachineType:SQC); 919 out_msg.Destination.remove(in_msg.Requestor); 920 DPRINTF(RubySlicc, "%s\n", (out_msg)); 921 APPEND_TRANSITION_COMMENT(" sc: Acks remaining: "); 922 APPEND_TRANSITION_COMMENT(tbe.NumPendingAcks); 923 tbe.ProbeRequestStartTime := curCycle(); 924 } 925 } 926 } 927 928 action(ic_probeInvCore, "ic", desc="probe invalidate core, no return data needed") { 929 peek(requestNetwork_in, CPURequestMsg) { // not the right network? 930 enqueue(probeNetwork_out, NBProbeRequestMsg, response_latency) { 931 out_msg.addr := address; 932 out_msg.Type := ProbeRequestType:PrbInv; 933 out_msg.ReturnData := false; 934 out_msg.MessageSize := MessageSizeType:Control; 935 out_msg.Destination.broadcast(MachineType:CorePair); // won't be realistic for multisocket 936 tbe.NumPendingAcks := tbe.NumPendingAcks +machineCount(MachineType:CorePair) - 1; 937 out_msg.Destination.broadcast(MachineType:TCP); 938 tbe.NumPendingAcks := tbe.NumPendingAcks + machineCount(MachineType:TCP); 939 out_msg.Destination.broadcast(MachineType:SQC); 940 tbe.NumPendingAcks := tbe.NumPendingAcks + machineCount(MachineType:SQC); 941 out_msg.Destination.remove(in_msg.Requestor); 942 APPEND_TRANSITION_COMMENT(" ic: Acks remaining: "); 943 APPEND_TRANSITION_COMMENT(tbe.NumPendingAcks); 944 DPRINTF(RubySlicc, "%s\n", out_msg); 945 tbe.ProbeRequestStartTime := curCycle(); 946 } 947 } 948 } 949 950 action(d_writeDataToMemory, "d", desc="Write data to memory") { 951 peek(responseNetwork_in, ResponseMsg) { 952 getDirectoryEntry(address).DataBlk := in_msg.DataBlk; 953 DPRINTF(RubySlicc, "Writing Data: %s to address %s\n", in_msg.DataBlk, 954 in_msg.addr); 955 } 956 } 957 958 action(t_allocateTBE, "t", desc="allocate TBE Entry") { 959 check_allocate(TBEs); 960 peek(regDir_in, CPURequestMsg) { 961 TBEs.allocate(address); 962 set_tbe(TBEs.lookup(address)); 963 if (in_msg.Type == CoherenceRequestType:WriteThrough) { 964 tbe.writeMask.clear(); 965 tbe.writeMask.orMask(in_msg.writeMask); 966 tbe.wtData := true; 967 tbe.WTRequestor := in_msg.WTRequestor; 968 tbe.LastSender := in_msg.Requestor; 969 } 970 if (in_msg.Type == CoherenceRequestType:Atomic) { 971 tbe.writeMask.clear(); 972 tbe.writeMask.orMask(in_msg.writeMask); 973 tbe.atomicData := true; 974 tbe.WTRequestor := in_msg.WTRequestor; 975 tbe.LastSender := in_msg.Requestor; 976 } 977 tbe.DataBlk := getDirectoryEntry(address).DataBlk; // Data only for WBs 978 tbe.Dirty := false; 979 if (in_msg.Type == CoherenceRequestType:WriteThrough) { 980 tbe.DataBlk.copyPartial(in_msg.DataBlk,tbe.writeMask); 981 tbe.Dirty := false; 982 } 983 tbe.OriginalRequestor := in_msg.Requestor; 984 tbe.NumPendingAcks := 0; 985 tbe.Cached := in_msg.ForceShared; 986 tbe.InitialRequestTime := in_msg.InitialRequestTime; 987 tbe.ForwardRequestTime := curCycle(); 988 tbe.ProbeRequestStartTime := in_msg.ProbeRequestStartTime; 989 tbe.DemandRequest := in_msg.DemandRequest; 990 } 991 } 992 993 action(tp_allocateTBEP, "tp", desc="allocate TBE Entry") { 994 check_allocate(TBEs); 995 peek(requestNetwork_in, CPURequestMsg) { 996 TBEs.allocate(address); 997 set_tbe(TBEs.lookup(address)); 998 if (in_msg.Type == CoherenceRequestType:WriteThrough) { 999 tbe.writeMask.clear(); 1000 tbe.writeMask.orMask(in_msg.writeMask); 1001 tbe.wtData := true; 1002 tbe.WTRequestor := in_msg.WTRequestor; 1003 tbe.LastSender := in_msg.Requestor; 1004 } 1005 if (in_msg.Type == CoherenceRequestType:Atomic) { 1006 tbe.writeMask.clear(); 1007 tbe.writeMask.orMask(in_msg.writeMask); 1008 tbe.atomicData := true; 1009 tbe.WTRequestor := in_msg.WTRequestor; 1010 tbe.LastSender := in_msg.Requestor; 1011 } 1012 tbe.DataBlk := getDirectoryEntry(address).DataBlk; // Data only for WBs 1013 tbe.Dirty := false; 1014 if (in_msg.Type == CoherenceRequestType:WriteThrough) { 1015 tbe.DataBlk.copyPartial(in_msg.DataBlk,tbe.writeMask); 1016 tbe.Dirty := false; 1017 } 1018 tbe.OriginalRequestor := in_msg.Requestor; 1019 tbe.NumPendingAcks := 0; 1020 tbe.Cached := in_msg.ForceShared; 1021 tbe.InitialRequestTime := in_msg.InitialRequestTime; 1022 tbe.ForwardRequestTime := curCycle(); 1023 tbe.ProbeRequestStartTime := in_msg.ProbeRequestStartTime; 1024 tbe.DemandRequest := false; 1025 } 1026 } 1027 1028 action(sa_setAcks, "sa", desc="setAcks") { 1029 peek(regDir_in, CPURequestMsg) { 1030 tbe.NumPendingAcks := in_msg.Acks; 1031 APPEND_TRANSITION_COMMENT(" waiting for acks "); 1032 APPEND_TRANSITION_COMMENT(tbe.NumPendingAcks); 1033 } 1034 } 1035 1036 action(tr_allocateTBE, "tr", desc="allocate TBE Entry for Region inv") { 1037 check_allocate(TBEs); 1038 TBEs.allocate(address); 1039 set_tbe(TBEs.lookup(address)); 1040 tbe.NumPendingAcks := 0; 1041 } 1042 1043 action(dt_deallocateTBE, "dt", desc="deallocate TBE Entry") { 1044 TBEs.deallocate(address); 1045 unset_tbe(); 1046 } 1047 1048 action(wdp_writeBackDataPrivate, "wdp", desc="Write back data if needed") { 1049 peek(requestNetwork_in, CPURequestMsg) { 1050 if (in_msg.Type == CoherenceRequestType:WriteThrough) { 1051 tbe.DataBlkAux := getDirectoryEntry(address).DataBlk; 1052 tbe.DataBlkAux.copyPartial(in_msg.DataBlk,in_msg.writeMask); 1053 getDirectoryEntry(address).DataBlk := tbe.DataBlkAux; 1054 } else{ 1055 assert(in_msg.Type == CoherenceRequestType:Atomic); 1056 tbe.DataBlkAux.atomicPartial(getDirectoryEntry(address).DataBlk,in_msg.writeMask); 1057 getDirectoryEntry(address).DataBlk := tbe.DataBlkAux; 1058 } 1059 } 1060 } 1061 1062 action(wd_writeBackData, "wd", desc="Write back data if needed") { 1063 if (tbe.wtData) { 1064 DataBlock tmp := getDirectoryEntry(address).DataBlk; 1065 tmp.copyPartial(tbe.DataBlk,tbe.writeMask); 1066 tbe.DataBlk := tmp; 1067 getDirectoryEntry(address).DataBlk := tbe.DataBlk; 1068 } else if (tbe.atomicData) { 1069 tbe.DataBlk.atomicPartial(getDirectoryEntry(address).DataBlk,tbe.writeMask); 1070 getDirectoryEntry(address).DataBlk := tbe.DataBlk; 1071 } else if (tbe.Dirty == true) { 1072 APPEND_TRANSITION_COMMENT(" Wrote data back "); 1073 getDirectoryEntry(address).DataBlk := tbe.DataBlk; 1074 } 1075 } 1076 1077 action(wdi_writeBackDataInv, "wdi", desc="Write back inv data if needed") { 1078 // Kind of opposite from above...? 1079 if (tbe.Dirty == true) { 1080 getDirectoryEntry(address).DataBlk := tbe.DataBlk; 1081 APPEND_TRANSITION_COMMENT("Writing dirty data to dir"); 1082 DPRINTF(RubySlicc, "Data %s: %s\n", address, tbe.DataBlk); 1083 } else { 1084 APPEND_TRANSITION_COMMENT("NOT!!! Writing dirty data to dir"); 1085 } 1086 } 1087 1088 action(wdt_writeBackDataInvNoTBE, "wdt", desc="Write back inv data if needed no TBE") { 1089 // Kind of opposite from above...? 1090 peek(responseNetwork_in, ResponseMsg) { 1091 if (in_msg.Dirty == true) { 1092 getDirectoryEntry(address).DataBlk := in_msg.DataBlk; 1093 APPEND_TRANSITION_COMMENT("Writing dirty data to dir"); 1094 DPRINTF(RubySlicc, "Data %s: %s\n", address, in_msg.DataBlk); 1095 } else { 1096 APPEND_TRANSITION_COMMENT("NOT!!! Writing dirty data to dir"); 1097 } 1098 } 1099 } 1100 1101 action(mt_writeMemDataToTBE, "mt", desc="write Mem data to TBE") { 1102 peek(memQueue_in, MemoryMsg) { 1103 if (tbe.Dirty == false) { 1104 tbe.DataBlk := getDirectoryEntry(address).DataBlk; 1105 } 1106 tbe.MemData := true; 1107 } 1108 } 1109 1110 action(ml_writeL3DataToTBE, "ml", desc="write L3 data to TBE") { 1111 assert(tbe.Dirty == false); 1112 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(address)); 1113 tbe.DataBlk := entry.DataBlk; 1114 tbe.LastSender := entry.LastSender; 1115 tbe.L3Hit := true; 1116 tbe.MemData := true; 1117 } 1118 1119 action(y_writeProbeDataToTBE, "y", desc="write Probe Data to TBE") { 1120 peek(responseNetwork_in, ResponseMsg) { 1121 if (in_msg.Dirty) { 1122 DPRINTF(RubySlicc, "Got dirty data for %s from %s\n", address, in_msg.Sender); 1123 DPRINTF(RubySlicc, "Data is %s\n", in_msg.DataBlk); 1124 if (tbe.wtData) { 1125 DataBlock tmp := in_msg.DataBlk; 1126 tmp.copyPartial(tbe.DataBlk,tbe.writeMask); 1127 tbe.DataBlk := tmp; 1128 } else if (tbe.Dirty) { 1129 if(tbe.atomicData == false && tbe.wtData == false) { 1130 DPRINTF(RubySlicc, "Got double data for %s from %s\n", address, in_msg.Sender); 1131 assert(tbe.DataBlk == in_msg.DataBlk); // in case of double data 1132 } 1133 } else { 1134 tbe.DataBlk := in_msg.DataBlk; 1135 tbe.Dirty := in_msg.Dirty; 1136 tbe.LastSender := in_msg.Sender; 1137 } 1138 } 1139 if (in_msg.Hit) { 1140 tbe.Cached := true; 1141 } 1142 } 1143 } 1144 1145 action(yc_writeCPUDataToTBE, "yc", desc="write CPU Data to TBE") { 1146 peek(responseNetwork_in, ResponseMsg) { 1147 if (in_msg.Dirty) { 1148 DPRINTF(RubySlicc, "Got dirty data for %s from %s\n", address, in_msg.Sender); 1149 DPRINTF(RubySlicc, "Data is %s\n", in_msg.DataBlk); 1150 if (tbe.Dirty) { 1151 DPRINTF(RubySlicc, "Got double data for %s from %s\n", address, in_msg.Sender); 1152 assert(tbe.DataBlk == in_msg.DataBlk); // in case of double data 1153 } 1154 tbe.DataBlk := in_msg.DataBlk; 1155 tbe.Dirty := false; 1156 tbe.LastSender := in_msg.Sender; 1157 } 1158 } 1159 } 1160 1161 action(x_decrementAcks, "x", desc="decrement Acks pending") { 1162 if (tbe.NumPendingAcks > 0) { 1163 tbe.NumPendingAcks := tbe.NumPendingAcks - 1; 1164 } else { 1165 APPEND_TRANSITION_COMMENT(" Double ack! "); 1166 } 1167 assert(tbe.NumPendingAcks >= 0); 1168 APPEND_TRANSITION_COMMENT(" Acks remaining: "); 1169 APPEND_TRANSITION_COMMENT(tbe.NumPendingAcks); 1170 } 1171 1172 action(o_checkForCompletion, "o", desc="check for ack completion") { 1173 if (tbe.NumPendingAcks == 0 && tbe.TriggeredAcksComplete == false) { 1174 enqueue(triggerQueue_out, TriggerMsg, 1) { 1175 out_msg.addr := address; 1176 out_msg.Type := TriggerType:AcksComplete; 1177 } 1178 tbe.TriggeredAcksComplete := true; 1179 } 1180 APPEND_TRANSITION_COMMENT(" Check: Acks remaining: "); 1181 APPEND_TRANSITION_COMMENT(tbe.NumPendingAcks); 1182 } 1183 1184 action(ont_checkForCompletionNoTrigger, "ont", desc="check for ack completion, no trigger") { 1185 if (tbe.NumPendingAcks == 0 && tbe.TriggeredAcksComplete == false) { 1186 tbe.TriggeredAcksComplete := true; 1187 } 1188 APPEND_TRANSITION_COMMENT(" Check: Acks remaining: "); 1189 APPEND_TRANSITION_COMMENT(tbe.NumPendingAcks); 1190 } 1191 1192 action(rvp_removeVicDirtyIgnore, "rvp", desc="Remove ignored core") { 1193 peek(requestNetwork_in, CPURequestMsg) { 1194 getDirectoryEntry(address).VicDirtyIgnore.remove(in_msg.Requestor); 1195 } 1196 } 1197 1198 action(rv_removeVicDirtyIgnore, "rv", desc="Remove ignored core") { 1199 peek(regDir_in, CPURequestMsg) { 1200 getDirectoryEntry(address).VicDirtyIgnore.remove(in_msg.Requestor); 1201 } 1202 } 1203 1204 action(r_sendRequestToRegionDir, "r", desc="send request to Region Directory") { 1205 peek(requestNetwork_in, CPURequestMsg) { 1206 enqueue(requestNetworkReg_out, CPURequestMsg, 1) { 1207 out_msg.addr := address; 1208 out_msg.Type := in_msg.Type; 1209 out_msg.Requestor := in_msg.Requestor; 1210 out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir)); 1211 out_msg.Shared := in_msg.Shared; 1212 out_msg.MessageSize := in_msg.MessageSize; 1213 DPRINTF(RubySlicc, "out dest: %s\n", mapAddressToMachine(address, MachineType:RegionDir)); 1214 } 1215 } 1216 } 1217 1218 action(ai_ackInvalidate, "ai", desc="Ack to let the reg-dir know that the inv is ordered") { 1219 peek(regBuf_in, CPURequestMsg) { 1220 enqueue(regAckNetwork_out, UnblockMsg, 1) { 1221 out_msg.addr := address; 1222 out_msg.Destination.add(in_msg.Requestor); 1223 out_msg.MessageSize := MessageSizeType:Response_Control; 1224 DPRINTF(RubySlicc, "ai out_msg: %s\n", out_msg); 1225 } 1226 } 1227 } 1228 1229 action(aic_ackInvalidate, "aic", desc="Ack to let the reg-dir know that the inv is ordered") { 1230 peek(responseNetwork_in, ResponseMsg) { 1231 if (in_msg.NoAckNeeded == false) { 1232 enqueue(regAckNetwork_out, UnblockMsg, 1) { 1233 out_msg.addr := address; 1234 if (machineIDToMachineType(in_msg.Sender) == MachineType:CorePair) { 1235 out_msg.Destination.add(createMachineID(MachineType:RegionBuffer, intToID(0))); 1236 } else { 1237 out_msg.Destination.add(createMachineID(MachineType:RegionBuffer, intToID(1))); 1238 } 1239 out_msg.MessageSize := MessageSizeType:Response_Control; 1240 DPRINTF(RubySlicc, "ai out_msg: %s\n", out_msg); 1241 out_msg.wasValid := in_msg.isValid; 1242 } 1243 } 1244 } 1245 } 1246 1247 action(al_allocateL3Block, "al", desc="allocate the L3 block on WB") { 1248 peek(responseNetwork_in, ResponseMsg) { 1249 if (L3CacheMemory.isTagPresent(address)) { 1250 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(address)); 1251 APPEND_TRANSITION_COMMENT(" al wrote data to L3 (hit) "); 1252 entry.DataBlk := in_msg.DataBlk; 1253 entry.LastSender := in_msg.Sender; 1254 } else { 1255 if (L3CacheMemory.cacheAvail(address) == false) { 1256 Addr victim := L3CacheMemory.cacheProbe(address); 1257 CacheEntry victim_entry := static_cast(CacheEntry, "pointer", 1258 L3CacheMemory.lookup(victim)); 1259 queueMemoryWrite(machineID, victim, to_memory_controller_latency, 1260 victim_entry.DataBlk); 1261 L3CacheMemory.deallocate(victim); 1262 } 1263 assert(L3CacheMemory.cacheAvail(address)); 1264 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.allocate(address, new CacheEntry)); 1265 APPEND_TRANSITION_COMMENT(" al wrote data to L3 "); 1266 entry.DataBlk := in_msg.DataBlk; 1267 entry.LastSender := in_msg.Sender; 1268 } 1269 } 1270 } 1271 1272 action(alwt_allocateL3BlockOnWT, "alwt", desc="allocate the L3 block on WT") { 1273 if ((tbe.wtData || tbe.atomicData) && useL3OnWT) { 1274 if (L3CacheMemory.isTagPresent(address)) { 1275 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(address)); 1276 APPEND_TRANSITION_COMMENT(" al wrote data to L3 (hit) "); 1277 entry.DataBlk := tbe.DataBlk; 1278 entry.LastSender := tbe.LastSender; 1279 } else { 1280 if (L3CacheMemory.cacheAvail(address) == false) { 1281 Addr victim := L3CacheMemory.cacheProbe(address); 1282 CacheEntry victim_entry := static_cast(CacheEntry, "pointer", 1283 L3CacheMemory.lookup(victim)); 1284 queueMemoryWrite(machineID, victim, to_memory_controller_latency, 1285 victim_entry.DataBlk); 1286 L3CacheMemory.deallocate(victim); 1287 } 1288 assert(L3CacheMemory.cacheAvail(address)); 1289 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.allocate(address, new CacheEntry)); 1290 APPEND_TRANSITION_COMMENT(" al wrote data to L3 "); 1291 entry.DataBlk := tbe.DataBlk; 1292 entry.LastSender := tbe.LastSender; 1293 } 1294 } 1295 } 1296 1297 action(ali_allocateL3Block, "ali", desc="allocate the L3 block on ForceInv") { 1298 if (tbe.Dirty == true) { 1299 if (L3CacheMemory.isTagPresent(address)) { 1300 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(address)); 1301 APPEND_TRANSITION_COMMENT(" al wrote data to L3 (hit) "); 1302 entry.DataBlk := tbe.DataBlk; 1303 entry.LastSender := tbe.LastSender; 1304 } else { 1305 if (L3CacheMemory.cacheAvail(address) == false) { 1306 Addr victim := L3CacheMemory.cacheProbe(address); 1307 CacheEntry victim_entry := static_cast(CacheEntry, "pointer", 1308 L3CacheMemory.lookup(victim)); 1309 queueMemoryWrite(machineID, victim, to_memory_controller_latency, 1310 victim_entry.DataBlk); 1311 L3CacheMemory.deallocate(victim); 1312 } 1313 assert(L3CacheMemory.cacheAvail(address)); 1314 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.allocate(address, new CacheEntry)); 1315 APPEND_TRANSITION_COMMENT(" al wrote data to L3 "); 1316 entry.DataBlk := tbe.DataBlk; 1317 entry.LastSender := tbe.LastSender; 1318 } 1319 } 1320 } 1321 1322 action(ali_allocateL3BlockNoTBE, "alt", desc="allocate the L3 block on ForceInv no TBE") { 1323 peek(responseNetwork_in, ResponseMsg) { 1324 if (in_msg.Dirty) { 1325 if (L3CacheMemory.isTagPresent(address)) { 1326 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.lookup(address)); 1327 APPEND_TRANSITION_COMMENT(" ali wrote data to L3 (hit) "); 1328 entry.DataBlk := in_msg.DataBlk; 1329 entry.LastSender := in_msg.Sender; 1330 } else { 1331 if (L3CacheMemory.cacheAvail(address) == false) { 1332 Addr victim := L3CacheMemory.cacheProbe(address); 1333 CacheEntry victim_entry := static_cast(CacheEntry, "pointer", 1334 L3CacheMemory.lookup(victim)); 1335 queueMemoryWrite(machineID, victim, to_memory_controller_latency, 1336 victim_entry.DataBlk); 1337 L3CacheMemory.deallocate(victim); 1338 } 1339 assert(L3CacheMemory.cacheAvail(address)); 1340 CacheEntry entry := static_cast(CacheEntry, "pointer", L3CacheMemory.allocate(address, new CacheEntry)); 1341 APPEND_TRANSITION_COMMENT(" ali wrote data to L3 "); 1342 entry.DataBlk := in_msg.DataBlk; 1343 entry.LastSender := in_msg.Sender; 1344 } 1345 } 1346 } 1347 } 1348 1349 action(dl_deallocateL3, "dl", desc="deallocate the L3 block") { 1350 L3CacheMemory.deallocate(address); 1351 } 1352 1353 action(p_popRequestQueue, "p", desc="pop request queue") { 1354 requestNetwork_in.dequeue(clockEdge()); 1355 } 1356 1357 action(prd_popRegionQueue, "prd", desc="pop request queue") { 1358 regDir_in.dequeue(clockEdge()); 1359 } 1360 1361 action(prb_popRegionBufQueue, "prb", desc="pop request queue") { 1362 regBuf_in.dequeue(clockEdge()); 1363 } 1364 1365 action(pr_popResponseQueue, "pr", desc="pop response queue") { 1366 responseNetwork_in.dequeue(clockEdge()); 1367 } 1368 1369 action(pm_popMemQueue, "pm", desc="pop mem queue") { 1370 memQueue_in.dequeue(clockEdge()); 1371 } 1372 1373 action(pt_popTriggerQueue, "pt", desc="pop trigger queue") { 1374 triggerQueue_in.dequeue(clockEdge()); 1375 } 1376 1377 action(ptl_popTriggerQueue, "ptl", desc="pop L3 trigger queue") { 1378 L3TriggerQueue_in.dequeue(clockEdge()); 1379 } 1380 1381 action(pu_popUnblockQueue, "pu", desc="pop unblock queue") { 1382 unblockNetwork_in.dequeue(clockEdge()); 1383 } 1384 1385 action(yy_recycleResponseQueue, "yy", desc="recycle response queue") { 1386 responseNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency)); 1387 } 1388 1389 action(ww_stallAndWaitRegRequestQueue, "ww", desc="recycle region dir request queue") { 1390 stall_and_wait(regDir_in, address); 1391 } 1392 1393 action(st_stallAndWaitRequest, "st", desc="Stall and wait on the address") { 1394 stall_and_wait(requestNetwork_in, address); 1395 } 1396 1397 action(wa_wakeUpDependents, "wa", desc="Wake up any requests waiting for this address") { 1398 wakeUpBuffers(address); 1399 } 1400 1401 action(wa_wakeUpAllDependents, "waa", desc="Wake up any requests waiting for this region") { 1402 wakeUpAllBuffers(); 1403 } 1404 1405 action(z_stall, "z", desc="...") { 1406 } 1407 1408 // TRANSITIONS 1409 1410 // transitions from U 1411 1412 transition({BR, BW, BL, BI, BS_M, BM_M, B_M, BP, BS_PM, BM_PM, B_PM, BS_Pm, BM_Pm, B_Pm, B}, {Inv, Downgrade}) { 1413 ww_stallAndWaitRegRequestQueue; 1414 } 1415 1416 transition(U, Inv, BI){L3TagArrayRead} { 1417 tr_allocateTBE; 1418 dcr_probeInvCoreData; // only need to invalidate sharers 1419 ai_ackInvalidate; 1420 prb_popRegionBufQueue; 1421 } 1422 1423 transition(U, Downgrade, BI){L3TagArrayRead} { 1424 tr_allocateTBE; 1425 ddr_probeDownCoreData; // only need to invalidate sharers 1426 ai_ackInvalidate; 1427 prb_popRegionBufQueue; 1428 } 1429 1430 // The next 2 transistions are needed in the event that an invalidation 1431 // is waiting for its ack from the core, but the event makes it through 1432 // the region directory before the acks. This wouldn't be needed if 1433 // we waited to ack the region dir until the directory got all the acks 1434 transition({BR, BW, BI, BL, BS_M, BM_M, B_M, BP, BS_PM, BM_PM, B_PM, BS_Pm, BM_Pm, B_Pm, B}, {RdBlkS, RdBlkM, RdBlk, WriteThrough, Atomic}) { 1435 ww_stallAndWaitRegRequestQueue; 1436 } 1437 1438 transition({BR, BW, BI, BL, BS_M, BM_M, B_M, BS_PM, BM_PM, B_PM, B, BS_Pm_BL, BM_Pm_BL, B_Pm_BL, BP_BL, BS_Pm_B, BM_Pm_B, B_Pm_B, BP_B}, {RdBlkSP, RdBlkMP, RdBlkP}) { 1439 st_stallAndWaitRequest; 1440 } 1441 1442 transition({BR, BW, BI, BL, BS_M, BM_M, B_M, BS_PM, BM_PM, B_PM, B, BS_Pm_BL, BM_Pm_BL, B_Pm_BL, BP_BL, BS_Pm_B, BM_Pm_B, B_Pm_B, BP_B}, {WriteThroughP,AtomicP}) { 1443 st_stallAndWaitRequest; 1444 } 1445 1446 transition(U, {RdBlkS}, BS_PM) {L3TagArrayRead} { 1447 t_allocateTBE; 1448 l_queueMemRdReq; 1449 sa_setAcks; 1450 o_checkForCompletion; 1451 ra_ackRegionDir; 1452 prd_popRegionQueue; 1453 } 1454 1455 transition(U, WriteThrough, BM_PM){L3TagArrayRead} { 1456 t_allocateTBE; 1457 w_sendResponseWBAck; 1458 l_queueMemRdReq; 1459 sa_setAcks; 1460 o_checkForCompletion; 1461 ra_ackRegionDir; 1462 prd_popRegionQueue; 1463 } 1464 1465 transition(U, {RdBlkM,Atomic}, BM_PM){L3TagArrayRead} { 1466 t_allocateTBE; 1467 l_queueMemRdReq; 1468 sa_setAcks; 1469 o_checkForCompletion; 1470 ra_ackRegionDir; 1471 prd_popRegionQueue; 1472 } 1473 1474 transition(U, RdBlk, B_PM){L3TagArrayRead} { 1475 t_allocateTBE; 1476 l_queueMemRdReq; 1477 sa_setAcks; 1478 o_checkForCompletion; 1479 ra_ackRegionDir; 1480 prd_popRegionQueue; 1481 } 1482 1483 transition(U, {RdBlkSP}, BS_M) {L3TagArrayRead} { 1484 tp_allocateTBEP; 1485 lrp_queueMemRdReqP; 1486 p_popRequestQueue; 1487 } 1488 1489 transition(U, WriteThroughP, BM_M) {L3TagArrayRead} { 1490 tp_allocateTBEP; 1491 wp_sendResponseWBAckP; 1492 lrp_queueMemRdReqP; 1493 p_popRequestQueue; 1494 } 1495 1496 transition(U, {RdBlkMP,AtomicP}, BM_M) {L3TagArrayRead} { 1497 tp_allocateTBEP; 1498 lrp_queueMemRdReqP; 1499 p_popRequestQueue; 1500 } 1501 1502 transition(U, RdBlkP, B_M) {L3TagArrayRead} { 1503 tp_allocateTBEP; 1504 lrp_queueMemRdReqP; 1505 p_popRequestQueue; 1506 } 1507 1508 transition(U, VicDirtyP, BL) {L3TagArrayRead} { 1509 tp_allocateTBEP; 1510 wp_sendResponseWBAckP; 1511 p_popRequestQueue; 1512 } 1513 1514 transition(U, VicCleanP, BL) {L3TagArrayRead} { 1515 tp_allocateTBEP; 1516 wp_sendResponseWBAckP; 1517 p_popRequestQueue; 1518 } 1519 1520 transition(BM_Pm, RdBlkSP, BM_Pm_B) {L3DataArrayWrite} { 1521 sb_sendResponseSBypass; 1522 p_popRequestQueue; 1523 } 1524 1525 transition(BS_Pm, RdBlkSP, BS_Pm_B) {L3DataArrayWrite} { 1526 sb_sendResponseSBypass; 1527 p_popRequestQueue; 1528 } 1529 1530 transition(B_Pm, RdBlkSP, B_Pm_B) {L3DataArrayWrite} { 1531 sb_sendResponseSBypass; 1532 p_popRequestQueue; 1533 } 1534 1535 transition(BP, RdBlkSP, BP_B) {L3DataArrayWrite} { 1536 sb_sendResponseSBypass; 1537 p_popRequestQueue; 1538 } 1539 1540 transition(BM_Pm, RdBlkMP, BM_Pm_B) {L3DataArrayWrite} { 1541 mb_sendResponseMBypass; 1542 p_popRequestQueue; 1543 } 1544 1545 transition(BS_Pm, RdBlkMP, BS_Pm_B) {L3DataArrayWrite} { 1546 mb_sendResponseMBypass; 1547 p_popRequestQueue; 1548 } 1549 1550 transition(B_Pm, RdBlkMP, B_Pm_B) {L3DataArrayWrite} { 1551 mb_sendResponseMBypass; 1552 p_popRequestQueue; 1553 } 1554 1555 transition(BP, RdBlkMP, BP_B) {L3DataArrayWrite} { 1556 mb_sendResponseMBypass; 1557 p_popRequestQueue; 1558 } 1559 1560 transition(BM_Pm, {WriteThroughP,AtomicP}, BM_Pm_B) {L3DataArrayWrite} { 1561 wdp_writeBackDataPrivate; 1562 mbwt_sendResponseWriteThroughBypass; 1563 p_popRequestQueue; 1564 } 1565 1566 transition(BS_Pm, {WriteThroughP,AtomicP}, BS_Pm_B) {L3DataArrayWrite} { 1567 wdp_writeBackDataPrivate; 1568 mbwt_sendResponseWriteThroughBypass; 1569 p_popRequestQueue; 1570 } 1571 1572 transition(B_Pm, {WriteThroughP,AtomicP}, B_Pm_B) {L3DataArrayWrite} { 1573 wdp_writeBackDataPrivate; 1574 mbwt_sendResponseWriteThroughBypass; 1575 p_popRequestQueue; 1576 } 1577 1578 transition(BP, {WriteThroughP,AtomicP}, BP_B) {L3DataArrayWrite} { 1579 wdp_writeBackDataPrivate; 1580 mbwt_sendResponseWriteThroughBypass; 1581 p_popRequestQueue; 1582 } 1583 1584 transition(BM_Pm, RdBlkP, BM_Pm_B) {L3DataArrayWrite} { 1585 esb_sendResponseESBypass; 1586 p_popRequestQueue; 1587 } 1588 1589 transition(BS_Pm, RdBlkP, BS_Pm_B) {L3DataArrayWrite} { 1590 esb_sendResponseESBypass; 1591 p_popRequestQueue; 1592 } 1593 1594 transition(B_Pm, RdBlkP, B_Pm_B) {L3DataArrayWrite}{ 1595 esb_sendResponseESBypass; 1596 p_popRequestQueue; 1597 } 1598 1599 transition(BP, RdBlkP, BP_B) {L3DataArrayWrite}{ 1600 esb_sendResponseESBypass; 1601 p_popRequestQueue; 1602 } 1603 1604 transition(BM_Pm_B, CoreUnblock, BM_Pm) { 1605 wa_wakeUpDependents; 1606 pu_popUnblockQueue; 1607 } 1608 1609 transition(BS_Pm_B, CoreUnblock, BS_Pm) { 1610 wa_wakeUpDependents; 1611 pu_popUnblockQueue; 1612 } 1613 1614 transition(B_Pm_B, CoreUnblock, B_Pm) { 1615 wa_wakeUpDependents; 1616 pu_popUnblockQueue; 1617 } 1618 1619 transition(BP_B, CoreUnblock, BP) { 1620 wa_wakeUpDependents; 1621 pu_popUnblockQueue; 1622 } 1623 1624 transition(BM_Pm_B, UnblockWriteThrough, BM_Pm) { 1625 wa_wakeUpDependents; 1626 pt_popTriggerQueue; 1627 } 1628 1629 transition(BS_Pm_B, UnblockWriteThrough, BS_Pm) { 1630 wa_wakeUpDependents; 1631 pt_popTriggerQueue; 1632 } 1633 1634 transition(B_Pm_B, UnblockWriteThrough, B_Pm) { 1635 wa_wakeUpDependents; 1636 pt_popTriggerQueue; 1637 } 1638 1639 transition(BP_B, UnblockWriteThrough, BP) { 1640 wa_wakeUpDependents; 1641 pt_popTriggerQueue; 1642 } 1643 1644 transition(BM_Pm, VicDirtyP, BM_Pm_BL) { 1645 wp_sendResponseWBAckP; 1646 p_popRequestQueue; 1647 } 1648 1649 transition(BS_Pm, VicDirtyP, BS_Pm_BL) { 1650 wp_sendResponseWBAckP; 1651 p_popRequestQueue; 1652 } 1653 1654 transition(B_Pm, VicDirtyP, B_Pm_BL) { 1655 wp_sendResponseWBAckP; 1656 p_popRequestQueue; 1657 } 1658 1659 transition(BP, VicDirtyP, BP_BL) { 1660 wp_sendResponseWBAckP; 1661 p_popRequestQueue; 1662 } 1663 1664 transition(BM_Pm, VicCleanP, BM_Pm_BL) { 1665 wp_sendResponseWBAckP; 1666 p_popRequestQueue; 1667 } 1668 1669 transition(BS_Pm, VicCleanP, BS_Pm_BL) { 1670 wp_sendResponseWBAckP; 1671 p_popRequestQueue; 1672 } 1673 1674 transition(B_Pm, VicCleanP, B_Pm_BL) { 1675 wp_sendResponseWBAckP; 1676 p_popRequestQueue; 1677 } 1678 1679 transition(BP, VicCleanP, BP_BL) { 1680 wp_sendResponseWBAckP; 1681 p_popRequestQueue; 1682 } 1683 1684 transition(BM_Pm_BL, CPUData, BM_Pm) { 1685 yc_writeCPUDataToTBE; 1686 d_writeDataToMemory; 1687 wa_wakeUpDependents; 1688 pr_popResponseQueue; 1689 } 1690 1691 transition(BS_Pm_BL, CPUData, BS_Pm) { 1692 yc_writeCPUDataToTBE; 1693 d_writeDataToMemory; 1694 wa_wakeUpDependents; 1695 pr_popResponseQueue; 1696 } 1697 1698 transition(B_Pm_BL, CPUData, B_Pm) { 1699 yc_writeCPUDataToTBE; 1700 d_writeDataToMemory; 1701 wa_wakeUpDependents; 1702 pr_popResponseQueue; 1703 } 1704 1705 transition(BP_BL, CPUData, BP) { 1706 yc_writeCPUDataToTBE; 1707 d_writeDataToMemory; 1708 wa_wakeUpDependents; 1709 pr_popResponseQueue; 1710 } 1711 1712 transition({BR, BW, BL}, {VicDirtyP, VicCleanP}) { 1713 st_stallAndWaitRequest; 1714 } 1715 1716 transition({BR, BW, BL}, {VicDirty, VicClean}) { 1717 ww_stallAndWaitRegRequestQueue; 1718 } 1719 1720 transition(BL, CPUData, U) {L3TagArrayWrite, L3DataArrayWrite} { 1721 dt_deallocateTBE; 1722 d_writeDataToMemory; 1723 al_allocateL3Block; 1724 wa_wakeUpDependents; 1725 pr_popResponseQueue; 1726 } 1727 1728 transition(BL, StaleWB, U) {L3TagArrayWrite} { 1729 dt_deallocateTBE; 1730 wa_wakeUpAllDependents; 1731 pr_popResponseQueue; 1732 } 1733 1734 transition({BI, B, BS_M, BM_M, B_M, BP, BS_PM, BM_PM, B_PM, BS_Pm, BM_Pm, B_Pm, BS_Pm_BL, BM_Pm_BL, B_Pm_BL, BP_BL, BS_Pm_B, BM_Pm_B, B_Pm_B, BP_B}, {VicDirty, VicClean}) { 1735 ww_stallAndWaitRegRequestQueue; 1736 } 1737 1738 transition({BI, B, BS_M, BM_M, B_M, BS_PM, BM_PM, B_PM, BS_Pm_BL, BM_Pm_BL, B_Pm_BL, BP_BL, BS_Pm_B, BM_Pm_B, B_Pm_B, BP_B}, {VicDirtyP, VicCleanP}) { 1739 st_stallAndWaitRequest; 1740 } 1741 1742 transition({U, BR, BW, BL, BI, BS_M, BM_M, B_M, BP, BS_PM, BM_PM, B_PM, BS_Pm, BM_Pm, B_Pm, B, BS_Pm_BL, BM_Pm_BL, B_Pm_BL, BP_BL, BS_Pm_B, BM_Pm_B, B_Pm_B, BP_B}, WBAck) { 1743 pm_popMemQueue; 1744 } 1745 1746 transition({U, BR, BW, BL, BI, BS_M, BM_M, B_M, BP, BS_PM, BM_PM, B_PM, BS_Pm, BM_Pm, B_Pm, B, BS_Pm_BL, BM_Pm_BL, B_Pm_BL, BP_BL, BS_Pm_B, BM_Pm_B, B_Pm_B, BP_B}, StaleVicDirtyP) { 1747 rvp_removeVicDirtyIgnore; 1748 wp_sendResponseWBAckP; 1749 p_popRequestQueue; 1750 } 1751 1752 transition({U, BR, BW, BL, BI, BS_M, BM_M, B_M, BP, BS_PM, BM_PM, B_PM, BS_Pm, BM_Pm, B_Pm, B, BS_Pm_BL, BM_Pm_BL, B_Pm_BL, BP_BL, BS_Pm_B, BM_Pm_B, B_Pm_B, BP_B}, StaleVicDirty) { 1753 rv_removeVicDirtyIgnore; 1754 w_sendResponseWBAck; 1755 prd_popRegionQueue; 1756 } 1757 1758 transition(U, VicDirty, BL) {L3TagArrayRead} { 1759 t_allocateTBE; 1760 ra_ackRegionDir; 1761 w_sendResponseWBAck; 1762 prd_popRegionQueue; 1763 } 1764 1765 transition(U, VicClean, BL) {L3TagArrayRead} { 1766 t_allocateTBE; 1767 ra_ackRegionDir; 1768 w_sendResponseWBAck; 1769 prd_popRegionQueue; 1770 } 1771 1772 transition({B, BR}, CoreUnblock, U) { 1773 wa_wakeUpDependents; 1774 pu_popUnblockQueue; 1775 } 1776 1777 transition({B, BR}, UnblockWriteThrough, U) { 1778 wa_wakeUpDependents; 1779 pt_popTriggerQueue; 1780 } 1781 1782 transition(BS_M, MemData, B) {L3TagArrayWrite, L3DataArrayWrite} { 1783 mt_writeMemDataToTBE; 1784 s_sendResponseS; 1785 wd_writeBackData; 1786 alwt_allocateL3BlockOnWT; 1787 dt_deallocateTBE; 1788 pm_popMemQueue; 1789 } 1790 1791 transition(BM_M, MemData, B){L3TagArrayWrite, L3DataArrayWrite} { 1792 mt_writeMemDataToTBE; 1793 m_sendResponseM; 1794 wd_writeBackData; 1795 alwt_allocateL3BlockOnWT; 1796 dt_deallocateTBE; 1797 pm_popMemQueue; 1798 } 1799 1800 transition(B_M, MemData, B){L3TagArrayWrite, L3DataArrayWrite} { 1801 mt_writeMemDataToTBE; 1802 es_sendResponseES; 1803 wd_writeBackData; 1804 alwt_allocateL3BlockOnWT; 1805 dt_deallocateTBE; 1806 pm_popMemQueue; 1807 } 1808 1809 transition(BS_PM, MemData, BS_Pm) {} { 1810 mt_writeMemDataToTBE; 1811 wa_wakeUpDependents; 1812 pm_popMemQueue; 1813 } 1814 1815 transition(BM_PM, MemData, BM_Pm){} { 1816 mt_writeMemDataToTBE; 1817 wa_wakeUpDependents; 1818 pm_popMemQueue; 1819 } 1820 1821 transition(B_PM, MemData, B_Pm){} { 1822 mt_writeMemDataToTBE; 1823 wa_wakeUpDependents; 1824 pm_popMemQueue; 1825 } 1826 1827 transition(BS_M, L3Hit, B) {L3TagArrayWrite, L3DataArrayWrite} { 1828 s_sendResponseS; 1829 wd_writeBackData; 1830 alwt_allocateL3BlockOnWT; 1831 dt_deallocateTBE; 1832 ptl_popTriggerQueue; 1833 } 1834 1835 transition(BM_M, L3Hit, B) {L3TagArrayWrite, L3DataArrayWrite} { 1836 m_sendResponseM; 1837 wd_writeBackData; 1838 alwt_allocateL3BlockOnWT; 1839 dt_deallocateTBE; 1840 ptl_popTriggerQueue; 1841 } 1842 1843 transition(B_M, L3Hit, B) {L3TagArrayWrite, L3DataArrayWrite} { 1844 es_sendResponseES; 1845 wd_writeBackData; 1846 alwt_allocateL3BlockOnWT; 1847 dt_deallocateTBE; 1848 ptl_popTriggerQueue; 1849 } 1850 1851 transition(BS_PM, L3Hit, BS_Pm) { 1852 wa_wakeUpDependents; 1853 ptl_popTriggerQueue; 1854 } 1855 1856 transition(BM_PM, L3Hit, BM_Pm) { 1857 wa_wakeUpDependents; 1858 ptl_popTriggerQueue; 1859 } 1860 1861 transition(B_PM, L3Hit, B_Pm) { 1862 wa_wakeUpDependents; 1863 ptl_popTriggerQueue; 1864 } 1865 1866 transition({BS_PM, BM_PM, B_PM, BS_Pm, BM_Pm, B_Pm, BP, BI}, CPUPrbResp) { 1867 aic_ackInvalidate; 1868 y_writeProbeDataToTBE; 1869 x_decrementAcks; 1870 ont_checkForCompletionNoTrigger; 1871 pr_popResponseQueue; 1872 } 1873 1874 transition({B, B_M, BS_M, BM_M}, {CPUPrbResp, LastCPUPrbResp}) { 1875 z_stall; 1876 } 1877 1878 transition({BS_Pm_BL, BM_Pm_BL, B_Pm_BL, BP_BL, BS_Pm_B, BM_Pm_B, B_Pm_B, BP_B}, {CPUPrbResp, LastCPUPrbResp}) { 1879 // recycling because PrbResponse and data come on the same network 1880 yy_recycleResponseQueue; 1881 } 1882 1883 transition(U, {CPUPrbResp, LastCPUPrbResp}) {L3TagArrayRead, L3DataArrayWrite} { 1884 aic_ackInvalidate; 1885 wdt_writeBackDataInvNoTBE; 1886 ali_allocateL3BlockNoTBE; 1887 pr_popResponseQueue; 1888 } 1889 1890 transition(BL, {CPUPrbResp, LastCPUPrbResp}) {} { 1891 aic_ackInvalidate; 1892 y_writeProbeDataToTBE; 1893 wdi_writeBackDataInv; 1894 ali_allocateL3Block; 1895 pr_popResponseQueue; 1896 } 1897 1898 transition(BS_PM, LastCPUPrbResp, BS_M) { 1899 aic_ackInvalidate; 1900 y_writeProbeDataToTBE; 1901 x_decrementAcks; 1902 ont_checkForCompletionNoTrigger; 1903 pr_popResponseQueue; 1904 } 1905 1906 transition(BS_PM, ProbeAcksComplete, BS_M) {} { 1907 pt_popTriggerQueue; 1908 } 1909 1910 transition(BM_PM, LastCPUPrbResp, BM_M) { 1911 aic_ackInvalidate; 1912 y_writeProbeDataToTBE; 1913 x_decrementAcks; 1914 ont_checkForCompletionNoTrigger; 1915 pr_popResponseQueue; 1916 } 1917 1918 transition(BM_PM, ProbeAcksComplete, BM_M) {} { 1919 pt_popTriggerQueue; 1920 } 1921 1922 transition(B_PM, LastCPUPrbResp, B_M) { 1923 aic_ackInvalidate; 1924 y_writeProbeDataToTBE; 1925 x_decrementAcks; 1926 ont_checkForCompletionNoTrigger; 1927 pr_popResponseQueue; 1928 } 1929 1930 transition(B_PM, ProbeAcksComplete, B_M){} { 1931 pt_popTriggerQueue; 1932 } 1933 1934 transition(BS_Pm, LastCPUPrbResp, B) { 1935 aic_ackInvalidate; 1936 y_writeProbeDataToTBE; 1937 x_decrementAcks; 1938 ont_checkForCompletionNoTrigger; 1939 s_sendResponseS; 1940 wd_writeBackData; 1941 alwt_allocateL3BlockOnWT; 1942 ali_allocateL3Block; 1943 dt_deallocateTBE; 1944 pr_popResponseQueue; 1945 } 1946 1947 transition(BS_Pm, ProbeAcksComplete, B){L3DataArrayWrite, L3TagArrayWrite} { 1948 s_sendResponseS; 1949 wd_writeBackData; 1950 alwt_allocateL3BlockOnWT; 1951 ali_allocateL3Block; 1952 dt_deallocateTBE; 1953 pt_popTriggerQueue; 1954 } 1955 1956 transition(BM_Pm, LastCPUPrbResp, B) { 1957 aic_ackInvalidate; 1958 y_writeProbeDataToTBE; 1959 x_decrementAcks; 1960 ont_checkForCompletionNoTrigger; 1961 m_sendResponseM; 1962 wd_writeBackData; 1963 alwt_allocateL3BlockOnWT; 1964 ali_allocateL3Block; 1965 dt_deallocateTBE; 1966 pr_popResponseQueue; 1967 } 1968 1969 transition(BM_Pm, ProbeAcksComplete, B){L3DataArrayWrite, L3TagArrayWrite} { 1970 m_sendResponseM; 1971 wd_writeBackData; 1972 alwt_allocateL3BlockOnWT; 1973 ali_allocateL3Block; 1974 dt_deallocateTBE; 1975 pt_popTriggerQueue; 1976 } 1977 1978 transition(B_Pm, LastCPUPrbResp, B) { 1979 aic_ackInvalidate; 1980 y_writeProbeDataToTBE; 1981 x_decrementAcks; 1982 ont_checkForCompletionNoTrigger; 1983 es_sendResponseES; 1984 wd_writeBackData; 1985 alwt_allocateL3BlockOnWT; 1986 ali_allocateL3Block; 1987 dt_deallocateTBE; 1988 pr_popResponseQueue; 1989 } 1990 1991 transition(B_Pm, ProbeAcksComplete, B){L3DataArrayWrite, L3TagArrayWrite} { 1992 es_sendResponseES; 1993 wd_writeBackData; 1994 alwt_allocateL3BlockOnWT; 1995 ali_allocateL3Block; 1996 dt_deallocateTBE; 1997 pt_popTriggerQueue; 1998 } 1999 2000 transition(BP, LastCPUPrbResp, B) { 2001 aic_ackInvalidate; 2002 y_writeProbeDataToTBE; 2003 x_decrementAcks; 2004 ont_checkForCompletionNoTrigger; 2005 c_sendResponseCtoD; 2006 wd_writeBackData; 2007 alwt_allocateL3BlockOnWT; 2008 dt_deallocateTBE; 2009 pr_popResponseQueue; 2010 } 2011 2012 transition(BP, ProbeAcksComplete, B){L3TagArrayWrite, L3TagArrayWrite} { 2013 c_sendResponseCtoD; 2014 wd_writeBackData; 2015 alwt_allocateL3BlockOnWT; 2016 dt_deallocateTBE; 2017 pt_popTriggerQueue; 2018 } 2019 2020 transition(BI, LastCPUPrbResp, B) { 2021 aic_ackInvalidate; 2022 y_writeProbeDataToTBE; 2023 x_decrementAcks; 2024 ont_checkForCompletionNoTrigger; 2025 wa_wakeUpDependents; 2026 wdi_writeBackDataInv; 2027 ali_allocateL3Block; 2028 dt_deallocateTBE; 2029 pr_popResponseQueue; 2030 } 2031 2032 transition(BI, ProbeAcksComplete, U) {L3TagArrayWrite, L3DataArrayWrite}{ 2033 wa_wakeUpDependents; 2034 wdi_writeBackDataInv; 2035 ali_allocateL3Block; 2036 dt_deallocateTBE; 2037 pt_popTriggerQueue; 2038 } 2039 2040} 2041