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