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