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