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