diff options
-rw-r--r-- | src/mem/protocol/MOESI_CMP_token-L1cache.sm | 161 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_hammer-cache.sm | 123 | ||||
-rw-r--r-- | src/mem/ruby/buffers/MessageBuffer.cc | 36 | ||||
-rw-r--r-- | src/mem/ruby/buffers/MessageBuffer.hh | 1 | ||||
-rw-r--r-- | src/mem/slicc/ast/WakeUpAllDependentsStatementAST.py | 43 | ||||
-rw-r--r-- | src/mem/slicc/ast/__init__.py | 1 | ||||
-rw-r--r-- | src/mem/slicc/parser.py | 5 | ||||
-rw-r--r-- | src/mem/slicc/symbols/StateMachine.py | 32 |
8 files changed, 295 insertions, 107 deletions
diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm index 8cb45249e..00e9404c9 100644 --- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm @@ -433,7 +433,7 @@ machine(L1Cache, "Token protocol") // ** IN_PORTS ** // Use Timer - in_port(useTimerTable_in, Address, useTimerTable) { + in_port(useTimerTable_in, Address, useTimerTable, rank=5) { if (useTimerTable_in.isReady()) { TBE tbe := L1_TBEs[useTimerTable.readyAddress()]; @@ -459,7 +459,7 @@ machine(L1Cache, "Token protocol") } // Reissue Timer - in_port(reissueTimerTable_in, Address, reissueTimerTable) { + in_port(reissueTimerTable_in, Address, reissueTimerTable, rank=4) { if (reissueTimerTable_in.isReady()) { trigger(Event:Request_Timeout, reissueTimerTable.readyAddress(), getCacheEntry(reissueTimerTable.readyAddress()), @@ -467,10 +467,8 @@ machine(L1Cache, "Token protocol") } } - - // Persistent Network - in_port(persistentNetwork_in, PersistentMsg, persistentToL1Cache) { + in_port(persistentNetwork_in, PersistentMsg, persistentToL1Cache, rank=3) { if (persistentNetwork_in.isReady()) { peek(persistentNetwork_in, PersistentMsg, block_on="Address") { assert(in_msg.Destination.isElement(machineID)); @@ -519,56 +517,8 @@ machine(L1Cache, "Token protocol") } } - - // Request Network - in_port(requestNetwork_in, RequestMsg, requestToL1Cache) { - if (requestNetwork_in.isReady()) { - peek(requestNetwork_in, RequestMsg, block_on="Address") { - assert(in_msg.Destination.isElement(machineID)); - - Entry cache_entry := getCacheEntry(in_msg.Address); - TBE tbe := L1_TBEs[in_msg.Address]; - - if (in_msg.Type == CoherenceRequestType:GETX) { - if (in_msg.isLocal) { - trigger(Event:Transient_Local_GETX, in_msg.Address, - cache_entry, tbe); - } - else { - trigger(Event:Transient_GETX, in_msg.Address, - cache_entry, tbe); - } - } else if (in_msg.Type == CoherenceRequestType:GETS) { - if (getTokens(cache_entry) == 1 || - getTokens(cache_entry) == (max_tokens() / 2) + 1) { - if (in_msg.isLocal) { - trigger(Event:Transient_Local_GETS_Last_Token, in_msg.Address, - cache_entry, tbe); - } - else { - trigger(Event:Transient_GETS_Last_Token, in_msg.Address, - cache_entry, tbe); - } - } - else { - if (in_msg.isLocal) { - trigger(Event:Transient_Local_GETS, in_msg.Address, - cache_entry, tbe); - } - else { - trigger(Event:Transient_GETS, in_msg.Address, - cache_entry, tbe); - } - } - } else { - error("Unexpected message"); - } - } - } - } - // Response Network - in_port(responseNetwork_in, ResponseMsg, responseToL1Cache) { + in_port(responseNetwork_in, ResponseMsg, responseToL1Cache, rank=2) { if (responseNetwork_in.isReady()) { peek(responseNetwork_in, ResponseMsg, block_on="Address") { assert(in_msg.Destination.isElement(machineID)); @@ -639,8 +589,55 @@ machine(L1Cache, "Token protocol") } } + // Request Network + in_port(requestNetwork_in, RequestMsg, requestToL1Cache) { + if (requestNetwork_in.isReady()) { + peek(requestNetwork_in, RequestMsg, block_on="Address") { + assert(in_msg.Destination.isElement(machineID)); + + Entry cache_entry := getCacheEntry(in_msg.Address); + TBE tbe := L1_TBEs[in_msg.Address]; + + if (in_msg.Type == CoherenceRequestType:GETX) { + if (in_msg.isLocal) { + trigger(Event:Transient_Local_GETX, in_msg.Address, + cache_entry, tbe); + } + else { + trigger(Event:Transient_GETX, in_msg.Address, + cache_entry, tbe); + } + } else if (in_msg.Type == CoherenceRequestType:GETS) { + if (getTokens(cache_entry) == 1 || + getTokens(cache_entry) == (max_tokens() / 2) + 1) { + if (in_msg.isLocal) { + trigger(Event:Transient_Local_GETS_Last_Token, in_msg.Address, + cache_entry, tbe); + } + else { + trigger(Event:Transient_GETS_Last_Token, in_msg.Address, + cache_entry, tbe); + } + } + else { + if (in_msg.isLocal) { + trigger(Event:Transient_Local_GETS, in_msg.Address, + cache_entry, tbe); + } + else { + trigger(Event:Transient_GETS, in_msg.Address, + cache_entry, tbe); + } + } + } else { + error("Unexpected message"); + } + } + } + } + // Mandatory Queue - in_port(mandatoryQueue_in, CacheMsg, mandatoryQueue, desc="...") { + in_port(mandatoryQueue_in, CacheMsg, mandatoryQueue, desc="...", rank=0) { if (mandatoryQueue_in.isReady()) { peek(mandatoryQueue_in, CacheMsg, block_on="LineAddress") { // Check for data access to blocks in I-cache and ifetchs to blocks in D-cache @@ -1339,6 +1336,11 @@ machine(L1Cache, "Token protocol") tbe.IssueTime := get_time(); } + action(ta_traceStalledAddress, "ta", desc="Trace Stalled Address") { + peek(mandatoryQueue_in, CacheMsg) { + APPEND_TRANSITION_COMMENT(in_msg.LineAddress); + } + } action(j_unsetReissueTimer, "j", desc="Unset reissue timer.") { if (reissueTimerTable.isSet(address)) { @@ -1527,8 +1529,19 @@ machine(L1Cache, "Token protocol") } } - action(zz_recycleMandatoryQueue, "\z", desc="Send the head of the mandatory queue to the back of the queue.") { - mandatoryQueue_in.recycle(); + action(zz_stallAndWaitMandatoryQueue, "\z", desc="Send the head of the mandatory queue to the back of the queue.") { + peek(mandatoryQueue_in, CacheMsg) { + APPEND_TRANSITION_COMMENT(in_msg.LineAddress); + } + stall_and_wait(mandatoryQueue_in, address); + } + + action(kd_wakeUpDependents, "kd", desc="wake-up dependents") { + wake_up_dependents(address); + } + + action(ka_wakeUpAllDependents, "ka", desc="wake-up all dependents") { + wake_up_all_dependents(); } //***************************************************** @@ -1537,15 +1550,16 @@ machine(L1Cache, "Token protocol") // Transitions for Load/Store/L2_Replacement from transient states transition({IM, SM, OM, IS, IM_L, IS_L, I_L, S_L, SM_L, M_W, MM_W}, L1_Replacement) { - zz_recycleMandatoryQueue; + ta_traceStalledAddress; + zz_stallAndWaitMandatoryQueue; } transition({IM, SM, OM, IS, IM_L, IS_L, SM_L}, {Store, Atomic}) { - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; } transition({IM, IS, IM_L, IS_L}, {Load, Ifetch}) { - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; } @@ -1615,8 +1629,10 @@ machine(L1Cache, "Token protocol") } transition(I, L1_Replacement) { + ta_traceStalledAddress; tr_tokenReplacement; gg_deallocateL1CacheBlock; + ka_wakeUpAllDependents; } transition(I, {Transient_GETX, Transient_Local_GETX}) { @@ -1674,8 +1690,10 @@ machine(L1Cache, "Token protocol") } transition(S, L1_Replacement, I) { + ta_traceStalledAddress; cc_sharedReplacement; // Only needed in some cases gg_deallocateL1CacheBlock; + ka_wakeUpAllDependents; } transition(S, {Transient_GETX, Transient_Local_GETX}, I) { @@ -1750,8 +1768,10 @@ machine(L1Cache, "Token protocol") } transition(O, L1_Replacement, I) { + ta_traceStalledAddress; c_ownedReplacement; gg_deallocateL1CacheBlock; + ka_wakeUpAllDependents; } transition(O, {Transient_GETX, Transient_Local_GETX}, I) { @@ -1835,8 +1855,10 @@ machine(L1Cache, "Token protocol") } transition(MM, L1_Replacement, I) { + ta_traceStalledAddress; c_ownedReplacement; gg_deallocateL1CacheBlock; + ka_wakeUpAllDependents; } transition(MM, {Transient_GETX, Transient_Local_GETX, Transient_GETS, Transient_Local_GETS}, I) { @@ -1864,11 +1886,13 @@ machine(L1Cache, "Token protocol") transition(MM_W, Use_TimeoutNoStarvers, MM) { s_deallocateTBE; jj_unsetUseTimer; + kd_wakeUpDependents; } transition(MM_W, Use_TimeoutNoStarvers_NoMig, M) { s_deallocateTBE; jj_unsetUseTimer; + kd_wakeUpDependents; } // Transitions from Dirty Exclusive @@ -1898,8 +1922,10 @@ machine(L1Cache, "Token protocol") } transition(M, L1_Replacement, I) { + ta_traceStalledAddress; c_ownedReplacement; gg_deallocateL1CacheBlock; + ka_wakeUpAllDependents; } transition(M, {Transient_GETX, Transient_Local_GETX}, I) { @@ -1948,6 +1974,7 @@ machine(L1Cache, "Token protocol") transition(M_W, {Use_TimeoutNoStarvers, Use_TimeoutNoStarvers_NoMig}, M) { s_deallocateTBE; jj_unsetUseTimer; + kd_wakeUpDependents; } transition(M_W, Use_TimeoutStarverX, I_L) { @@ -2056,6 +2083,7 @@ machine(L1Cache, "Token protocol") o_scheduleUseTimeout; j_unsetReissueTimer; n_popResponseQueue; + kd_wakeUpDependents; } transition(SM, Data_Shared) { @@ -2077,6 +2105,7 @@ machine(L1Cache, "Token protocol") o_scheduleUseTimeout; j_unsetReissueTimer; n_popResponseQueue; + kd_wakeUpDependents; } transition({IM, SM}, {Transient_GETX, Transient_Local_GETX}, IM) { // We don't have the data yet, but we might have collected some tokens. We give them up here to avoid livelock @@ -2106,6 +2135,7 @@ machine(L1Cache, "Token protocol") o_scheduleUseTimeout; j_unsetReissueTimer; n_popResponseQueue; + kd_wakeUpDependents; } transition(OM, Data_Shared) { @@ -2121,6 +2151,7 @@ machine(L1Cache, "Token protocol") o_scheduleUseTimeout; j_unsetReissueTimer; n_popResponseQueue; + kd_wakeUpDependents; } transition(OM, Request_Timeout) { @@ -2142,6 +2173,7 @@ machine(L1Cache, "Token protocol") s_deallocateTBE; j_unsetReissueTimer; n_popResponseQueue; + kd_wakeUpDependents; } transition(IS, Data_Owner, O) { @@ -2151,6 +2183,7 @@ machine(L1Cache, "Token protocol") s_deallocateTBE; j_unsetReissueTimer; n_popResponseQueue; + kd_wakeUpDependents; } transition(IS, Data_All_Tokens, M_W) { @@ -2160,6 +2193,7 @@ machine(L1Cache, "Token protocol") o_scheduleUseTimeout; j_unsetReissueTimer; n_popResponseQueue; + kd_wakeUpDependents; } transition(IS, Request_Timeout) { @@ -2247,6 +2281,7 @@ machine(L1Cache, "Token protocol") j_unsetReissueTimer; o_scheduleUseTimeout; n_popResponseQueue; + kd_wakeUpDependents; } transition(SM_L, Data_All_Tokens, S_L) { @@ -2288,6 +2323,7 @@ machine(L1Cache, "Token protocol") j_unsetReissueTimer; o_scheduleUseTimeout; n_popResponseQueue; + kd_wakeUpDependents; } @@ -2295,22 +2331,27 @@ machine(L1Cache, "Token protocol") transition(I_L, Own_Lock_or_Unlock, I) { l_popPersistentQueue; + kd_wakeUpDependents; } transition(S_L, Own_Lock_or_Unlock, S) { l_popPersistentQueue; + kd_wakeUpDependents; } transition(IM_L, Own_Lock_or_Unlock, IM) { l_popPersistentQueue; + kd_wakeUpDependents; } transition(IS_L, Own_Lock_or_Unlock, IS) { l_popPersistentQueue; + kd_wakeUpDependents; } transition(SM_L, Own_Lock_or_Unlock, SM) { l_popPersistentQueue; + kd_wakeUpDependents; } } diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm index 1f14db4f7..78bc9e3e7 100644 --- a/src/mem/protocol/MOESI_hammer-cache.sm +++ b/src/mem/protocol/MOESI_hammer-cache.sm @@ -278,7 +278,7 @@ machine(L1Cache, "AMD Hammer-like protocol") // ** IN_PORTS ** // Trigger Queue - in_port(triggerQueue_in, TriggerMsg, triggerQueue) { + in_port(triggerQueue_in, TriggerMsg, triggerQueue, rank=3) { if (triggerQueue_in.isReady()) { peek(triggerQueue_in, TriggerMsg) { @@ -298,10 +298,35 @@ machine(L1Cache, "AMD Hammer-like protocol") } } - // Nothing from the request network + // Nothing from the unblock network + + // Response Network + in_port(responseToCache_in, ResponseMsg, responseToCache, rank=2) { + if (responseToCache_in.isReady()) { + peek(responseToCache_in, ResponseMsg, block_on="Address") { + + Entry cache_entry := getCacheEntry(in_msg.Address); + TBE tbe := TBEs[in_msg.Address]; + + if (in_msg.Type == CoherenceResponseType:ACK) { + trigger(Event:Ack, in_msg.Address, cache_entry, tbe); + } else if (in_msg.Type == CoherenceResponseType:ACK_SHARED) { + trigger(Event:Shared_Ack, in_msg.Address, cache_entry, tbe); + } else if (in_msg.Type == CoherenceResponseType:DATA) { + trigger(Event:Data, in_msg.Address, cache_entry, tbe); + } else if (in_msg.Type == CoherenceResponseType:DATA_SHARED) { + trigger(Event:Shared_Data, in_msg.Address, cache_entry, tbe); + } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) { + trigger(Event:Exclusive_Data, in_msg.Address, cache_entry, tbe); + } else { + error("Unexpected message"); + } + } + } + } // Forward Network - in_port(forwardToCache_in, RequestMsg, forwardToCache) { + in_port(forwardToCache_in, RequestMsg, forwardToCache, rank=1) { if (forwardToCache_in.isReady()) { peek(forwardToCache_in, RequestMsg, block_on="Address") { @@ -339,35 +364,10 @@ machine(L1Cache, "AMD Hammer-like protocol") } } - // Response Network - in_port(responseToCache_in, ResponseMsg, responseToCache) { - if (responseToCache_in.isReady()) { - peek(responseToCache_in, ResponseMsg, block_on="Address") { - - Entry cache_entry := getCacheEntry(in_msg.Address); - TBE tbe := TBEs[in_msg.Address]; - - if (in_msg.Type == CoherenceResponseType:ACK) { - trigger(Event:Ack, in_msg.Address, cache_entry, tbe); - } else if (in_msg.Type == CoherenceResponseType:ACK_SHARED) { - trigger(Event:Shared_Ack, in_msg.Address, cache_entry, tbe); - } else if (in_msg.Type == CoherenceResponseType:DATA) { - trigger(Event:Data, in_msg.Address, cache_entry, tbe); - } else if (in_msg.Type == CoherenceResponseType:DATA_SHARED) { - trigger(Event:Shared_Data, in_msg.Address, cache_entry, tbe); - } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) { - trigger(Event:Exclusive_Data, in_msg.Address, cache_entry, tbe); - } else { - error("Unexpected message"); - } - } - } - } - - // Nothing from the unblock network + // Nothing from the request network // Mandatory Queue - in_port(mandatoryQueue_in, CacheMsg, mandatoryQueue, desc="...") { + in_port(mandatoryQueue_in, CacheMsg, mandatoryQueue, desc="...", rank=0) { if (mandatoryQueue_in.isReady()) { peek(mandatoryQueue_in, CacheMsg, block_on="LineAddress") { @@ -1017,8 +1017,16 @@ machine(L1Cache, "AMD Hammer-like protocol") } } - action(zz_recycleMandatoryQueue, "\z", desc="Send the head of the mandatory queue to the back of the queue.") { - mandatoryQueue_in.recycle(); + action(zz_stallAndWaitMandatoryQueue, "\z", desc="Send the head of the mandatory queue to the back of the queue.") { + stall_and_wait(mandatoryQueue_in, address); + } + + action(kd_wakeUpDependents, "kd", desc="wake-up dependents") { + wake_up_dependents(address); + } + + action(ka_wakeUpAllDependents, "ka", desc="wake-up all dependents") { + wake_up_all_dependents(); } //***************************************************** @@ -1027,19 +1035,19 @@ machine(L1Cache, "AMD Hammer-like protocol") // Transitions for Load/Store/L2_Replacement from transient states transition({IM, SM, ISM, OM, IS, SS, OI, MI, II, IT, ST, OT, MT, MMT}, {Store, L2_Replacement}) { - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; } transition({M_W, MM_W}, {L2_Replacement}) { - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; } transition({IM, IS, OI, MI, II, IT, ST, OT, MT, MMT}, {Load, Ifetch}) { - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; } transition({IM, SM, ISM, OM, IS, SS, MM_W, M_W, OI, MI, II, IT, ST, OT, MT, MMT}, L1_to_L2) { - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; } transition({IT, ST, OT, MT, MMT}, {Other_GETX, NC_DMA_GETS, Other_GETS, Merged_GETS, Other_GETS_No_Mig, Invalidate}) { @@ -1053,6 +1061,7 @@ machine(L1Cache, "AMD Hammer-like protocol") vv_allocateL2CacheBlock; hp_copyFromTBEToL2; s_deallocateTBE; + ka_wakeUpAllDependents; } transition(I, Trigger_L2_to_L1D, IT) { @@ -1062,7 +1071,7 @@ machine(L1Cache, "AMD Hammer-like protocol") nb_copyFromTBEToL1; // Not really needed for state I s_deallocateTBE; uu_profileMiss; - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; ll_L2toL1Transfer; } @@ -1073,7 +1082,7 @@ machine(L1Cache, "AMD Hammer-like protocol") nb_copyFromTBEToL1; s_deallocateTBE; uu_profileMiss; - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; ll_L2toL1Transfer; } @@ -1084,7 +1093,7 @@ machine(L1Cache, "AMD Hammer-like protocol") nb_copyFromTBEToL1; s_deallocateTBE; uu_profileMiss; - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; ll_L2toL1Transfer; } @@ -1095,7 +1104,7 @@ machine(L1Cache, "AMD Hammer-like protocol") nb_copyFromTBEToL1; s_deallocateTBE; uu_profileMiss; - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; ll_L2toL1Transfer; } @@ -1106,7 +1115,7 @@ machine(L1Cache, "AMD Hammer-like protocol") nb_copyFromTBEToL1; s_deallocateTBE; uu_profileMiss; - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; ll_L2toL1Transfer; } @@ -1117,7 +1126,7 @@ machine(L1Cache, "AMD Hammer-like protocol") nb_copyFromTBEToL1; s_deallocateTBE; uu_profileMiss; - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; ll_L2toL1Transfer; } @@ -1128,7 +1137,7 @@ machine(L1Cache, "AMD Hammer-like protocol") nb_copyFromTBEToL1; s_deallocateTBE; uu_profileMiss; - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; ll_L2toL1Transfer; } @@ -1139,7 +1148,7 @@ machine(L1Cache, "AMD Hammer-like protocol") nb_copyFromTBEToL1; s_deallocateTBE; uu_profileMiss; - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; ll_L2toL1Transfer; } @@ -1150,7 +1159,7 @@ machine(L1Cache, "AMD Hammer-like protocol") nb_copyFromTBEToL1; s_deallocateTBE; uu_profileMiss; - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; ll_L2toL1Transfer; } @@ -1161,28 +1170,33 @@ machine(L1Cache, "AMD Hammer-like protocol") nb_copyFromTBEToL1; s_deallocateTBE; uu_profileMiss; - zz_recycleMandatoryQueue; + zz_stallAndWaitMandatoryQueue; ll_L2toL1Transfer; } transition(IT, Complete_L2_to_L1, I) { j_popTriggerQueue; + kd_wakeUpDependents; } transition(ST, Complete_L2_to_L1, S) { j_popTriggerQueue; + kd_wakeUpDependents; } transition(OT, Complete_L2_to_L1, O) { j_popTriggerQueue; + kd_wakeUpDependents; } transition(MT, Complete_L2_to_L1, M) { j_popTriggerQueue; + kd_wakeUpDependents; } transition(MMT, Complete_L2_to_L1, MM) { j_popTriggerQueue; + kd_wakeUpDependents; } // Transitions from Idle @@ -1212,6 +1226,7 @@ machine(L1Cache, "AMD Hammer-like protocol") transition(I, L2_Replacement) { rr_deallocateL2CacheBlock; + ka_wakeUpAllDependents; } transition(I, {Other_GETX, NC_DMA_GETS, Other_GETS, Other_GETS_No_Mig, Invalidate}) { @@ -1234,6 +1249,7 @@ machine(L1Cache, "AMD Hammer-like protocol") transition(S, L2_Replacement, I) { rr_deallocateL2CacheBlock; + ka_wakeUpAllDependents; } transition(S, {Other_GETX, Invalidate}, I) { @@ -1264,6 +1280,7 @@ machine(L1Cache, "AMD Hammer-like protocol") i_allocateTBE; d_issuePUT; rr_deallocateL2CacheBlock; + ka_wakeUpAllDependents; } transition(O, {Other_GETX, Invalidate}, I) { @@ -1296,6 +1313,7 @@ machine(L1Cache, "AMD Hammer-like protocol") i_allocateTBE; d_issuePUT; rr_deallocateL2CacheBlock; + ka_wakeUpAllDependents; } transition(MM, {Other_GETX, Invalidate}, I) { @@ -1338,6 +1356,7 @@ machine(L1Cache, "AMD Hammer-like protocol") i_allocateTBE; d_issuePUT; rr_deallocateL2CacheBlock; + ka_wakeUpAllDependents; } transition(M, {Other_GETX, Invalidate}, I) { @@ -1386,6 +1405,7 @@ machine(L1Cache, "AMD Hammer-like protocol") o_checkForCompletion; sx_external_store_hit; n_popResponseQueue; + kd_wakeUpDependents; } // Transitions from SM @@ -1424,6 +1444,7 @@ machine(L1Cache, "AMD Hammer-like protocol") gm_sendUnblockM; s_deallocateTBE; j_popTriggerQueue; + kd_wakeUpDependents; } // Transitions from OM @@ -1455,6 +1476,7 @@ machine(L1Cache, "AMD Hammer-like protocol") gm_sendUnblockM; s_deallocateTBE; j_popTriggerQueue; + kd_wakeUpDependents; } // Transitions from IS @@ -1484,6 +1506,7 @@ machine(L1Cache, "AMD Hammer-like protocol") hx_external_load_hit; uo_updateCurrentOwner; n_popResponseQueue; + kd_wakeUpDependents; } transition(IS, Exclusive_Data, M_W) { @@ -1492,6 +1515,7 @@ machine(L1Cache, "AMD Hammer-like protocol") o_checkForCompletion; hx_external_load_hit; n_popResponseQueue; + kd_wakeUpDependents; } transition(IS, Shared_Data, SS) { @@ -1502,6 +1526,7 @@ machine(L1Cache, "AMD Hammer-like protocol") hx_external_load_hit; uo_updateCurrentOwner; n_popResponseQueue; + kd_wakeUpDependents; } // Transitions from SS @@ -1549,6 +1574,7 @@ machine(L1Cache, "AMD Hammer-like protocol") gm_sendUnblockM; s_deallocateTBE; j_popTriggerQueue; + kd_wakeUpDependents; } // Transitions from M_W @@ -1568,6 +1594,7 @@ machine(L1Cache, "AMD Hammer-like protocol") gm_sendUnblockM; s_deallocateTBE; j_popTriggerQueue; + kd_wakeUpDependents; } // Transitions from OI/MI @@ -1591,12 +1618,14 @@ machine(L1Cache, "AMD Hammer-like protocol") t_sendExclusiveDataFromTBEToMemory; s_deallocateTBE; l_popForwardQueue; + kd_wakeUpDependents; } transition(OI, Writeback_Ack, I) { qq_sendDataFromTBEToMemory; s_deallocateTBE; l_popForwardQueue; + kd_wakeUpDependents; } // Transitions from II @@ -1609,10 +1638,12 @@ machine(L1Cache, "AMD Hammer-like protocol") g_sendUnblock; s_deallocateTBE; l_popForwardQueue; + kd_wakeUpDependents; } transition(II, Writeback_Nack, I) { s_deallocateTBE; l_popForwardQueue; + kd_wakeUpDependents; } } diff --git a/src/mem/ruby/buffers/MessageBuffer.cc b/src/mem/ruby/buffers/MessageBuffer.cc index 656787795..f6b79c580 100644 --- a/src/mem/ruby/buffers/MessageBuffer.cc +++ b/src/mem/ruby/buffers/MessageBuffer.cc @@ -56,6 +56,8 @@ MessageBuffer::MessageBuffer(const string &name) m_not_avail_count = 0; m_priority_rank = 0; m_name = name; + + m_stall_msg_map.clear(); } int @@ -337,11 +339,43 @@ MessageBuffer::reanalyzeMessages(const Address& addr) m_prio_heap.push_back(msgNode); push_heap(m_prio_heap.begin(), m_prio_heap.end(), - greater<MessageBufferNode>()); + greater<MessageBufferNode>()); g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, msgNode.m_time); m_stall_msg_map[addr].pop_front(); } + m_stall_msg_map.erase(addr); +} + +void +MessageBuffer::reanalyzeAllMessages() +{ + DPRINTF(RubyQueue, "ReanalyzeAllMessages %s\n", m_name); + + // + // Put all stalled messages associated with this address back on the + // prio heap + // + for (StallMsgMapType::iterator map_iter = m_stall_msg_map.begin(); + map_iter != m_stall_msg_map.end(); + ++map_iter) { + + while(!(map_iter->second).empty()) { + m_msg_counter++; + MessageBufferNode msgNode(g_eventQueue_ptr->getTime() + 1, + m_msg_counter, + (map_iter->second).front()); + + m_prio_heap.push_back(msgNode); + push_heap(m_prio_heap.begin(), m_prio_heap.end(), + greater<MessageBufferNode>()); + + g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr, + msgNode.m_time); + (map_iter->second).pop_front(); + } + } + m_stall_msg_map.clear(); } void diff --git a/src/mem/ruby/buffers/MessageBuffer.hh b/src/mem/ruby/buffers/MessageBuffer.hh index df04d810c..62cc65670 100644 --- a/src/mem/ruby/buffers/MessageBuffer.hh +++ b/src/mem/ruby/buffers/MessageBuffer.hh @@ -61,6 +61,7 @@ class MessageBuffer } void reanalyzeMessages(const Address& addr); + void reanalyzeAllMessages(); void stallMessage(const Address& addr); // TRUE if head of queue timestamp <= SystemTime diff --git a/src/mem/slicc/ast/WakeUpAllDependentsStatementAST.py b/src/mem/slicc/ast/WakeUpAllDependentsStatementAST.py new file mode 100644 index 000000000..cd453bdc3 --- /dev/null +++ b/src/mem/slicc/ast/WakeUpAllDependentsStatementAST.py @@ -0,0 +1,43 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# Copyright (c) 2010 Advanced Micro Devices, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.StatementAST import StatementAST + +class WakeUpAllDependentsStatementAST(StatementAST): + def __init__(self, slicc): + super(StatementAST, self).__init__(slicc) + + def __repr__(self): + return "[WakeUpAllDependentsStatementAst: %r]" % self.variable + + def generate(self, code, return_type): + code(''' + if (m_waiting_buffers.size() > 0) { + wakeUpAllBuffers(); + } + ''') diff --git a/src/mem/slicc/ast/__init__.py b/src/mem/slicc/ast/__init__.py index ae797ecd3..4af6c2036 100644 --- a/src/mem/slicc/ast/__init__.py +++ b/src/mem/slicc/ast/__init__.py @@ -72,4 +72,5 @@ from slicc.ast.TypeFieldEnumAST import * from slicc.ast.TypeFieldMemberAST import * from slicc.ast.TypeFieldMethodAST import * from slicc.ast.VarExprAST import * +from slicc.ast.WakeUpAllDependentsStatementAST import * from slicc.ast.WakeUpDependentsStatementAST import * diff --git a/src/mem/slicc/parser.py b/src/mem/slicc/parser.py index bb958f746..823e08819 100644 --- a/src/mem/slicc/parser.py +++ b/src/mem/slicc/parser.py @@ -159,6 +159,7 @@ class SLICC(Grammar): 'peek' : 'PEEK', 'stall_and_wait' : 'STALL_AND_WAIT', 'wake_up_dependents' : 'WAKE_UP_DEPENDENTS', + 'wake_up_all_dependents' : 'WAKE_UP_ALL_DEPENDENTS', 'enqueue' : 'ENQUEUE', 'copy_head' : 'COPY_HEAD', 'check_allocate' : 'CHECK_ALLOCATE', @@ -561,6 +562,10 @@ class SLICC(Grammar): "statement : WAKE_UP_DEPENDENTS '(' var ')' SEMI" p[0] = ast.WakeUpDependentsStatementAST(self, p[3]) + def p_statement__wake_up_all_dependents(self, p): + "statement : WAKE_UP_ALL_DEPENDENTS '(' ')' SEMI" + p[0] = ast.WakeUpAllDependentsStatementAST(self) + def p_statement__peek(self, p): "statement : PEEK '(' var ',' type pairs ')' statements" p[0] = ast.PeekStatementAST(self, p[3], p[5], p[6], p[8], "peek") diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py index b0d663c43..6a5817d55 100644 --- a/src/mem/slicc/symbols/StateMachine.py +++ b/src/mem/slicc/symbols/StateMachine.py @@ -258,6 +258,7 @@ public: const MachineType getMachineType() const; void stallBuffer(MessageBuffer* buf, Address addr); void wakeUpBuffers(Address addr); + void wakeUpAllBuffers(); void initNetworkPtr(Network* net_ptr) { m_net_ptr = net_ptr; } void print(std::ostream& out) const; void printConfig(std::ostream& out) const; @@ -734,6 +735,37 @@ $c_ident::wakeUpBuffers(Address addr) } void +$c_ident::wakeUpAllBuffers() +{ + // + // Wake up all possible buffers that could be waiting on any message. + // + + std::vector<MsgVecType*> wokeUpMsgVecs; + + for (WaitingBufType::iterator buf_iter = m_waiting_buffers.begin(); + buf_iter != m_waiting_buffers.end(); + ++buf_iter) { + for (MsgVecType::iterator vec_iter = buf_iter->second->begin(); + vec_iter != buf_iter->second->end(); + ++vec_iter) { + if (*vec_iter != NULL) { + (*vec_iter)->reanalyzeAllMessages(); + } + } + wokeUpMsgVecs.push_back(buf_iter->second); + } + + for (std::vector<MsgVecType*>::iterator wb_iter = wokeUpMsgVecs.begin(); + wb_iter != wokeUpMsgVecs.end(); + ++wb_iter) { + delete (*wb_iter); + } + + m_waiting_buffers.clear(); +} + +void $c_ident::blockOnQueue(Address addr, MessageBuffer* port) { m_is_blocking = true; |