base.cc revision 11484
12SN/A/*
21762SN/A * Copyright (c) 2012-2013 ARM Limited
32SN/A * All rights reserved.
42SN/A *
52SN/A * The license below extends only to copyright in the software and shall
62SN/A * not be construed as granting a license to any other intellectual
72SN/A * property including but not limited to intellectual property relating
82SN/A * to a hardware implementation of the functionality of the software
92SN/A * licensed hereunder.  You may use the software subject to the license
102SN/A * terms below provided that you ensure that this notice is replicated
112SN/A * unmodified and in its entirety in all distributions of the software,
122SN/A * modified or unmodified, in source code or in binary form.
132SN/A *
142SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
152SN/A * All rights reserved.
162SN/A *
172SN/A * Redistribution and use in source and binary forms, with or without
182SN/A * modification, are permitted provided that the following conditions are
192SN/A * met: redistributions of source code must retain the above copyright
202SN/A * notice, this list of conditions and the following disclaimer;
212SN/A * redistributions in binary form must reproduce the above copyright
222SN/A * notice, this list of conditions and the following disclaimer in the
232SN/A * documentation and/or other materials provided with the distribution;
242SN/A * neither the name of the copyright holders nor the names of its
252SN/A * contributors may be used to endorse or promote products derived from
262SN/A * this software without specific prior written permission.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292665Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352147SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
367678Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
378229Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
387878Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392147SN/A *
402147SN/A * Authors: Erik Hallnor
412680Sktlim@umich.edu */
422132SN/A
432147SN/A/**
445999Snate@binkert.org * @file
452147SN/A * Definition of BaseCache functions.
462147SN/A */
472147SN/A
482147SN/A#include "debug/Cache.hh"
492147SN/A#include "debug/Drain.hh"
502147SN/A#include "mem/cache/tags/fa_lru.hh"
512147SN/A#include "mem/cache/tags/lru.hh"
522147SN/A#include "mem/cache/tags/random_repl.hh"
532147SN/A#include "mem/cache/base.hh"
542090SN/A#include "mem/cache/cache.hh"
552147SN/A#include "mem/cache/mshr.hh"
564695Sgblack@eecs.umich.edu#include "sim/full_system.hh"
5710417Sandreas.hansson@arm.com
5810417Sandreas.hansson@arm.comusing namespace std;
592SN/A
602SN/ABaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name,
612612SN/A                                          BaseCache *_cache,
622612SN/A                                          const std::string &_label)
632612SN/A    : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label),
642612SN/A      blocked(false), mustSendRetry(false), sendRetryEvent(this)
652612SN/A{
662612SN/A}
672612SN/A
682612SN/ABaseCache::BaseCache(const BaseCacheParams *p, unsigned blk_size)
692612SN/A    : MemObject(p),
704695Sgblack@eecs.umich.edu      cpuSidePort(nullptr), memSidePort(nullptr),
7110417Sandreas.hansson@arm.com      mshrQueue("MSHRs", p->mshrs, 0, p->demand_mshr_reserve), // see below
7210417Sandreas.hansson@arm.com      writeBuffer("write buffer", p->write_buffers, p->mshrs), // see below
732612SN/A      blkSize(blk_size),
742612SN/A      lookupLatency(p->hit_latency),
758545Ssaidi@eecs.umich.edu      forwardLatency(p->hit_latency),
768545Ssaidi@eecs.umich.edu      fillLatency(p->response_latency),
778545Ssaidi@eecs.umich.edu      responseLatency(p->response_latency),
788545Ssaidi@eecs.umich.edu      numTarget(p->tgts_per_mshr),
798545Ssaidi@eecs.umich.edu      forwardSnoops(true),
8010417Sandreas.hansson@arm.com      isReadOnly(p->is_read_only),
8110417Sandreas.hansson@arm.com      blocked(0),
828545Ssaidi@eecs.umich.edu      order(0),
838545Ssaidi@eecs.umich.edu      noTargetMSHR(nullptr),
845004Sgblack@eecs.umich.edu      missCount(p->max_miss_count),
854183Sgblack@eecs.umich.edu      addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()),
864183Sgblack@eecs.umich.edu      system(p->system)
874183Sgblack@eecs.umich.edu{
884183Sgblack@eecs.umich.edu    // the MSHR queue has no reserve entries as we check the MSHR
895004Sgblack@eecs.umich.edu    // queue on every single allocation, whereas the write queue has
905004Sgblack@eecs.umich.edu    // as many reserve entries as we have MSHRs, since every MSHR may
9110417Sandreas.hansson@arm.com    // eventually require a writeback, and we do not check the write
9210417Sandreas.hansson@arm.com    // buffer before committing to an MSHR
935004Sgblack@eecs.umich.edu
945004Sgblack@eecs.umich.edu    // forward snoops is overridden in init() once we can query
955004Sgblack@eecs.umich.edu    // whether the connected master is actually snooping or not
965004Sgblack@eecs.umich.edu}
975004Sgblack@eecs.umich.edu
985004Sgblack@eecs.umich.eduvoid
995004Sgblack@eecs.umich.eduBaseCache::CacheSlavePort::setBlocked()
1005004Sgblack@eecs.umich.edu{
1015004Sgblack@eecs.umich.edu    assert(!blocked);
10210417Sandreas.hansson@arm.com    DPRINTF(CachePort, "Port is blocking new requests\n");
10310417Sandreas.hansson@arm.com    blocked = true;
1044183Sgblack@eecs.umich.edu    // if we already scheduled a retry in this cycle, but it has not yet
1054183Sgblack@eecs.umich.edu    // happened, cancel it
1062SN/A    if (sendRetryEvent.scheduled()) {
107        owner.deschedule(sendRetryEvent);
108        DPRINTF(CachePort, "Port descheduled retry\n");
109        mustSendRetry = true;
110    }
111}
112
113void
114BaseCache::CacheSlavePort::clearBlocked()
115{
116    assert(blocked);
117    DPRINTF(CachePort, "Port is accepting new requests\n");
118    blocked = false;
119    if (mustSendRetry) {
120        // @TODO: need to find a better time (next cycle?)
121        owner.schedule(sendRetryEvent, curTick() + 1);
122    }
123}
124
125void
126BaseCache::CacheSlavePort::processSendRetry()
127{
128    DPRINTF(CachePort, "Port is sending retry\n");
129
130    // reset the flag and call retry
131    mustSendRetry = false;
132    sendRetryReq();
133}
134
135void
136BaseCache::init()
137{
138    if (!cpuSidePort->isConnected() || !memSidePort->isConnected())
139        fatal("Cache ports on %s are not connected\n", name());
140    cpuSidePort->sendRangeChange();
141    forwardSnoops = cpuSidePort->isSnooping();
142}
143
144BaseMasterPort &
145BaseCache::getMasterPort(const std::string &if_name, PortID idx)
146{
147    if (if_name == "mem_side") {
148        return *memSidePort;
149    }  else {
150        return MemObject::getMasterPort(if_name, idx);
151    }
152}
153
154BaseSlavePort &
155BaseCache::getSlavePort(const std::string &if_name, PortID idx)
156{
157    if (if_name == "cpu_side") {
158        return *cpuSidePort;
159    } else {
160        return MemObject::getSlavePort(if_name, idx);
161    }
162}
163
164bool
165BaseCache::inRange(Addr addr) const
166{
167    for (const auto& r : addrRanges) {
168        if (r.contains(addr)) {
169            return true;
170       }
171    }
172    return false;
173}
174
175void
176BaseCache::regStats()
177{
178    using namespace Stats;
179
180    // Hit statistics
181    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
182        MemCmd cmd(access_idx);
183        const string &cstr = cmd.toString();
184
185        hits[access_idx]
186            .init(system->maxMasters())
187            .name(name() + "." + cstr + "_hits")
188            .desc("number of " + cstr + " hits")
189            .flags(total | nozero | nonan)
190            ;
191        for (int i = 0; i < system->maxMasters(); i++) {
192            hits[access_idx].subname(i, system->getMasterName(i));
193        }
194    }
195
196// These macros make it easier to sum the right subset of commands and
197// to change the subset of commands that are considered "demand" vs
198// "non-demand"
199#define SUM_DEMAND(s) \
200    (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::WriteLineReq] + \
201     s[MemCmd::ReadExReq] + s[MemCmd::ReadCleanReq] + s[MemCmd::ReadSharedReq])
202
203// should writebacks be included here?  prior code was inconsistent...
204#define SUM_NON_DEMAND(s) \
205    (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
206
207    demandHits
208        .name(name() + ".demand_hits")
209        .desc("number of demand (read+write) hits")
210        .flags(total | nozero | nonan)
211        ;
212    demandHits = SUM_DEMAND(hits);
213    for (int i = 0; i < system->maxMasters(); i++) {
214        demandHits.subname(i, system->getMasterName(i));
215    }
216
217    overallHits
218        .name(name() + ".overall_hits")
219        .desc("number of overall hits")
220        .flags(total | nozero | nonan)
221        ;
222    overallHits = demandHits + SUM_NON_DEMAND(hits);
223    for (int i = 0; i < system->maxMasters(); i++) {
224        overallHits.subname(i, system->getMasterName(i));
225    }
226
227    // Miss statistics
228    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
229        MemCmd cmd(access_idx);
230        const string &cstr = cmd.toString();
231
232        misses[access_idx]
233            .init(system->maxMasters())
234            .name(name() + "." + cstr + "_misses")
235            .desc("number of " + cstr + " misses")
236            .flags(total | nozero | nonan)
237            ;
238        for (int i = 0; i < system->maxMasters(); i++) {
239            misses[access_idx].subname(i, system->getMasterName(i));
240        }
241    }
242
243    demandMisses
244        .name(name() + ".demand_misses")
245        .desc("number of demand (read+write) misses")
246        .flags(total | nozero | nonan)
247        ;
248    demandMisses = SUM_DEMAND(misses);
249    for (int i = 0; i < system->maxMasters(); i++) {
250        demandMisses.subname(i, system->getMasterName(i));
251    }
252
253    overallMisses
254        .name(name() + ".overall_misses")
255        .desc("number of overall misses")
256        .flags(total | nozero | nonan)
257        ;
258    overallMisses = demandMisses + SUM_NON_DEMAND(misses);
259    for (int i = 0; i < system->maxMasters(); i++) {
260        overallMisses.subname(i, system->getMasterName(i));
261    }
262
263    // Miss latency statistics
264    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
265        MemCmd cmd(access_idx);
266        const string &cstr = cmd.toString();
267
268        missLatency[access_idx]
269            .init(system->maxMasters())
270            .name(name() + "." + cstr + "_miss_latency")
271            .desc("number of " + cstr + " miss cycles")
272            .flags(total | nozero | nonan)
273            ;
274        for (int i = 0; i < system->maxMasters(); i++) {
275            missLatency[access_idx].subname(i, system->getMasterName(i));
276        }
277    }
278
279    demandMissLatency
280        .name(name() + ".demand_miss_latency")
281        .desc("number of demand (read+write) miss cycles")
282        .flags(total | nozero | nonan)
283        ;
284    demandMissLatency = SUM_DEMAND(missLatency);
285    for (int i = 0; i < system->maxMasters(); i++) {
286        demandMissLatency.subname(i, system->getMasterName(i));
287    }
288
289    overallMissLatency
290        .name(name() + ".overall_miss_latency")
291        .desc("number of overall miss cycles")
292        .flags(total | nozero | nonan)
293        ;
294    overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
295    for (int i = 0; i < system->maxMasters(); i++) {
296        overallMissLatency.subname(i, system->getMasterName(i));
297    }
298
299    // access formulas
300    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
301        MemCmd cmd(access_idx);
302        const string &cstr = cmd.toString();
303
304        accesses[access_idx]
305            .name(name() + "." + cstr + "_accesses")
306            .desc("number of " + cstr + " accesses(hits+misses)")
307            .flags(total | nozero | nonan)
308            ;
309        accesses[access_idx] = hits[access_idx] + misses[access_idx];
310
311        for (int i = 0; i < system->maxMasters(); i++) {
312            accesses[access_idx].subname(i, system->getMasterName(i));
313        }
314    }
315
316    demandAccesses
317        .name(name() + ".demand_accesses")
318        .desc("number of demand (read+write) accesses")
319        .flags(total | nozero | nonan)
320        ;
321    demandAccesses = demandHits + demandMisses;
322    for (int i = 0; i < system->maxMasters(); i++) {
323        demandAccesses.subname(i, system->getMasterName(i));
324    }
325
326    overallAccesses
327        .name(name() + ".overall_accesses")
328        .desc("number of overall (read+write) accesses")
329        .flags(total | nozero | nonan)
330        ;
331    overallAccesses = overallHits + overallMisses;
332    for (int i = 0; i < system->maxMasters(); i++) {
333        overallAccesses.subname(i, system->getMasterName(i));
334    }
335
336    // miss rate formulas
337    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
338        MemCmd cmd(access_idx);
339        const string &cstr = cmd.toString();
340
341        missRate[access_idx]
342            .name(name() + "." + cstr + "_miss_rate")
343            .desc("miss rate for " + cstr + " accesses")
344            .flags(total | nozero | nonan)
345            ;
346        missRate[access_idx] = misses[access_idx] / accesses[access_idx];
347
348        for (int i = 0; i < system->maxMasters(); i++) {
349            missRate[access_idx].subname(i, system->getMasterName(i));
350        }
351    }
352
353    demandMissRate
354        .name(name() + ".demand_miss_rate")
355        .desc("miss rate for demand accesses")
356        .flags(total | nozero | nonan)
357        ;
358    demandMissRate = demandMisses / demandAccesses;
359    for (int i = 0; i < system->maxMasters(); i++) {
360        demandMissRate.subname(i, system->getMasterName(i));
361    }
362
363    overallMissRate
364        .name(name() + ".overall_miss_rate")
365        .desc("miss rate for overall accesses")
366        .flags(total | nozero | nonan)
367        ;
368    overallMissRate = overallMisses / overallAccesses;
369    for (int i = 0; i < system->maxMasters(); i++) {
370        overallMissRate.subname(i, system->getMasterName(i));
371    }
372
373    // miss latency formulas
374    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
375        MemCmd cmd(access_idx);
376        const string &cstr = cmd.toString();
377
378        avgMissLatency[access_idx]
379            .name(name() + "." + cstr + "_avg_miss_latency")
380            .desc("average " + cstr + " miss latency")
381            .flags(total | nozero | nonan)
382            ;
383        avgMissLatency[access_idx] =
384            missLatency[access_idx] / misses[access_idx];
385
386        for (int i = 0; i < system->maxMasters(); i++) {
387            avgMissLatency[access_idx].subname(i, system->getMasterName(i));
388        }
389    }
390
391    demandAvgMissLatency
392        .name(name() + ".demand_avg_miss_latency")
393        .desc("average overall miss latency")
394        .flags(total | nozero | nonan)
395        ;
396    demandAvgMissLatency = demandMissLatency / demandMisses;
397    for (int i = 0; i < system->maxMasters(); i++) {
398        demandAvgMissLatency.subname(i, system->getMasterName(i));
399    }
400
401    overallAvgMissLatency
402        .name(name() + ".overall_avg_miss_latency")
403        .desc("average overall miss latency")
404        .flags(total | nozero | nonan)
405        ;
406    overallAvgMissLatency = overallMissLatency / overallMisses;
407    for (int i = 0; i < system->maxMasters(); i++) {
408        overallAvgMissLatency.subname(i, system->getMasterName(i));
409    }
410
411    blocked_cycles.init(NUM_BLOCKED_CAUSES);
412    blocked_cycles
413        .name(name() + ".blocked_cycles")
414        .desc("number of cycles access was blocked")
415        .subname(Blocked_NoMSHRs, "no_mshrs")
416        .subname(Blocked_NoTargets, "no_targets")
417        ;
418
419
420    blocked_causes.init(NUM_BLOCKED_CAUSES);
421    blocked_causes
422        .name(name() + ".blocked")
423        .desc("number of cycles access was blocked")
424        .subname(Blocked_NoMSHRs, "no_mshrs")
425        .subname(Blocked_NoTargets, "no_targets")
426        ;
427
428    avg_blocked
429        .name(name() + ".avg_blocked_cycles")
430        .desc("average number of cycles each access was blocked")
431        .subname(Blocked_NoMSHRs, "no_mshrs")
432        .subname(Blocked_NoTargets, "no_targets")
433        ;
434
435    avg_blocked = blocked_cycles / blocked_causes;
436
437    unusedPrefetches
438        .name(name() + ".unused_prefetches")
439        .desc("number of HardPF blocks evicted w/o reference")
440        .flags(nozero)
441        ;
442
443    writebacks
444        .init(system->maxMasters())
445        .name(name() + ".writebacks")
446        .desc("number of writebacks")
447        .flags(total | nozero | nonan)
448        ;
449    for (int i = 0; i < system->maxMasters(); i++) {
450        writebacks.subname(i, system->getMasterName(i));
451    }
452
453    // MSHR statistics
454    // MSHR hit statistics
455    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
456        MemCmd cmd(access_idx);
457        const string &cstr = cmd.toString();
458
459        mshr_hits[access_idx]
460            .init(system->maxMasters())
461            .name(name() + "." + cstr + "_mshr_hits")
462            .desc("number of " + cstr + " MSHR hits")
463            .flags(total | nozero | nonan)
464            ;
465        for (int i = 0; i < system->maxMasters(); i++) {
466            mshr_hits[access_idx].subname(i, system->getMasterName(i));
467        }
468    }
469
470    demandMshrHits
471        .name(name() + ".demand_mshr_hits")
472        .desc("number of demand (read+write) MSHR hits")
473        .flags(total | nozero | nonan)
474        ;
475    demandMshrHits = SUM_DEMAND(mshr_hits);
476    for (int i = 0; i < system->maxMasters(); i++) {
477        demandMshrHits.subname(i, system->getMasterName(i));
478    }
479
480    overallMshrHits
481        .name(name() + ".overall_mshr_hits")
482        .desc("number of overall MSHR hits")
483        .flags(total | nozero | nonan)
484        ;
485    overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
486    for (int i = 0; i < system->maxMasters(); i++) {
487        overallMshrHits.subname(i, system->getMasterName(i));
488    }
489
490    // MSHR miss statistics
491    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
492        MemCmd cmd(access_idx);
493        const string &cstr = cmd.toString();
494
495        mshr_misses[access_idx]
496            .init(system->maxMasters())
497            .name(name() + "." + cstr + "_mshr_misses")
498            .desc("number of " + cstr + " MSHR misses")
499            .flags(total | nozero | nonan)
500            ;
501        for (int i = 0; i < system->maxMasters(); i++) {
502            mshr_misses[access_idx].subname(i, system->getMasterName(i));
503        }
504    }
505
506    demandMshrMisses
507        .name(name() + ".demand_mshr_misses")
508        .desc("number of demand (read+write) MSHR misses")
509        .flags(total | nozero | nonan)
510        ;
511    demandMshrMisses = SUM_DEMAND(mshr_misses);
512    for (int i = 0; i < system->maxMasters(); i++) {
513        demandMshrMisses.subname(i, system->getMasterName(i));
514    }
515
516    overallMshrMisses
517        .name(name() + ".overall_mshr_misses")
518        .desc("number of overall MSHR misses")
519        .flags(total | nozero | nonan)
520        ;
521    overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
522    for (int i = 0; i < system->maxMasters(); i++) {
523        overallMshrMisses.subname(i, system->getMasterName(i));
524    }
525
526    // MSHR miss latency 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_miss_latency[access_idx]
532            .init(system->maxMasters())
533            .name(name() + "." + cstr + "_mshr_miss_latency")
534            .desc("number of " + cstr + " MSHR miss cycles")
535            .flags(total | nozero | nonan)
536            ;
537        for (int i = 0; i < system->maxMasters(); i++) {
538            mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
539        }
540    }
541
542    demandMshrMissLatency
543        .name(name() + ".demand_mshr_miss_latency")
544        .desc("number of demand (read+write) MSHR miss cycles")
545        .flags(total | nozero | nonan)
546        ;
547    demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
548    for (int i = 0; i < system->maxMasters(); i++) {
549        demandMshrMissLatency.subname(i, system->getMasterName(i));
550    }
551
552    overallMshrMissLatency
553        .name(name() + ".overall_mshr_miss_latency")
554        .desc("number of overall MSHR miss cycles")
555        .flags(total | nozero | nonan)
556        ;
557    overallMshrMissLatency =
558        demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
559    for (int i = 0; i < system->maxMasters(); i++) {
560        overallMshrMissLatency.subname(i, system->getMasterName(i));
561    }
562
563    // MSHR uncacheable statistics
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        mshr_uncacheable[access_idx]
569            .init(system->maxMasters())
570            .name(name() + "." + cstr + "_mshr_uncacheable")
571            .desc("number of " + cstr + " MSHR uncacheable")
572            .flags(total | nozero | nonan)
573            ;
574        for (int i = 0; i < system->maxMasters(); i++) {
575            mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
576        }
577    }
578
579    overallMshrUncacheable
580        .name(name() + ".overall_mshr_uncacheable_misses")
581        .desc("number of overall MSHR uncacheable misses")
582        .flags(total | nozero | nonan)
583        ;
584    overallMshrUncacheable =
585        SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
586    for (int i = 0; i < system->maxMasters(); i++) {
587        overallMshrUncacheable.subname(i, system->getMasterName(i));
588    }
589
590    // MSHR miss latency statistics
591    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
592        MemCmd cmd(access_idx);
593        const string &cstr = cmd.toString();
594
595        mshr_uncacheable_lat[access_idx]
596            .init(system->maxMasters())
597            .name(name() + "." + cstr + "_mshr_uncacheable_latency")
598            .desc("number of " + cstr + " MSHR uncacheable cycles")
599            .flags(total | nozero | nonan)
600            ;
601        for (int i = 0; i < system->maxMasters(); i++) {
602            mshr_uncacheable_lat[access_idx].subname(
603                i, system->getMasterName(i));
604        }
605    }
606
607    overallMshrUncacheableLatency
608        .name(name() + ".overall_mshr_uncacheable_latency")
609        .desc("number of overall MSHR uncacheable cycles")
610        .flags(total | nozero | nonan)
611        ;
612    overallMshrUncacheableLatency =
613        SUM_DEMAND(mshr_uncacheable_lat) +
614        SUM_NON_DEMAND(mshr_uncacheable_lat);
615    for (int i = 0; i < system->maxMasters(); i++) {
616        overallMshrUncacheableLatency.subname(i, system->getMasterName(i));
617    }
618
619#if 0
620    // MSHR access formulas
621    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
622        MemCmd cmd(access_idx);
623        const string &cstr = cmd.toString();
624
625        mshrAccesses[access_idx]
626            .name(name() + "." + cstr + "_mshr_accesses")
627            .desc("number of " + cstr + " mshr accesses(hits+misses)")
628            .flags(total | nozero | nonan)
629            ;
630        mshrAccesses[access_idx] =
631            mshr_hits[access_idx] + mshr_misses[access_idx]
632            + mshr_uncacheable[access_idx];
633    }
634
635    demandMshrAccesses
636        .name(name() + ".demand_mshr_accesses")
637        .desc("number of demand (read+write) mshr accesses")
638        .flags(total | nozero | nonan)
639        ;
640    demandMshrAccesses = demandMshrHits + demandMshrMisses;
641
642    overallMshrAccesses
643        .name(name() + ".overall_mshr_accesses")
644        .desc("number of overall (read+write) mshr accesses")
645        .flags(total | nozero | nonan)
646        ;
647    overallMshrAccesses = overallMshrHits + overallMshrMisses
648        + overallMshrUncacheable;
649#endif
650
651    // MSHR miss rate 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        mshrMissRate[access_idx]
657            .name(name() + "." + cstr + "_mshr_miss_rate")
658            .desc("mshr miss rate for " + cstr + " accesses")
659            .flags(total | nozero | nonan)
660            ;
661        mshrMissRate[access_idx] =
662            mshr_misses[access_idx] / accesses[access_idx];
663
664        for (int i = 0; i < system->maxMasters(); i++) {
665            mshrMissRate[access_idx].subname(i, system->getMasterName(i));
666        }
667    }
668
669    demandMshrMissRate
670        .name(name() + ".demand_mshr_miss_rate")
671        .desc("mshr miss rate for demand accesses")
672        .flags(total | nozero | nonan)
673        ;
674    demandMshrMissRate = demandMshrMisses / demandAccesses;
675    for (int i = 0; i < system->maxMasters(); i++) {
676        demandMshrMissRate.subname(i, system->getMasterName(i));
677    }
678
679    overallMshrMissRate
680        .name(name() + ".overall_mshr_miss_rate")
681        .desc("mshr miss rate for overall accesses")
682        .flags(total | nozero | nonan)
683        ;
684    overallMshrMissRate = overallMshrMisses / overallAccesses;
685    for (int i = 0; i < system->maxMasters(); i++) {
686        overallMshrMissRate.subname(i, system->getMasterName(i));
687    }
688
689    // mshrMiss 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        avgMshrMissLatency[access_idx]
695            .name(name() + "." + cstr + "_avg_mshr_miss_latency")
696            .desc("average " + cstr + " mshr miss latency")
697            .flags(total | nozero | nonan)
698            ;
699        avgMshrMissLatency[access_idx] =
700            mshr_miss_latency[access_idx] / mshr_misses[access_idx];
701
702        for (int i = 0; i < system->maxMasters(); i++) {
703            avgMshrMissLatency[access_idx].subname(
704                i, system->getMasterName(i));
705        }
706    }
707
708    demandAvgMshrMissLatency
709        .name(name() + ".demand_avg_mshr_miss_latency")
710        .desc("average overall mshr miss latency")
711        .flags(total | nozero | nonan)
712        ;
713    demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
714    for (int i = 0; i < system->maxMasters(); i++) {
715        demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
716    }
717
718    overallAvgMshrMissLatency
719        .name(name() + ".overall_avg_mshr_miss_latency")
720        .desc("average overall mshr miss latency")
721        .flags(total | nozero | nonan)
722        ;
723    overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
724    for (int i = 0; i < system->maxMasters(); i++) {
725        overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
726    }
727
728    // mshrUncacheable latency formulas
729    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
730        MemCmd cmd(access_idx);
731        const string &cstr = cmd.toString();
732
733        avgMshrUncacheableLatency[access_idx]
734            .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
735            .desc("average " + cstr + " mshr uncacheable latency")
736            .flags(total | nozero | nonan)
737            ;
738        avgMshrUncacheableLatency[access_idx] =
739            mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
740
741        for (int i = 0; i < system->maxMasters(); i++) {
742            avgMshrUncacheableLatency[access_idx].subname(
743                i, system->getMasterName(i));
744        }
745    }
746
747    overallAvgMshrUncacheableLatency
748        .name(name() + ".overall_avg_mshr_uncacheable_latency")
749        .desc("average overall mshr uncacheable latency")
750        .flags(total | nozero | nonan)
751        ;
752    overallAvgMshrUncacheableLatency =
753        overallMshrUncacheableLatency / overallMshrUncacheable;
754    for (int i = 0; i < system->maxMasters(); i++) {
755        overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
756    }
757
758}
759