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