base.cc revision 11436
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 BaseCacheParams *p, unsigned blk_size)
69    : MemObject(p),
70      cpuSidePort(nullptr), memSidePort(nullptr),
71      mshrQueue("MSHRs", p->mshrs, 0, p->demand_mshr_reserve), // see below
72      writeBuffer("write buffer", p->write_buffers, p->mshrs), // see below
73      blkSize(blk_size),
74      lookupLatency(p->hit_latency),
75      forwardLatency(p->hit_latency),
76      fillLatency(p->response_latency),
77      responseLatency(p->response_latency),
78      numTarget(p->tgts_per_mshr),
79      forwardSnoops(true),
80      isReadOnly(p->is_read_only),
81      blocked(0),
82      order(0),
83      noTargetMSHR(NULL),
84      missCount(p->max_miss_count),
85      addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()),
86      system(p->system)
87{
88    // the MSHR queue has no reserve entries as we check the MSHR
89    // queue on every single allocation, whereas the write queue has
90    // as many reserve entries as we have MSHRs, since every MSHR may
91    // eventually require a writeback, and we do not check the write
92    // buffer before committing to an MSHR
93
94    // forward snoops is overridden in init() once we can query
95    // whether the connected master is actually snooping or not
96}
97
98void
99BaseCache::CacheSlavePort::setBlocked()
100{
101    assert(!blocked);
102    DPRINTF(CachePort, "Port is blocking new requests\n");
103    blocked = true;
104    // if we already scheduled a retry in this cycle, but it has not yet
105    // happened, cancel it
106    if (sendRetryEvent.scheduled()) {
107        owner.deschedule(sendRetryEvent);
108        DPRINTF(CachePort, "Port descheduled retry\n");
109        mustSendRetry = true;
110    }
111}
112
113void
114BaseCache::CacheSlavePort::clearBlocked()
115{
116    assert(blocked);
117    DPRINTF(CachePort, "Port is accepting new requests\n");
118    blocked = false;
119    if (mustSendRetry) {
120        // @TODO: need to find a better time (next cycle?)
121        owner.schedule(sendRetryEvent, curTick() + 1);
122    }
123}
124
125void
126BaseCache::CacheSlavePort::processSendRetry()
127{
128    DPRINTF(CachePort, "Port is sending retry\n");
129
130    // reset the flag and call retry
131    mustSendRetry = false;
132    sendRetryReq();
133}
134
135void
136BaseCache::init()
137{
138    if (!cpuSidePort->isConnected() || !memSidePort->isConnected())
139        fatal("Cache ports on %s are not connected\n", name());
140    cpuSidePort->sendRangeChange();
141    forwardSnoops = cpuSidePort->isSnooping();
142}
143
144BaseMasterPort &
145BaseCache::getMasterPort(const std::string &if_name, PortID idx)
146{
147    if (if_name == "mem_side") {
148        return *memSidePort;
149    }  else {
150        return MemObject::getMasterPort(if_name, idx);
151    }
152}
153
154BaseSlavePort &
155BaseCache::getSlavePort(const std::string &if_name, PortID idx)
156{
157    if (if_name == "cpu_side") {
158        return *cpuSidePort;
159    } else {
160        return MemObject::getSlavePort(if_name, idx);
161    }
162}
163
164bool
165BaseCache::inRange(Addr addr) const
166{
167    for (const auto& r : addrRanges) {
168        if (r.contains(addr)) {
169            return true;
170       }
171    }
172    return false;
173}
174
175void
176BaseCache::regStats()
177{
178    using namespace Stats;
179
180    // Hit statistics
181    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
182        MemCmd cmd(access_idx);
183        const string &cstr = cmd.toString();
184
185        hits[access_idx]
186            .init(system->maxMasters())
187            .name(name() + "." + cstr + "_hits")
188            .desc("number of " + cstr + " hits")
189            .flags(total | nozero | nonan)
190            ;
191        for (int i = 0; i < system->maxMasters(); i++) {
192            hits[access_idx].subname(i, system->getMasterName(i));
193        }
194    }
195
196// These macros make it easier to sum the right subset of commands and
197// to change the subset of commands that are considered "demand" vs
198// "non-demand"
199#define SUM_DEMAND(s) \
200    (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + \
201     s[MemCmd::ReadExReq] + s[MemCmd::ReadCleanReq] + s[MemCmd::ReadSharedReq])
202
203// should writebacks be included here?  prior code was inconsistent...
204#define SUM_NON_DEMAND(s) \
205    (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
206
207    demandHits
208        .name(name() + ".demand_hits")
209        .desc("number of demand (read+write) hits")
210        .flags(total | nozero | nonan)
211        ;
212    demandHits = SUM_DEMAND(hits);
213    for (int i = 0; i < system->maxMasters(); i++) {
214        demandHits.subname(i, system->getMasterName(i));
215    }
216
217    overallHits
218        .name(name() + ".overall_hits")
219        .desc("number of overall hits")
220        .flags(total | nozero | nonan)
221        ;
222    overallHits = demandHits + SUM_NON_DEMAND(hits);
223    for (int i = 0; i < system->maxMasters(); i++) {
224        overallHits.subname(i, system->getMasterName(i));
225    }
226
227    // Miss statistics
228    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
229        MemCmd cmd(access_idx);
230        const string &cstr = cmd.toString();
231
232        misses[access_idx]
233            .init(system->maxMasters())
234            .name(name() + "." + cstr + "_misses")
235            .desc("number of " + cstr + " misses")
236            .flags(total | nozero | nonan)
237            ;
238        for (int i = 0; i < system->maxMasters(); i++) {
239            misses[access_idx].subname(i, system->getMasterName(i));
240        }
241    }
242
243    demandMisses
244        .name(name() + ".demand_misses")
245        .desc("number of demand (read+write) misses")
246        .flags(total | nozero | nonan)
247        ;
248    demandMisses = SUM_DEMAND(misses);
249    for (int i = 0; i < system->maxMasters(); i++) {
250        demandMisses.subname(i, system->getMasterName(i));
251    }
252
253    overallMisses
254        .name(name() + ".overall_misses")
255        .desc("number of overall misses")
256        .flags(total | nozero | nonan)
257        ;
258    overallMisses = demandMisses + SUM_NON_DEMAND(misses);
259    for (int i = 0; i < system->maxMasters(); i++) {
260        overallMisses.subname(i, system->getMasterName(i));
261    }
262
263    // Miss latency statistics
264    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
265        MemCmd cmd(access_idx);
266        const string &cstr = cmd.toString();
267
268        missLatency[access_idx]
269            .init(system->maxMasters())
270            .name(name() + "." + cstr + "_miss_latency")
271            .desc("number of " + cstr + " miss cycles")
272            .flags(total | nozero | nonan)
273            ;
274        for (int i = 0; i < system->maxMasters(); i++) {
275            missLatency[access_idx].subname(i, system->getMasterName(i));
276        }
277    }
278
279    demandMissLatency
280        .name(name() + ".demand_miss_latency")
281        .desc("number of demand (read+write) miss cycles")
282        .flags(total | nozero | nonan)
283        ;
284    demandMissLatency = SUM_DEMAND(missLatency);
285    for (int i = 0; i < system->maxMasters(); i++) {
286        demandMissLatency.subname(i, system->getMasterName(i));
287    }
288
289    overallMissLatency
290        .name(name() + ".overall_miss_latency")
291        .desc("number of overall miss cycles")
292        .flags(total | nozero | nonan)
293        ;
294    overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
295    for (int i = 0; i < system->maxMasters(); i++) {
296        overallMissLatency.subname(i, system->getMasterName(i));
297    }
298
299    // access formulas
300    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
301        MemCmd cmd(access_idx);
302        const string &cstr = cmd.toString();
303
304        accesses[access_idx]
305            .name(name() + "." + cstr + "_accesses")
306            .desc("number of " + cstr + " accesses(hits+misses)")
307            .flags(total | nozero | nonan)
308            ;
309        accesses[access_idx] = hits[access_idx] + misses[access_idx];
310
311        for (int i = 0; i < system->maxMasters(); i++) {
312            accesses[access_idx].subname(i, system->getMasterName(i));
313        }
314    }
315
316    demandAccesses
317        .name(name() + ".demand_accesses")
318        .desc("number of demand (read+write) accesses")
319        .flags(total | nozero | nonan)
320        ;
321    demandAccesses = demandHits + demandMisses;
322    for (int i = 0; i < system->maxMasters(); i++) {
323        demandAccesses.subname(i, system->getMasterName(i));
324    }
325
326    overallAccesses
327        .name(name() + ".overall_accesses")
328        .desc("number of overall (read+write) accesses")
329        .flags(total | nozero | nonan)
330        ;
331    overallAccesses = overallHits + overallMisses;
332    for (int i = 0; i < system->maxMasters(); i++) {
333        overallAccesses.subname(i, system->getMasterName(i));
334    }
335
336    // miss rate formulas
337    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
338        MemCmd cmd(access_idx);
339        const string &cstr = cmd.toString();
340
341        missRate[access_idx]
342            .name(name() + "." + cstr + "_miss_rate")
343            .desc("miss rate for " + cstr + " accesses")
344            .flags(total | nozero | nonan)
345            ;
346        missRate[access_idx] = misses[access_idx] / accesses[access_idx];
347
348        for (int i = 0; i < system->maxMasters(); i++) {
349            missRate[access_idx].subname(i, system->getMasterName(i));
350        }
351    }
352
353    demandMissRate
354        .name(name() + ".demand_miss_rate")
355        .desc("miss rate for demand accesses")
356        .flags(total | nozero | nonan)
357        ;
358    demandMissRate = demandMisses / demandAccesses;
359    for (int i = 0; i < system->maxMasters(); i++) {
360        demandMissRate.subname(i, system->getMasterName(i));
361    }
362
363    overallMissRate
364        .name(name() + ".overall_miss_rate")
365        .desc("miss rate for overall accesses")
366        .flags(total | nozero | nonan)
367        ;
368    overallMissRate = overallMisses / overallAccesses;
369    for (int i = 0; i < system->maxMasters(); i++) {
370        overallMissRate.subname(i, system->getMasterName(i));
371    }
372
373    // miss latency formulas
374    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
375        MemCmd cmd(access_idx);
376        const string &cstr = cmd.toString();
377
378        avgMissLatency[access_idx]
379            .name(name() + "." + cstr + "_avg_miss_latency")
380            .desc("average " + cstr + " miss latency")
381            .flags(total | nozero | nonan)
382            ;
383        avgMissLatency[access_idx] =
384            missLatency[access_idx] / misses[access_idx];
385
386        for (int i = 0; i < system->maxMasters(); i++) {
387            avgMissLatency[access_idx].subname(i, system->getMasterName(i));
388        }
389    }
390
391    demandAvgMissLatency
392        .name(name() + ".demand_avg_miss_latency")
393        .desc("average overall miss latency")
394        .flags(total | nozero | nonan)
395        ;
396    demandAvgMissLatency = demandMissLatency / demandMisses;
397    for (int i = 0; i < system->maxMasters(); i++) {
398        demandAvgMissLatency.subname(i, system->getMasterName(i));
399    }
400
401    overallAvgMissLatency
402        .name(name() + ".overall_avg_miss_latency")
403        .desc("average overall miss latency")
404        .flags(total | nozero | nonan)
405        ;
406    overallAvgMissLatency = overallMissLatency / overallMisses;
407    for (int i = 0; i < system->maxMasters(); i++) {
408        overallAvgMissLatency.subname(i, system->getMasterName(i));
409    }
410
411    blocked_cycles.init(NUM_BLOCKED_CAUSES);
412    blocked_cycles
413        .name(name() + ".blocked_cycles")
414        .desc("number of cycles access was blocked")
415        .subname(Blocked_NoMSHRs, "no_mshrs")
416        .subname(Blocked_NoTargets, "no_targets")
417        ;
418
419
420    blocked_causes.init(NUM_BLOCKED_CAUSES);
421    blocked_causes
422        .name(name() + ".blocked")
423        .desc("number of cycles access was blocked")
424        .subname(Blocked_NoMSHRs, "no_mshrs")
425        .subname(Blocked_NoTargets, "no_targets")
426        ;
427
428    avg_blocked
429        .name(name() + ".avg_blocked_cycles")
430        .desc("average number of cycles each access was blocked")
431        .subname(Blocked_NoMSHRs, "no_mshrs")
432        .subname(Blocked_NoTargets, "no_targets")
433        ;
434
435    avg_blocked = blocked_cycles / blocked_causes;
436
437    fastWrites
438        .name(name() + ".fast_writes")
439        .desc("number of fast writes performed")
440        ;
441
442    cacheCopies
443        .name(name() + ".cache_copies")
444        .desc("number of cache copies performed")
445        ;
446
447    unusedPrefetches
448        .name(name() + ".unused_prefetches")
449        .desc("number of HardPF blocks evicted w/o reference")
450        .flags(nozero)
451        ;
452
453    writebacks
454        .init(system->maxMasters())
455        .name(name() + ".writebacks")
456        .desc("number of writebacks")
457        .flags(total | nozero | nonan)
458        ;
459    for (int i = 0; i < system->maxMasters(); i++) {
460        writebacks.subname(i, system->getMasterName(i));
461    }
462
463    // MSHR statistics
464    // MSHR hit statistics
465    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
466        MemCmd cmd(access_idx);
467        const string &cstr = cmd.toString();
468
469        mshr_hits[access_idx]
470            .init(system->maxMasters())
471            .name(name() + "." + cstr + "_mshr_hits")
472            .desc("number of " + cstr + " MSHR hits")
473            .flags(total | nozero | nonan)
474            ;
475        for (int i = 0; i < system->maxMasters(); i++) {
476            mshr_hits[access_idx].subname(i, system->getMasterName(i));
477        }
478    }
479
480    demandMshrHits
481        .name(name() + ".demand_mshr_hits")
482        .desc("number of demand (read+write) MSHR hits")
483        .flags(total | nozero | nonan)
484        ;
485    demandMshrHits = SUM_DEMAND(mshr_hits);
486    for (int i = 0; i < system->maxMasters(); i++) {
487        demandMshrHits.subname(i, system->getMasterName(i));
488    }
489
490    overallMshrHits
491        .name(name() + ".overall_mshr_hits")
492        .desc("number of overall MSHR hits")
493        .flags(total | nozero | nonan)
494        ;
495    overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
496    for (int i = 0; i < system->maxMasters(); i++) {
497        overallMshrHits.subname(i, system->getMasterName(i));
498    }
499
500    // MSHR miss statistics
501    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
502        MemCmd cmd(access_idx);
503        const string &cstr = cmd.toString();
504
505        mshr_misses[access_idx]
506            .init(system->maxMasters())
507            .name(name() + "." + cstr + "_mshr_misses")
508            .desc("number of " + cstr + " MSHR misses")
509            .flags(total | nozero | nonan)
510            ;
511        for (int i = 0; i < system->maxMasters(); i++) {
512            mshr_misses[access_idx].subname(i, system->getMasterName(i));
513        }
514    }
515
516    demandMshrMisses
517        .name(name() + ".demand_mshr_misses")
518        .desc("number of demand (read+write) MSHR misses")
519        .flags(total | nozero | nonan)
520        ;
521    demandMshrMisses = SUM_DEMAND(mshr_misses);
522    for (int i = 0; i < system->maxMasters(); i++) {
523        demandMshrMisses.subname(i, system->getMasterName(i));
524    }
525
526    overallMshrMisses
527        .name(name() + ".overall_mshr_misses")
528        .desc("number of overall MSHR misses")
529        .flags(total | nozero | nonan)
530        ;
531    overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
532    for (int i = 0; i < system->maxMasters(); i++) {
533        overallMshrMisses.subname(i, system->getMasterName(i));
534    }
535
536    // MSHR miss latency statistics
537    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
538        MemCmd cmd(access_idx);
539        const string &cstr = cmd.toString();
540
541        mshr_miss_latency[access_idx]
542            .init(system->maxMasters())
543            .name(name() + "." + cstr + "_mshr_miss_latency")
544            .desc("number of " + cstr + " MSHR miss cycles")
545            .flags(total | nozero | nonan)
546            ;
547        for (int i = 0; i < system->maxMasters(); i++) {
548            mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
549        }
550    }
551
552    demandMshrMissLatency
553        .name(name() + ".demand_mshr_miss_latency")
554        .desc("number of demand (read+write) MSHR miss cycles")
555        .flags(total | nozero | nonan)
556        ;
557    demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
558    for (int i = 0; i < system->maxMasters(); i++) {
559        demandMshrMissLatency.subname(i, system->getMasterName(i));
560    }
561
562    overallMshrMissLatency
563        .name(name() + ".overall_mshr_miss_latency")
564        .desc("number of overall MSHR miss cycles")
565        .flags(total | nozero | nonan)
566        ;
567    overallMshrMissLatency =
568        demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
569    for (int i = 0; i < system->maxMasters(); i++) {
570        overallMshrMissLatency.subname(i, system->getMasterName(i));
571    }
572
573    // MSHR uncacheable statistics
574    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
575        MemCmd cmd(access_idx);
576        const string &cstr = cmd.toString();
577
578        mshr_uncacheable[access_idx]
579            .init(system->maxMasters())
580            .name(name() + "." + cstr + "_mshr_uncacheable")
581            .desc("number of " + cstr + " MSHR uncacheable")
582            .flags(total | nozero | nonan)
583            ;
584        for (int i = 0; i < system->maxMasters(); i++) {
585            mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
586        }
587    }
588
589    overallMshrUncacheable
590        .name(name() + ".overall_mshr_uncacheable_misses")
591        .desc("number of overall MSHR uncacheable misses")
592        .flags(total | nozero | nonan)
593        ;
594    overallMshrUncacheable =
595        SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
596    for (int i = 0; i < system->maxMasters(); i++) {
597        overallMshrUncacheable.subname(i, system->getMasterName(i));
598    }
599
600    // MSHR miss latency statistics
601    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
602        MemCmd cmd(access_idx);
603        const string &cstr = cmd.toString();
604
605        mshr_uncacheable_lat[access_idx]
606            .init(system->maxMasters())
607            .name(name() + "." + cstr + "_mshr_uncacheable_latency")
608            .desc("number of " + cstr + " MSHR uncacheable cycles")
609            .flags(total | nozero | nonan)
610            ;
611        for (int i = 0; i < system->maxMasters(); i++) {
612            mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i));
613        }
614    }
615
616    overallMshrUncacheableLatency
617        .name(name() + ".overall_mshr_uncacheable_latency")
618        .desc("number of overall MSHR uncacheable cycles")
619        .flags(total | nozero | nonan)
620        ;
621    overallMshrUncacheableLatency =
622        SUM_DEMAND(mshr_uncacheable_lat) +
623        SUM_NON_DEMAND(mshr_uncacheable_lat);
624    for (int i = 0; i < system->maxMasters(); i++) {
625        overallMshrUncacheableLatency.subname(i, system->getMasterName(i));
626    }
627
628#if 0
629    // MSHR access formulas
630    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
631        MemCmd cmd(access_idx);
632        const string &cstr = cmd.toString();
633
634        mshrAccesses[access_idx]
635            .name(name() + "." + cstr + "_mshr_accesses")
636            .desc("number of " + cstr + " mshr accesses(hits+misses)")
637            .flags(total | nozero | nonan)
638            ;
639        mshrAccesses[access_idx] =
640            mshr_hits[access_idx] + mshr_misses[access_idx]
641            + mshr_uncacheable[access_idx];
642    }
643
644    demandMshrAccesses
645        .name(name() + ".demand_mshr_accesses")
646        .desc("number of demand (read+write) mshr accesses")
647        .flags(total | nozero | nonan)
648        ;
649    demandMshrAccesses = demandMshrHits + demandMshrMisses;
650
651    overallMshrAccesses
652        .name(name() + ".overall_mshr_accesses")
653        .desc("number of overall (read+write) mshr accesses")
654        .flags(total | nozero | nonan)
655        ;
656    overallMshrAccesses = overallMshrHits + overallMshrMisses
657        + overallMshrUncacheable;
658#endif
659
660    // MSHR miss rate formulas
661    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
662        MemCmd cmd(access_idx);
663        const string &cstr = cmd.toString();
664
665        mshrMissRate[access_idx]
666            .name(name() + "." + cstr + "_mshr_miss_rate")
667            .desc("mshr miss rate for " + cstr + " accesses")
668            .flags(total | nozero | nonan)
669            ;
670        mshrMissRate[access_idx] =
671            mshr_misses[access_idx] / accesses[access_idx];
672
673        for (int i = 0; i < system->maxMasters(); i++) {
674            mshrMissRate[access_idx].subname(i, system->getMasterName(i));
675        }
676    }
677
678    demandMshrMissRate
679        .name(name() + ".demand_mshr_miss_rate")
680        .desc("mshr miss rate for demand accesses")
681        .flags(total | nozero | nonan)
682        ;
683    demandMshrMissRate = demandMshrMisses / demandAccesses;
684    for (int i = 0; i < system->maxMasters(); i++) {
685        demandMshrMissRate.subname(i, system->getMasterName(i));
686    }
687
688    overallMshrMissRate
689        .name(name() + ".overall_mshr_miss_rate")
690        .desc("mshr miss rate for overall accesses")
691        .flags(total | nozero | nonan)
692        ;
693    overallMshrMissRate = overallMshrMisses / overallAccesses;
694    for (int i = 0; i < system->maxMasters(); i++) {
695        overallMshrMissRate.subname(i, system->getMasterName(i));
696    }
697
698    // mshrMiss latency formulas
699    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
700        MemCmd cmd(access_idx);
701        const string &cstr = cmd.toString();
702
703        avgMshrMissLatency[access_idx]
704            .name(name() + "." + cstr + "_avg_mshr_miss_latency")
705            .desc("average " + cstr + " mshr miss latency")
706            .flags(total | nozero | nonan)
707            ;
708        avgMshrMissLatency[access_idx] =
709            mshr_miss_latency[access_idx] / mshr_misses[access_idx];
710
711        for (int i = 0; i < system->maxMasters(); i++) {
712            avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i));
713        }
714    }
715
716    demandAvgMshrMissLatency
717        .name(name() + ".demand_avg_mshr_miss_latency")
718        .desc("average overall mshr miss latency")
719        .flags(total | nozero | nonan)
720        ;
721    demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
722    for (int i = 0; i < system->maxMasters(); i++) {
723        demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
724    }
725
726    overallAvgMshrMissLatency
727        .name(name() + ".overall_avg_mshr_miss_latency")
728        .desc("average overall mshr miss latency")
729        .flags(total | nozero | nonan)
730        ;
731    overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
732    for (int i = 0; i < system->maxMasters(); i++) {
733        overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
734    }
735
736    // mshrUncacheable latency formulas
737    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
738        MemCmd cmd(access_idx);
739        const string &cstr = cmd.toString();
740
741        avgMshrUncacheableLatency[access_idx]
742            .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
743            .desc("average " + cstr + " mshr uncacheable latency")
744            .flags(total | nozero | nonan)
745            ;
746        avgMshrUncacheableLatency[access_idx] =
747            mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
748
749        for (int i = 0; i < system->maxMasters(); i++) {
750            avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i));
751        }
752    }
753
754    overallAvgMshrUncacheableLatency
755        .name(name() + ".overall_avg_mshr_uncacheable_latency")
756        .desc("average overall mshr uncacheable latency")
757        .flags(total | nozero | nonan)
758        ;
759    overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
760    for (int i = 0; i < system->maxMasters(); i++) {
761        overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
762    }
763
764    mshr_cap_events
765        .init(system->maxMasters())
766        .name(name() + ".mshr_cap_events")
767        .desc("number of times MSHR cap was activated")
768        .flags(total | nozero | nonan)
769        ;
770    for (int i = 0; i < system->maxMasters(); i++) {
771        mshr_cap_events.subname(i, system->getMasterName(i));
772    }
773
774    //software prefetching stats
775    soft_prefetch_mshr_full
776        .init(system->maxMasters())
777        .name(name() + ".soft_prefetch_mshr_full")
778        .desc("number of mshr full events for SW prefetching instrutions")
779        .flags(total | nozero | nonan)
780        ;
781    for (int i = 0; i < system->maxMasters(); i++) {
782        soft_prefetch_mshr_full.subname(i, system->getMasterName(i));
783    }
784
785    mshr_no_allocate_misses
786        .name(name() +".no_allocate_misses")
787        .desc("Number of misses that were no-allocate")
788        ;
789
790}
791