base.cc revision 11486
11689SN/A/*
27944SGiacomo.Gabrielli@arm.com * Copyright (c) 2012-2013 ARM Limited
37944SGiacomo.Gabrielli@arm.com * All rights reserved.
47944SGiacomo.Gabrielli@arm.com *
57944SGiacomo.Gabrielli@arm.com * The license below extends only to copyright in the software and shall
67944SGiacomo.Gabrielli@arm.com * not be construed as granting a license to any other intellectual
77944SGiacomo.Gabrielli@arm.com * property including but not limited to intellectual property relating
87944SGiacomo.Gabrielli@arm.com * to a hardware implementation of the functionality of the software
97944SGiacomo.Gabrielli@arm.com * licensed hereunder.  You may use the software subject to the license
107944SGiacomo.Gabrielli@arm.com * terms below provided that you ensure that this notice is replicated
117944SGiacomo.Gabrielli@arm.com * unmodified and in its entirety in all distributions of the software,
127944SGiacomo.Gabrielli@arm.com * modified or unmodified, in source code or in binary form.
137944SGiacomo.Gabrielli@arm.com *
142326SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
151689SN/A * All rights reserved.
161689SN/A *
171689SN/A * Redistribution and use in source and binary forms, with or without
181689SN/A * modification, are permitted provided that the following conditions are
191689SN/A * met: redistributions of source code must retain the above copyright
201689SN/A * notice, this list of conditions and the following disclaimer;
211689SN/A * redistributions in binary form must reproduce the above copyright
221689SN/A * notice, this list of conditions and the following disclaimer in the
231689SN/A * documentation and/or other materials provided with the distribution;
241689SN/A * neither the name of the copyright holders nor the names of its
251689SN/A * contributors may be used to endorse or promote products derived from
261689SN/A * this software without specific prior written permission.
271689SN/A *
281689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
291689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
301689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
311689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
321689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
331689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
341689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
351689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
361689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
371689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
381689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392665Ssaidi@eecs.umich.edu *
402665Ssaidi@eecs.umich.edu * Authors: Erik Hallnor
411689SN/A */
421689SN/A
432292SN/A/**
442292SN/A * @file
451060SN/A * Definition of BaseCache functions.
461060SN/A */
471061SN/A
481060SN/A#include "mem/cache/base.hh"
491061SN/A
501060SN/A#include "debug/Cache.hh"
511062SN/A#include "debug/Drain.hh"
528229Snate@binkert.org#include "mem/cache/cache.hh"
538229Snate@binkert.org#include "mem/cache/mshr.hh"
548229Snate@binkert.org#include "mem/cache/tags/fa_lru.hh"
558229Snate@binkert.org#include "mem/cache/tags/lru.hh"
567813Ssteve.reinhardt@amd.com#include "mem/cache/tags/random_repl.hh"
575529Snate@binkert.org#include "sim/full_system.hh"
581060SN/A
595529Snate@binkert.orgusing namespace std;
602292SN/A
612292SN/ABaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name,
622292SN/A                                          BaseCache *_cache,
631060SN/A                                          const std::string &_label)
641689SN/A    : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label),
651689SN/A      blocked(false), mustSendRetry(false), sendRetryEvent(this)
661689SN/A{
671689SN/A}
681060SN/A
691060SN/ABaseCache::BaseCache(const BaseCacheParams *p, unsigned blk_size)
701060SN/A    : MemObject(p),
712292SN/A      cpuSidePort(nullptr), memSidePort(nullptr),
722292SN/A      mshrQueue("MSHRs", p->mshrs, 0, p->demand_mshr_reserve), // see below
732292SN/A      writeBuffer("write buffer", p->write_buffers, p->mshrs), // see below
742292SN/A      blkSize(blk_size),
752292SN/A      lookupLatency(p->hit_latency),
762292SN/A      forwardLatency(p->hit_latency),
772292SN/A      fillLatency(p->response_latency),
782292SN/A      responseLatency(p->response_latency),
791060SN/A      numTarget(p->tgts_per_mshr),
801061SN/A      forwardSnoops(true),
811060SN/A      isReadOnly(p->is_read_only),
821060SN/A      blocked(0),
831060SN/A      order(0),
841060SN/A      noTargetMSHR(nullptr),
852733Sktlim@umich.edu      missCount(p->max_miss_count),
861061SN/A      addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()),
871060SN/A      system(p->system)
882292SN/A{
891061SN/A    // the MSHR queue has no reserve entries as we check the MSHR
901061SN/A    // queue on every single allocation, whereas the write queue has
911061SN/A    // as many reserve entries as we have MSHRs, since every MSHR may
921060SN/A    // eventually require a writeback, and we do not check the write
932292SN/A    // buffer before committing to an MSHR
941061SN/A
951060SN/A    // forward snoops is overridden in init() once we can query
962733Sktlim@umich.edu    // whether the connected master is actually snooping or not
972292SN/A}
982292SN/A
992292SN/Avoid
1002292SN/ABaseCache::CacheSlavePort::setBlocked()
1012292SN/A{
1022292SN/A    assert(!blocked);
1032292SN/A    DPRINTF(CachePort, "Port is blocking new requests\n");
1042292SN/A    blocked = true;
1052292SN/A    // if we already scheduled a retry in this cycle, but it has not yet
1062292SN/A    // happened, cancel it
1072292SN/A    if (sendRetryEvent.scheduled()) {
1082292SN/A        owner.deschedule(sendRetryEvent);
1092292SN/A        DPRINTF(CachePort, "Port descheduled retry\n");
1102348SN/A        mustSendRetry = true;
1112348SN/A    }
1122348SN/A}
1132326SN/A
1142326SN/Avoid
1152292SN/ABaseCache::CacheSlavePort::clearBlocked()
1162292SN/A{
1172292SN/A    assert(blocked);
1182292SN/A    DPRINTF(CachePort, "Port is accepting new requests\n");
1192292SN/A    blocked = false;
1202292SN/A    if (mustSendRetry) {
1215336Shines@cs.fsu.edu        // @TODO: need to find a better time (next cycle?)
1222326SN/A        owner.schedule(sendRetryEvent, curTick() + 1);
1231060SN/A    }
1241060SN/A}
1252292SN/A
1265529Snate@binkert.orgvoid
1271061SN/ABaseCache::CacheSlavePort::processSendRetry()
1282292SN/A{
1292292SN/A    DPRINTF(CachePort, "Port is sending retry\n");
1301061SN/A
1312292SN/A    // reset the flag and call retry
1322292SN/A    mustSendRetry = false;
1331060SN/A    sendRetryReq();
1342292SN/A}
1351062SN/A
1361062SN/Avoid
1372348SN/ABaseCache::init()
1382307SN/A{
1391060SN/A    if (!cpuSidePort->isConnected() || !memSidePort->isConnected())
1402292SN/A        fatal("Cache ports on %s are not connected\n", name());
1416221Snate@binkert.org    cpuSidePort->sendRangeChange();
1422292SN/A    forwardSnoops = cpuSidePort->isSnooping();
1432292SN/A}
1441060SN/A
1451060SN/ABaseMasterPort &
1462292SN/ABaseCache::getMasterPort(const std::string &if_name, PortID idx)
1471060SN/A{
1481060SN/A    if (if_name == "mem_side") {
1492348SN/A        return *memSidePort;
1502307SN/A    }  else {
1512307SN/A        return MemObject::getMasterPort(if_name, idx);
1522348SN/A    }
1532307SN/A}
1542307SN/A
1552348SN/ABaseSlavePort &
1562307SN/ABaseCache::getSlavePort(const std::string &if_name, PortID idx)
1572307SN/A{
1582292SN/A    if (if_name == "cpu_side") {
1596221Snate@binkert.org        return *cpuSidePort;
1602292SN/A    } else {
1612292SN/A        return MemObject::getSlavePort(if_name, idx);
1622292SN/A    }
1632292SN/A}
1642292SN/A
1651060SN/Abool
1661060SN/ABaseCache::inRange(Addr addr) const
1672292SN/A{
1686221Snate@binkert.org    for (const auto& r : addrRanges) {
1692292SN/A        if (r.contains(addr)) {
1702292SN/A            return true;
1711060SN/A       }
1721060SN/A    }
1732292SN/A    return false;
1746221Snate@binkert.org}
1752292SN/A
1762292SN/Avoid
1772292SN/ABaseCache::regStats()
1782292SN/A{
1792292SN/A    using namespace Stats;
1801061SN/A
1811060SN/A    // Hit statistics
1822292SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
1831061SN/A        MemCmd cmd(access_idx);
1841061SN/A        const string &cstr = cmd.toString();
1852292SN/A
1862292SN/A        hits[access_idx]
1872292SN/A            .init(system->maxMasters())
1882292SN/A            .name(name() + "." + cstr + "_hits")
1891060SN/A            .desc("number of " + cstr + " hits")
1902348SN/A            .flags(total | nozero | nonan)
1912348SN/A            ;
1922348SN/A        for (int i = 0; i < system->maxMasters(); i++) {
1932333SN/A            hits[access_idx].subname(i, system->getMasterName(i));
1942333SN/A        }
1957944SGiacomo.Gabrielli@arm.com    }
1967944SGiacomo.Gabrielli@arm.com
1977944SGiacomo.Gabrielli@arm.com// These macros make it easier to sum the right subset of commands and
1987944SGiacomo.Gabrielli@arm.com// to change the subset of commands that are considered "demand" vs
1997944SGiacomo.Gabrielli@arm.com// "non-demand"
2002292SN/A#define SUM_DEMAND(s) \
2012326SN/A    (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::WriteLineReq] + \
2022326SN/A     s[MemCmd::ReadExReq] + s[MemCmd::ReadCleanReq] + s[MemCmd::ReadSharedReq])
2032292SN/A
2042326SN/A// should writebacks be included here?  prior code was inconsistent...
2052326SN/A#define SUM_NON_DEMAND(s) \
2061755SN/A    (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
2072292SN/A
2082292SN/A    demandHits
2092292SN/A        .name(name() + ".demand_hits")
2102292SN/A        .desc("number of demand (read+write) hits")
2112292SN/A        .flags(total | nozero | nonan)
2122292SN/A        ;
2132292SN/A    demandHits = SUM_DEMAND(hits);
2141060SN/A    for (int i = 0; i < system->maxMasters(); i++) {
2151060SN/A        demandHits.subname(i, system->getMasterName(i));
2162292SN/A    }
2171061SN/A
2181061SN/A    overallHits
2192292SN/A        .name(name() + ".overall_hits")
2202292SN/A        .desc("number of overall hits")
2212292SN/A        .flags(total | nozero | nonan)
2222292SN/A        ;
2236221Snate@binkert.org    overallHits = demandHits + SUM_NON_DEMAND(hits);
2241061SN/A    for (int i = 0; i < system->maxMasters(); i++) {
2252292SN/A        overallHits.subname(i, system->getMasterName(i));
2262301SN/A    }
2271755SN/A
2282292SN/A    // Miss statistics
2292292SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
2302292SN/A        MemCmd cmd(access_idx);
2312292SN/A        const string &cstr = cmd.toString();
2322292SN/A
2332292SN/A        misses[access_idx]
2342292SN/A            .init(system->maxMasters())
2352292SN/A            .name(name() + "." + cstr + "_misses")
2362292SN/A            .desc("number of " + cstr + " misses")
2372292SN/A            .flags(total | nozero | nonan)
2382292SN/A            ;
2392292SN/A        for (int i = 0; i < system->maxMasters(); i++) {
2402292SN/A            misses[access_idx].subname(i, system->getMasterName(i));
2412292SN/A        }
2422292SN/A    }
2437944SGiacomo.Gabrielli@arm.com
2447944SGiacomo.Gabrielli@arm.com    demandMisses
2457944SGiacomo.Gabrielli@arm.com        .name(name() + ".demand_misses")
2467944SGiacomo.Gabrielli@arm.com        .desc("number of demand (read+write) misses")
2477944SGiacomo.Gabrielli@arm.com        .flags(total | nozero | nonan)
2487944SGiacomo.Gabrielli@arm.com        ;
2492292SN/A    demandMisses = SUM_DEMAND(misses);
2501061SN/A    for (int i = 0; i < system->maxMasters(); i++) {
2511061SN/A        demandMisses.subname(i, system->getMasterName(i));
2522292SN/A    }
2532292SN/A
2542292SN/A    overallMisses
2552292SN/A        .name(name() + ".overall_misses")
2566221Snate@binkert.org        .desc("number of overall misses")
2571060SN/A        .flags(total | nozero | nonan)
2582292SN/A        ;
2596221Snate@binkert.org    overallMisses = demandMisses + SUM_NON_DEMAND(misses);
2601060SN/A    for (int i = 0; i < system->maxMasters(); i++) {
2612292SN/A        overallMisses.subname(i, system->getMasterName(i));
2622292SN/A    }
2631060SN/A
2641060SN/A    // Miss latency statistics
2652292SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
2666221Snate@binkert.org        MemCmd cmd(access_idx);
2672292SN/A        const string &cstr = cmd.toString();
2682292SN/A
2692292SN/A        missLatency[access_idx]
2702292SN/A            .init(system->maxMasters())
2712292SN/A            .name(name() + "." + cstr + "_miss_latency")
2721060SN/A            .desc("number of " + cstr + " miss cycles")
2732733Sktlim@umich.edu            .flags(total | nozero | nonan)
2741060SN/A            ;
2752292SN/A        for (int i = 0; i < system->maxMasters(); i++) {
2762292SN/A            missLatency[access_idx].subname(i, system->getMasterName(i));
2772292SN/A        }
2782292SN/A    }
2792292SN/A
2802292SN/A    demandMissLatency
2811061SN/A        .name(name() + ".demand_miss_latency")
2821061SN/A        .desc("number of demand (read+write) miss cycles")
2831061SN/A        .flags(total | nozero | nonan)
2842292SN/A        ;
2851061SN/A    demandMissLatency = SUM_DEMAND(missLatency);
2861060SN/A    for (int i = 0; i < system->maxMasters(); i++) {
2871060SN/A        demandMissLatency.subname(i, system->getMasterName(i));
2881060SN/A    }
2891060SN/A
2901060SN/A    overallMissLatency
2911060SN/A        .name(name() + ".overall_miss_latency")
2921060SN/A        .desc("number of overall miss cycles")
2931060SN/A        .flags(total | nozero | nonan)
2941060SN/A        ;
2951060SN/A    overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
2961060SN/A    for (int i = 0; i < system->maxMasters(); i++) {
2972292SN/A        overallMissLatency.subname(i, system->getMasterName(i));
2982292SN/A    }
2992292SN/A
3002292SN/A    // access formulas
3012292SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
3022292SN/A        MemCmd cmd(access_idx);
3032292SN/A        const string &cstr = cmd.toString();
3042292SN/A
3052292SN/A        accesses[access_idx]
3062292SN/A            .name(name() + "." + cstr + "_accesses")
3072348SN/A            .desc("number of " + cstr + " accesses(hits+misses)")
3082333SN/A            .flags(total | nozero | nonan)
3092333SN/A            ;
3107944SGiacomo.Gabrielli@arm.com        accesses[access_idx] = hits[access_idx] + misses[access_idx];
3117944SGiacomo.Gabrielli@arm.com
3127944SGiacomo.Gabrielli@arm.com        for (int i = 0; i < system->maxMasters(); i++) {
3137944SGiacomo.Gabrielli@arm.com            accesses[access_idx].subname(i, system->getMasterName(i));
3147944SGiacomo.Gabrielli@arm.com        }
3152292SN/A    }
3162348SN/A
3172348SN/A    demandAccesses
3182348SN/A        .name(name() + ".demand_accesses")
3192348SN/A        .desc("number of demand (read+write) accesses")
3202348SN/A        .flags(total | nozero | nonan)
3212292SN/A        ;
3222292SN/A    demandAccesses = demandHits + demandMisses;
3232292SN/A    for (int i = 0; i < system->maxMasters(); i++) {
3242292SN/A        demandAccesses.subname(i, system->getMasterName(i));
3252292SN/A    }
3262292SN/A
3271060SN/A    overallAccesses
3281060SN/A        .name(name() + ".overall_accesses")
3292292SN/A        .desc("number of overall (read+write) accesses")
3302292SN/A        .flags(total | nozero | nonan)
3311755SN/A        ;
3322292SN/A    overallAccesses = overallHits + overallMisses;
3332292SN/A    for (int i = 0; i < system->maxMasters(); i++) {
3341061SN/A        overallAccesses.subname(i, system->getMasterName(i));
3352292SN/A    }
3361061SN/A
3371061SN/A    // miss rate formulas
3381061SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
3391061SN/A        MemCmd cmd(access_idx);
3401061SN/A        const string &cstr = cmd.toString();
3411681SN/A
3421061SN/A        missRate[access_idx]
3431061SN/A            .name(name() + "." + cstr + "_miss_rate")
3441061SN/A            .desc("miss rate for " + cstr + " accesses")
3451061SN/A            .flags(total | nozero | nonan)
3462292SN/A            ;
3472292SN/A        missRate[access_idx] = misses[access_idx] / accesses[access_idx];
3482292SN/A
3492292SN/A        for (int i = 0; i < system->maxMasters(); i++) {
3502292SN/A            missRate[access_idx].subname(i, system->getMasterName(i));
3512292SN/A        }
3522292SN/A    }
3532292SN/A
3542292SN/A    demandMissRate
3552292SN/A        .name(name() + ".demand_miss_rate")
3562292SN/A        .desc("miss rate for demand accesses")
3572326SN/A        .flags(total | nozero | nonan)
3582326SN/A        ;
3592326SN/A    demandMissRate = demandMisses / demandAccesses;
3602292SN/A    for (int i = 0; i < system->maxMasters(); i++) {
3612292SN/A        demandMissRate.subname(i, system->getMasterName(i));
3622292SN/A    }
3632292SN/A
3642292SN/A    overallMissRate
3652292SN/A        .name(name() + ".overall_miss_rate")
3662292SN/A        .desc("miss rate for overall accesses")
3672292SN/A        .flags(total | nozero | nonan)
3682292SN/A        ;
3692292SN/A    overallMissRate = overallMisses / overallAccesses;
3702292SN/A    for (int i = 0; i < system->maxMasters(); i++) {
3712292SN/A        overallMissRate.subname(i, system->getMasterName(i));
3722292SN/A    }
3732292SN/A
3742292SN/A    // miss latency formulas
3752292SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
3762292SN/A        MemCmd cmd(access_idx);
3772292SN/A        const string &cstr = cmd.toString();
3782292SN/A
3792292SN/A        avgMissLatency[access_idx]
3802292SN/A            .name(name() + "." + cstr + "_avg_miss_latency")
3812292SN/A            .desc("average " + cstr + " miss latency")
3822326SN/A            .flags(total | nozero | nonan)
3832326SN/A            ;
3842292SN/A        avgMissLatency[access_idx] =
3852292SN/A            missLatency[access_idx] / misses[access_idx];
3862292SN/A
3872292SN/A        for (int i = 0; i < system->maxMasters(); i++) {
3882292SN/A            avgMissLatency[access_idx].subname(i, system->getMasterName(i));
3892292SN/A        }
3902292SN/A    }
3912292SN/A
3922292SN/A    demandAvgMissLatency
3932292SN/A        .name(name() + ".demand_avg_miss_latency")
3942292SN/A        .desc("average overall miss latency")
3952292SN/A        .flags(total | nozero | nonan)
3962292SN/A        ;
3972292SN/A    demandAvgMissLatency = demandMissLatency / demandMisses;
3982292SN/A    for (int i = 0; i < system->maxMasters(); i++) {
3996221Snate@binkert.org        demandAvgMissLatency.subname(i, system->getMasterName(i));
4002292SN/A    }
4012292SN/A
4026221Snate@binkert.org    overallAvgMissLatency
4032292SN/A        .name(name() + ".overall_avg_miss_latency")
4042292SN/A        .desc("average overall miss latency")
4052292SN/A        .flags(total | nozero | nonan)
4062292SN/A        ;
4072292SN/A    overallAvgMissLatency = overallMissLatency / overallMisses;
4082292SN/A    for (int i = 0; i < system->maxMasters(); i++) {
4091060SN/A        overallAvgMissLatency.subname(i, system->getMasterName(i));
4101060SN/A    }
4111060SN/A
4121060SN/A    blocked_cycles.init(NUM_BLOCKED_CAUSES);
4131060SN/A    blocked_cycles
4141060SN/A        .name(name() + ".blocked_cycles")
4151060SN/A        .desc("number of cycles access was blocked")
4161060SN/A        .subname(Blocked_NoMSHRs, "no_mshrs")
4171060SN/A        .subname(Blocked_NoTargets, "no_targets")
4181060SN/A        ;
4192292SN/A
4201060SN/A
4211060SN/A    blocked_causes.init(NUM_BLOCKED_CAUSES);
4221060SN/A    blocked_causes
4231060SN/A        .name(name() + ".blocked")
4241060SN/A        .desc("number of cycles access was blocked")
4251060SN/A        .subname(Blocked_NoMSHRs, "no_mshrs")
4261060SN/A        .subname(Blocked_NoTargets, "no_targets")
4271060SN/A        ;
4281060SN/A
4291060SN/A    avg_blocked
4301060SN/A        .name(name() + ".avg_blocked_cycles")
4311060SN/A        .desc("average number of cycles each access was blocked")
4321060SN/A        .subname(Blocked_NoMSHRs, "no_mshrs")
4332348SN/A        .subname(Blocked_NoTargets, "no_targets")
4342307SN/A        ;
4351060SN/A
4361060SN/A    avg_blocked = blocked_cycles / blocked_causes;
4372292SN/A
4381060SN/A    unusedPrefetches
4391060SN/A        .name(name() + ".unused_prefetches")
4401060SN/A        .desc("number of HardPF blocks evicted w/o reference")
4411060SN/A        .flags(nozero)
4421060SN/A        ;
4431060SN/A
4441060SN/A    writebacks
4452292SN/A        .init(system->maxMasters())
4461060SN/A        .name(name() + ".writebacks")
4472326SN/A        .desc("number of writebacks")
4481061SN/A        .flags(total | nozero | nonan)
4491684SN/A        ;
4502326SN/A    for (int i = 0; i < system->maxMasters(); i++) {
4512326SN/A        writebacks.subname(i, system->getMasterName(i));
4521755SN/A    }
4532292SN/A
4541684SN/A    // MSHR statistics
4551684SN/A    // MSHR hit statistics
4561684SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
4571684SN/A        MemCmd cmd(access_idx);
4581684SN/A        const string &cstr = cmd.toString();
4591684SN/A
4601684SN/A        mshr_hits[access_idx]
4611684SN/A            .init(system->maxMasters())
4621684SN/A            .name(name() + "." + cstr + "_mshr_hits")
4631684SN/A            .desc("number of " + cstr + " MSHR hits")
4641684SN/A            .flags(total | nozero | nonan)
4651684SN/A            ;
4661684SN/A        for (int i = 0; i < system->maxMasters(); i++) {
4671062SN/A            mshr_hits[access_idx].subname(i, system->getMasterName(i));
4682292SN/A        }
4692292SN/A    }
4702292SN/A
4712292SN/A    demandMshrHits
4722292SN/A        .name(name() + ".demand_mshr_hits")
4732292SN/A        .desc("number of demand (read+write) MSHR hits")
4745999Snate@binkert.org        .flags(total | nozero | nonan)
4752292SN/A        ;
4765999Snate@binkert.org    demandMshrHits = SUM_DEMAND(mshr_hits);
4772326SN/A    for (int i = 0; i < system->maxMasters(); i++) {
4785999Snate@binkert.org        demandMshrHits.subname(i, system->getMasterName(i));
4792292SN/A    }
4805999Snate@binkert.org
4812292SN/A    overallMshrHits
4825999Snate@binkert.org        .name(name() + ".overall_mshr_hits")
4832292SN/A        .desc("number of overall MSHR hits")
4845999Snate@binkert.org        .flags(total | nozero | nonan)
4852292SN/A        ;
4865999Snate@binkert.org    overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
4872292SN/A    for (int i = 0; i < system->maxMasters(); i++) {
4885999Snate@binkert.org        overallMshrHits.subname(i, system->getMasterName(i));
4892292SN/A    }
4905999Snate@binkert.org
4912292SN/A    // MSHR miss statistics
4925999Snate@binkert.org    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
4932292SN/A        MemCmd cmd(access_idx);
4942292SN/A        const string &cstr = cmd.toString();
4952292SN/A
4965999Snate@binkert.org        mshr_misses[access_idx]
4972292SN/A            .init(system->maxMasters())
4982292SN/A            .name(name() + "." + cstr + "_mshr_misses")
4995999Snate@binkert.org            .desc("number of " + cstr + " MSHR misses")
5002727Sktlim@umich.edu            .flags(total | nozero | nonan)
5011062SN/A            ;
5022727Sktlim@umich.edu        for (int i = 0; i < system->maxMasters(); i++) {
5032727Sktlim@umich.edu            mshr_misses[access_idx].subname(i, system->getMasterName(i));
5042727Sktlim@umich.edu        }
5055999Snate@binkert.org    }
5062348SN/A
5075999Snate@binkert.org    demandMshrMisses
5082727Sktlim@umich.edu        .name(name() + ".demand_mshr_misses")
5092727Sktlim@umich.edu        .desc("number of demand (read+write) MSHR misses")
5102727Sktlim@umich.edu        .flags(total | nozero | nonan)
5115999Snate@binkert.org        ;
5122301SN/A    demandMshrMisses = SUM_DEMAND(mshr_misses);
5132348SN/A    for (int i = 0; i < system->maxMasters(); i++) {
5142348SN/A        demandMshrMisses.subname(i, system->getMasterName(i));
5152348SN/A    }
5165999Snate@binkert.org
5175999Snate@binkert.org    overallMshrMisses
5182348SN/A        .name(name() + ".overall_mshr_misses")
5195999Snate@binkert.org        .desc("number of overall MSHR misses")
5202301SN/A        .flags(total | nozero | nonan)
5212348SN/A        ;
5222326SN/A    overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
5232727Sktlim@umich.edu    for (int i = 0; i < system->maxMasters(); i++) {
5242348SN/A        overallMshrMisses.subname(i, system->getMasterName(i));
5255999Snate@binkert.org    }
5262348SN/A
5272326SN/A    // MSHR miss latency statistics
5287897Shestness@cs.utexas.edu    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
5297897Shestness@cs.utexas.edu        MemCmd cmd(access_idx);
5307897Shestness@cs.utexas.edu        const string &cstr = cmd.toString();
5317897Shestness@cs.utexas.edu
5327897Shestness@cs.utexas.edu        mshr_miss_latency[access_idx]
5337897Shestness@cs.utexas.edu            .init(system->maxMasters())
5347897Shestness@cs.utexas.edu            .name(name() + "." + cstr + "_mshr_miss_latency")
5357897Shestness@cs.utexas.edu            .desc("number of " + cstr + " MSHR miss cycles")
5367897Shestness@cs.utexas.edu            .flags(total | nozero | nonan)
5377897Shestness@cs.utexas.edu            ;
5381060SN/A        for (int i = 0; i < system->maxMasters(); i++) {
5391060SN/A            mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
5402292SN/A        }
541    }
542
543    demandMshrMissLatency
544        .name(name() + ".demand_mshr_miss_latency")
545        .desc("number of demand (read+write) MSHR miss cycles")
546        .flags(total | nozero | nonan)
547        ;
548    demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
549    for (int i = 0; i < system->maxMasters(); i++) {
550        demandMshrMissLatency.subname(i, system->getMasterName(i));
551    }
552
553    overallMshrMissLatency
554        .name(name() + ".overall_mshr_miss_latency")
555        .desc("number of overall MSHR miss cycles")
556        .flags(total | nozero | nonan)
557        ;
558    overallMshrMissLatency =
559        demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
560    for (int i = 0; i < system->maxMasters(); i++) {
561        overallMshrMissLatency.subname(i, system->getMasterName(i));
562    }
563
564    // MSHR uncacheable statistics
565    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
566        MemCmd cmd(access_idx);
567        const string &cstr = cmd.toString();
568
569        mshr_uncacheable[access_idx]
570            .init(system->maxMasters())
571            .name(name() + "." + cstr + "_mshr_uncacheable")
572            .desc("number of " + cstr + " MSHR uncacheable")
573            .flags(total | nozero | nonan)
574            ;
575        for (int i = 0; i < system->maxMasters(); i++) {
576            mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
577        }
578    }
579
580    overallMshrUncacheable
581        .name(name() + ".overall_mshr_uncacheable_misses")
582        .desc("number of overall MSHR uncacheable misses")
583        .flags(total | nozero | nonan)
584        ;
585    overallMshrUncacheable =
586        SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
587    for (int i = 0; i < system->maxMasters(); i++) {
588        overallMshrUncacheable.subname(i, system->getMasterName(i));
589    }
590
591    // MSHR miss latency statistics
592    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
593        MemCmd cmd(access_idx);
594        const string &cstr = cmd.toString();
595
596        mshr_uncacheable_lat[access_idx]
597            .init(system->maxMasters())
598            .name(name() + "." + cstr + "_mshr_uncacheable_latency")
599            .desc("number of " + cstr + " MSHR uncacheable cycles")
600            .flags(total | nozero | nonan)
601            ;
602        for (int i = 0; i < system->maxMasters(); i++) {
603            mshr_uncacheable_lat[access_idx].subname(
604                i, system->getMasterName(i));
605        }
606    }
607
608    overallMshrUncacheableLatency
609        .name(name() + ".overall_mshr_uncacheable_latency")
610        .desc("number of overall MSHR uncacheable cycles")
611        .flags(total | nozero | nonan)
612        ;
613    overallMshrUncacheableLatency =
614        SUM_DEMAND(mshr_uncacheable_lat) +
615        SUM_NON_DEMAND(mshr_uncacheable_lat);
616    for (int i = 0; i < system->maxMasters(); i++) {
617        overallMshrUncacheableLatency.subname(i, system->getMasterName(i));
618    }
619
620#if 0
621    // MSHR access formulas
622    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
623        MemCmd cmd(access_idx);
624        const string &cstr = cmd.toString();
625
626        mshrAccesses[access_idx]
627            .name(name() + "." + cstr + "_mshr_accesses")
628            .desc("number of " + cstr + " mshr accesses(hits+misses)")
629            .flags(total | nozero | nonan)
630            ;
631        mshrAccesses[access_idx] =
632            mshr_hits[access_idx] + mshr_misses[access_idx]
633            + mshr_uncacheable[access_idx];
634    }
635
636    demandMshrAccesses
637        .name(name() + ".demand_mshr_accesses")
638        .desc("number of demand (read+write) mshr accesses")
639        .flags(total | nozero | nonan)
640        ;
641    demandMshrAccesses = demandMshrHits + demandMshrMisses;
642
643    overallMshrAccesses
644        .name(name() + ".overall_mshr_accesses")
645        .desc("number of overall (read+write) mshr accesses")
646        .flags(total | nozero | nonan)
647        ;
648    overallMshrAccesses = overallMshrHits + overallMshrMisses
649        + overallMshrUncacheable;
650#endif
651
652    // MSHR miss rate formulas
653    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
654        MemCmd cmd(access_idx);
655        const string &cstr = cmd.toString();
656
657        mshrMissRate[access_idx]
658            .name(name() + "." + cstr + "_mshr_miss_rate")
659            .desc("mshr miss rate for " + cstr + " accesses")
660            .flags(total | nozero | nonan)
661            ;
662        mshrMissRate[access_idx] =
663            mshr_misses[access_idx] / accesses[access_idx];
664
665        for (int i = 0; i < system->maxMasters(); i++) {
666            mshrMissRate[access_idx].subname(i, system->getMasterName(i));
667        }
668    }
669
670    demandMshrMissRate
671        .name(name() + ".demand_mshr_miss_rate")
672        .desc("mshr miss rate for demand accesses")
673        .flags(total | nozero | nonan)
674        ;
675    demandMshrMissRate = demandMshrMisses / demandAccesses;
676    for (int i = 0; i < system->maxMasters(); i++) {
677        demandMshrMissRate.subname(i, system->getMasterName(i));
678    }
679
680    overallMshrMissRate
681        .name(name() + ".overall_mshr_miss_rate")
682        .desc("mshr miss rate for overall accesses")
683        .flags(total | nozero | nonan)
684        ;
685    overallMshrMissRate = overallMshrMisses / overallAccesses;
686    for (int i = 0; i < system->maxMasters(); i++) {
687        overallMshrMissRate.subname(i, system->getMasterName(i));
688    }
689
690    // mshrMiss latency formulas
691    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
692        MemCmd cmd(access_idx);
693        const string &cstr = cmd.toString();
694
695        avgMshrMissLatency[access_idx]
696            .name(name() + "." + cstr + "_avg_mshr_miss_latency")
697            .desc("average " + cstr + " mshr miss latency")
698            .flags(total | nozero | nonan)
699            ;
700        avgMshrMissLatency[access_idx] =
701            mshr_miss_latency[access_idx] / mshr_misses[access_idx];
702
703        for (int i = 0; i < system->maxMasters(); i++) {
704            avgMshrMissLatency[access_idx].subname(
705                i, system->getMasterName(i));
706        }
707    }
708
709    demandAvgMshrMissLatency
710        .name(name() + ".demand_avg_mshr_miss_latency")
711        .desc("average overall mshr miss latency")
712        .flags(total | nozero | nonan)
713        ;
714    demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
715    for (int i = 0; i < system->maxMasters(); i++) {
716        demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
717    }
718
719    overallAvgMshrMissLatency
720        .name(name() + ".overall_avg_mshr_miss_latency")
721        .desc("average overall mshr miss latency")
722        .flags(total | nozero | nonan)
723        ;
724    overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
725    for (int i = 0; i < system->maxMasters(); i++) {
726        overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
727    }
728
729    // mshrUncacheable latency formulas
730    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
731        MemCmd cmd(access_idx);
732        const string &cstr = cmd.toString();
733
734        avgMshrUncacheableLatency[access_idx]
735            .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
736            .desc("average " + cstr + " mshr uncacheable latency")
737            .flags(total | nozero | nonan)
738            ;
739        avgMshrUncacheableLatency[access_idx] =
740            mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
741
742        for (int i = 0; i < system->maxMasters(); i++) {
743            avgMshrUncacheableLatency[access_idx].subname(
744                i, system->getMasterName(i));
745        }
746    }
747
748    overallAvgMshrUncacheableLatency
749        .name(name() + ".overall_avg_mshr_uncacheable_latency")
750        .desc("average overall mshr uncacheable latency")
751        .flags(total | nozero | nonan)
752        ;
753    overallAvgMshrUncacheableLatency =
754        overallMshrUncacheableLatency / overallMshrUncacheable;
755    for (int i = 0; i < system->maxMasters(); i++) {
756        overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
757    }
758
759}
760