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