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