diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mem/protocol/MI_example-cache.sm | 30 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_CMP_token-L1cache.sm | 51 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_hammer-cache.sm | 57 | ||||
-rw-r--r-- | src/mem/protocol/RubySlicc_ComponentMapping.sm | 1 | ||||
-rw-r--r-- | src/mem/protocol/RubySlicc_Exports.sm | 12 | ||||
-rw-r--r-- | src/mem/protocol/RubySlicc_Types.sm | 11 | ||||
-rw-r--r-- | src/mem/ruby/common/Histogram.cc | 7 | ||||
-rw-r--r-- | src/mem/ruby/profiler/Profiler.cc | 343 | ||||
-rw-r--r-- | src/mem/ruby/profiler/Profiler.hh | 37 | ||||
-rw-r--r-- | src/mem/ruby/system/Sequencer.cc | 183 | ||||
-rw-r--r-- | src/mem/ruby/system/Sequencer.hh | 126 | ||||
-rw-r--r-- | src/mem/slicc/ast/MachineAST.py | 21 | ||||
-rw-r--r-- | src/mem/slicc/parser.py | 8 | ||||
-rw-r--r-- | src/mem/slicc/symbols/Type.py | 36 |
14 files changed, 469 insertions, 454 deletions
diff --git a/src/mem/protocol/MI_example-cache.sm b/src/mem/protocol/MI_example-cache.sm index 2b505f047..8aed261fa 100644 --- a/src/mem/protocol/MI_example-cache.sm +++ b/src/mem/protocol/MI_example-cache.sm @@ -177,18 +177,6 @@ machine(L1Cache, "MI Example L1 Cache") return getCacheEntry(addr).DataBlk; } - GenericMachineType getNondirectHitMachType(MachineID sender) { - if (machineIDToMachineType(sender) == MachineType:L1Cache) { - // - // NOTE direct local hits should not call this - // - return GenericMachineType:L1Cache_wCC; - } else { - return ConvertMachToGenericMach(machineIDToMachineType(sender)); - } - } - - // NETWORK PORTS out_port(requestNetwork_out, RequestMsg, requestFromCache); @@ -347,36 +335,30 @@ 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); - sequencer.readCallback(address, - GenericMachineType:L1Cache, - cache_entry.DataBlk); + sequencer.readCallback(address, cache_entry.DataBlk, false); } action(rx_load_hit, "rx", desc="External load completed.") { peek(responseNetwork_in, ResponseMsg) { assert(is_valid(cache_entry)); DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk); - sequencer.readCallback(address, - getNondirectHitMachType(in_msg.Sender), - cache_entry.DataBlk); + sequencer.readCallback(address, cache_entry.DataBlk, true, + machineIDToMachineType(in_msg.Sender)); } } action(s_store_hit, "s", desc="Notify sequencer that store completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk); - sequencer.writeCallback(address, - GenericMachineType:L1Cache, - cache_entry.DataBlk); + sequencer.writeCallback(address, cache_entry.DataBlk, false); } action(sx_store_hit, "sx", desc="External store completed.") { peek(responseNetwork_in, ResponseMsg) { assert(is_valid(cache_entry)); DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk); - sequencer.writeCallback(address, - getNondirectHitMachType(in_msg.Sender), - cache_entry.DataBlk); + sequencer.writeCallback(address, cache_entry.DataBlk, true, + machineIDToMachineType(in_msg.Sender)); } } diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm index 91e4f355e..e472d0437 100644 --- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm @@ -399,26 +399,21 @@ machine(L1Cache, "Token protocol") } } - GenericMachineType getNondirectHitMachType(Address addr, MachineID sender) { + // NOTE: direct local hits should not call this function + bool isExternalHit(Address addr, MachineID sender) { if (machineIDToMachineType(sender) == MachineType:L1Cache) { - // - // NOTE direct local hits should not call this - // - return GenericMachineType:L1Cache_wCC; + return true; } else if (machineIDToMachineType(sender) == MachineType:L2Cache) { - if (sender == (mapAddressToRange(addr, - MachineType:L2Cache, - l2_select_low_bit, - l2_select_num_bits))) { - - return GenericMachineType:L2Cache; + if (sender == mapAddressToRange(addr, MachineType:L2Cache, + l2_select_low_bit, l2_select_num_bits)) { + return false; } else { - return GenericMachineType:L2Cache_wCC; + return true; } - } else { - return ConvertMachToGenericMach(machineIDToMachineType(sender)); } + + return true; } bool okToIssueStarving(Address addr, MachineID machineID) { @@ -1289,10 +1284,8 @@ machine(L1Cache, "Token protocol") DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n", address, cache_entry.DataBlk); - sequencer.readCallback(address, - GenericMachineType:L1Cache, - cache_entry.DataBlk); - + sequencer.readCallback(address, cache_entry.DataBlk, false, + MachineType:L1Cache); } action(x_external_load_hit, "x", desc="Notify sequencer the load completed.") { @@ -1300,11 +1293,9 @@ machine(L1Cache, "Token protocol") DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n", address, cache_entry.DataBlk); peek(responseNetwork_in, ResponseMsg) { - - sequencer.readCallback(address, - getNondirectHitMachType(address, in_msg.Sender), - cache_entry.DataBlk); - + sequencer.readCallback(address, cache_entry.DataBlk, + isExternalHit(address, in_msg.Sender), + machineIDToMachineType(in_msg.Sender)); } } @@ -1313,10 +1304,8 @@ machine(L1Cache, "Token protocol") DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n", address, cache_entry.DataBlk); - sequencer.writeCallback(address, - GenericMachineType:L1Cache, - cache_entry.DataBlk); - + sequencer.writeCallback(address, cache_entry.DataBlk, false, + MachineType:L1Cache); cache_entry.Dirty := true; DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); } @@ -1326,11 +1315,9 @@ machine(L1Cache, "Token protocol") DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n", address, cache_entry.DataBlk); peek(responseNetwork_in, ResponseMsg) { - - sequencer.writeCallback(address, - getNondirectHitMachType(address, in_msg.Sender), - cache_entry.DataBlk); - + sequencer.writeCallback(address, cache_entry.DataBlk, + isExternalHit(address, in_msg.Sender), + machineIDToMachineType(in_msg.Sender)); } cache_entry.Dirty := true; DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm index 8ffa2c2ac..b99a03098 100644 --- a/src/mem/protocol/MOESI_hammer-cache.sm +++ b/src/mem/protocol/MOESI_hammer-cache.sm @@ -33,7 +33,7 @@ * Brad Beckmann */ -machine(L1Cache, "AMD Hammer-like protocol") +machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") : Sequencer * sequencer, CacheMemory * L1Icache, CacheMemory * L1Dcache, @@ -288,24 +288,12 @@ machine(L1Cache, "AMD Hammer-like protocol") } } - GenericMachineType getNondirectHitMachType(Address addr, MachineID sender) { - if (machineIDToMachineType(sender) == MachineType:L1Cache) { - // - // NOTE direct local hits should not call this - // - return GenericMachineType:L1Cache_wCC; - } else { - return ConvertMachToGenericMach(machineIDToMachineType(sender)); - } - } - - GenericMachineType testAndClearLocalHit(Entry cache_entry) { + MachineType testAndClearLocalHit(Entry cache_entry) { if (is_valid(cache_entry) && cache_entry.FromL2) { cache_entry.FromL2 := false; - return GenericMachineType:L2Cache; - } else { - return GenericMachineType:L1Cache; + return MachineType:L2Cache; } + return MachineType:L1Cache; } bool IsAtomicAccessed(Entry cache_entry) { @@ -853,8 +841,8 @@ machine(L1Cache, "AMD Hammer-like protocol") action(h_load_hit, "h", desc="Notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); - sequencer.readCallback(address, testAndClearLocalHit(cache_entry), - cache_entry.DataBlk); + sequencer.readCallback(address, cache_entry.DataBlk, false, + testAndClearLocalHit(cache_entry)); } action(hx_external_load_hit, "hx", desc="load required external msgs") { @@ -863,12 +851,9 @@ machine(L1Cache, "AMD Hammer-like protocol") DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); peek(responseToCache_in, ResponseMsg) { - sequencer.readCallback(address, - getNondirectHitMachType(in_msg.Addr, in_msg.Sender), - cache_entry.DataBlk, - tbe.InitialRequestTime, - tbe.ForwardRequestTime, - tbe.FirstResponseTime); + sequencer.readCallback(address, cache_entry.DataBlk, true, + machineIDToMachineType(in_msg.Sender), tbe.InitialRequestTime, + tbe.ForwardRequestTime, tbe.FirstResponseTime); } } @@ -876,8 +861,8 @@ machine(L1Cache, "AMD Hammer-like protocol") assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); peek(mandatoryQueue_in, RubyRequest) { - sequencer.writeCallback(address, testAndClearLocalHit(cache_entry), - cache_entry.DataBlk); + sequencer.writeCallback(address, cache_entry.DataBlk, false, + testAndClearLocalHit(cache_entry)); cache_entry.Dirty := true; if (in_msg.Type == RubyRequestType:ATOMIC) { @@ -889,7 +874,7 @@ machine(L1Cache, "AMD Hammer-like protocol") action(hh_flush_hit, "\hf", desc="Notify sequencer that flush completed.") { assert(is_valid(tbe)); DPRINTF(RubySlicc, "%s\n", tbe.DataBlk); - sequencer.writeCallback(address, GenericMachineType:L1Cache,tbe.DataBlk); + sequencer.writeCallback(address, tbe.DataBlk, false, MachineType:L1Cache); } action(sx_external_store_hit, "sx", desc="store required external msgs.") { @@ -898,12 +883,9 @@ machine(L1Cache, "AMD Hammer-like protocol") DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); peek(responseToCache_in, ResponseMsg) { - sequencer.writeCallback(address, - getNondirectHitMachType(address, in_msg.Sender), - cache_entry.DataBlk, - tbe.InitialRequestTime, - tbe.ForwardRequestTime, - tbe.FirstResponseTime); + sequencer.writeCallback(address, cache_entry.DataBlk, true, + machineIDToMachineType(in_msg.Sender), tbe.InitialRequestTime, + tbe.ForwardRequestTime, tbe.FirstResponseTime); } DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); cache_entry.Dirty := true; @@ -914,12 +896,9 @@ machine(L1Cache, "AMD Hammer-like protocol") assert(is_valid(tbe)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); - sequencer.writeCallback(address, - getNondirectHitMachType(address, tbe.LastResponder), - cache_entry.DataBlk, - tbe.InitialRequestTime, - tbe.ForwardRequestTime, - tbe.FirstResponseTime); + sequencer.writeCallback(address, cache_entry.DataBlk, true, + machineIDToMachineType(tbe.LastResponder), tbe.InitialRequestTime, + tbe.ForwardRequestTime, tbe.FirstResponseTime); cache_entry.Dirty := true; } diff --git a/src/mem/protocol/RubySlicc_ComponentMapping.sm b/src/mem/protocol/RubySlicc_ComponentMapping.sm index 4f6f0e3d1..7c40901d7 100644 --- a/src/mem/protocol/RubySlicc_ComponentMapping.sm +++ b/src/mem/protocol/RubySlicc_ComponentMapping.sm @@ -38,4 +38,3 @@ NodeID map_Address_to_DirectoryNode(Address addr); NodeID machineIDToNodeID(MachineID machID); NodeID machineIDToVersion(MachineID machID); MachineType machineIDToMachineType(MachineID machID); -GenericMachineType ConvertMachToGenericMach(MachineType machType); diff --git a/src/mem/protocol/RubySlicc_Exports.sm b/src/mem/protocol/RubySlicc_Exports.sm index 015ae8cb3..e0371f896 100644 --- a/src/mem/protocol/RubySlicc_Exports.sm +++ b/src/mem/protocol/RubySlicc_Exports.sm @@ -168,18 +168,6 @@ enumeration(MemoryControlRequestType, desc="...", default="MemoryControlRequestT Default, desc="Replace this with access_types passed to the DMA Ruby object"; } -enumeration(GenericMachineType, desc="...", default="GenericMachineType_NULL") { - L1Cache, desc="L1 Cache Mach"; - L2Cache, desc="L2 Cache Mach"; - L3Cache, desc="L3 Cache Mach"; - Directory, desc="Directory Mach"; - DMA, desc="DMA Mach"; - Collector, desc="Collector Mach"; - L1Cache_wCC, desc="L1 Cache Mach with Cache Coherence (used for miss latency profile)"; - L2Cache_wCC, desc="L1 Cache Mach with Cache Coherence (used for miss latency profile)"; - NULL, desc="null mach type"; -} - // MessageSizeType enumeration(MessageSizeType, default="MessageSizeType_Undefined", desc="...") { Undefined, desc="Undefined"; diff --git a/src/mem/protocol/RubySlicc_Types.sm b/src/mem/protocol/RubySlicc_Types.sm index acd86a8fe..a601b2cfc 100644 --- a/src/mem/protocol/RubySlicc_Types.sm +++ b/src/mem/protocol/RubySlicc_Types.sm @@ -97,17 +97,18 @@ structure (NetDest, external = "yes", non_obj="yes") { structure (Sequencer, external = "yes") { void readCallback(Address, DataBlock); - void readCallback(Address, GenericMachineType, DataBlock); - void readCallback(Address, GenericMachineType, DataBlock, + void readCallback(Address, DataBlock, bool); + void readCallback(Address, DataBlock, bool, MachineType); + void readCallback(Address, DataBlock, bool, MachineType, Cycles, Cycles, Cycles); void writeCallback(Address, DataBlock); - void writeCallback(Address, GenericMachineType, DataBlock); - void writeCallback(Address, GenericMachineType, DataBlock, + void writeCallback(Address, DataBlock, bool); + void writeCallback(Address, DataBlock, bool, MachineType); + void writeCallback(Address, DataBlock, bool, MachineType, Cycles, Cycles, Cycles); void checkCoherence(Address); - void profileNack(Address, int, int, uint64); void evictionCallback(Address); void recordRequestType(SequencerRequestType); bool checkResourceAvailable(CacheResourceType, Address); diff --git a/src/mem/ruby/common/Histogram.cc b/src/mem/ruby/common/Histogram.cc index 0558e5198..e377bc253 100644 --- a/src/mem/ruby/common/Histogram.cc +++ b/src/mem/ruby/common/Histogram.cc @@ -124,7 +124,12 @@ Histogram::add(Histogram& hist) uint32_t t_bins = m_data.size(); if (hist.getBins() != t_bins) { - fatal("Histograms with different number of bins cannot be combined!"); + if (m_count == 0) { + m_data.resize(hist.getBins()); + } else { + fatal("Histograms with different number of bins " + "cannot be combined!"); + } } m_max = max(m_max, hist.getMax()); diff --git a/src/mem/ruby/profiler/Profiler.cc b/src/mem/ruby/profiler/Profiler.cc index 76c4dba74..9a963684f 100644 --- a/src/mem/ruby/profiler/Profiler.cc +++ b/src/mem/ruby/profiler/Profiler.cc @@ -213,6 +213,169 @@ Profiler::printOutstandingReqProfile(ostream &out) const } void +Profiler::printMissLatencyProfile(ostream &out) const +{ + // Collate the miss latencies histograms from all the sequencers + Histogram latency_hist; + std::vector<Histogram> type_latency_hist(RubyRequestType_NUM); + + Histogram hit_latency_hist; + std::vector<Histogram> hit_type_latency_hist(RubyRequestType_NUM); + + std::vector<Histogram> hit_mach_latency_hist(MachineType_NUM); + std::vector<std::vector<Histogram> > + hit_type_mach_latency_hist(RubyRequestType_NUM, + std::vector<Histogram>(MachineType_NUM)); + + Histogram miss_latency_hist; + std::vector<Histogram> miss_type_latency_hist(RubyRequestType_NUM); + + std::vector<Histogram> miss_mach_latency_hist(MachineType_NUM); + std::vector<std::vector<Histogram> > + miss_type_mach_latency_hist(RubyRequestType_NUM, + std::vector<Histogram>(MachineType_NUM)); + + std::vector<Histogram> issue_to_initial_delay_hist(MachineType_NUM); + std::vector<Histogram> initial_to_forward_delay_hist(MachineType_NUM); + std::vector<Histogram> + forward_to_first_response_delay_hist(MachineType_NUM); + std::vector<Histogram> + first_response_to_completion_delay_hist(MachineType_NUM); + std::vector<uint64_t> incomplete_times(MachineType_NUM); + + for (uint32_t i = 0; i < MachineType_NUM; i++) { + for (map<uint32_t, AbstractController*>::iterator it = + g_abs_controls[i].begin(); + it != g_abs_controls[i].end(); ++it) { + + AbstractController *ctr = (*it).second; + Sequencer *seq = ctr->getSequencer(); + if (seq != NULL) { + // add all the latencies + latency_hist.add(seq->getLatencyHist()); + hit_latency_hist.add(seq->getHitLatencyHist()); + miss_latency_hist.add(seq->getMissLatencyHist()); + + // add the per request type latencies + for (uint32_t j = 0; j < RubyRequestType_NUM; ++j) { + type_latency_hist[j] + .add(seq->getTypeLatencyHist(j)); + hit_type_latency_hist[j] + .add(seq->getHitTypeLatencyHist(j)); + miss_type_latency_hist[j] + .add(seq->getMissTypeLatencyHist(j)); + } + + // add the per machine type miss latencies + for (uint32_t j = 0; j < MachineType_NUM; ++j) { + hit_mach_latency_hist[j] + .add(seq->getHitMachLatencyHist(j)); + miss_mach_latency_hist[j] + .add(seq->getMissMachLatencyHist(j)); + + issue_to_initial_delay_hist[j].add( + seq->getIssueToInitialDelayHist(MachineType(j))); + + initial_to_forward_delay_hist[j].add( + seq->getInitialToForwardDelayHist(MachineType(j))); + forward_to_first_response_delay_hist[j].add(seq-> + getForwardRequestToFirstResponseHist(MachineType(j))); + + first_response_to_completion_delay_hist[j].add(seq-> + getFirstResponseToCompletionDelayHist(MachineType(j))); + incomplete_times[j] += + seq->getIncompleteTimes(MachineType(j)); + } + + // add the per (request, machine) type miss latencies + for (uint32_t j = 0; j < RubyRequestType_NUM; j++) { + for (uint32_t k = 0; k < MachineType_NUM; k++) { + hit_type_mach_latency_hist[j][k].add( + seq->getHitTypeMachLatencyHist(j,k)); + miss_type_mach_latency_hist[j][k].add( + seq->getMissTypeMachLatencyHist(j,k)); + } + } + } + } + } + + out << "latency: " << latency_hist << endl; + for (int i = 0; i < RubyRequestType_NUM; i++) { + if (type_latency_hist[i].size() > 0) { + out << "latency: " << RubyRequestType(i) << ": " + << type_latency_hist[i] << endl; + } + } + + out << "hit latency: " << hit_latency_hist << endl; + for (int i = 0; i < RubyRequestType_NUM; i++) { + if (hit_type_latency_hist[i].size() > 0) { + out << "hit latency: " << RubyRequestType(i) << ": " + << hit_type_latency_hist[i] << endl; + } + } + + for (int i = 0; i < MachineType_NUM; i++) { + if (hit_mach_latency_hist[i].size() > 0) { + out << "hit latency: " << MachineType(i) << ": " + << hit_mach_latency_hist[i] << endl; + } + } + + for (int i = 0; i < RubyRequestType_NUM; i++) { + for (int j = 0; j < MachineType_NUM; j++) { + if (hit_type_mach_latency_hist[i][j].size() > 0) { + out << "hit latency: " << RubyRequestType(i) + << ": " << MachineType(j) << ": " + << hit_type_mach_latency_hist[i][j] << endl; + } + } + } + + out << "miss latency: " << miss_latency_hist << endl; + for (int i = 0; i < RubyRequestType_NUM; i++) { + if (miss_type_latency_hist[i].size() > 0) { + out << "miss latency: " << RubyRequestType(i) << ": " + << miss_type_latency_hist[i] << endl; + } + } + + for (int i = 0; i < MachineType_NUM; i++) { + if (miss_mach_latency_hist[i].size() > 0) { + out << "miss latency: " << MachineType(i) << ": " + << miss_mach_latency_hist[i] << endl; + + out << "miss latency: " << MachineType(i) + << "::issue_to_initial_request: " + << issue_to_initial_delay_hist[i] << endl; + out << "miss latency: " << MachineType(i) + << "::initial_to_forward_request: " + << initial_to_forward_delay_hist[i] << endl; + out << "miss latency: " << MachineType(i) + << "::forward_to_first_response: " + << forward_to_first_response_delay_hist[i] << endl; + out << "miss latency: " << MachineType(i) + << "::first_response_to_completion: " + << first_response_to_completion_delay_hist[i] << endl; + out << "incomplete times: " << incomplete_times[i] << endl; + } + } + + for (int i = 0; i < RubyRequestType_NUM; i++) { + for (int j = 0; j < MachineType_NUM; j++) { + if (miss_type_mach_latency_hist[i][j].size() > 0) { + out << "miss latency: " << RubyRequestType(i) + << ": " << MachineType(j) << ": " + << miss_type_mach_latency_hist[i][j] << endl; + } + } + } + + out << endl; +} + +void Profiler::printStats(ostream& out, bool short_stats) { out << endl; @@ -296,68 +459,7 @@ Profiler::printStats(ostream& out, bool short_stats) if (!short_stats) { out << "All Non-Zero Cycle Demand Cache Accesses" << endl; out << "----------------------------------------" << endl; - out << "miss_latency: " << m_allMissLatencyHistogram << endl; - for (int i = 0; i < m_missLatencyHistograms.size(); i++) { - if (m_missLatencyHistograms[i].size() > 0) { - out << "miss_latency_" << RubyRequestType(i) << ": " - << m_missLatencyHistograms[i] << endl; - } - } - for (int i = 0; i < m_machLatencyHistograms.size(); i++) { - if (m_machLatencyHistograms[i].size() > 0) { - out << "miss_latency_" << GenericMachineType(i) << ": " - << m_machLatencyHistograms[i] << endl; - } - } - - out << "miss_latency_wCC_issue_to_initial_request: " - << m_wCCIssueToInitialRequestHistogram << endl; - out << "miss_latency_wCC_initial_forward_request: " - << m_wCCInitialRequestToForwardRequestHistogram << endl; - out << "miss_latency_wCC_forward_to_first_response: " - << m_wCCForwardRequestToFirstResponseHistogram << endl; - out << "miss_latency_wCC_first_response_to_completion: " - << m_wCCFirstResponseToCompleteHistogram << endl; - out << "imcomplete_wCC_Times: " << m_wCCIncompleteTimes << endl; - out << "miss_latency_dir_issue_to_initial_request: " - << m_dirIssueToInitialRequestHistogram << endl; - out << "miss_latency_dir_initial_forward_request: " - << m_dirInitialRequestToForwardRequestHistogram << endl; - out << "miss_latency_dir_forward_to_first_response: " - << m_dirForwardRequestToFirstResponseHistogram << endl; - out << "miss_latency_dir_first_response_to_completion: " - << m_dirFirstResponseToCompleteHistogram << endl; - out << "imcomplete_dir_Times: " << m_dirIncompleteTimes << endl; - - for (int i = 0; i < m_missMachLatencyHistograms.size(); i++) { - for (int j = 0; j < m_missMachLatencyHistograms[i].size(); j++) { - if (m_missMachLatencyHistograms[i][j].size() > 0) { - out << "miss_latency_" << RubyRequestType(i) - << "_" << GenericMachineType(j) << ": " - << m_missMachLatencyHistograms[i][j] << endl; - } - } - } - - out << endl; - - out << "All Non-Zero Cycle SW Prefetch Requests" << endl; - out << "------------------------------------" << endl; - out << "prefetch_latency: " << m_allSWPrefetchLatencyHistogram << endl; - for (int i = 0; i < m_SWPrefetchLatencyHistograms.size(); i++) { - if (m_SWPrefetchLatencyHistograms[i].size() > 0) { - out << "prefetch_latency_" << RubyRequestType(i) << ": " - << m_SWPrefetchLatencyHistograms[i] << endl; - } - } - for (int i = 0; i < m_SWPrefetchMachLatencyHistograms.size(); i++) { - if (m_SWPrefetchMachLatencyHistograms[i].size() > 0) { - out << "prefetch_latency_" << GenericMachineType(i) << ": " - << m_SWPrefetchMachLatencyHistograms[i] << endl; - } - } - out << "prefetch_latency_L2Miss:" - << m_SWPrefetchL2MissLatencyHistogram << endl; + printMissLatencyProfile(out); if (m_all_sharing_histogram.size() > 0) { out << "all_sharing: " << m_all_sharing_histogram << endl; @@ -434,44 +536,6 @@ Profiler::clearStats() m_real_time_start_time = time(NULL); m_busyBankCount = 0; - - m_missLatencyHistograms.resize(RubyRequestType_NUM); - for (int i = 0; i < m_missLatencyHistograms.size(); i++) { - m_missLatencyHistograms[i].clear(200); - } - m_machLatencyHistograms.resize(GenericMachineType_NUM+1); - for (int i = 0; i < m_machLatencyHistograms.size(); i++) { - m_machLatencyHistograms[i].clear(200); - } - m_missMachLatencyHistograms.resize(RubyRequestType_NUM); - for (int i = 0; i < m_missLatencyHistograms.size(); i++) { - m_missMachLatencyHistograms[i].resize(GenericMachineType_NUM+1); - for (int j = 0; j < m_missMachLatencyHistograms[i].size(); j++) { - m_missMachLatencyHistograms[i][j].clear(200); - } - } - m_allMissLatencyHistogram.clear(200); - m_wCCIssueToInitialRequestHistogram.clear(200); - m_wCCInitialRequestToForwardRequestHistogram.clear(200); - m_wCCForwardRequestToFirstResponseHistogram.clear(200); - m_wCCFirstResponseToCompleteHistogram.clear(200); - m_wCCIncompleteTimes = 0; - m_dirIssueToInitialRequestHistogram.clear(200); - m_dirInitialRequestToForwardRequestHistogram.clear(200); - m_dirForwardRequestToFirstResponseHistogram.clear(200); - m_dirFirstResponseToCompleteHistogram.clear(200); - m_dirIncompleteTimes = 0; - - m_SWPrefetchLatencyHistograms.resize(RubyRequestType_NUM); - for (int i = 0; i < m_SWPrefetchLatencyHistograms.size(); i++) { - m_SWPrefetchLatencyHistograms[i].clear(200); - } - m_SWPrefetchMachLatencyHistograms.resize(GenericMachineType_NUM+1); - for (int i = 0; i < m_SWPrefetchMachLatencyHistograms.size(); i++) { - m_SWPrefetchMachLatencyHistograms[i].clear(200); - } - m_allSWPrefetchLatencyHistogram.clear(200); - m_read_sharing_histogram.clear(); m_write_sharing_histogram.clear(); m_all_sharing_histogram.clear(); @@ -530,85 +594,6 @@ Profiler::bankBusy() m_busyBankCount++; } -// non-zero cycle demand request -void -Profiler::missLatency(Cycles cycles, - RubyRequestType type, - const GenericMachineType respondingMach) -{ - m_allMissLatencyHistogram.add(cycles); - m_missLatencyHistograms[type].add(cycles); - m_machLatencyHistograms[respondingMach].add(cycles); - m_missMachLatencyHistograms[type][respondingMach].add(cycles); -} - -void -Profiler::missLatencyWcc(Cycles issuedTime, - Cycles initialRequestTime, - Cycles forwardRequestTime, - Cycles firstResponseTime, - Cycles completionTime) -{ - if ((issuedTime <= initialRequestTime) && - (initialRequestTime <= forwardRequestTime) && - (forwardRequestTime <= firstResponseTime) && - (firstResponseTime <= completionTime)) { - m_wCCIssueToInitialRequestHistogram.add(initialRequestTime - issuedTime); - - m_wCCInitialRequestToForwardRequestHistogram.add(forwardRequestTime - - initialRequestTime); - - m_wCCForwardRequestToFirstResponseHistogram.add(firstResponseTime - - forwardRequestTime); - - m_wCCFirstResponseToCompleteHistogram.add(completionTime - - firstResponseTime); - } else { - m_wCCIncompleteTimes++; - } -} - -void -Profiler::missLatencyDir(Cycles issuedTime, - Cycles initialRequestTime, - Cycles forwardRequestTime, - Cycles firstResponseTime, - Cycles completionTime) -{ - if ((issuedTime <= initialRequestTime) && - (initialRequestTime <= forwardRequestTime) && - (forwardRequestTime <= firstResponseTime) && - (firstResponseTime <= completionTime)) { - m_dirIssueToInitialRequestHistogram.add(initialRequestTime - issuedTime); - - m_dirInitialRequestToForwardRequestHistogram.add(forwardRequestTime - - initialRequestTime); - - m_dirForwardRequestToFirstResponseHistogram.add(firstResponseTime - - forwardRequestTime); - - m_dirFirstResponseToCompleteHistogram.add(completionTime - - firstResponseTime); - } else { - m_dirIncompleteTimes++; - } -} - -// non-zero cycle prefetch request -void -Profiler::swPrefetchLatency(Cycles cycles, RubyRequestType type, - const GenericMachineType respondingMach) -{ - m_allSWPrefetchLatencyHistogram.add(cycles); - m_SWPrefetchLatencyHistograms[type].add(cycles); - m_SWPrefetchMachLatencyHistograms[respondingMach].add(cycles); - - if (respondingMach == GenericMachineType_Directory || - respondingMach == GenericMachineType_NUM) { - m_SWPrefetchL2MissLatencyHistogram.add(cycles); - } -} - // Helper function static double process_memory_total() diff --git a/src/mem/ruby/profiler/Profiler.hh b/src/mem/ruby/profiler/Profiler.hh index 23efed67a..e7b3c5f8d 100644 --- a/src/mem/ruby/profiler/Profiler.hh +++ b/src/mem/ruby/profiler/Profiler.hh @@ -52,7 +52,6 @@ #include "base/hashmap.hh" #include "mem/protocol/AccessType.hh" -#include "mem/protocol/GenericMachineType.hh" #include "mem/protocol/PrefetchBit.hh" #include "mem/protocol/RubyAccessMode.hh" #include "mem/protocol/RubyRequestType.hh" @@ -110,21 +109,7 @@ class Profiler : public SimObject void controllerBusy(MachineID machID); void bankBusy(); - - void missLatency(Cycles t, RubyRequestType type, - const GenericMachineType respondingMach); - - void missLatencyWcc(Cycles issuedTime, Cycles initialRequestTime, - Cycles forwardRequestTime, Cycles firstResponseTime, - Cycles completionTime); - - void missLatencyDir(Cycles issuedTime, Cycles initialRequestTime, - Cycles forwardRequestTime, Cycles firstResponseTime, - Cycles completionTime); - void swPrefetchLatency(Cycles t, RubyRequestType type, - const GenericMachineType respondingMach); - void print(std::ostream& out) const; void rubyWatch(int proc); @@ -141,6 +126,7 @@ class Profiler : public SimObject void printRequestProfile(std::ostream &out) const; void printDelayProfile(std::ostream &out) const; void printOutstandingReqProfile(std::ostream &out) const; + void printMissLatencyProfile(std::ostream &out) const; private: // Private copy constructor and assignment operator @@ -161,27 +147,6 @@ class Profiler : public SimObject int64 m_cache_to_cache; int64 m_memory_to_cache; - std::vector<Histogram> m_missLatencyHistograms; - std::vector<Histogram> m_machLatencyHistograms; - std::vector< std::vector<Histogram> > m_missMachLatencyHistograms; - Histogram m_wCCIssueToInitialRequestHistogram; - Histogram m_wCCInitialRequestToForwardRequestHistogram; - Histogram m_wCCForwardRequestToFirstResponseHistogram; - Histogram m_wCCFirstResponseToCompleteHistogram; - int64 m_wCCIncompleteTimes; - Histogram m_dirIssueToInitialRequestHistogram; - Histogram m_dirInitialRequestToForwardRequestHistogram; - Histogram m_dirForwardRequestToFirstResponseHistogram; - Histogram m_dirFirstResponseToCompleteHistogram; - int64 m_dirIncompleteTimes; - - Histogram m_allMissLatencyHistogram; - - Histogram m_allSWPrefetchLatencyHistogram; - Histogram m_SWPrefetchL2MissLatencyHistogram; - std::vector<Histogram> m_SWPrefetchLatencyHistograms; - std::vector<Histogram> m_SWPrefetchMachLatencyHistograms; - Histogram m_average_latency_estimate; m5::hash_set<Address> m_watch_address_set; diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index 606dff0ab..8e61766b8 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -136,6 +136,61 @@ Sequencer::wakeup() void Sequencer::clearStats() { m_outstandReqHist.clear(); + + // Initialize the histograms that track latency of all requests + m_latencyHist.clear(20); + m_typeLatencyHist.resize(RubyRequestType_NUM); + for (int i = 0; i < RubyRequestType_NUM; i++) { + m_typeLatencyHist[i].clear(20); + } + + // Initialize the histograms that track latency of requests that + // hit in the cache attached to the sequencer. + m_hitLatencyHist.clear(20); + m_hitTypeLatencyHist.resize(RubyRequestType_NUM); + m_hitTypeMachLatencyHist.resize(RubyRequestType_NUM); + + for (int i = 0; i < RubyRequestType_NUM; i++) { + m_hitTypeLatencyHist[i].clear(20); + m_hitTypeMachLatencyHist[i].resize(MachineType_NUM); + for (int j = 0; j < MachineType_NUM; j++) { + m_hitTypeMachLatencyHist[i][j].clear(20); + } + } + + // Initialize the histograms that track the latency of requests that + // missed in the cache attached to the sequencer. + m_missLatencyHist.clear(20); + m_missTypeLatencyHist.resize(RubyRequestType_NUM); + m_missTypeMachLatencyHist.resize(RubyRequestType_NUM); + + for (int i = 0; i < RubyRequestType_NUM; i++) { + m_missTypeLatencyHist[i].clear(20); + m_missTypeMachLatencyHist[i].resize(MachineType_NUM); + for (int j = 0; j < MachineType_NUM; j++) { + m_missTypeMachLatencyHist[i][j].clear(20); + } + } + + m_hitMachLatencyHist.resize(MachineType_NUM); + m_missMachLatencyHist.resize(MachineType_NUM); + m_IssueToInitialDelayHist.resize(MachineType_NUM); + m_InitialToForwardDelayHist.resize(MachineType_NUM); + m_ForwardToFirstResponseDelayHist.resize(MachineType_NUM); + m_FirstResponseToCompletionDelayHist.resize(MachineType_NUM); + m_IncompleteTimes.resize(MachineType_NUM); + + for (int i = 0; i < MachineType_NUM; i++) { + m_missMachLatencyHist[i].clear(20); + m_hitMachLatencyHist[i].clear(20); + + m_IssueToInitialDelayHist[i].clear(20); + m_InitialToForwardDelayHist[i].clear(20); + m_ForwardToFirstResponseDelayHist[i].clear(20); + m_FirstResponseToCompletionDelayHist[i].clear(20); + + m_IncompleteTimes[i] = 0; + } } void @@ -370,26 +425,58 @@ Sequencer::handleLlsc(const Address& address, SequencerRequest* request) } void -Sequencer::writeCallback(const Address& address, DataBlock& data) +Sequencer::recordMissLatency(const Cycles cycles, const RubyRequestType type, + const MachineType respondingMach, + bool isExternalHit, Cycles issuedTime, + Cycles initialRequestTime, + Cycles forwardRequestTime, + Cycles firstResponseTime, Cycles completionTime) { - writeCallback(address, GenericMachineType_NULL, data); -} + m_latencyHist.add(cycles); + m_typeLatencyHist[type].add(cycles); + + if (isExternalHit) { + m_missLatencyHist.add(cycles); + m_missTypeLatencyHist[type].add(cycles); + + if (respondingMach != MachineType_NUM) { + m_missMachLatencyHist[respondingMach].add(cycles); + m_missTypeMachLatencyHist[type][respondingMach].add(cycles); + + if ((issuedTime <= initialRequestTime) && + (initialRequestTime <= forwardRequestTime) && + (forwardRequestTime <= firstResponseTime) && + (firstResponseTime <= completionTime)) { + + m_IssueToInitialDelayHist[respondingMach].add( + initialRequestTime - issuedTime); + m_InitialToForwardDelayHist[respondingMach].add( + forwardRequestTime - initialRequestTime); + m_ForwardToFirstResponseDelayHist[respondingMach].add( + firstResponseTime - forwardRequestTime); + m_FirstResponseToCompletionDelayHist[respondingMach].add( + completionTime - firstResponseTime); + } else { + m_IncompleteTimes[respondingMach]++; + } + } + } else { + m_hitLatencyHist.add(cycles); + m_hitTypeLatencyHist[type].add(cycles); -void -Sequencer::writeCallback(const Address& address, - GenericMachineType mach, - DataBlock& data) -{ - writeCallback(address, mach, data, Cycles(0), Cycles(0), Cycles(0)); + if (respondingMach != MachineType_NUM) { + m_hitMachLatencyHist[respondingMach].add(cycles); + m_hitTypeMachLatencyHist[type][respondingMach].add(cycles); + } + } } void -Sequencer::writeCallback(const Address& address, - GenericMachineType mach, - DataBlock& data, - Cycles initialRequestTime, - Cycles forwardRequestTime, - Cycles firstResponseTime) +Sequencer::writeCallback(const Address& address, DataBlock& data, + const bool externalHit, const MachineType mach, + const Cycles initialRequestTime, + const Cycles forwardRequestTime, + const Cycles firstResponseTime) { assert(address == line_address(address)); assert(m_writeRequestTable.count(line_address(address))); @@ -427,28 +514,13 @@ Sequencer::writeCallback(const Address& address, m_controller->unblock(address); } - hitCallback(request, mach, data, success, + hitCallback(request, data, success, mach, externalHit, initialRequestTime, forwardRequestTime, firstResponseTime); } void -Sequencer::readCallback(const Address& address, DataBlock& data) -{ - readCallback(address, GenericMachineType_NULL, data); -} - -void -Sequencer::readCallback(const Address& address, - GenericMachineType mach, - DataBlock& data) -{ - readCallback(address, mach, data, Cycles(0), Cycles(0), Cycles(0)); -} - -void -Sequencer::readCallback(const Address& address, - GenericMachineType mach, - DataBlock& data, +Sequencer::readCallback(const Address& address, DataBlock& data, + bool externalHit, const MachineType mach, Cycles initialRequestTime, Cycles forwardRequestTime, Cycles firstResponseTime) @@ -466,18 +538,17 @@ Sequencer::readCallback(const Address& address, assert((request->m_type == RubyRequestType_LD) || (request->m_type == RubyRequestType_IFETCH)); - hitCallback(request, mach, data, true, + hitCallback(request, data, true, mach, externalHit, initialRequestTime, forwardRequestTime, firstResponseTime); } void -Sequencer::hitCallback(SequencerRequest* srequest, - GenericMachineType mach, - DataBlock& data, - bool success, - Cycles initialRequestTime, - Cycles forwardRequestTime, - Cycles firstResponseTime) +Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data, + bool llscSuccess, + const MachineType mach, const bool externalHit, + const Cycles initialRequestTime, + const Cycles forwardRequestTime, + const Cycles firstResponseTime) { PacketPtr pkt = srequest->pkt; Address request_address(pkt->getAddr()); @@ -494,29 +565,17 @@ Sequencer::hitCallback(SequencerRequest* srequest, } assert(curCycle() >= issued_time); - Cycles miss_latency = curCycle() - issued_time; - - // Profile the miss latency for all non-zero demand misses - if (miss_latency != 0) { - g_system_ptr->getProfiler()->missLatency(miss_latency, type, mach); + Cycles total_latency = curCycle() - issued_time; - if (mach == GenericMachineType_L1Cache_wCC) { - g_system_ptr->getProfiler()->missLatencyWcc(issued_time, - initialRequestTime, forwardRequestTime, - firstResponseTime, curCycle()); - } - - if (mach == GenericMachineType_Directory) { - g_system_ptr->getProfiler()->missLatencyDir(issued_time, - initialRequestTime, forwardRequestTime, - firstResponseTime, curCycle()); - } + // Profile the latency for all demand accesses. + recordMissLatency(total_latency, type, mach, externalHit, issued_time, + initialRequestTime, forwardRequestTime, + firstResponseTime, curCycle()); - DPRINTFR(ProtocolTrace, "%15s %3s %10s%20s %6s>%-6s %s %d cycles\n", - curTick(), m_version, "Seq", - success ? "Done" : "SC_Failed", "", "", - request_address, miss_latency); - } + DPRINTFR(ProtocolTrace, "%15s %3s %10s%20s %6s>%-6s %s %d cycles\n", + curTick(), m_version, "Seq", + llscSuccess ? "Done" : "SC_Failed", "", "", + request_address, total_latency); // update the data if (g_system_ptr->m_warmup_enabled) { diff --git a/src/mem/ruby/system/Sequencer.hh b/src/mem/ruby/system/Sequencer.hh index 058edb9ce..86e6aa2a9 100644 --- a/src/mem/ruby/system/Sequencer.hh +++ b/src/mem/ruby/system/Sequencer.hh @@ -32,7 +32,7 @@ #include <iostream> #include "base/hashmap.hh" -#include "mem/protocol/GenericMachineType.hh" +#include "mem/protocol/MachineType.hh" #include "mem/protocol/RubyRequestType.hh" #include "mem/protocol/SequencerRequestType.hh" #include "mem/ruby/common/Address.hh" @@ -65,36 +65,24 @@ class Sequencer : public RubyPort // Public Methods void wakeup(); // Used only for deadlock detection - void printProgress(std::ostream& out) const; - void clearStats(); - void writeCallback(const Address& address, DataBlock& data); - void writeCallback(const Address& address, - GenericMachineType mach, - DataBlock& data); - - void writeCallback(const Address& address, - GenericMachineType mach, DataBlock& data, - Cycles initialRequestTime, - Cycles forwardRequestTime, - Cycles firstResponseTime); - - void readCallback(const Address& address, DataBlock& data); + const bool externalHit = false, + const MachineType mach = MachineType_NUM, + const Cycles initialRequestTime = Cycles(0), + const Cycles forwardRequestTime = Cycles(0), + const Cycles firstResponseTime = Cycles(0)); void readCallback(const Address& address, - GenericMachineType mach, - DataBlock& data); - - void readCallback(const Address& address, - GenericMachineType mach, DataBlock& data, - Cycles initialRequestTime, - Cycles forwardRequestTime, - Cycles firstResponseTime); + const bool externalHit = false, + const MachineType mach = MachineType_NUM, + const Cycles initialRequestTime = Cycles(0), + const Cycles forwardRequestTime = Cycles(0), + const Cycles firstResponseTime = Cycles(0)); RequestStatus makeRequest(PacketPtr pkt); bool empty() const; @@ -118,19 +106,63 @@ class Sequencer : public RubyPort void recordRequestType(SequencerRequestType requestType); Histogram& getOutstandReqHist() { return m_outstandReqHist; } + Histogram& getLatencyHist() { return m_latencyHist; } + Histogram& getTypeLatencyHist(uint32_t t) + { return m_typeLatencyHist[t]; } + + Histogram& getHitLatencyHist() { return m_hitLatencyHist; } + Histogram& getHitTypeLatencyHist(uint32_t t) + { return m_hitTypeLatencyHist[t]; } + + Histogram& getHitMachLatencyHist(uint32_t t) + { return m_hitMachLatencyHist[t]; } + + Histogram& getHitTypeMachLatencyHist(uint32_t r, uint32_t t) + { return m_hitTypeMachLatencyHist[r][t]; } + + Histogram& getMissLatencyHist() { return m_missLatencyHist; } + Histogram& getMissTypeLatencyHist(uint32_t t) + { return m_missTypeLatencyHist[t]; } + + Histogram& getMissMachLatencyHist(uint32_t t) + { return m_missMachLatencyHist[t]; } + + Histogram& getMissTypeMachLatencyHist(uint32_t r, uint32_t t) + { return m_missTypeMachLatencyHist[r][t]; } + + Histogram& getIssueToInitialDelayHist(uint32_t t) + { return m_IssueToInitialDelayHist[t]; } + + Histogram& getInitialToForwardDelayHist(const MachineType t) + { return m_InitialToForwardDelayHist[t]; } + + Histogram& getForwardRequestToFirstResponseHist(const MachineType t) + { return m_ForwardToFirstResponseDelayHist[t]; } + + Histogram& getFirstResponseToCompletionDelayHist(const MachineType t) + { return m_FirstResponseToCompletionDelayHist[t]; } + + const uint64_t getIncompleteTimes(const MachineType t) const + { return m_IncompleteTimes[t]; } + private: void issueRequest(PacketPtr pkt, RubyRequestType type); - void hitCallback(SequencerRequest* request, - GenericMachineType mach, - DataBlock& data, - bool success, - Cycles initialRequestTime, - Cycles forwardRequestTime, - Cycles firstResponseTime); + void hitCallback(SequencerRequest* request, DataBlock& data, + bool llscSuccess, + const MachineType mach, const bool externalHit, + const Cycles initialRequestTime, + const Cycles forwardRequestTime, + const Cycles firstResponseTime); - RequestStatus insertRequest(PacketPtr pkt, RubyRequestType request_type); + void recordMissLatency(const Cycles t, const RubyRequestType type, + const MachineType respondingMach, + bool isExternalHit, Cycles issuedTime, + Cycles initialRequestTime, + Cycles forwardRequestTime, Cycles firstResponseTime, + Cycles completionTime); + RequestStatus insertRequest(PacketPtr pkt, RubyRequestType request_type); bool handleLlsc(const Address& address, SequencerRequest* request); // Private copy constructor and assignment operator @@ -161,6 +193,38 @@ class Sequencer : public RubyPort //! Histogram for number of outstanding requests per cycle. Histogram m_outstandReqHist; + //! Histogram for holding latency profile of all requests. + Histogram m_latencyHist; + std::vector<Histogram> m_typeLatencyHist; + + //! Histogram for holding latency profile of all requests that + //! hit in the controller connected to this sequencer. + Histogram m_hitLatencyHist; + std::vector<Histogram> m_hitTypeLatencyHist; + + //! Histograms for profiling the latencies for requests that + //! did not required external messages. + std::vector<Histogram> m_hitMachLatencyHist; + std::vector< std::vector<Histogram> > m_hitTypeMachLatencyHist; + + //! Histogram for holding latency profile of all requests that + //! miss in the controller connected to this sequencer. + Histogram m_missLatencyHist; + std::vector<Histogram> m_missTypeLatencyHist; + + //! Histograms for profiling the latencies for requests that + //! required external messages. + std::vector<Histogram> m_missMachLatencyHist; + std::vector< std::vector<Histogram> > m_missTypeMachLatencyHist; + + //! Histograms for recording the breakdown of miss latency + std::vector<Histogram> m_IssueToInitialDelayHist; + std::vector<Histogram> m_InitialToForwardDelayHist; + std::vector<Histogram> m_ForwardToFirstResponseDelayHist; + std::vector<Histogram> m_FirstResponseToCompletionDelayHist; + std::vector<uint64_t> m_IncompleteTimes; + + class SequencerWakeupEvent : public Event { private: diff --git a/src/mem/slicc/ast/MachineAST.py b/src/mem/slicc/ast/MachineAST.py index d494cb7ce..5d14f7688 100644 --- a/src/mem/slicc/ast/MachineAST.py +++ b/src/mem/slicc/ast/MachineAST.py @@ -29,10 +29,11 @@ from slicc.ast.DeclAST import DeclAST from slicc.symbols import StateMachine, Type class MachineAST(DeclAST): - def __init__(self, slicc, ident, pairs_ast, config_parameters, decls): + def __init__(self, slicc, idents, pairs_ast, config_parameters, decls): super(MachineAST, self).__init__(slicc, pairs_ast) - self.ident = ident + self.ident = idents[0] + self.machine_types = idents self.pairs_ast = pairs_ast self.config_parameters = config_parameters self.decls = decls @@ -71,10 +72,18 @@ class MachineAST(DeclAST): def findMachines(self): # Add to MachineType enumeration - machine_type = self.symtab.find("MachineType", Type) - if not machine_type.addEnum(self.ident, self.pairs_ast.pairs): - self.error("Duplicate machine name: %s:%s" % (machine_type, - self.ident)) + for mtype in self.machine_types: + machine_type = self.symtab.find("MachineType", Type) + pairs = self.pairs_ast.pairs + + if mtype == self.ident: + pairs["Primary"] = True + else: + pairs["Primary"] = False + + if not machine_type.addEnum(mtype, pairs): + self.error("Duplicate machine name: %s:%s" % ( + machine_type, mtype)) # Generate code for all the internal decls self.decls.findMachines() diff --git a/src/mem/slicc/parser.py b/src/mem/slicc/parser.py index 96e029ecf..aa96ceef1 100644 --- a/src/mem/slicc/parser.py +++ b/src/mem/slicc/parser.py @@ -258,8 +258,12 @@ class SLICC(Grammar): filename = os.path.join(self.base_dir, p[2]) p[0] = self.parse_file(filename) - def p_decl__machine(self, p): - "decl : MACHINE '(' ident pairs ')' ':' params '{' decls '}'" + def p_decl__machine0(self, p): + "decl : MACHINE '(' idents ')' ':' params '{' decls '}'" + p[0] = ast.MachineAST(self, p[3], [], p[7], p[9]) + + def p_decl__machine1(self, p): + "decl : MACHINE '(' idents pairs ')' ':' params '{' decls '}'" p[0] = ast.MachineAST(self, p[3], p[4], p[7], p[9]) def p_decl__action(self, p): diff --git a/src/mem/slicc/symbols/Type.py b/src/mem/slicc/symbols/Type.py index 1c2177ce1..29b68f2c5 100644 --- a/src/mem/slicc/symbols/Type.py +++ b/src/mem/slicc/symbols/Type.py @@ -477,7 +477,6 @@ ${{self.c_ident}}::print(ostream& out) const if self.isMachineType: code('#include "base/misc.hh"') - code('#include "mem/protocol/GenericMachineType.hh"') code('#include "mem/ruby/common/Address.hh"') code('struct MachineID;') @@ -534,23 +533,6 @@ MachineID map_Address_to_DMA(const Address &addr); MachineID get${{enum.ident}}MachineID(NodeID RubyNode); ''') - code(''' -inline GenericMachineType -ConvertMachToGenericMach(MachineType machType) -{ -''') - for enum in self.enums.itervalues(): - genericType = self.enums[enum.ident].get('genericType', - enum.ident) - code(''' - if (machType == MachineType_${{enum.ident}}) - return GenericMachineType_${{genericType}}; -''') - code(''' - panic("cannot convert to a GenericMachineType"); -} -''') - if self.isStateDecl: code(''' @@ -610,7 +592,8 @@ AccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj) if self.isMachineType: for enum in self.enums.itervalues(): - code('#include "mem/protocol/${{enum.ident}}_Controller.hh"') + if enum.get("Primary"): + code('#include "mem/protocol/${{enum.ident}}_Controller.hh"') code('#include "mem/ruby/system/MachineID.hh"') code(''' @@ -747,7 +730,11 @@ ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj) code.indent() code(' case ${{self.c_ident}}_NUM:') for enum in reversed(self.enums.values()): - code(' base += ${{enum.ident}}_Controller::getNumControllers();') + # Check if there is a defined machine with this type + if enum.get("Primary"): + code(' base += ${{enum.ident}}_Controller::getNumControllers();') + else: + code(' base += 0;') code(' case ${{self.c_ident}}_${{enum.ident}}:') code(' break;') code.dedent() @@ -771,10 +758,11 @@ ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj) # For each field for enum in self.enums.itervalues(): - code(''' - case ${{self.c_ident}}_${{enum.ident}}: - return ${{enum.ident}}_Controller::getNumControllers(); -''') + code('case ${{self.c_ident}}_${{enum.ident}}:') + if enum.get("Primary"): + code('return ${{enum.ident}}_Controller::getNumControllers();') + else: + code('return 0;') # total num code(''' |