base.cc revision 10821:581fb2484bd6
1/*
2 * Copyright (c) 2012-2013 ARM Limited
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2003-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Erik Hallnor
41 */
42
43/**
44 * @file
45 * Definition of BaseCache functions.
46 */
47
48#include "debug/Cache.hh"
49#include "debug/Drain.hh"
50#include "mem/cache/tags/fa_lru.hh"
51#include "mem/cache/tags/lru.hh"
52#include "mem/cache/tags/random_repl.hh"
53#include "mem/cache/base.hh"
54#include "mem/cache/cache.hh"
55#include "mem/cache/mshr.hh"
56#include "sim/full_system.hh"
57
58using namespace std;
59
60BaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name,
61                                          BaseCache *_cache,
62                                          const std::string &_label)
63    : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label),
64      blocked(false), mustSendRetry(false), sendRetryEvent(this)
65{
66}
67
68BaseCache::BaseCache(const Params *p)
69    : MemObject(p),
70      cpuSidePort(nullptr), memSidePort(nullptr),
71      mshrQueue("MSHRs", p->mshrs, 4, p->demand_mshr_reserve, MSHRQueue_MSHRs),
72      writeBuffer("write buffer", p->write_buffers, p->mshrs+1000, 0,
73                  MSHRQueue_WriteBuffer),
74      blkSize(p->system->cacheLineSize()),
75      lookupLatency(p->hit_latency),
76      forwardLatency(p->hit_latency),
77      fillLatency(p->response_latency),
78      responseLatency(p->response_latency),
79      numTarget(p->tgts_per_mshr),
80      forwardSnoops(p->forward_snoops),
81      isTopLevel(p->is_top_level),
82      blocked(0),
83      order(0),
84      noTargetMSHR(NULL),
85      missCount(p->max_miss_count),
86      addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()),
87      system(p->system)
88{
89}
90
91void
92BaseCache::CacheSlavePort::setBlocked()
93{
94    assert(!blocked);
95    DPRINTF(CachePort, "Port is blocking new requests\n");
96    blocked = true;
97    // if we already scheduled a retry in this cycle, but it has not yet
98    // happened, cancel it
99    if (sendRetryEvent.scheduled()) {
100        owner.deschedule(sendRetryEvent);
101        DPRINTF(CachePort, "Port descheduled retry\n");
102        mustSendRetry = true;
103    }
104}
105
106void
107BaseCache::CacheSlavePort::clearBlocked()
108{
109    assert(blocked);
110    DPRINTF(CachePort, "Port is accepting new requests\n");
111    blocked = false;
112    if (mustSendRetry) {
113        // @TODO: need to find a better time (next cycle?)
114        owner.schedule(sendRetryEvent, curTick() + 1);
115    }
116}
117
118void
119BaseCache::CacheSlavePort::processSendRetry()
120{
121    DPRINTF(CachePort, "Port is sending retry\n");
122
123    // reset the flag and call retry
124    mustSendRetry = false;
125    sendRetryReq();
126}
127
128void
129BaseCache::init()
130{
131    if (!cpuSidePort->isConnected() || !memSidePort->isConnected())
132        fatal("Cache ports on %s are not connected\n", name());
133    cpuSidePort->sendRangeChange();
134}
135
136BaseMasterPort &
137BaseCache::getMasterPort(const std::string &if_name, PortID idx)
138{
139    if (if_name == "mem_side") {
140        return *memSidePort;
141    }  else {
142        return MemObject::getMasterPort(if_name, idx);
143    }
144}
145
146BaseSlavePort &
147BaseCache::getSlavePort(const std::string &if_name, PortID idx)
148{
149    if (if_name == "cpu_side") {
150        return *cpuSidePort;
151    } else {
152        return MemObject::getSlavePort(if_name, idx);
153    }
154}
155
156bool
157BaseCache::inRange(Addr addr) const
158{
159    for (const auto& r : addrRanges) {
160        if (r.contains(addr)) {
161            return true;
162       }
163    }
164    return false;
165}
166
167void
168BaseCache::regStats()
169{
170    using namespace Stats;
171
172    // Hit statistics
173    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
174        MemCmd cmd(access_idx);
175        const string &cstr = cmd.toString();
176
177        hits[access_idx]
178            .init(system->maxMasters())
179            .name(name() + "." + cstr + "_hits")
180            .desc("number of " + cstr + " hits")
181            .flags(total | nozero | nonan)
182            ;
183        for (int i = 0; i < system->maxMasters(); i++) {
184            hits[access_idx].subname(i, system->getMasterName(i));
185        }
186    }
187
188// These macros make it easier to sum the right subset of commands and
189// to change the subset of commands that are considered "demand" vs
190// "non-demand"
191#define SUM_DEMAND(s) \
192    (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
193
194// should writebacks be included here?  prior code was inconsistent...
195#define SUM_NON_DEMAND(s) \
196    (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
197
198    demandHits
199        .name(name() + ".demand_hits")
200        .desc("number of demand (read+write) hits")
201        .flags(total | nozero | nonan)
202        ;
203    demandHits = SUM_DEMAND(hits);
204    for (int i = 0; i < system->maxMasters(); i++) {
205        demandHits.subname(i, system->getMasterName(i));
206    }
207
208    overallHits
209        .name(name() + ".overall_hits")
210        .desc("number of overall hits")
211        .flags(total | nozero | nonan)
212        ;
213    overallHits = demandHits + SUM_NON_DEMAND(hits);
214    for (int i = 0; i < system->maxMasters(); i++) {
215        overallHits.subname(i, system->getMasterName(i));
216    }
217
218    // Miss statistics
219    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
220        MemCmd cmd(access_idx);
221        const string &cstr = cmd.toString();
222
223        misses[access_idx]
224            .init(system->maxMasters())
225            .name(name() + "." + cstr + "_misses")
226            .desc("number of " + cstr + " misses")
227            .flags(total | nozero | nonan)
228            ;
229        for (int i = 0; i < system->maxMasters(); i++) {
230            misses[access_idx].subname(i, system->getMasterName(i));
231        }
232    }
233
234    demandMisses
235        .name(name() + ".demand_misses")
236        .desc("number of demand (read+write) misses")
237        .flags(total | nozero | nonan)
238        ;
239    demandMisses = SUM_DEMAND(misses);
240    for (int i = 0; i < system->maxMasters(); i++) {
241        demandMisses.subname(i, system->getMasterName(i));
242    }
243
244    overallMisses
245        .name(name() + ".overall_misses")
246        .desc("number of overall misses")
247        .flags(total | nozero | nonan)
248        ;
249    overallMisses = demandMisses + SUM_NON_DEMAND(misses);
250    for (int i = 0; i < system->maxMasters(); i++) {
251        overallMisses.subname(i, system->getMasterName(i));
252    }
253
254    // Miss latency statistics
255    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
256        MemCmd cmd(access_idx);
257        const string &cstr = cmd.toString();
258
259        missLatency[access_idx]
260            .init(system->maxMasters())
261            .name(name() + "." + cstr + "_miss_latency")
262            .desc("number of " + cstr + " miss cycles")
263            .flags(total | nozero | nonan)
264            ;
265        for (int i = 0; i < system->maxMasters(); i++) {
266            missLatency[access_idx].subname(i, system->getMasterName(i));
267        }
268    }
269
270    demandMissLatency
271        .name(name() + ".demand_miss_latency")
272        .desc("number of demand (read+write) miss cycles")
273        .flags(total | nozero | nonan)
274        ;
275    demandMissLatency = SUM_DEMAND(missLatency);
276    for (int i = 0; i < system->maxMasters(); i++) {
277        demandMissLatency.subname(i, system->getMasterName(i));
278    }
279
280    overallMissLatency
281        .name(name() + ".overall_miss_latency")
282        .desc("number of overall miss cycles")
283        .flags(total | nozero | nonan)
284        ;
285    overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
286    for (int i = 0; i < system->maxMasters(); i++) {
287        overallMissLatency.subname(i, system->getMasterName(i));
288    }
289
290    // access formulas
291    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
292        MemCmd cmd(access_idx);
293        const string &cstr = cmd.toString();
294
295        accesses[access_idx]
296            .name(name() + "." + cstr + "_accesses")
297            .desc("number of " + cstr + " accesses(hits+misses)")
298            .flags(total | nozero | nonan)
299            ;
300        accesses[access_idx] = hits[access_idx] + misses[access_idx];
301
302        for (int i = 0; i < system->maxMasters(); i++) {
303            accesses[access_idx].subname(i, system->getMasterName(i));
304        }
305    }
306
307    demandAccesses
308        .name(name() + ".demand_accesses")
309        .desc("number of demand (read+write) accesses")
310        .flags(total | nozero | nonan)
311        ;
312    demandAccesses = demandHits + demandMisses;
313    for (int i = 0; i < system->maxMasters(); i++) {
314        demandAccesses.subname(i, system->getMasterName(i));
315    }
316
317    overallAccesses
318        .name(name() + ".overall_accesses")
319        .desc("number of overall (read+write) accesses")
320        .flags(total | nozero | nonan)
321        ;
322    overallAccesses = overallHits + overallMisses;
323    for (int i = 0; i < system->maxMasters(); i++) {
324        overallAccesses.subname(i, system->getMasterName(i));
325    }
326
327    // miss rate formulas
328    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
329        MemCmd cmd(access_idx);
330        const string &cstr = cmd.toString();
331
332        missRate[access_idx]
333            .name(name() + "." + cstr + "_miss_rate")
334            .desc("miss rate for " + cstr + " accesses")
335            .flags(total | nozero | nonan)
336            ;
337        missRate[access_idx] = misses[access_idx] / accesses[access_idx];
338
339        for (int i = 0; i < system->maxMasters(); i++) {
340            missRate[access_idx].subname(i, system->getMasterName(i));
341        }
342    }
343
344    demandMissRate
345        .name(name() + ".demand_miss_rate")
346        .desc("miss rate for demand accesses")
347        .flags(total | nozero | nonan)
348        ;
349    demandMissRate = demandMisses / demandAccesses;
350    for (int i = 0; i < system->maxMasters(); i++) {
351        demandMissRate.subname(i, system->getMasterName(i));
352    }
353
354    overallMissRate
355        .name(name() + ".overall_miss_rate")
356        .desc("miss rate for overall accesses")
357        .flags(total | nozero | nonan)
358        ;
359    overallMissRate = overallMisses / overallAccesses;
360    for (int i = 0; i < system->maxMasters(); i++) {
361        overallMissRate.subname(i, system->getMasterName(i));
362    }
363
364    // miss latency formulas
365    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
366        MemCmd cmd(access_idx);
367        const string &cstr = cmd.toString();
368
369        avgMissLatency[access_idx]
370            .name(name() + "." + cstr + "_avg_miss_latency")
371            .desc("average " + cstr + " miss latency")
372            .flags(total | nozero | nonan)
373            ;
374        avgMissLatency[access_idx] =
375            missLatency[access_idx] / misses[access_idx];
376
377        for (int i = 0; i < system->maxMasters(); i++) {
378            avgMissLatency[access_idx].subname(i, system->getMasterName(i));
379        }
380    }
381
382    demandAvgMissLatency
383        .name(name() + ".demand_avg_miss_latency")
384        .desc("average overall miss latency")
385        .flags(total | nozero | nonan)
386        ;
387    demandAvgMissLatency = demandMissLatency / demandMisses;
388    for (int i = 0; i < system->maxMasters(); i++) {
389        demandAvgMissLatency.subname(i, system->getMasterName(i));
390    }
391
392    overallAvgMissLatency
393        .name(name() + ".overall_avg_miss_latency")
394        .desc("average overall miss latency")
395        .flags(total | nozero | nonan)
396        ;
397    overallAvgMissLatency = overallMissLatency / overallMisses;
398    for (int i = 0; i < system->maxMasters(); i++) {
399        overallAvgMissLatency.subname(i, system->getMasterName(i));
400    }
401
402    blocked_cycles.init(NUM_BLOCKED_CAUSES);
403    blocked_cycles
404        .name(name() + ".blocked_cycles")
405        .desc("number of cycles access was blocked")
406        .subname(Blocked_NoMSHRs, "no_mshrs")
407        .subname(Blocked_NoTargets, "no_targets")
408        ;
409
410
411    blocked_causes.init(NUM_BLOCKED_CAUSES);
412    blocked_causes
413        .name(name() + ".blocked")
414        .desc("number of cycles access was blocked")
415        .subname(Blocked_NoMSHRs, "no_mshrs")
416        .subname(Blocked_NoTargets, "no_targets")
417        ;
418
419    avg_blocked
420        .name(name() + ".avg_blocked_cycles")
421        .desc("average number of cycles each access was blocked")
422        .subname(Blocked_NoMSHRs, "no_mshrs")
423        .subname(Blocked_NoTargets, "no_targets")
424        ;
425
426    avg_blocked = blocked_cycles / blocked_causes;
427
428    fastWrites
429        .name(name() + ".fast_writes")
430        .desc("number of fast writes performed")
431        ;
432
433    cacheCopies
434        .name(name() + ".cache_copies")
435        .desc("number of cache copies performed")
436        ;
437
438    writebacks
439        .init(system->maxMasters())
440        .name(name() + ".writebacks")
441        .desc("number of writebacks")
442        .flags(total | nozero | nonan)
443        ;
444    for (int i = 0; i < system->maxMasters(); i++) {
445        writebacks.subname(i, system->getMasterName(i));
446    }
447
448    // MSHR statistics
449    // MSHR hit statistics
450    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
451        MemCmd cmd(access_idx);
452        const string &cstr = cmd.toString();
453
454        mshr_hits[access_idx]
455            .init(system->maxMasters())
456            .name(name() + "." + cstr + "_mshr_hits")
457            .desc("number of " + cstr + " MSHR hits")
458            .flags(total | nozero | nonan)
459            ;
460        for (int i = 0; i < system->maxMasters(); i++) {
461            mshr_hits[access_idx].subname(i, system->getMasterName(i));
462        }
463    }
464
465    demandMshrHits
466        .name(name() + ".demand_mshr_hits")
467        .desc("number of demand (read+write) MSHR hits")
468        .flags(total | nozero | nonan)
469        ;
470    demandMshrHits = SUM_DEMAND(mshr_hits);
471    for (int i = 0; i < system->maxMasters(); i++) {
472        demandMshrHits.subname(i, system->getMasterName(i));
473    }
474
475    overallMshrHits
476        .name(name() + ".overall_mshr_hits")
477        .desc("number of overall MSHR hits")
478        .flags(total | nozero | nonan)
479        ;
480    overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
481    for (int i = 0; i < system->maxMasters(); i++) {
482        overallMshrHits.subname(i, system->getMasterName(i));
483    }
484
485    // MSHR miss statistics
486    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
487        MemCmd cmd(access_idx);
488        const string &cstr = cmd.toString();
489
490        mshr_misses[access_idx]
491            .init(system->maxMasters())
492            .name(name() + "." + cstr + "_mshr_misses")
493            .desc("number of " + cstr + " MSHR misses")
494            .flags(total | nozero | nonan)
495            ;
496        for (int i = 0; i < system->maxMasters(); i++) {
497            mshr_misses[access_idx].subname(i, system->getMasterName(i));
498        }
499    }
500
501    demandMshrMisses
502        .name(name() + ".demand_mshr_misses")
503        .desc("number of demand (read+write) MSHR misses")
504        .flags(total | nozero | nonan)
505        ;
506    demandMshrMisses = SUM_DEMAND(mshr_misses);
507    for (int i = 0; i < system->maxMasters(); i++) {
508        demandMshrMisses.subname(i, system->getMasterName(i));
509    }
510
511    overallMshrMisses
512        .name(name() + ".overall_mshr_misses")
513        .desc("number of overall MSHR misses")
514        .flags(total | nozero | nonan)
515        ;
516    overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
517    for (int i = 0; i < system->maxMasters(); i++) {
518        overallMshrMisses.subname(i, system->getMasterName(i));
519    }
520
521    // MSHR miss latency statistics
522    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
523        MemCmd cmd(access_idx);
524        const string &cstr = cmd.toString();
525
526        mshr_miss_latency[access_idx]
527            .init(system->maxMasters())
528            .name(name() + "." + cstr + "_mshr_miss_latency")
529            .desc("number of " + cstr + " MSHR miss cycles")
530            .flags(total | nozero | nonan)
531            ;
532        for (int i = 0; i < system->maxMasters(); i++) {
533            mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
534        }
535    }
536
537    demandMshrMissLatency
538        .name(name() + ".demand_mshr_miss_latency")
539        .desc("number of demand (read+write) MSHR miss cycles")
540        .flags(total | nozero | nonan)
541        ;
542    demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
543    for (int i = 0; i < system->maxMasters(); i++) {
544        demandMshrMissLatency.subname(i, system->getMasterName(i));
545    }
546
547    overallMshrMissLatency
548        .name(name() + ".overall_mshr_miss_latency")
549        .desc("number of overall MSHR miss cycles")
550        .flags(total | nozero | nonan)
551        ;
552    overallMshrMissLatency =
553        demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
554    for (int i = 0; i < system->maxMasters(); i++) {
555        overallMshrMissLatency.subname(i, system->getMasterName(i));
556    }
557
558    // MSHR uncacheable statistics
559    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
560        MemCmd cmd(access_idx);
561        const string &cstr = cmd.toString();
562
563        mshr_uncacheable[access_idx]
564            .init(system->maxMasters())
565            .name(name() + "." + cstr + "_mshr_uncacheable")
566            .desc("number of " + cstr + " MSHR uncacheable")
567            .flags(total | nozero | nonan)
568            ;
569        for (int i = 0; i < system->maxMasters(); i++) {
570            mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
571        }
572    }
573
574    overallMshrUncacheable
575        .name(name() + ".overall_mshr_uncacheable_misses")
576        .desc("number of overall MSHR uncacheable misses")
577        .flags(total | nozero | nonan)
578        ;
579    overallMshrUncacheable =
580        SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
581    for (int i = 0; i < system->maxMasters(); i++) {
582        overallMshrUncacheable.subname(i, system->getMasterName(i));
583    }
584
585    // MSHR miss latency statistics
586    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
587        MemCmd cmd(access_idx);
588        const string &cstr = cmd.toString();
589
590        mshr_uncacheable_lat[access_idx]
591            .init(system->maxMasters())
592            .name(name() + "." + cstr + "_mshr_uncacheable_latency")
593            .desc("number of " + cstr + " MSHR uncacheable cycles")
594            .flags(total | nozero | nonan)
595            ;
596        for (int i = 0; i < system->maxMasters(); i++) {
597            mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i));
598        }
599    }
600
601    overallMshrUncacheableLatency
602        .name(name() + ".overall_mshr_uncacheable_latency")
603        .desc("number of overall MSHR uncacheable cycles")
604        .flags(total | nozero | nonan)
605        ;
606    overallMshrUncacheableLatency =
607        SUM_DEMAND(mshr_uncacheable_lat) +
608        SUM_NON_DEMAND(mshr_uncacheable_lat);
609    for (int i = 0; i < system->maxMasters(); i++) {
610        overallMshrUncacheableLatency.subname(i, system->getMasterName(i));
611    }
612
613#if 0
614    // MSHR access formulas
615    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
616        MemCmd cmd(access_idx);
617        const string &cstr = cmd.toString();
618
619        mshrAccesses[access_idx]
620            .name(name() + "." + cstr + "_mshr_accesses")
621            .desc("number of " + cstr + " mshr accesses(hits+misses)")
622            .flags(total | nozero | nonan)
623            ;
624        mshrAccesses[access_idx] =
625            mshr_hits[access_idx] + mshr_misses[access_idx]
626            + mshr_uncacheable[access_idx];
627    }
628
629    demandMshrAccesses
630        .name(name() + ".demand_mshr_accesses")
631        .desc("number of demand (read+write) mshr accesses")
632        .flags(total | nozero | nonan)
633        ;
634    demandMshrAccesses = demandMshrHits + demandMshrMisses;
635
636    overallMshrAccesses
637        .name(name() + ".overall_mshr_accesses")
638        .desc("number of overall (read+write) mshr accesses")
639        .flags(total | nozero | nonan)
640        ;
641    overallMshrAccesses = overallMshrHits + overallMshrMisses
642        + overallMshrUncacheable;
643#endif
644
645    // MSHR miss rate formulas
646    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
647        MemCmd cmd(access_idx);
648        const string &cstr = cmd.toString();
649
650        mshrMissRate[access_idx]
651            .name(name() + "." + cstr + "_mshr_miss_rate")
652            .desc("mshr miss rate for " + cstr + " accesses")
653            .flags(total | nozero | nonan)
654            ;
655        mshrMissRate[access_idx] =
656            mshr_misses[access_idx] / accesses[access_idx];
657
658        for (int i = 0; i < system->maxMasters(); i++) {
659            mshrMissRate[access_idx].subname(i, system->getMasterName(i));
660        }
661    }
662
663    demandMshrMissRate
664        .name(name() + ".demand_mshr_miss_rate")
665        .desc("mshr miss rate for demand accesses")
666        .flags(total | nozero | nonan)
667        ;
668    demandMshrMissRate = demandMshrMisses / demandAccesses;
669    for (int i = 0; i < system->maxMasters(); i++) {
670        demandMshrMissRate.subname(i, system->getMasterName(i));
671    }
672
673    overallMshrMissRate
674        .name(name() + ".overall_mshr_miss_rate")
675        .desc("mshr miss rate for overall accesses")
676        .flags(total | nozero | nonan)
677        ;
678    overallMshrMissRate = overallMshrMisses / overallAccesses;
679    for (int i = 0; i < system->maxMasters(); i++) {
680        overallMshrMissRate.subname(i, system->getMasterName(i));
681    }
682
683    // mshrMiss latency formulas
684    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
685        MemCmd cmd(access_idx);
686        const string &cstr = cmd.toString();
687
688        avgMshrMissLatency[access_idx]
689            .name(name() + "." + cstr + "_avg_mshr_miss_latency")
690            .desc("average " + cstr + " mshr miss latency")
691            .flags(total | nozero | nonan)
692            ;
693        avgMshrMissLatency[access_idx] =
694            mshr_miss_latency[access_idx] / mshr_misses[access_idx];
695
696        for (int i = 0; i < system->maxMasters(); i++) {
697            avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i));
698        }
699    }
700
701    demandAvgMshrMissLatency
702        .name(name() + ".demand_avg_mshr_miss_latency")
703        .desc("average overall mshr miss latency")
704        .flags(total | nozero | nonan)
705        ;
706    demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
707    for (int i = 0; i < system->maxMasters(); i++) {
708        demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
709    }
710
711    overallAvgMshrMissLatency
712        .name(name() + ".overall_avg_mshr_miss_latency")
713        .desc("average overall mshr miss latency")
714        .flags(total | nozero | nonan)
715        ;
716    overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
717    for (int i = 0; i < system->maxMasters(); i++) {
718        overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
719    }
720
721    // mshrUncacheable latency formulas
722    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
723        MemCmd cmd(access_idx);
724        const string &cstr = cmd.toString();
725
726        avgMshrUncacheableLatency[access_idx]
727            .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
728            .desc("average " + cstr + " mshr uncacheable latency")
729            .flags(total | nozero | nonan)
730            ;
731        avgMshrUncacheableLatency[access_idx] =
732            mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
733
734        for (int i = 0; i < system->maxMasters(); i++) {
735            avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i));
736        }
737    }
738
739    overallAvgMshrUncacheableLatency
740        .name(name() + ".overall_avg_mshr_uncacheable_latency")
741        .desc("average overall mshr uncacheable latency")
742        .flags(total | nozero | nonan)
743        ;
744    overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
745    for (int i = 0; i < system->maxMasters(); i++) {
746        overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
747    }
748
749    mshr_cap_events
750        .init(system->maxMasters())
751        .name(name() + ".mshr_cap_events")
752        .desc("number of times MSHR cap was activated")
753        .flags(total | nozero | nonan)
754        ;
755    for (int i = 0; i < system->maxMasters(); i++) {
756        mshr_cap_events.subname(i, system->getMasterName(i));
757    }
758
759    //software prefetching stats
760    soft_prefetch_mshr_full
761        .init(system->maxMasters())
762        .name(name() + ".soft_prefetch_mshr_full")
763        .desc("number of mshr full events for SW prefetching instrutions")
764        .flags(total | nozero | nonan)
765        ;
766    for (int i = 0; i < system->maxMasters(); i++) {
767        soft_prefetch_mshr_full.subname(i, system->getMasterName(i));
768    }
769
770    mshr_no_allocate_misses
771        .name(name() +".no_allocate_misses")
772        .desc("Number of misses that were no-allocate")
773        ;
774
775}
776
777unsigned int
778BaseCache::drain(DrainManager *dm)
779{
780    int count = memSidePort->drain(dm) + cpuSidePort->drain(dm) +
781        mshrQueue.drain(dm) + writeBuffer.drain(dm);
782
783    // Set status
784    if (count != 0) {
785        setDrainState(Drainable::Draining);
786        DPRINTF(Drain, "Cache not drained\n");
787        return count;
788    }
789
790    setDrainState(Drainable::Drained);
791    return 0;
792}
793
794BaseCache *
795BaseCacheParams::create()
796{
797    assert(tags);
798
799    return new Cache(this);
800}
801