diff options
-rw-r--r-- | src/mem/protocol/MESI_Three_Level-L0cache.sm | 28 | ||||
-rw-r--r-- | src/mem/protocol/MESI_Two_Level-L1cache.sm | 29 | ||||
-rw-r--r-- | src/mem/protocol/MI_example-cache.sm | 4 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_CMP_directory-L1cache.sm | 17 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_CMP_token-L1cache.sm | 25 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_hammer-cache.sm | 35 | ||||
-rw-r--r-- | src/mem/protocol/RubySlicc_Types.sm | 1 | ||||
-rw-r--r-- | src/mem/ruby/structures/CacheMemory.cc | 8 | ||||
-rw-r--r-- | src/mem/ruby/structures/CacheMemory.hh | 2 | ||||
-rw-r--r-- | src/mem/ruby/system/Sequencer.cc | 12 |
10 files changed, 121 insertions, 40 deletions
diff --git a/src/mem/protocol/MESI_Three_Level-L0cache.sm b/src/mem/protocol/MESI_Three_Level-L0cache.sm index 4a0766ce8..7e8626dc9 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 8033e5983..b9be4663f 100644 --- a/src/mem/protocol/MESI_Two_Level-L1cache.sm +++ b/src/mem/protocol/MESI_Two_Level-L1cache.sm @@ -810,36 +810,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; } @@ -1081,7 +1092,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 f3b1600f9..334106615 100644 --- a/src/mem/protocol/MI_example-cache.sm +++ b/src/mem/protocol/MI_example-cache.sm @@ -352,6 +352,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); } @@ -359,6 +360,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)); } @@ -367,6 +369,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); } @@ -374,6 +377,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 6c5d3a20f..2ef80efd2 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 c5a7cd940..230adfc4b 100644 --- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm @@ -1282,12 +1282,22 @@ machine(L1Cache, "Token protocol") } } + 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); - action(h_load_hit, "h", desc="Notify sequencer the load completed.") { + 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); } @@ -1297,6 +1307,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)); @@ -1308,6 +1320,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; @@ -1319,6 +1332,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)); @@ -1700,7 +1715,7 @@ machine(L1Cache, "Token protocol") } transition({S, SM, S_L, SM_L}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } @@ -1782,7 +1797,7 @@ machine(L1Cache, "Token protocol") // Transitions from Owned transition({O, OM}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } @@ -1872,7 +1887,7 @@ machine(L1Cache, "Token protocol") // Transitions from Modified transition({MM, MM_W}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } @@ -1947,7 +1962,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 303bf1784..88b7308ed 100644 --- a/src/mem/protocol/MOESI_hammer-cache.sm +++ b/src/mem/protocol/MOESI_hammer-cache.sm @@ -853,9 +853,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)); } @@ -865,7 +874,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); @@ -876,6 +886,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)); @@ -897,7 +908,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); @@ -910,7 +922,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); @@ -1504,7 +1517,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition({S, SM, ISM}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstHit; k_popMandatoryQueue; } @@ -1518,7 +1531,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition(SR, Ifetch, S) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstMiss; uu_profileL2Hit; k_popMandatoryQueue; @@ -1566,7 +1579,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; } @@ -1580,7 +1593,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition(OR, Ifetch, O) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstMiss; uu_profileL2Hit; k_popMandatoryQueue; @@ -1631,7 +1644,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; } @@ -1657,7 +1670,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition(MMR, Ifetch, MM) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstMiss; uu_profileL2Hit; k_popMandatoryQueue; @@ -1738,7 +1751,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 @@ -344,6 +344,14 @@ CacheMemory::setMRU(Addr address) } 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 { uint64_t warmedUpBlocks = 0; 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; |