diff --git a/src/mem/protocol/MESI_Three_Level-L0cache.sm b/src/mem/protocol/MESI_Three_Level-L0cache.sm index 4299f0db4..fb9e762da 100644 --- a/src/mem/protocol/MESI_Three_Level-L0cache.sm +++ b/src/mem/protocol/MESI_Three_Level-L0cache.sm @@ -459,21 +459,38 @@ machine(L0Cache, "MESI Directory L0 Cache") } } - action(h_load_hit, "h", desc="If not prefetch, notify sequencer the load completed.") { + action(h_load_hit, "hd", desc="If not prefetch, notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + Dcache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk); } - action(hx_load_hit, "hx", desc="If not prefetch, notify sequencer the load completed.") { + action(h_ifetch_hit, "hi", desc="If not prefetch, notify sequencer the ifetch completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + Icache.setMRU(cache_entry); + sequencer.readCallback(address, cache_entry.DataBlk); + } + + action(hx_load_hit, "hxd", desc="notify sequencer the load completed.") { + assert(is_valid(cache_entry)); + DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + Dcache.setMRU(cache_entry); + sequencer.readCallback(address, cache_entry.DataBlk, true); + } + + action(hx_ifetch_hit, "hxi", desc="notify sequencer the ifetch completed.") { + assert(is_valid(cache_entry)); + DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + Icache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk, true); } action(hh_store_hit, "\h", desc="If not prefetch, notify sequencer that store completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + Dcache.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk); cache_entry.Dirty := true; } @@ -481,6 +498,7 @@ machine(L0Cache, "MESI Directory L0 Cache") action(hhx_store_hit, "\hx", desc="If not prefetch, notify sequencer that store completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + Dcache.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk, true); cache_entry.Dirty := true; } @@ -625,7 +643,7 @@ machine(L0Cache, "MESI Directory L0 Cache") } transition({S,E,M}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } @@ -712,7 +730,7 @@ machine(L0Cache, "MESI Directory L0 Cache") transition(Inst_IS, Data, S) { u_writeInstToCache; - hx_load_hit; + hx_ifetch_hit; s_deallocateTBE; o_popIncomingResponseQueue; kd_wakeUpDependents; @@ -720,7 +738,7 @@ machine(L0Cache, "MESI Directory L0 Cache") transition(Inst_IS, Data_Exclusive, E) { u_writeInstToCache; - hx_load_hit; + hx_ifetch_hit; s_deallocateTBE; o_popIncomingResponseQueue; kd_wakeUpDependents; diff --git a/src/mem/protocol/MESI_Two_Level-L1cache.sm b/src/mem/protocol/MESI_Two_Level-L1cache.sm index 00c390c4a..f4978050d 100644 --- a/src/mem/protocol/MESI_Two_Level-L1cache.sm +++ b/src/mem/protocol/MESI_Two_Level-L1cache.sm @@ -809,36 +809,47 @@ machine(L1Cache, "MESI Directory L1 Cache CMP") sequencer.invalidateSC(address); } - action(h_load_hit, "h", - desc="If not prefetch, notify sequencer the load completed.") + action(h_load_hit, "hd", + desc="Notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Dcache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk); } - action(hx_load_hit, "hx", - desc="If not prefetch, notify sequencer the load completed.") + action(h_ifetch_hit, "hi", desc="Notify sequencer the instruction fetch completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Icache.setMRU(cache_entry); + sequencer.readCallback(address, cache_entry.DataBlk); + } + + action(hx_load_hit, "hx", desc="Notify sequencer the load completed.") + { + assert(is_valid(cache_entry)); + DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.readCallback(address, cache_entry.DataBlk, true); } - action(hh_store_hit, "\h", - desc="If not prefetch, notify sequencer that store completed.") + action(hh_store_hit, "\h", desc="Notify sequencer that store completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Dcache.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk); cache_entry.Dirty := true; } - action(hhx_store_hit, "\hx", - desc="If not prefetch, notify sequencer that store completed.") + action(hhx_store_hit, "\hx", desc="Notify sequencer that store completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.writeCallback(address, cache_entry.DataBlk, true); cache_entry.Dirty := true; } @@ -1080,7 +1091,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP") } transition({S,E,M}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } diff --git a/src/mem/protocol/MI_example-cache.sm b/src/mem/protocol/MI_example-cache.sm index 4a1d6e946..d247ce663 100644 --- a/src/mem/protocol/MI_example-cache.sm +++ b/src/mem/protocol/MI_example-cache.sm @@ -353,6 +353,7 @@ machine(L1Cache, "MI Example L1 Cache") action(r_load_hit, "r", desc="Notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk); + cacheMemory.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk, false); } @@ -360,6 +361,7 @@ machine(L1Cache, "MI Example L1 Cache") peek(responseNetwork_in, ResponseMsg) { assert(is_valid(cache_entry)); DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk); + cacheMemory.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk, true, machineIDToMachineType(in_msg.Sender)); } @@ -368,6 +370,7 @@ machine(L1Cache, "MI Example L1 Cache") action(s_store_hit, "s", desc="Notify sequencer that store completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk); + cacheMemory.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk, false); } @@ -375,6 +378,7 @@ machine(L1Cache, "MI Example L1 Cache") peek(responseNetwork_in, ResponseMsg) { assert(is_valid(cache_entry)); DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk); + cacheMemory.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk, true, machineIDToMachineType(in_msg.Sender)); } diff --git a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm index 17a39a210..7a8f35333 100644 --- a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm @@ -635,21 +635,32 @@ machine(L1Cache, "Directory protocol") } } - action(h_load_hit, "h", desc="Notify sequencer the load completed.") { + action(h_load_hit, "hd", desc="Notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Dcache.setMRU(cache_entry); + sequencer.readCallback(address, cache_entry.DataBlk); + } + + action(h_ifetch_hit, "hi", desc="Notify the sequencer about ifetch completion.") { + assert(is_valid(cache_entry)); + DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Icache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk); } action(hx_load_hit, "hx", desc="Notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.readCallback(address, cache_entry.DataBlk, true); } action(hh_store_hit, "\h", desc="Notify sequencer that store completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Dcache.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk); cache_entry.Dirty := true; } @@ -657,6 +668,8 @@ machine(L1Cache, "Directory protocol") action(xx_store_hit, "\xx", desc="Notify sequencer that store completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.writeCallback(address, cache_entry.DataBlk, true); cache_entry.Dirty := true; } @@ -964,7 +977,7 @@ machine(L1Cache, "Directory protocol") } transition({S, SM, O, OM, MM, MM_W, M, M_W}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm index 067adfc54..1d47f1c8a 100644 --- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm @@ -1284,12 +1284,22 @@ machine(L1Cache, "Token protocol") } } - - action(h_load_hit, "h", desc="Notify sequencer the load completed.") { + action(h_load_hit, "hd", desc="Notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n", address, cache_entry.DataBlk); + L1Dcache.setMRU(cache_entry); + sequencer.readCallback(address, cache_entry.DataBlk, false, + MachineType:L1Cache); + } + + action(h_ifetch_hit, "hi", desc="Notify sequencer the load completed.") { + assert(is_valid(cache_entry)); + DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n", + address, cache_entry.DataBlk); + + L1Icache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk, false, MachineType:L1Cache); } @@ -1299,6 +1309,8 @@ machine(L1Cache, "Token protocol") DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n", address, cache_entry.DataBlk); peek(responseNetwork_in, ResponseMsg) { + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.readCallback(address, cache_entry.DataBlk, isExternalHit(address, in_msg.Sender), machineIDToMachineType(in_msg.Sender)); @@ -1310,6 +1322,7 @@ machine(L1Cache, "Token protocol") DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n", address, cache_entry.DataBlk); + L1Dcache.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk, false, MachineType:L1Cache); cache_entry.Dirty := true; @@ -1321,6 +1334,8 @@ machine(L1Cache, "Token protocol") DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n", address, cache_entry.DataBlk); peek(responseNetwork_in, ResponseMsg) { + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.writeCallback(address, cache_entry.DataBlk, isExternalHit(address, in_msg.Sender), machineIDToMachineType(in_msg.Sender)); @@ -1702,7 +1717,7 @@ machine(L1Cache, "Token protocol") } transition({S, SM, S_L, SM_L}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } @@ -1784,7 +1799,7 @@ machine(L1Cache, "Token protocol") // Transitions from Owned transition({O, OM}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } @@ -1874,7 +1889,7 @@ machine(L1Cache, "Token protocol") // Transitions from Modified transition({MM, MM_W}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } @@ -1949,7 +1964,7 @@ machine(L1Cache, "Token protocol") // Transitions from Dirty Exclusive transition({M, M_W}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm index 0b7acb701..269e47dfd 100644 --- a/src/mem/protocol/MOESI_hammer-cache.sm +++ b/src/mem/protocol/MOESI_hammer-cache.sm @@ -857,9 +857,18 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } } - action(h_load_hit, "h", desc="Notify sequencer the load completed.") { + action(h_load_hit, "hd", desc="Notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Dcache.setMRU(cache_entry); + sequencer.readCallback(address, cache_entry.DataBlk, false, + testAndClearLocalHit(cache_entry)); + } + + action(h_ifetch_hit, "hi", desc="Notify sequencer the ifetch completed.") { + assert(is_valid(cache_entry)); + DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Icache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk, false, testAndClearLocalHit(cache_entry)); } @@ -869,7 +878,8 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") assert(is_valid(tbe)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); peek(responseToCache_in, ResponseMsg) { - + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.readCallback(address, cache_entry.DataBlk, true, machineIDToMachineType(in_msg.Sender), tbe.InitialRequestTime, tbe.ForwardRequestTime, tbe.FirstResponseTime); @@ -880,6 +890,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); peek(mandatoryQueue_in, RubyRequest) { + L1Dcache.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk, false, testAndClearLocalHit(cache_entry)); @@ -901,7 +912,8 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") assert(is_valid(tbe)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); peek(responseToCache_in, ResponseMsg) { - + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.writeCallback(address, cache_entry.DataBlk, true, machineIDToMachineType(in_msg.Sender), tbe.InitialRequestTime, tbe.ForwardRequestTime, tbe.FirstResponseTime); @@ -914,7 +926,8 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") assert(is_valid(cache_entry)); assert(is_valid(tbe)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); - + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.writeCallback(address, cache_entry.DataBlk, true, machineIDToMachineType(tbe.LastResponder), tbe.InitialRequestTime, tbe.ForwardRequestTime, tbe.FirstResponseTime); @@ -1508,7 +1521,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition({S, SM, ISM}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstHit; k_popMandatoryQueue; } @@ -1522,7 +1535,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition(SR, Ifetch, S) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstMiss; uu_profileL2Hit; k_popMandatoryQueue; @@ -1570,7 +1583,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition({O, OM, SS, MM_W, M_W}, {Ifetch}) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstHit; k_popMandatoryQueue; } @@ -1584,7 +1597,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition(OR, Ifetch, O) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstMiss; uu_profileL2Hit; k_popMandatoryQueue; @@ -1635,7 +1648,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") // Transitions from Modified transition({MM, M}, {Ifetch}) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstHit; k_popMandatoryQueue; } @@ -1661,7 +1674,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition(MMR, Ifetch, MM) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstMiss; uu_profileL2Hit; k_popMandatoryQueue; @@ -1742,7 +1755,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition(MR, Ifetch, M) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstMiss; uu_profileL2Hit; k_popMandatoryQueue; diff --git a/src/mem/protocol/RubySlicc_Types.sm b/src/mem/protocol/RubySlicc_Types.sm index d032adfd8..f464b3c7d 100644 --- a/src/mem/protocol/RubySlicc_Types.sm +++ b/src/mem/protocol/RubySlicc_Types.sm @@ -156,6 +156,7 @@ structure (CacheMemory, external = "yes") { Cycles getTagLatency(); Cycles getDataLatency(); void setMRU(Addr); + void setMRU(AbstractCacheEntry); void recordRequestType(CacheRequestType, Addr); bool checkResourceAvailable(CacheResourceType, Addr); diff --git a/src/mem/ruby/structures/CacheMemory.cc b/src/mem/ruby/structures/CacheMemory.cc index ab2647759..931f58a8e 100644 --- a/src/mem/ruby/structures/CacheMemory.cc +++ b/src/mem/ruby/structures/CacheMemory.cc @@ -343,6 +343,14 @@ CacheMemory::setMRU(Addr address) m_replacementPolicy_ptr->touch(cacheSet, loc, curTick()); } +void +CacheMemory::setMRU(const AbstractCacheEntry *e) +{ + uint32_t cacheSet = e->getSetIndex(); + uint32_t loc = e->getWayIndex(); + m_replacementPolicy_ptr->touch(cacheSet, loc, curTick()); +} + void CacheMemory::recordCacheContents(int cntrl, CacheRecorder* tr) const { diff --git a/src/mem/ruby/structures/CacheMemory.hh b/src/mem/ruby/structures/CacheMemory.hh index 1af446950..7ce674e61 100644 --- a/src/mem/ruby/structures/CacheMemory.hh +++ b/src/mem/ruby/structures/CacheMemory.hh @@ -106,6 +106,8 @@ class CacheMemory : public SimObject // Set this address to most recently used void setMRU(Addr address); + // Set this entry to most recently used + void setMRU(const AbstractCacheEntry *e); // Functions for locking and unlocking cache lines corresponding to the // provided address. These are required for supporting atomic memory diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index b21c70743..740db7d8d 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -496,19 +496,15 @@ Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data, const Cycles forwardRequestTime, const Cycles firstResponseTime) { + warn_once("Replacement policy updates recently became the responsibility " + "of SLICC state machines. Make sure to setMRU() near callbacks " + "in .sm files!"); + PacketPtr pkt = srequest->pkt; Addr request_address(pkt->getAddr()); - Addr request_line_address = makeLineAddress(pkt->getAddr()); RubyRequestType type = srequest->m_type; Cycles issued_time = srequest->issue_time; - // Set this cache entry to the most recently used - if (type == RubyRequestType_IFETCH) { - m_instCache_ptr->setMRU(request_line_address); - } else { - m_dataCache_ptr->setMRU(request_line_address); - } - assert(curCycle() >= issued_time); Cycles total_latency = curCycle() - issued_time;