base.cc revision 10887:279efb97ec99
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      isReadOnly(p->is_read_only),
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] + \
193     s[MemCmd::ReadExReq] + s[MemCmd::ReadCleanReq] + s[MemCmd::ReadSharedReq])
194
195// should writebacks be included here?  prior code was inconsistent...
196#define SUM_NON_DEMAND(s) \
197    (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
198
199    demandHits
200        .name(name() + ".demand_hits")
201        .desc("number of demand (read+write) hits")
202        .flags(total | nozero | nonan)
203        ;
204    demandHits = SUM_DEMAND(hits);
205    for (int i = 0; i < system->maxMasters(); i++) {
206        demandHits.subname(i, system->getMasterName(i));
207    }
208
209    overallHits
210        .name(name() + ".overall_hits")
211        .desc("number of overall hits")
212        .flags(total | nozero | nonan)
213        ;
214    overallHits = demandHits + SUM_NON_DEMAND(hits);
215    for (int i = 0; i < system->maxMasters(); i++) {
216        overallHits.subname(i, system->getMasterName(i));
217    }
218
219    // Miss statistics
220    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
221        MemCmd cmd(access_idx);
222        const string &cstr = cmd.toString();
223
224        misses[access_idx]
225            .init(system->maxMasters())
226            .name(name() + "." + cstr + "_misses")
227            .desc("number of " + cstr + " misses")
228            .flags(total | nozero | nonan)
229            ;
230        for (int i = 0; i < system->maxMasters(); i++) {
231            misses[access_idx].subname(i, system->getMasterName(i));
232        }
233    }
234
235    demandMisses
236        .name(name() + ".demand_misses")
237        .desc("number of demand (read+write) misses")
238        .flags(total | nozero | nonan)
239        ;
240    demandMisses = SUM_DEMAND(misses);
241    for (int i = 0; i < system->maxMasters(); i++) {
242        demandMisses.subname(i, system->getMasterName(i));
243    }
244
245    overallMisses
246        .name(name() + ".overall_misses")
247        .desc("number of overall misses")
248        .flags(total | nozero | nonan)
249        ;
250    overallMisses = demandMisses + SUM_NON_DEMAND(misses);
251    for (int i = 0; i < system->maxMasters(); i++) {
252        overallMisses.subname(i, system->getMasterName(i));
253    }
254
255    // Miss latency statistics
256    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
257        MemCmd cmd(access_idx);
258        const string &cstr = cmd.toString();
259
260        missLatency[access_idx]
261            .init(system->maxMasters())
262            .name(name() + "." + cstr + "_miss_latency")
263            .desc("number of " + cstr + " miss cycles")
264            .flags(total | nozero | nonan)
265            ;
266        for (int i = 0; i < system->maxMasters(); i++) {
267            missLatency[access_idx].subname(i, system->getMasterName(i));
268        }
269    }
270
271    demandMissLatency
272        .name(name() + ".demand_miss_latency")
273        .desc("number of demand (read+write) miss cycles")
274        .flags(total | nozero | nonan)
275        ;
276    demandMissLatency = SUM_DEMAND(missLatency);
277    for (int i = 0; i < system->maxMasters(); i++) {
278        demandMissLatency.subname(i, system->getMasterName(i));
279    }
280
281    overallMissLatency
282        .name(name() + ".overall_miss_latency")
283        .desc("number of overall miss cycles")
284        .flags(total | nozero | nonan)
285        ;
286    overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
287    for (int i = 0; i < system->maxMasters(); i++) {
288        overallMissLatency.subname(i, system->getMasterName(i));
289    }
290
291    // access formulas
292    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
293        MemCmd cmd(access_idx);
294        const string &cstr = cmd.toString();
295
296        accesses[access_idx]
297            .name(name() + "." + cstr + "_accesses")
298            .desc("number of " + cstr + " accesses(hits+misses)")
299            .flags(total | nozero | nonan)
300            ;
301        accesses[access_idx] = hits[access_idx] + misses[access_idx];
302
303        for (int i = 0; i < system->maxMasters(); i++) {
304            accesses[access_idx].subname(i, system->getMasterName(i));
305        }
306    }
307
308    demandAccesses
309        .name(name() + ".demand_accesses")
310        .desc("number of demand (read+write) accesses")
311        .flags(total | nozero | nonan)
312        ;
313    demandAccesses = demandHits + demandMisses;
314    for (int i = 0; i < system->maxMasters(); i++) {
315        demandAccesses.subname(i, system->getMasterName(i));
316    }
317
318    overallAccesses
319        .name(name() + ".overall_accesses")
320        .desc("number of overall (read+write) accesses")
321        .flags(total | nozero | nonan)
322        ;
323    overallAccesses = overallHits + overallMisses;
324    for (int i = 0; i < system->maxMasters(); i++) {
325        overallAccesses.subname(i, system->getMasterName(i));
326    }
327
328    // miss rate formulas
329    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
330        MemCmd cmd(access_idx);
331        const string &cstr = cmd.toString();
332
333        missRate[access_idx]
334            .name(name() + "." + cstr + "_miss_rate")
335            .desc("miss rate for " + cstr + " accesses")
336            .flags(total | nozero | nonan)
337            ;
338        missRate[access_idx] = misses[access_idx] / accesses[access_idx];
339
340        for (int i = 0; i < system->maxMasters(); i++) {
341            missRate[access_idx].subname(i, system->getMasterName(i));
342        }
343    }
344
345    demandMissRate
346        .name(name() + ".demand_miss_rate")
347        .desc("miss rate for demand accesses")
348        .flags(total | nozero | nonan)
349        ;
350    demandMissRate = demandMisses / demandAccesses;
351    for (int i = 0; i < system->maxMasters(); i++) {
352        demandMissRate.subname(i, system->getMasterName(i));
353    }
354
355    overallMissRate
356        .name(name() + ".overall_miss_rate")
357        .desc("miss rate for overall accesses")
358        .flags(total | nozero | nonan)
359        ;
360    overallMissRate = overallMisses / overallAccesses;
361    for (int i = 0; i < system->maxMasters(); i++) {
362        overallMissRate.subname(i, system->getMasterName(i));
363    }
364
365    // miss latency formulas
366    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
367        MemCmd cmd(access_idx);
368        const string &cstr = cmd.toString();
369
370        avgMissLatency[access_idx]
371            .name(name() + "." + cstr + "_avg_miss_latency")
372            .desc("average " + cstr + " miss latency")
373            .flags(total | nozero | nonan)
374            ;
375        avgMissLatency[access_idx] =
376            missLatency[access_idx] / misses[access_idx];
377
378        for (int i = 0; i < system->maxMasters(); i++) {
379            avgMissLatency[access_idx].subname(i, system->getMasterName(i));
380        }
381    }
382
383    demandAvgMissLatency
384        .name(name() + ".demand_avg_miss_latency")
385        .desc("average overall miss latency")
386        .flags(total | nozero | nonan)
387        ;
388    demandAvgMissLatency = demandMissLatency / demandMisses;
389    for (int i = 0; i < system->maxMasters(); i++) {
390        demandAvgMissLatency.subname(i, system->getMasterName(i));
391    }
392
393    overallAvgMissLatency
394        .name(name() + ".overall_avg_miss_latency")
395        .desc("average overall miss latency")
396        .flags(total | nozero | nonan)
397        ;
398    overallAvgMissLatency = overallMissLatency / overallMisses;
399    for (int i = 0; i < system->maxMasters(); i++) {
400        overallAvgMissLatency.subname(i, system->getMasterName(i));
401    }
402
403    blocked_cycles.init(NUM_BLOCKED_CAUSES);
404    blocked_cycles
405        .name(name() + ".blocked_cycles")
406        .desc("number of cycles access was blocked")
407        .subname(Blocked_NoMSHRs, "no_mshrs")
408        .subname(Blocked_NoTargets, "no_targets")
409        ;
410
411
412    blocked_causes.init(NUM_BLOCKED_CAUSES);
413    blocked_causes
414        .name(name() + ".blocked")
415        .desc("number of cycles access was blocked")
416        .subname(Blocked_NoMSHRs, "no_mshrs")
417        .subname(Blocked_NoTargets, "no_targets")
418        ;
419
420    avg_blocked
421        .name(name() + ".avg_blocked_cycles")
422        .desc("average number of cycles each access was blocked")
423        .subname(Blocked_NoMSHRs, "no_mshrs")
424        .subname(Blocked_NoTargets, "no_targets")
425        ;
426
427    avg_blocked = blocked_cycles / blocked_causes;
428
429    fastWrites
430        .name(name() + ".fast_writes")
431        .desc("number of fast writes performed")
432        ;
433
434    cacheCopies
435        .name(name() + ".cache_copies")
436        .desc("number of cache copies performed")
437        ;
438
439    writebacks
440        .init(system->maxMasters())
441        .name(name() + ".writebacks")
442        .desc("number of writebacks")
443        .flags(total | nozero | nonan)
444        ;
445    for (int i = 0; i < system->maxMasters(); i++) {
446        writebacks.subname(i, system->getMasterName(i));
447    }
448
449    // MSHR statistics
450    // MSHR hit statistics
451    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
452        MemCmd cmd(access_idx);
453        const string &cstr = cmd.toString();
454
455        mshr_hits[access_idx]
456            .init(system->maxMasters())
457            .name(name() + "." + cstr + "_mshr_hits")
458            .desc("number of " + cstr + " MSHR hits")
459            .flags(total | nozero | nonan)
460            ;
461        for (int i = 0; i < system->maxMasters(); i++) {
462            mshr_hits[access_idx].subname(i, system->getMasterName(i));
463        }
464    }
465
466    demandMshrHits
467        .name(name() + ".demand_mshr_hits")
468        .desc("number of demand (read+write) MSHR hits")
469        .flags(total | nozero | nonan)
470        ;
471    demandMshrHits = SUM_DEMAND(mshr_hits);
472    for (int i = 0; i < system->maxMasters(); i++) {
473        demandMshrHits.subname(i, system->getMasterName(i));
474    }
475
476    overallMshrHits
477        .name(name() + ".overall_mshr_hits")
478        .desc("number of overall MSHR hits")
479        .flags(total | nozero | nonan)
480        ;
481    overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
482    for (int i = 0; i < system->maxMasters(); i++) {
483        overallMshrHits.subname(i, system->getMasterName(i));
484    }
485
486    // MSHR miss statistics
487    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
488        MemCmd cmd(access_idx);
489        const string &cstr = cmd.toString();
490
491        mshr_misses[access_idx]
492            .init(system->maxMasters())
493            .name(name() + "." + cstr + "_mshr_misses")
494            .desc("number of " + cstr + " MSHR misses")
495            .flags(total | nozero | nonan)
496            ;
497        for (int i = 0; i < system->maxMasters(); i++) {
498            mshr_misses[access_idx].subname(i, system->getMasterName(i));
499        }
500    }
501
502    demandMshrMisses
503        .name(name() + ".demand_mshr_misses")
504        .desc("number of demand (read+write) MSHR misses")
505        .flags(total | nozero | nonan)
506        ;
507    demandMshrMisses = SUM_DEMAND(mshr_misses);
508    for (int i = 0; i < system->maxMasters(); i++) {
509        demandMshrMisses.subname(i, system->getMasterName(i));
510    }
511
512    overallMshrMisses
513        .name(name() + ".overall_mshr_misses")
514        .desc("number of overall MSHR misses")
515        .flags(total | nozero | nonan)
516        ;
517    overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
518    for (int i = 0; i < system->maxMasters(); i++) {
519        overallMshrMisses.subname(i, system->getMasterName(i));
520    }
521
522    // MSHR miss latency statistics
523    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
524        MemCmd cmd(access_idx);
525        const string &cstr = cmd.toString();
526
527        mshr_miss_latency[access_idx]
528            .init(system->maxMasters())
529            .name(name() + "." + cstr + "_mshr_miss_latency")
530            .desc("number of " + cstr + " MSHR miss cycles")
531            .flags(total | nozero | nonan)
532            ;
533        for (int i = 0; i < system->maxMasters(); i++) {
534            mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
535        }
536    }
537
538    demandMshrMissLatency
539        .name(name() + ".demand_mshr_miss_latency")
540        .desc("number of demand (read+write) MSHR miss cycles")
541        .flags(total | nozero | nonan)
542        ;
543    demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
544    for (int i = 0; i < system->maxMasters(); i++) {
545        demandMshrMissLatency.subname(i, system->getMasterName(i));
546    }
547
548    overallMshrMissLatency
549        .name(name() + ".overall_mshr_miss_latency")
550        .desc("number of overall MSHR miss cycles")
551        .flags(total | nozero | nonan)
552        ;
553    overallMshrMissLatency =
554        demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
555    for (int i = 0; i < system->maxMasters(); i++) {
556        overallMshrMissLatency.subname(i, system->getMasterName(i));
557    }
558
559    // MSHR uncacheable statistics
560    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
561        MemCmd cmd(access_idx);
562        const string &cstr = cmd.toString();
563
564        mshr_uncacheable[access_idx]
565            .init(system->maxMasters())
566            .name(name() + "." + cstr + "_mshr_uncacheable")
567            .desc("number of " + cstr + " MSHR uncacheable")
568            .flags(total | nozero | nonan)
569            ;
570        for (int i = 0; i < system->maxMasters(); i++) {
571            mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
572        }
573    }
574
575    overallMshrUncacheable
576        .name(name() + ".overall_mshr_uncacheable_misses")
577        .desc("number of overall MSHR uncacheable misses")
578        .flags(total | nozero | nonan)
579        ;
580    overallMshrUncacheable =
581        SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
582    for (int i = 0; i < system->maxMasters(); i++) {
583        overallMshrUncacheable.subname(i, system->getMasterName(i));
584    }
585
586    // MSHR miss latency statistics
587    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
588        MemCmd cmd(access_idx);
589        const string &cstr = cmd.toString();
590
591        mshr_uncacheable_lat[access_idx]
592            .init(system->maxMasters())
593            .name(name() + "." + cstr + "_mshr_uncacheable_latency")
594            .desc("number of " + cstr + " MSHR uncacheable cycles")
595            .flags(total | nozero | nonan)
596            ;
597        for (int i = 0; i < system->maxMasters(); i++) {
598            mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i));
599        }
600    }
601
602    overallMshrUncacheableLatency
603        .name(name() + ".overall_mshr_uncacheable_latency")
604        .desc("number of overall MSHR uncacheable cycles")
605        .flags(total | nozero | nonan)
606        ;
607    overallMshrUncacheableLatency =
608        SUM_DEMAND(mshr_uncacheable_lat) +
609        SUM_NON_DEMAND(mshr_uncacheable_lat);
610    for (int i = 0; i < system->maxMasters(); i++) {
611        overallMshrUncacheableLatency.subname(i, system->getMasterName(i));
612    }
613
614#if 0
615    // MSHR access formulas
616    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
617        MemCmd cmd(access_idx);
618        const string &cstr = cmd.toString();
619
620        mshrAccesses[access_idx]
621            .name(name() + "." + cstr + "_mshr_accesses")
622            .desc("number of " + cstr + " mshr accesses(hits+misses)")
623            .flags(total | nozero | nonan)
624            ;
625        mshrAccesses[access_idx] =
626            mshr_hits[access_idx] + mshr_misses[access_idx]
627            + mshr_uncacheable[access_idx];
628    }
629
630    demandMshrAccesses
631        .name(name() + ".demand_mshr_accesses")
632        .desc("number of demand (read+write) mshr accesses")
633        .flags(total | nozero | nonan)
634        ;
635    demandMshrAccesses = demandMshrHits + demandMshrMisses;
636
637    overallMshrAccesses
638        .name(name() + ".overall_mshr_accesses")
639        .desc("number of overall (read+write) mshr accesses")
640        .flags(total | nozero | nonan)
641        ;
642    overallMshrAccesses = overallMshrHits + overallMshrMisses
643        + overallMshrUncacheable;
644#endif
645
646    // MSHR miss rate formulas
647    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
648        MemCmd cmd(access_idx);
649        const string &cstr = cmd.toString();
650
651        mshrMissRate[access_idx]
652            .name(name() + "." + cstr + "_mshr_miss_rate")
653            .desc("mshr miss rate for " + cstr + " accesses")
654            .flags(total | nozero | nonan)
655            ;
656        mshrMissRate[access_idx] =
657            mshr_misses[access_idx] / accesses[access_idx];
658
659        for (int i = 0; i < system->maxMasters(); i++) {
660            mshrMissRate[access_idx].subname(i, system->getMasterName(i));
661        }
662    }
663
664    demandMshrMissRate
665        .name(name() + ".demand_mshr_miss_rate")
666        .desc("mshr miss rate for demand accesses")
667        .flags(total | nozero | nonan)
668        ;
669    demandMshrMissRate = demandMshrMisses / demandAccesses;
670    for (int i = 0; i < system->maxMasters(); i++) {
671        demandMshrMissRate.subname(i, system->getMasterName(i));
672    }
673
674    overallMshrMissRate
675        .name(name() + ".overall_mshr_miss_rate")
676        .desc("mshr miss rate for overall accesses")
677        .flags(total | nozero | nonan)
678        ;
679    overallMshrMissRate = overallMshrMisses / overallAccesses;
680    for (int i = 0; i < system->maxMasters(); i++) {
681        overallMshrMissRate.subname(i, system->getMasterName(i));
682    }
683
684    // mshrMiss latency formulas
685    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
686        MemCmd cmd(access_idx);
687        const string &cstr = cmd.toString();
688
689        avgMshrMissLatency[access_idx]
690            .name(name() + "." + cstr + "_avg_mshr_miss_latency")
691            .desc("average " + cstr + " mshr miss latency")
692            .flags(total | nozero | nonan)
693            ;
694        avgMshrMissLatency[access_idx] =
695            mshr_miss_latency[access_idx] / mshr_misses[access_idx];
696
697        for (int i = 0; i < system->maxMasters(); i++) {
698            avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i));
699        }
700    }
701
702    demandAvgMshrMissLatency
703        .name(name() + ".demand_avg_mshr_miss_latency")
704        .desc("average overall mshr miss latency")
705        .flags(total | nozero | nonan)
706        ;
707    demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
708    for (int i = 0; i < system->maxMasters(); i++) {
709        demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
710    }
711
712    overallAvgMshrMissLatency
713        .name(name() + ".overall_avg_mshr_miss_latency")
714        .desc("average overall mshr miss latency")
715        .flags(total | nozero | nonan)
716        ;
717    overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
718    for (int i = 0; i < system->maxMasters(); i++) {
719        overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
720    }
721
722    // mshrUncacheable latency formulas
723    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
724        MemCmd cmd(access_idx);
725        const string &cstr = cmd.toString();
726
727        avgMshrUncacheableLatency[access_idx]
728            .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
729            .desc("average " + cstr + " mshr uncacheable latency")
730            .flags(total | nozero | nonan)
731            ;
732        avgMshrUncacheableLatency[access_idx] =
733            mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
734
735        for (int i = 0; i < system->maxMasters(); i++) {
736            avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i));
737        }
738    }
739
740    overallAvgMshrUncacheableLatency
741        .name(name() + ".overall_avg_mshr_uncacheable_latency")
742        .desc("average overall mshr uncacheable latency")
743        .flags(total | nozero | nonan)
744        ;
745    overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
746    for (int i = 0; i < system->maxMasters(); i++) {
747        overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
748    }
749
750    mshr_cap_events
751        .init(system->maxMasters())
752        .name(name() + ".mshr_cap_events")
753        .desc("number of times MSHR cap was activated")
754        .flags(total | nozero | nonan)
755        ;
756    for (int i = 0; i < system->maxMasters(); i++) {
757        mshr_cap_events.subname(i, system->getMasterName(i));
758    }
759
760    //software prefetching stats
761    soft_prefetch_mshr_full
762        .init(system->maxMasters())
763        .name(name() + ".soft_prefetch_mshr_full")
764        .desc("number of mshr full events for SW prefetching instrutions")
765        .flags(total | nozero | nonan)
766        ;
767    for (int i = 0; i < system->maxMasters(); i++) {
768        soft_prefetch_mshr_full.subname(i, system->getMasterName(i));
769    }
770
771    mshr_no_allocate_misses
772        .name(name() +".no_allocate_misses")
773        .desc("Number of misses that were no-allocate")
774        ;
775
776}
777
778unsigned int
779BaseCache::drain(DrainManager *dm)
780{
781    int count = memSidePort->drain(dm) + cpuSidePort->drain(dm) +
782        mshrQueue.drain(dm) + writeBuffer.drain(dm);
783
784    // Set status
785    if (count != 0) {
786        setDrainState(Drainable::Draining);
787        DPRINTF(Drain, "Cache not drained\n");
788        return count;
789    }
790
791    setDrainState(Drainable::Drained);
792    return 0;
793}
794
795BaseCache *
796BaseCacheParams::create()
797{
798    assert(tags);
799
800    return new Cache(this);
801}
802