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