diff options
-rw-r--r-- | src/mem/protocol/MOESI_CMP_directory-L1cache.sm | 95 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_CMP_directory-L2cache.sm | 252 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_CMP_directory-dir.sm | 76 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_CMP_directory-dma.sm | 44 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_CMP_directory-msg.sm | 34 |
5 files changed, 300 insertions, 201 deletions
diff --git a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm index 0d48e2195..f1512672c 100644 --- a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_directory-L1cache.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. * @@ -289,7 +301,35 @@ machine(MachineType:L1Cache, "Directory protocol") } } - // Nothing from the request network + // Response Network + in_port(responseToL1Cache_in, ResponseMsg, responseToL1Cache) { + if (responseToL1Cache_in.isReady(clockEdge())) { + peek(responseToL1Cache_in, ResponseMsg, block_on="addr") { + if (in_msg.Type == CoherenceResponseType:ACK) { + trigger(Event:Ack, in_msg.addr, + getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); + } else if (in_msg.Type == CoherenceResponseType:DATA) { + trigger(Event:Data, in_msg.addr, + getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); + } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) { + trigger(Event:Exclusive_Data, in_msg.addr, + getCacheEntry(in_msg.addr), 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_ACK_DATA) { + trigger(Event:Writeback_Ack_Data, 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 { + error("Unexpected message"); + } + } + } + } + // Request Network in_port(requestNetwork_in, RequestMsg, requestToL1Cache) { @@ -312,15 +352,6 @@ machine(MachineType:L1Cache, "Directory protocol") } else if (in_msg.Type == CoherenceRequestType:DMA_READ) { trigger(Event:Fwd_DMA, 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_ACK_DATA) { - trigger(Event:Writeback_Ack_Data, 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 if (in_msg.Type == CoherenceRequestType:INV) { trigger(Event:Inv, in_msg.addr, getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); @@ -331,27 +362,6 @@ machine(MachineType:L1Cache, "Directory protocol") } } - // Response Network - in_port(responseToL1Cache_in, ResponseMsg, responseToL1Cache) { - if (responseToL1Cache_in.isReady(clockEdge())) { - peek(responseToL1Cache_in, ResponseMsg, block_on="addr") { - if (in_msg.Type == CoherenceResponseType:ACK) { - trigger(Event:Ack, in_msg.addr, - getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); - } else if (in_msg.Type == CoherenceResponseType:DATA) { - trigger(Event:Data, in_msg.addr, - getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); - } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) { - trigger(Event:Exclusive_Data, in_msg.addr, - getCacheEntry(in_msg.addr), TBEs[in_msg.addr]); - } else { - error("Unexpected message"); - } - } - } - } - - // Nothing from the unblock network // Mandatory Queue betweens Node's CPU and it's L1 caches in_port(mandatoryQueue_in, RubyRequest, mandatoryQueue, desc="...") { if (mandatoryQueue_in.isReady(clockEdge())) { @@ -822,18 +832,17 @@ machine(MachineType:L1Cache, "Directory protocol") // L2 will usually request data for a writeback action(qq_sendWBDataFromTBEToL2, "\q", desc="Send data from TBE to L2") { - enqueue(responseNetwork_out, ResponseMsg, request_latency) { + enqueue(requestNetwork_out, RequestMsg, request_latency) { assert(is_valid(tbe)); out_msg.addr := address; - out_msg.Sender := machineID; - out_msg.SenderMachine := MachineType:L1Cache; + out_msg.Requestor := machineID; + out_msg.RequestorMachine := MachineType:L1Cache; out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, l2_select_low_bit, l2_select_num_bits, intToID(0))); - out_msg.Dirty := tbe.Dirty; if (tbe.Dirty) { - out_msg.Type := CoherenceResponseType:WRITEBACK_DIRTY_DATA; + out_msg.Type := CoherenceRequestType:WRITEBACK_DIRTY_DATA; } else { - out_msg.Type := CoherenceResponseType:WRITEBACK_CLEAN_DATA; + out_msg.Type := CoherenceRequestType:WRITEBACK_CLEAN_DATA; } out_msg.DataBlk := tbe.DataBlk; out_msg.MessageSize := MessageSizeType:Writeback_Data; @@ -1281,38 +1290,38 @@ machine(MachineType:L1Cache, "Directory protocol") transition({SI, OI, MI}, Writeback_Ack_Data, I) { qq_sendWBDataFromTBEToL2; // always send data s_deallocateTBE; - l_popForwardQueue; + n_popResponseQueue; } transition({SI, OI, MI}, Writeback_Ack, I) { g_sendUnblock; s_deallocateTBE; - l_popForwardQueue; + n_popResponseQueue; } transition({MI, OI}, Writeback_Nack, OI) { // FIXME: This might cause deadlock by re-using the writeback // channel, we should handle this case differently. dd_issuePUTO; - l_popForwardQueue; + n_popResponseQueue; } // Transitions from II transition(II, {Writeback_Ack, Writeback_Ack_Data}, I) { g_sendUnblock; s_deallocateTBE; - l_popForwardQueue; + n_popResponseQueue; } // transition({II, SI}, Writeback_Nack, I) { transition(II, Writeback_Nack, I) { s_deallocateTBE; - l_popForwardQueue; + n_popResponseQueue; } transition(SI, Writeback_Nack) { dd_issuePUTS; - l_popForwardQueue; + n_popResponseQueue; } transition(II, Inv) { 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; } } diff --git a/src/mem/protocol/MOESI_CMP_directory-dir.sm b/src/mem/protocol/MOESI_CMP_directory-dir.sm index 9b73a2bb2..04e28881e 100644 --- a/src/mem/protocol/MOESI_CMP_directory-dir.sm +++ b/src/mem/protocol/MOESI_CMP_directory-dir.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. * @@ -243,12 +255,6 @@ machine(MachineType:Directory, "Directory protocol") } else if (in_msg.Type == CoherenceResponseType:UNBLOCK_EXCLUSIVE) { trigger(Event:Exclusive_Unblock, in_msg.addr, TBEs[in_msg.addr]); - } else if (in_msg.Type == CoherenceResponseType:WRITEBACK_DIRTY_DATA) { - trigger(Event:Dirty_Writeback, in_msg.addr, - TBEs[in_msg.addr]); - } else if (in_msg.Type == CoherenceResponseType:WRITEBACK_CLEAN_ACK) { - trigger(Event:Clean_Writeback, in_msg.addr, - TBEs[in_msg.addr]); } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) { trigger(Event:Data, in_msg.addr, TBEs[in_msg.addr]); @@ -275,6 +281,12 @@ machine(MachineType:Directory, "Directory protocol") trigger(Event:PUTO, in_msg.addr, TBEs[in_msg.addr]); } else if (in_msg.Type == CoherenceRequestType:PUTO_SHARERS) { trigger(Event:PUTO_SHARERS, in_msg.addr, TBEs[in_msg.addr]); + } else if (in_msg.Type == CoherenceRequestType:WRITEBACK_DIRTY_DATA) { + trigger(Event:Dirty_Writeback, in_msg.addr, + TBEs[in_msg.addr]); + } else if (in_msg.Type == CoherenceRequestType:WRITEBACK_CLEAN_ACK) { + trigger(Event:Clean_Writeback, in_msg.addr, + TBEs[in_msg.addr]); } else if (in_msg.Type == CoherenceRequestType:DMA_READ) { trigger(Event:DMA_READ, makeLineAddress(in_msg.addr), TBEs[makeLineAddress(in_msg.addr)]); @@ -308,11 +320,11 @@ machine(MachineType:Directory, "Directory protocol") action(a_sendWriteBackAck, "a", desc="Send writeback ack to requestor") { peek(requestQueue_in, RequestMsg) { - enqueue(forwardNetwork_out, RequestMsg, directory_latency) { + enqueue(responseNetwork_out, ResponseMsg, directory_latency) { out_msg.addr := address; - out_msg.Type := CoherenceRequestType:WB_ACK; - out_msg.Requestor := in_msg.Requestor; - out_msg.RequestorMachine := MachineType:Directory; + out_msg.Type := CoherenceResponseType:WB_ACK; + out_msg.Sender := in_msg.Requestor; + out_msg.SenderMachine := MachineType:Directory; out_msg.Destination.add(in_msg.Requestor); out_msg.MessageSize := MessageSizeType:Writeback_Control; } @@ -321,11 +333,11 @@ machine(MachineType:Directory, "Directory protocol") action(b_sendWriteBackNack, "b", desc="Send writeback nack to requestor") { peek(requestQueue_in, RequestMsg) { - enqueue(forwardNetwork_out, RequestMsg, directory_latency) { + enqueue(responseNetwork_out, ResponseMsg, directory_latency) { out_msg.addr := address; - out_msg.Type := CoherenceRequestType:WB_NACK; - out_msg.Requestor := in_msg.Requestor; - out_msg.RequestorMachine := MachineType:Directory; + out_msg.Type := CoherenceResponseType:WB_NACK; + out_msg.Sender := in_msg.Requestor; + out_msg.SenderMachine := MachineType:Directory; out_msg.Destination.add(in_msg.Requestor); out_msg.MessageSize := MessageSizeType:Writeback_Control; } @@ -472,13 +484,13 @@ machine(MachineType:Directory, "Directory protocol") } } - action(qw_queueMemoryWBRequest, "qw", desc="Queue off-chip writeback request") { - peek(unblockNetwork_in, ResponseMsg) { + action(qw_queueMemoryWBFromCacheRequest, "qw", desc="Queue off-chip writeback request") { + peek(requestQueue_in, RequestMsg) { if (is_valid(tbe)) { queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency, in_msg.DataBlk); } else { - queueMemoryWrite(in_msg.Sender, address, to_memory_controller_latency, + queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency, in_msg.DataBlk); } } @@ -495,7 +507,7 @@ machine(MachineType:Directory, "Directory protocol") } } - action(qw_queueMemoryWBRequest2, "/qw", desc="Queue off-chip writeback request") { + action(qw_queueMemoryWBFromDMARequest, "/qw", desc="Queue off-chip writeback request") { peek(requestQueue_in, RequestMsg) { queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency, in_msg.DataBlk); @@ -567,7 +579,7 @@ machine(MachineType:Directory, "Directory protocol") } transition(I, DMA_WRITE, XI_U) { - qw_queueMemoryWBRequest2; + qw_queueMemoryWBFromDMARequest; a_sendDMAAck; // ack count may be zero i_popIncomingRequestQueue; } @@ -597,7 +609,7 @@ machine(MachineType:Directory, "Directory protocol") } transition(S, DMA_WRITE, XI_U) { - qw_queueMemoryWBRequest2; + qw_queueMemoryWBFromDMARequest; a_sendDMAAck; // ack count may be zero g_sendInvalidations; // the DMA will collect invalidations i_popIncomingRequestQueue; @@ -768,47 +780,47 @@ machine(MachineType:Directory, "Directory protocol") transition(MI, Dirty_Writeback, I) { c_clearOwner; cc_clearSharers; - qw_queueMemoryWBRequest; - j_popIncomingUnblockQueue; + qw_queueMemoryWBFromCacheRequest; + i_popIncomingRequestQueue; } transition(MIS, Dirty_Writeback, S) { c_moveOwnerToSharer; - qw_queueMemoryWBRequest; - j_popIncomingUnblockQueue; + qw_queueMemoryWBFromCacheRequest; + i_popIncomingRequestQueue; } transition(MIS, Clean_Writeback, S) { c_moveOwnerToSharer; - j_popIncomingUnblockQueue; + i_popIncomingRequestQueue; } transition(OS, Dirty_Writeback, S) { c_clearOwner; - qw_queueMemoryWBRequest; - j_popIncomingUnblockQueue; + qw_queueMemoryWBFromCacheRequest; + i_popIncomingRequestQueue; } transition(OSS, Dirty_Writeback, S) { c_moveOwnerToSharer; - qw_queueMemoryWBRequest; - j_popIncomingUnblockQueue; + qw_queueMemoryWBFromCacheRequest; + i_popIncomingRequestQueue; } transition(OSS, Clean_Writeback, S) { c_moveOwnerToSharer; - j_popIncomingUnblockQueue; + i_popIncomingRequestQueue; } transition(MI, Clean_Writeback, I) { c_clearOwner; cc_clearSharers; - j_popIncomingUnblockQueue; + i_popIncomingRequestQueue; } transition(OS, Clean_Writeback, S) { c_clearOwner; - j_popIncomingUnblockQueue; + i_popIncomingRequestQueue; } transition({MI, MIS}, Unblock, M) { diff --git a/src/mem/protocol/MOESI_CMP_directory-dma.sm b/src/mem/protocol/MOESI_CMP_directory-dma.sm index f3f91671f..16dc32a50 100644 --- a/src/mem/protocol/MOESI_CMP_directory-dma.sm +++ b/src/mem/protocol/MOESI_CMP_directory-dma.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) 2009-2013 Mark D. Hill and David A. Wood * Copyright (c) 2010-2011 Advanced Micro Devices, Inc. * All rights reserved. @@ -106,22 +118,6 @@ machine(MachineType:DMA, "DMA Controller") out_port(respToDirectory_out, ResponseMsg, respToDir, desc="..."); out_port(triggerQueue_out, TriggerMsg, triggerQueue, desc="..."); - in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") { - if (dmaRequestQueue_in.isReady(clockEdge())) { - peek(dmaRequestQueue_in, SequencerMsg) { - if (in_msg.Type == SequencerRequestType:LD ) { - trigger(Event:ReadRequest, in_msg.LineAddress, - TBEs[in_msg.LineAddress]); - } else if (in_msg.Type == SequencerRequestType:ST) { - trigger(Event:WriteRequest, in_msg.LineAddress, - TBEs[in_msg.LineAddress]); - } else { - error("Invalid request type"); - } - } - } - } - in_port(dmaResponseQueue_in, ResponseMsg, responseFromDir, desc="...") { if (dmaResponseQueue_in.isReady(clockEdge())) { peek( dmaResponseQueue_in, ResponseMsg) { @@ -155,6 +151,22 @@ machine(MachineType:DMA, "DMA Controller") } } + in_port(dmaRequestQueue_in, SequencerMsg, mandatoryQueue, desc="...") { + if (dmaRequestQueue_in.isReady(clockEdge())) { + peek(dmaRequestQueue_in, SequencerMsg) { + if (in_msg.Type == SequencerRequestType:LD ) { + trigger(Event:ReadRequest, in_msg.LineAddress, + TBEs[in_msg.LineAddress]); + } else if (in_msg.Type == SequencerRequestType:ST) { + trigger(Event:WriteRequest, in_msg.LineAddress, + TBEs[in_msg.LineAddress]); + } else { + error("Invalid request type"); + } + } + } + } + action(s_sendReadRequest, "s", desc="Send a DMA read request to memory") { peek(dmaRequestQueue_in, SequencerMsg) { enqueue(reqToDirectory_out, RequestMsg, request_latency) { diff --git a/src/mem/protocol/MOESI_CMP_directory-msg.sm b/src/mem/protocol/MOESI_CMP_directory-msg.sm index 5f6f8268a..7dc582215 100644 --- a/src/mem/protocol/MOESI_CMP_directory-msg.sm +++ b/src/mem/protocol/MOESI_CMP_directory-msg.sm @@ -1,5 +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-2005 Mark D. Hill and David A. Wood * All rights reserved. * @@ -40,11 +51,10 @@ enumeration(CoherenceRequestType, desc="...") { PUTO, desc="Put Owned"; PUTO_SHARERS, desc="Put Owned, but sharers exist so don't remove from sharers list"; PUTS, desc="Put Shared"; - WB_ACK, desc="Writeback ack"; - WB_ACK_DATA, desc="Writeback ack"; - WB_NACK, desc="Writeback neg. ack"; INV, desc="Invalidation"; - + WRITEBACK_CLEAN_DATA, desc="Clean writeback (contains data)"; + WRITEBACK_CLEAN_ACK, desc="Clean writeback (contains no data)"; + WRITEBACK_DIRTY_DATA, desc="Dirty writeback (contains data)"; DMA_READ, desc="DMA Read"; DMA_WRITE, desc="DMA Write"; } @@ -56,9 +66,9 @@ enumeration(CoherenceResponseType, desc="...") { DATA_EXCLUSIVE, desc="Data, no processor has a copy"; UNBLOCK, desc="Unblock"; UNBLOCK_EXCLUSIVE, desc="Unblock, we're in E/M"; - WRITEBACK_CLEAN_DATA, desc="Clean writeback (contains data)"; - WRITEBACK_CLEAN_ACK, desc="Clean writeback (contains no data)"; - WRITEBACK_DIRTY_DATA, desc="Dirty writeback (contains data)"; + WB_ACK, desc="Writeback ack"; + WB_ACK_DATA, desc="Writeback ack"; + WB_NACK, desc="Writeback neg. ack"; DMA_ACK, desc="Ack that a DMA write completed"; } @@ -100,7 +110,9 @@ structure(RequestMsg, desc="...", interface="Message") { bool functionalRead(Packet *pkt) { // Read only those messages that contain the data if (Type == CoherenceRequestType:DMA_READ || - Type == CoherenceRequestType:DMA_WRITE) { + Type == CoherenceRequestType:DMA_WRITE || + Type == CoherenceRequestType:WRITEBACK_CLEAN_DATA || + Type == CoherenceRequestType:WRITEBACK_DIRTY_DATA) { return testAndRead(addr, DataBlk, pkt); } return false; @@ -127,9 +139,7 @@ structure(ResponseMsg, desc="...", interface="Message") { bool functionalRead(Packet *pkt) { // Read only those messages that contain the data if (Type == CoherenceResponseType:DATA || - Type == CoherenceResponseType:DATA_EXCLUSIVE || - Type == CoherenceResponseType:WRITEBACK_CLEAN_DATA || - Type == CoherenceResponseType:WRITEBACK_DIRTY_DATA) { + Type == CoherenceResponseType:DATA_EXCLUSIVE) { return testAndRead(addr, DataBlk, pkt); } return false; |