summaryrefslogtreecommitdiff
path: root/src/mem/protocol/MOESI_CMP_directory-L2cache.sm
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/protocol/MOESI_CMP_directory-L2cache.sm')
-rw-r--r--src/mem/protocol/MOESI_CMP_directory-L2cache.sm252
1 files changed, 154 insertions, 98 deletions
diff --git a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm
index 6252219e0..379e609d5 100644
--- a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2019 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 1999-2013 Mark D. Hill and David A. Wood
* All rights reserved.
*
@@ -620,30 +632,12 @@ machine(MachineType:L2Cache, "Token protocol")
} else if (in_msg.Type == CoherenceResponseType:UNBLOCK_EXCLUSIVE) {
trigger(Event:Exclusive_Unblock, in_msg.addr,
getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
- } else if (in_msg.Type == CoherenceResponseType:WRITEBACK_DIRTY_DATA) {
- Entry cache_entry := getCacheEntry(in_msg.addr);
- if (is_invalid(cache_entry) &&
- L2cache.cacheAvail(in_msg.addr) == false) {
- trigger(Event:L2_Replacement, L2cache.cacheProbe(in_msg.addr),
- getCacheEntry(L2cache.cacheProbe(in_msg.addr)),
- TBEs[L2cache.cacheProbe(in_msg.addr)]);
- }
- else {
- trigger(Event:L1_WBDIRTYDATA, in_msg.addr,
- cache_entry, TBEs[in_msg.addr]);
- }
- } else if (in_msg.Type == CoherenceResponseType:WRITEBACK_CLEAN_DATA) {
- Entry cache_entry := getCacheEntry(in_msg.addr);
- if (is_invalid(cache_entry) &&
- L2cache.cacheAvail(in_msg.addr) == false) {
- trigger(Event:L2_Replacement, L2cache.cacheProbe(in_msg.addr),
- getCacheEntry(L2cache.cacheProbe(in_msg.addr)),
- TBEs[L2cache.cacheProbe(in_msg.addr)]);
- }
- else {
- trigger(Event:L1_WBCLEANDATA, in_msg.addr,
- cache_entry, TBEs[in_msg.addr]);
- }
+ } else if (in_msg.Type == CoherenceResponseType:WB_ACK) {
+ trigger(Event:Writeback_Ack, in_msg.addr,
+ getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
+ } else if (in_msg.Type == CoherenceResponseType:WB_NACK) {
+ trigger(Event:Writeback_Nack, in_msg.addr,
+ getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
} else if (in_msg.Type == CoherenceResponseType:DMA_ACK) {
trigger(Event:DmaAck, in_msg.addr,
getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
@@ -676,12 +670,6 @@ machine(MachineType:L2Cache, "Token protocol")
} else if (in_msg.Type == CoherenceRequestType:INV) {
trigger(Event:Inv, in_msg.addr,
getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
- } else if (in_msg.Type == CoherenceRequestType:WB_ACK) {
- trigger(Event:Writeback_Ack, in_msg.addr,
- getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
- } else if (in_msg.Type == CoherenceRequestType:WB_NACK) {
- trigger(Event:Writeback_Nack, in_msg.addr,
- getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
} else {
error("Unexpected message");
}
@@ -715,6 +703,30 @@ machine(MachineType:L2Cache, "Token protocol")
trigger(Event:L1_PUTS, in_msg.addr,
cache_entry, TBEs[in_msg.addr]);
}
+ } else if (in_msg.Type == CoherenceRequestType:WRITEBACK_DIRTY_DATA) {
+ Entry cache_entry := getCacheEntry(in_msg.addr);
+ if (is_invalid(cache_entry) &&
+ L2cache.cacheAvail(in_msg.addr) == false) {
+ trigger(Event:L2_Replacement, L2cache.cacheProbe(in_msg.addr),
+ getCacheEntry(L2cache.cacheProbe(in_msg.addr)),
+ TBEs[L2cache.cacheProbe(in_msg.addr)]);
+ }
+ else {
+ trigger(Event:L1_WBDIRTYDATA, in_msg.addr,
+ cache_entry, TBEs[in_msg.addr]);
+ }
+ } else if (in_msg.Type == CoherenceRequestType:WRITEBACK_CLEAN_DATA) {
+ Entry cache_entry := getCacheEntry(in_msg.addr);
+ if (is_invalid(cache_entry) &&
+ L2cache.cacheAvail(in_msg.addr) == false) {
+ trigger(Event:L2_Replacement, L2cache.cacheProbe(in_msg.addr),
+ getCacheEntry(L2cache.cacheProbe(in_msg.addr)),
+ TBEs[L2cache.cacheProbe(in_msg.addr)]);
+ }
+ else {
+ trigger(Event:L1_WBCLEANDATA, in_msg.addr,
+ cache_entry, TBEs[in_msg.addr]);
+ }
} else {
error("Unexpected message");
}
@@ -1191,9 +1203,15 @@ machine(MachineType:L2Cache, "Token protocol")
}
}
- action(gg_clearOwnerFromL1Response, "g\g", desc="Clear sharer from L1 response queue") {
- peek(responseNetwork_in, ResponseMsg) {
- removeOwnerFromDir(cache_entry, in_msg.addr, in_msg.Sender);
+ action(gg_clearSharerFromL1Request, "clsl1r", desc="Clear sharer from L1 request queue") {
+ peek(L1requestNetwork_in, RequestMsg) {
+ removeSharerFromDir(cache_entry, in_msg.addr, in_msg.Requestor);
+ }
+ }
+
+ action(gg_clearOwnerFromL1Request, "clol1r", desc="Clear owner from L1 request queue") {
+ peek(L1requestNetwork_in, RequestMsg) {
+ removeOwnerFromDir(cache_entry, in_msg.addr, in_msg.Requestor);
}
}
@@ -1330,12 +1348,11 @@ machine(MachineType:L2Cache, "Token protocol")
action(l_writebackAckNeedData, "l", desc="Send writeback ack to L1 requesting data") {
peek(L1requestNetwork_in, RequestMsg) {
- enqueue( localRequestNetwork_out, RequestMsg, response_latency ) {
+ enqueue( responseNetwork_out, ResponseMsg, response_latency ) {
out_msg.addr := in_msg.addr;
- // out_msg.Type := CoherenceResponseType:WRITEBACK_SEND_DATA;
- out_msg.Type := CoherenceRequestType:WB_ACK_DATA;
- out_msg.Requestor := machineID;
- out_msg.RequestorMachine := MachineType:L2Cache;
+ out_msg.Type := CoherenceResponseType:WB_ACK_DATA;
+ out_msg.Sender := machineID;
+ out_msg.SenderMachine := MachineType:L2Cache;
out_msg.Destination.add(in_msg.Requestor);
out_msg.MessageSize := MessageSizeType:Writeback_Control;
}
@@ -1344,12 +1361,11 @@ machine(MachineType:L2Cache, "Token protocol")
action(l_writebackAckDropData, "\l", desc="Send writeback ack to L1 indicating to drop data") {
peek(L1requestNetwork_in, RequestMsg) {
- enqueue( localRequestNetwork_out, RequestMsg, response_latency ) {
+ enqueue( responseNetwork_out, ResponseMsg, response_latency ) {
out_msg.addr := in_msg.addr;
- // out_msg.Type := CoherenceResponseType:WRITEBACK_ACK;
- out_msg.Type := CoherenceRequestType:WB_ACK;
- out_msg.Requestor := machineID;
- out_msg.RequestorMachine := MachineType:L2Cache;
+ out_msg.Type := CoherenceResponseType:WB_ACK;
+ out_msg.Sender := machineID;
+ out_msg.SenderMachine := MachineType:L2Cache;
out_msg.Destination.add(in_msg.Requestor);
out_msg.MessageSize := MessageSizeType:Writeback_Control;
}
@@ -1358,11 +1374,11 @@ machine(MachineType:L2Cache, "Token protocol")
action(ll_writebackNack, "\ll", desc="Send writeback nack to L1") {
peek(L1requestNetwork_in, RequestMsg) {
- enqueue( localRequestNetwork_out, RequestMsg, response_latency ) {
+ enqueue( responseNetwork_out, ResponseMsg, response_latency ) {
out_msg.addr := in_msg.addr;
- out_msg.Type := CoherenceRequestType:WB_NACK;
- out_msg.Requestor := machineID;
- out_msg.RequestorMachine := MachineType:L2Cache;
+ out_msg.Type := CoherenceResponseType:WB_NACK;
+ out_msg.Sender := machineID;
+ out_msg.SenderMachine := MachineType:L2Cache;
out_msg.Destination.add(in_msg.Requestor);
out_msg.MessageSize := MessageSizeType:Writeback_Control;
}
@@ -1429,19 +1445,18 @@ machine(MachineType:L2Cache, "Token protocol")
action( qq_sendDataFromTBEToMemory, "qq", desc="Send data from TBE to directory") {
- enqueue(responseNetwork_out, ResponseMsg, response_latency) {
+ enqueue(globalRequestNetwork_out, RequestMsg, response_latency) {
assert(is_valid(tbe));
out_msg.addr := address;
- out_msg.Sender := machineID;
- out_msg.SenderMachine := MachineType:L2Cache;
+ out_msg.Requestor := machineID;
+ out_msg.RequestorMachine := MachineType:L2Cache;
out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
- out_msg.Dirty := tbe.Dirty;
if (tbe.Dirty) {
- out_msg.Type := CoherenceResponseType:WRITEBACK_DIRTY_DATA;
+ out_msg.Type := CoherenceRequestType:WRITEBACK_DIRTY_DATA;
out_msg.DataBlk := tbe.DataBlk;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
} else {
- out_msg.Type := CoherenceResponseType:WRITEBACK_CLEAN_ACK;
+ out_msg.Type := CoherenceRequestType:WRITEBACK_CLEAN_ACK;
// NOTE: in a real system this would not send data. We send
// data here only so we can check it at the memory
out_msg.DataBlk := tbe.DataBlk;
@@ -1492,15 +1507,23 @@ machine(MachineType:L2Cache, "Token protocol")
}
- action(u_writeDataToCache, "u", desc="Write data to cache") {
- peek(responseNetwork_in, ResponseMsg) {
+ action(u_writeCleanDataToCache, "wCd", desc="Write clean data to cache") {
+ peek(L1requestNetwork_in, RequestMsg) {
assert(is_valid(cache_entry));
cache_entry.DataBlk := in_msg.DataBlk;
DPRINTF(RubySlicc, "Address: %#x, Data Block: %s\n",
address, cache_entry.DataBlk);
- if ((cache_entry.Dirty == false) && in_msg.Dirty) {
- cache_entry.Dirty := in_msg.Dirty;
- }
+ assert(cache_entry.Dirty == false);
+ }
+ }
+
+ action(u_writeDirtyDataToCache, "wDd", desc="Write dirty data to cache") {
+ peek(L1requestNetwork_in, RequestMsg) {
+ assert(is_valid(cache_entry));
+ cache_entry.DataBlk := in_msg.DataBlk;
+ DPRINTF(RubySlicc, "Address: %#x, Data Block: %s\n",
+ address, cache_entry.DataBlk);
+ cache_entry.Dirty := true;
}
}
@@ -1538,13 +1561,20 @@ machine(MachineType:L2Cache, "Token protocol")
localDirectory.deallocate(address);
}
- action(zz_recycleRequestQueue, "\zz", desc="Send the head of the mandatory queue to the back of the queue.") {
+ action(zz_recycleGlobalRequestQueue, "\zglb", desc="Send the head of the mandatory queue to the back of the queue.") {
peek(requestNetwork_in, RequestMsg) {
APPEND_TRANSITION_COMMENT(in_msg.Requestor);
}
requestNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
}
+ action(zz_recycleL1RequestQueue, "\zl1", desc="Send the head of the mandatory queue to the back of the queue.") {
+ peek(L1requestNetwork_in, RequestMsg) {
+ APPEND_TRANSITION_COMMENT(in_msg.Requestor);
+ }
+ L1requestNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
+ }
+
action(zz_recycleResponseQueue, "\z\z", desc="Send the head of the mandatory queue to the back of the queue.") {
peek(responseNetwork_in, ResponseMsg) {
APPEND_TRANSITION_COMMENT(in_msg.Sender);
@@ -1586,23 +1616,23 @@ machine(MachineType:L2Cache, "Token protocol")
}
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) {
- zz_recycleResponseQueue;
+ zz_recycleL1RequestQueue;
}
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}) {
- zz_recycleRequestQueue;
+ zz_recycleGlobalRequestQueue;
}
transition({OGMIO, IGMIO, IGMO}, Fwd_DMA) {
- zz_recycleRequestQueue;
+ zz_recycleGlobalRequestQueue;
}
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}) {
- zz_recycleRequestQueue;
+ zz_recycleGlobalRequestQueue;
}
transition({IGM, IGS, ILOSD, ILOSXD, ILOD, ILXD, ILOXD}, {Own_GETX}) {
- zz_recycleRequestQueue;
+ zz_recycleGlobalRequestQueue;
}
// must happened because we forwarded GETX to local exclusive trying to do wb
@@ -2643,8 +2673,8 @@ machine(MachineType:L2Cache, "Token protocol")
gg_clearLocalSharers;
vv_allocateL2CacheBlock;
y_copyDirToCacheAndRemove;
- u_writeDataToCache;
- n_popResponseQueue;
+ u_writeDirtyDataToCache;
+ o_popL1RequestQueue;
wa_wakeUpDependents;
}
@@ -2653,8 +2683,8 @@ machine(MachineType:L2Cache, "Token protocol")
gg_clearLocalSharers;
vv_allocateL2CacheBlock;
y_copyDirToCacheAndRemove;
- u_writeDataToCache;
- n_popResponseQueue;
+ u_writeCleanDataToCache;
+ o_popL1RequestQueue;
wa_wakeUpDependents;
}
@@ -2667,67 +2697,93 @@ machine(MachineType:L2Cache, "Token protocol")
transition(ILSW, L1_WBCLEANDATA, SLS) {
vv_allocateL2CacheBlock;
y_copyDirToCacheAndRemove;
- u_writeDataToCache;
- gg_clearSharerFromL1Response;
- n_popResponseQueue;
+ u_writeCleanDataToCache;
+ gg_clearSharerFromL1Request;
+ o_popL1RequestQueue;
wa_wakeUpDependents;
}
transition(IW, L1_WBCLEANDATA, S) {
vv_allocateL2CacheBlock;
y_copyDirToCacheAndRemove;
- u_writeDataToCache;
- gg_clearSharerFromL1Response;
- n_popResponseQueue;
+ u_writeCleanDataToCache;
+ gg_clearSharerFromL1Request;
+ o_popL1RequestQueue;
wa_wakeUpDependents;
}
// Owner can have dirty data
- transition(ILOW, {L1_WBCLEANDATA, L1_WBDIRTYDATA}, O) {
+ transition(ILOW, L1_WBDIRTYDATA, O) {
vv_allocateL2CacheBlock;
y_copyDirToCacheAndRemove;
- gg_clearOwnerFromL1Response;
- u_writeDataToCache;
- n_popResponseQueue;
+ gg_clearOwnerFromL1Request;
+ u_writeDirtyDataToCache;
+ o_popL1RequestQueue;
+ wa_wakeUpDependents;
+ }
+
+ transition(ILOW, L1_WBCLEANDATA, O) {
+ vv_allocateL2CacheBlock;
+ y_copyDirToCacheAndRemove;
+ gg_clearOwnerFromL1Request;
+ u_writeCleanDataToCache;
+ o_popL1RequestQueue;
wa_wakeUpDependents;
}
transition(ILOXW, L1_WBDIRTYDATA, M) {
vv_allocateL2CacheBlock;
y_copyDirToCacheAndRemove;
- gg_clearOwnerFromL1Response;
- u_writeDataToCache;
- n_popResponseQueue;
+ gg_clearOwnerFromL1Request;
+ u_writeDirtyDataToCache;
+ o_popL1RequestQueue;
wa_wakeUpDependents;
}
transition(ILOXW, L1_WBCLEANDATA, M) {
vv_allocateL2CacheBlock;
y_copyDirToCacheAndRemove;
- gg_clearOwnerFromL1Response;
- u_writeDataToCache;
- n_popResponseQueue;
+ gg_clearOwnerFromL1Request;
+ u_writeCleanDataToCache;
+ o_popL1RequestQueue;
wa_wakeUpDependents;
}
- transition(ILOSW, {L1_WBCLEANDATA, L1_WBDIRTYDATA}, OLS) {
+ transition(ILOSW, L1_WBDIRTYDATA, OLS) {
vv_allocateL2CacheBlock;
y_copyDirToCacheAndRemove;
- gg_clearOwnerFromL1Response;
- u_writeDataToCache;
- n_popResponseQueue;
+ gg_clearOwnerFromL1Request;
+ u_writeDirtyDataToCache;
+ o_popL1RequestQueue;
wa_wakeUpDependents;
}
- transition(ILOSXW, {L1_WBCLEANDATA, L1_WBDIRTYDATA}, OLSX) {
+ transition(ILOSW, L1_WBCLEANDATA, OLS) {
vv_allocateL2CacheBlock;
y_copyDirToCacheAndRemove;
- gg_clearOwnerFromL1Response;
- u_writeDataToCache;
- n_popResponseQueue;
+ gg_clearOwnerFromL1Request;
+ u_writeCleanDataToCache;
+ o_popL1RequestQueue;
+ wa_wakeUpDependents;
+ }
+
+ transition(ILOSXW, L1_WBDIRTYDATA, OLSX) {
+ vv_allocateL2CacheBlock;
+ y_copyDirToCacheAndRemove;
+ gg_clearOwnerFromL1Request;
+ u_writeDirtyDataToCache;
+ o_popL1RequestQueue;
wa_wakeUpDependents;
}
+ transition(ILOSXW, L1_WBCLEANDATA, OLSX) {
+ vv_allocateL2CacheBlock;
+ y_copyDirToCacheAndRemove;
+ gg_clearOwnerFromL1Request;
+ u_writeCleanDataToCache;
+ o_popL1RequestQueue;
+ wa_wakeUpDependents;
+ }
transition(SLSW, {Unblock}, SLS) {
gg_clearSharerFromL1Response;
@@ -2838,39 +2894,39 @@ machine(MachineType:L2Cache, "Token protocol")
transition({MI, OI}, Writeback_Ack, I) {
qq_sendDataFromTBEToMemory;
s_deallocateTBE;
- m_popRequestQueue;
+ n_popResponseQueue;
wa_wakeUpDependents;
}
transition(MII, Writeback_Nack, I) {
s_deallocateTBE;
- m_popRequestQueue;
+ n_popResponseQueue;
wa_wakeUpDependents;
}
transition(OI, Writeback_Nack) {
b_issuePUTO;
- m_popRequestQueue;
+ n_popResponseQueue;
}
transition(OLSI, Writeback_Ack, ILS) {
qq_sendDataFromTBEToMemory;
s_deallocateTBE;
- m_popRequestQueue;
+ n_popResponseQueue;
wa_wakeUpDependents;
}
transition(MII, Writeback_Ack, I) {
f_sendUnblock;
s_deallocateTBE;
- m_popRequestQueue;
+ n_popResponseQueue;
wa_wakeUpDependents;
}
transition(ILSI, Writeback_Ack, ILS) {
f_sendUnblock;
s_deallocateTBE;
- m_popRequestQueue;
+ n_popResponseQueue;
wa_wakeUpDependents;
}
}