changeset 7bf0a839c237 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=7bf0a839c237
description:
Resurrection of the CMP token protocol to GEM5
diffstat:
17 files changed, 1578 insertions(+), 336 deletions(-)
src/mem/protocol/MOESI_CMP_token-L1cache.sm | 351 +++++---
src/mem/protocol/MOESI_CMP_token-L2cache.sm | 174 ++--
src/mem/protocol/MOESI_CMP_token-dir.sm | 862 ++++++++++++++++++++--
src/mem/protocol/MOESI_CMP_token-dma.sm | 165 ++++
src/mem/protocol/MOESI_CMP_token-msg.sm | 54 +
src/mem/protocol/MOESI_CMP_token.slicc | 1
src/mem/protocol/RubySlicc_Util.sm | 1
src/mem/ruby/SConscript | 1
src/mem/ruby/common/NetDest.cc | 5
src/mem/ruby/common/NetDest.hh | 2
src/mem/ruby/config/MOESI_CMP_token.rb | 92 ++
src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb | 55 +
src/mem/ruby/config/cfg.rb | 1
src/mem/ruby/config/defaults.rb | 27
src/mem/ruby/system/PersistentTable.cc | 82 +-
src/mem/ruby/system/PersistentTable.hh | 40 -
src/mem/ruby/system/SConscript | 1
diffs (truncated from 3183 to 300 lines):
diff -r daf49a57df75 -r 7bf0a839c237 src/mem/protocol/MOESI_CMP_token-L1cache.sm
--- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm Wed Nov 18 16:34:32
2009 -0800
+++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm Wed Nov 18 16:34:33
2009 -0800
@@ -32,21 +32,32 @@
*
*/
-machine(L1Cache, "Token protocol") {
+machine(L1Cache, "Token protocol")
+ : int l1_request_latency,
+ int l1_response_latency,
+ int l2_select_low_bit,
+ int l2_select_num_bits,
+ int N_tokens,
+ int retry_threshold,
+ int fixed_timeout_latency,
+ bool dynamic_timeout_enabled
+{
// From this node's L1 cache TO the network
+
+ // a local L1 -> this L2 bank
+ MessageBuffer responseFromL1Cache, network="To", virtual_network="1",
ordered="false";
+ MessageBuffer persistentFromL1Cache, network="To", virtual_network="2",
ordered="true";
// a local L1 -> this L2 bank, currently ordered with directory forwarded
requests
- MessageBuffer requestFromL1Cache, network="To", virtual_network="0",
ordered="false";
- // a local L1 -> this L2 bank
- MessageBuffer responseFromL1Cache, network="To", virtual_network="2",
ordered="false";
- MessageBuffer persistentFromL1Cache, network="To", virtual_network="3",
ordered="true";
+ MessageBuffer requestFromL1Cache, network="To", virtual_network="4",
ordered="false";
+
// To this node's L1 cache FROM the network
// a L2 bank -> this L1
- MessageBuffer requestToL1Cache, network="From", virtual_network="0",
ordered="false";
+ MessageBuffer responseToL1Cache, network="From", virtual_network="1",
ordered="false";
+ MessageBuffer persistentToL1Cache, network="From", virtual_network="2",
ordered="true";
// a L2 bank -> this L1
- MessageBuffer responseToL1Cache, network="From", virtual_network="2",
ordered="false";
- MessageBuffer persistentToL1Cache, network="From", virtual_network="3",
ordered="true";
+ MessageBuffer requestToL1Cache, network="From", virtual_network="4",
ordered="false";
// STATES
enumeration(State, desc="Cache states", default="L1Cache_State_I") {
@@ -111,10 +122,6 @@
// TYPES
- int getRetryThreshold();
- int getFixedTimeoutLatency();
- bool getDynamicTimeoutEnabled();
-
// CacheEntry
structure(Entry, desc="...", interface="AbstractCacheEntry") {
State CacheState, desc="cache state";
@@ -143,7 +150,7 @@
external_type(CacheMemory) {
bool cacheAvail(Address);
Address cacheProbe(Address);
- void allocate(Address);
+ void allocate(Address, Entry);
void deallocate(Address);
Entry lookup(Address);
void changePermission(Address, AccessPermission);
@@ -157,17 +164,28 @@
bool isPresent(Address);
}
+ external_type(PersistentTable) {
+ void persistentRequestLock(Address, MachineID, AccessType);
+ void persistentRequestUnlock(Address, MachineID);
+ bool okToIssueStarving(Address, MachineID);
+ MachineID findSmallest(Address);
+ AccessType typeOfSmallest(Address);
+ void markEntries(Address);
+ bool isLocked(Address);
+ int countStarvingForAddress(Address);
+ int countReadStarvingForAddress(Address);
+ }
TBETable L1_TBEs, template_hack="<L1Cache_TBE>";
- CacheMemory L1IcacheMemory, template_hack="<L1Cache_Entry>",
constructor_hack='L1_CACHE_NUM_SETS_BITS,L1_CACHE_ASSOC,MachineType_L1Cache,int_to_string(i)+"_L1I"',
abstract_chip_ptr="true";
- CacheMemory L1DcacheMemory, template_hack="<L1Cache_Entry>",
constructor_hack='L1_CACHE_NUM_SETS_BITS,L1_CACHE_ASSOC,MachineType_L1Cache,int_to_string(i)+"_L1D"',
abstract_chip_ptr="true";
+ CacheMemory L1IcacheMemory, factory='RubySystem::getCache(m_cfg["icache"])';
+ CacheMemory L1DcacheMemory, factory='RubySystem::getCache(m_cfg["dcache"])';
MessageBuffer mandatoryQueue, ordered="false", abstract_chip_ptr="true";
- Sequencer sequencer, abstract_chip_ptr="true", constructor_hack="i";
+ Sequencer sequencer, factory='RubySystem::getSequencer(m_cfg["sequencer"])';
bool starving, default="false";
- PersistentTable persistentTable, constructor_hack="i";
+ PersistentTable persistentTable;
TimerTable useTimerTable;
TimerTable reissueTimerTable;
@@ -175,11 +193,11 @@
int outstandingPersistentRequests, default="0";
int averageLatencyHysteresis, default="(8)"; // Constant that provides
hysteresis for calculated the estimated average
- int averageLatencyCounter, default="(500 <<
(*m_L1Cache_averageLatencyHysteresis_vec[i]))";
+ int averageLatencyCounter, default="(500 <<
(*m_L1Cache_averageLatencyHysteresis_ptr))";
int averageLatencyEstimate() {
DEBUG_EXPR( (averageLatencyCounter >> averageLatencyHysteresis) );
- profile_average_latency_estimate( (averageLatencyCounter >>
averageLatencyHysteresis) );
+ //profile_average_latency_estimate( (averageLatencyCounter >>
averageLatencyHysteresis) );
return averageLatencyCounter >> averageLatencyHysteresis;
}
@@ -366,30 +384,33 @@
}
}
- GenericMachineType getNondirectHitMachType(Address addr, MachineID sender) {
- if (machineIDToMachineType(sender) == MachineType:L1Cache) {
- return GenericMachineType:L1Cache_wCC; // NOTE direct L1 hits should
not call this
- } else if (machineIDToMachineType(sender) == MachineType:L2Cache) {
- if ( sender == (map_L1CacheMachId_to_L2Cache(addr,machineID))) {
- return GenericMachineType:L2Cache;
- } else {
- return GenericMachineType:L2Cache_wCC;
- }
- } else {
- return ConvertMachToGenericMach(machineIDToMachineType(sender));
- }
- }
+// GenericMachineType getNondirectHitMachType(Address addr, MachineID sender)
{
+// if (machineIDToMachineType(sender) == MachineType:L1Cache) {
+// return GenericMachineType:L1Cache_wCC; // NOTE direct L1 hits should
not call this
+// } else if (machineIDToMachineType(sender) == MachineType:L2Cache) {
+//
+// if (sender == (mapAddressToRange(addr,
+// MachineType:L2Cache,
+// l2_select_low_bit,
+// l2_select_num_bits))) {
+//
+// return GenericMachineType:L2Cache;
+// } else {
+// return GenericMachineType:L2Cache_wCC;
+// }
+// } else {
+// return ConvertMachToGenericMach(machineIDToMachineType(sender));
+// }
+// }
- bool okToIssueStarving(Address addr) {
- return persistentTable.okToIssueStarving(addr);
+ bool okToIssueStarving(Address addr, MachineID machinID) {
+ return persistentTable.okToIssueStarving(addr, machineID);
}
void markPersistentEntries(Address addr) {
persistentTable.markEntries(addr);
}
- MessageBuffer triggerQueue, ordered="false", random="false";
-
// ** OUT_PORTS **
out_port(persistentNetwork_out, PersistentMsg, persistentFromL1Cache);
out_port(requestNetwork_out, RequestMsg, requestFromL1Cache);
@@ -507,7 +528,11 @@
// Mark TBE flag if response received off-chip. Use this to update
average latency estimate
if ( in_msg.SenderMachine == MachineType:L2Cache ) {
- if (in_msg.Sender == map_L1CacheMachId_to_L2Cache(in_msg.Address,
machineID)) {
+ if (in_msg.Sender == mapAddressToRange(in_msg.Address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits)) {
+
// came from an off-chip L2 cache
if (L1_TBEs.isPresent(in_msg.Address)) {
// L1_TBEs[in_msg.Address].ExternalResponse := true;
@@ -523,15 +548,15 @@
// profile_memory_response( in_msg.Address);
}
} else if ( in_msg.SenderMachine == MachineType:L1Cache) {
- if (isLocalProcessor(machineID, in_msg.Sender) == false) {
- if (L1_TBEs.isPresent(in_msg.Address)) {
+ //if (isLocalProcessor(machineID, in_msg.Sender) == false) {
+ //if (L1_TBEs.isPresent(in_msg.Address)) {
// L1_TBEs[in_msg.Address].ExternalResponse := true;
// profile_offchipL1_response(in_msg.Address );
- }
- }
- else {
+ //}
+ //}
+ //else {
// profile_onchipL1_response(in_msg.Address );
- }
+ //}
} else {
error("unexpected SenderMachine");
}
@@ -570,42 +595,42 @@
// ** INSTRUCTION ACCESS ***
// Check to see if it is in the OTHER L1
- if (L1DcacheMemory.isTagPresent(in_msg.Address)) {
+ if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) {
// The block is in the wrong L1, try to write it to the L2
- trigger(Event:L1_Replacement, in_msg.Address);
+ trigger(Event:L1_Replacement, in_msg.LineAddress);
}
- if (L1IcacheMemory.isTagPresent(in_msg.Address)) {
+ if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) {
// The tag matches for the L1, so the L1 fetches the line. We
know it can't be in the L2 due to exclusion
- trigger(mandatory_request_type_to_event(in_msg.Type),
in_msg.Address);
+ trigger(mandatory_request_type_to_event(in_msg.Type),
in_msg.LineAddress);
} else {
- if (L1IcacheMemory.cacheAvail(in_msg.Address)) {
+ if (L1IcacheMemory.cacheAvail(in_msg.LineAddress)) {
// L1 does't have the line, but we have space for it in the L1
- trigger(mandatory_request_type_to_event(in_msg.Type),
in_msg.Address);
+ trigger(mandatory_request_type_to_event(in_msg.Type),
in_msg.LineAddress);
} else {
// No room in the L1, so we need to make room
- trigger(Event:L1_Replacement,
L1IcacheMemory.cacheProbe(in_msg.Address));
+ trigger(Event:L1_Replacement,
L1IcacheMemory.cacheProbe(in_msg.LineAddress));
}
}
} else {
// *** DATA ACCESS ***
// Check to see if it is in the OTHER L1
- if (L1IcacheMemory.isTagPresent(in_msg.Address)) {
+ if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) {
// The block is in the wrong L1, try to write it to the L2
- trigger(Event:L1_Replacement, in_msg.Address);
+ trigger(Event:L1_Replacement, in_msg.LineAddress);
}
- if (L1DcacheMemory.isTagPresent(in_msg.Address)) {
+ if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) {
// The tag matches for the L1, so the L1 fetches the line. We
know it can't be in the L2 due to exclusion
- trigger(mandatory_request_type_to_event(in_msg.Type),
in_msg.Address);
+ trigger(mandatory_request_type_to_event(in_msg.Type),
in_msg.LineAddress);
} else {
- if (L1DcacheMemory.cacheAvail(in_msg.Address)) {
+ if (L1DcacheMemory.cacheAvail(in_msg.LineAddress)) {
// L1 does't have the line, but we have space for it in the L1
- trigger(mandatory_request_type_to_event(in_msg.Type),
in_msg.Address);
+ trigger(mandatory_request_type_to_event(in_msg.Type),
in_msg.LineAddress);
} else {
// No room in the L1, so we need to make room
- trigger(Event:L1_Replacement,
L1DcacheMemory.cacheProbe(in_msg.Address));
+ trigger(Event:L1_Replacement,
L1DcacheMemory.cacheProbe(in_msg.LineAddress));
}
}
}
@@ -618,19 +643,31 @@
action(a_issueReadRequest, "a", desc="Issue GETS") {
if (L1_TBEs[address].IssueCount == 0) {
// Update outstanding requests
- profile_outstanding_request(outstandingRequests);
+ //profile_outstanding_request(outstandingRequests);
outstandingRequests := outstandingRequests + 1;
}
- if (L1_TBEs[address].IssueCount >= getRetryThreshold() ) {
+ if (L1_TBEs[address].IssueCount >= retry_threshold) {
// Issue a persistent request if possible
- if (okToIssueStarving(address) && (starving == false)) {
- enqueue(persistentNetwork_out, PersistentMsg,
latency="L1_REQUEST_LATENCY") {
+ if (okToIssueStarving(address, machineID) && (starving == false)) {
+ enqueue(persistentNetwork_out, PersistentMsg, latency =
l1_request_latency) {
out_msg.Address := address;
out_msg.Type := PersistentRequestType:GETS_PERSISTENT;
out_msg.Requestor := machineID;
out_msg.Destination.broadcast(MachineType:L1Cache);
- out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));
+
+ //
+ // Currently the configuration system limits the system to only one
+ // chip. Therefore, if we assume one shared L2 cache, then only
one
+ // pertinent L2 cache exist.
+ //
+ //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));
+
+ out_msg.Destination.add(mapAddressToRange(address,
+ MachineType:L2Cache,
+ l2_select_low_bit,
+ l2_select_num_bits));
+
out_msg.Destination.add(map_Address_to_Directory(address));
out_msg.MessageSize := MessageSizeType:Persistent_Control;
out_msg.Prefetch := L1_TBEs[address].Prefetch;
@@ -640,11 +677,11 @@
starving := true;
if (L1_TBEs[address].IssueCount == 0) {
- profile_persistent_prediction(address,
L1_TBEs[address].AccessType);
+ //profile_persistent_prediction(address,
L1_TBEs[address].AccessType);
}
// Update outstanding requests
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev