summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/protocol/MOESI_CMP_token-L1cache.sm161
-rw-r--r--src/mem/protocol/MOESI_hammer-cache.sm123
-rw-r--r--src/mem/ruby/buffers/MessageBuffer.cc36
-rw-r--r--src/mem/ruby/buffers/MessageBuffer.hh1
-rw-r--r--src/mem/slicc/ast/WakeUpAllDependentsStatementAST.py43
-rw-r--r--src/mem/slicc/ast/__init__.py1
-rw-r--r--src/mem/slicc/parser.py5
-rw-r--r--src/mem/slicc/symbols/StateMachine.py32
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;