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