base.cc revision 8708
12810SN/A/*
22810SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
32810SN/A * All rights reserved.
42810SN/A *
52810SN/A * Redistribution and use in source and binary forms, with or without
62810SN/A * modification, are permitted provided that the following conditions are
72810SN/A * met: redistributions of source code must retain the above copyright
82810SN/A * notice, this list of conditions and the following disclaimer;
92810SN/A * redistributions in binary form must reproduce the above copyright
102810SN/A * notice, this list of conditions and the following disclaimer in the
112810SN/A * documentation and/or other materials provided with the distribution;
122810SN/A * neither the name of the copyright holders nor the names of its
132810SN/A * contributors may be used to endorse or promote products derived from
142810SN/A * this software without specific prior written permission.
152810SN/A *
162810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272810SN/A *
282810SN/A * Authors: Erik Hallnor
292810SN/A */
302810SN/A
312810SN/A/**
322810SN/A * @file
332810SN/A * Definition of BaseCache functions.
342810SN/A */
352810SN/A
363348SN/A#include "cpu/base.hh"
373348SN/A#include "cpu/smt.hh"
388232Snate@binkert.org#include "debug/Cache.hh"
395338Sstever@gmail.com#include "mem/cache/base.hh"
405338Sstever@gmail.com#include "mem/cache/mshr.hh"
412810SN/A
422810SN/Ausing namespace std;
432810SN/A
444965SN/ABaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache,
456122SSteve.Reinhardt@amd.com                                const std::string &_label)
465314SN/A    : SimpleTimingPort(_name, _cache), cache(_cache),
475314SN/A      label(_label), otherPort(NULL),
486122SSteve.Reinhardt@amd.com      blocked(false), mustSendRetry(false)
492810SN/A{
504475SN/A}
514475SN/A
524475SN/A
535034SN/ABaseCache::BaseCache(const Params *p)
545034SN/A    : MemObject(p),
555314SN/A      mshrQueue("MSHRs", p->mshrs, 4, MSHRQueue_MSHRs),
565314SN/A      writeBuffer("write buffer", p->write_buffers, p->mshrs+1000,
574628SN/A                  MSHRQueue_WriteBuffer),
585034SN/A      blkSize(p->block_size),
595034SN/A      hitLatency(p->latency),
605034SN/A      numTarget(p->tgts_per_mshr),
616122SSteve.Reinhardt@amd.com      forwardSnoops(p->forward_snoops),
628134SAli.Saidi@ARM.com      isTopLevel(p->is_top_level),
634626SN/A      blocked(0),
644626SN/A      noTargetMSHR(NULL),
655034SN/A      missCount(p->max_miss_count),
666122SSteve.Reinhardt@amd.com      drainEvent(NULL),
676978SLisa.Hsu@amd.com      addrRange(p->addr_range),
686978SLisa.Hsu@amd.com      _numCpus(p->num_cpus)
694458SN/A{
702810SN/A}
712810SN/A
722811SN/Avoid
732810SN/ABaseCache::CachePort::recvStatusChange(Port::Status status)
742810SN/A{
754458SN/A    if (status == Port::RangeChange) {
764458SN/A        otherPort->sendStatusChange(Port::RangeChange);
774458SN/A    }
782810SN/A}
792810SN/A
805314SN/A
815314SN/Abool
825314SN/ABaseCache::CachePort::checkFunctional(PacketPtr pkt)
835314SN/A{
845314SN/A    pkt->pushLabel(label);
855314SN/A    bool done = SimpleTimingPort::checkFunctional(pkt);
865314SN/A    pkt->popLabel();
875314SN/A    return done;
885314SN/A}
895314SN/A
905314SN/A
916227Snate@binkert.orgunsigned
926227Snate@binkert.orgBaseCache::CachePort::deviceBlockSize() const
932810SN/A{
942810SN/A    return cache->getBlockSize();
952810SN/A}
962810SN/A
973606SN/A
984458SN/Abool
994458SN/ABaseCache::CachePort::recvRetryCommon()
1003013SN/A{
1013236SN/A    assert(waitingOnRetry);
1024458SN/A    waitingOnRetry = false;
1034458SN/A    return false;
1044458SN/A}
1053246SN/A
1063309SN/A
1073013SN/Avoid
1082810SN/ABaseCache::CachePort::setBlocked()
1092810SN/A{
1103013SN/A    assert(!blocked);
1113013SN/A    DPRINTF(Cache, "Cache Blocking\n");
1122810SN/A    blocked = true;
1133013SN/A    //Clear the retry flag
1143013SN/A    mustSendRetry = false;
1152810SN/A}
1162810SN/A
1172810SN/Avoid
1182810SN/ABaseCache::CachePort::clearBlocked()
1192810SN/A{
1203013SN/A    assert(blocked);
1213013SN/A    DPRINTF(Cache, "Cache Unblocking\n");
1223013SN/A    blocked = false;
1232897SN/A    if (mustSendRetry)
1242897SN/A    {
1253013SN/A        DPRINTF(Cache, "Cache Sending Retry\n");
1262897SN/A        mustSendRetry = false;
1274666SN/A        SendRetryEvent *ev = new SendRetryEvent(this, true);
1284666SN/A        // @TODO: need to find a better time (next bus cycle?)
1298708Sandreas.hansson@arm.com        cache->schedule(ev, curTick() + 1);
1302897SN/A    }
1312810SN/A}
1322810SN/A
1332844SN/A
1342810SN/Avoid
1352858SN/ABaseCache::init()
1362858SN/A{
1372858SN/A    if (!cpuSidePort || !memSidePort)
1382858SN/A        panic("Cache not hooked up on both sides\n");
1392858SN/A    cpuSidePort->sendStatusChange(Port::RangeChange);
1402858SN/A}
1412858SN/A
1424628SN/A
1432858SN/Avoid
1442810SN/ABaseCache::regStats()
1452810SN/A{
1462810SN/A    using namespace Stats;
1472810SN/A
1482810SN/A    // Hit statistics
1494022SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
1504022SN/A        MemCmd cmd(access_idx);
1514022SN/A        const string &cstr = cmd.toString();
1522810SN/A
1532810SN/A        hits[access_idx]
1546978SLisa.Hsu@amd.com#if FULL_SYSTEM
1556978SLisa.Hsu@amd.com            .init(_numCpus + 1)
1566978SLisa.Hsu@amd.com#else
1576978SLisa.Hsu@amd.com            .init(_numCpus)
1586978SLisa.Hsu@amd.com#endif
1592810SN/A            .name(name() + "." + cstr + "_hits")
1602810SN/A            .desc("number of " + cstr + " hits")
1612810SN/A            .flags(total | nozero | nonan)
1622810SN/A            ;
1632810SN/A    }
1642810SN/A
1654871SN/A// These macros make it easier to sum the right subset of commands and
1664871SN/A// to change the subset of commands that are considered "demand" vs
1674871SN/A// "non-demand"
1684871SN/A#define SUM_DEMAND(s) \
1694871SN/A    (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
1704871SN/A
1714871SN/A// should writebacks be included here?  prior code was inconsistent...
1724871SN/A#define SUM_NON_DEMAND(s) \
1734871SN/A    (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
1744871SN/A
1752810SN/A    demandHits
1762810SN/A        .name(name() + ".demand_hits")
1772810SN/A        .desc("number of demand (read+write) hits")
1782810SN/A        .flags(total)
1792810SN/A        ;
1804871SN/A    demandHits = SUM_DEMAND(hits);
1812810SN/A
1822810SN/A    overallHits
1832810SN/A        .name(name() + ".overall_hits")
1842810SN/A        .desc("number of overall hits")
1852810SN/A        .flags(total)
1862810SN/A        ;
1874871SN/A    overallHits = demandHits + SUM_NON_DEMAND(hits);
1882810SN/A
1892810SN/A    // Miss statistics
1904022SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
1914022SN/A        MemCmd cmd(access_idx);
1924022SN/A        const string &cstr = cmd.toString();
1932810SN/A
1942810SN/A        misses[access_idx]
1956978SLisa.Hsu@amd.com#if FULL_SYSTEM
1966978SLisa.Hsu@amd.com            .init(_numCpus + 1)
1976978SLisa.Hsu@amd.com#else
1986978SLisa.Hsu@amd.com            .init(_numCpus)
1996978SLisa.Hsu@amd.com#endif
2002810SN/A            .name(name() + "." + cstr + "_misses")
2012810SN/A            .desc("number of " + cstr + " misses")
2022810SN/A            .flags(total | nozero | nonan)
2032810SN/A            ;
2042810SN/A    }
2052810SN/A
2062810SN/A    demandMisses
2072810SN/A        .name(name() + ".demand_misses")
2082810SN/A        .desc("number of demand (read+write) misses")
2092810SN/A        .flags(total)
2102810SN/A        ;
2114871SN/A    demandMisses = SUM_DEMAND(misses);
2122810SN/A
2132810SN/A    overallMisses
2142810SN/A        .name(name() + ".overall_misses")
2152810SN/A        .desc("number of overall misses")
2162810SN/A        .flags(total)
2172810SN/A        ;
2184871SN/A    overallMisses = demandMisses + SUM_NON_DEMAND(misses);
2192810SN/A
2202810SN/A    // Miss latency statistics
2214022SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
2224022SN/A        MemCmd cmd(access_idx);
2234022SN/A        const string &cstr = cmd.toString();
2242810SN/A
2252810SN/A        missLatency[access_idx]
2262810SN/A            .init(maxThreadsPerCPU)
2272810SN/A            .name(name() + "." + cstr + "_miss_latency")
2282810SN/A            .desc("number of " + cstr + " miss cycles")
2292810SN/A            .flags(total | nozero | nonan)
2302810SN/A            ;
2312810SN/A    }
2322810SN/A
2332810SN/A    demandMissLatency
2342810SN/A        .name(name() + ".demand_miss_latency")
2352810SN/A        .desc("number of demand (read+write) miss cycles")
2362810SN/A        .flags(total)
2372810SN/A        ;
2384871SN/A    demandMissLatency = SUM_DEMAND(missLatency);
2392810SN/A
2402810SN/A    overallMissLatency
2412810SN/A        .name(name() + ".overall_miss_latency")
2422810SN/A        .desc("number of overall miss cycles")
2432810SN/A        .flags(total)
2442810SN/A        ;
2454871SN/A    overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
2462810SN/A
2472810SN/A    // access formulas
2484022SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
2494022SN/A        MemCmd cmd(access_idx);
2504022SN/A        const string &cstr = cmd.toString();
2512810SN/A
2522810SN/A        accesses[access_idx]
2532810SN/A            .name(name() + "." + cstr + "_accesses")
2542810SN/A            .desc("number of " + cstr + " accesses(hits+misses)")
2552810SN/A            .flags(total | nozero | nonan)
2562810SN/A            ;
2572810SN/A
2582810SN/A        accesses[access_idx] = hits[access_idx] + misses[access_idx];
2592810SN/A    }
2602810SN/A
2612810SN/A    demandAccesses
2622810SN/A        .name(name() + ".demand_accesses")
2632810SN/A        .desc("number of demand (read+write) accesses")
2642810SN/A        .flags(total)
2652810SN/A        ;
2662810SN/A    demandAccesses = demandHits + demandMisses;
2672810SN/A
2682810SN/A    overallAccesses
2692810SN/A        .name(name() + ".overall_accesses")
2702810SN/A        .desc("number of overall (read+write) accesses")
2712810SN/A        .flags(total)
2722810SN/A        ;
2732810SN/A    overallAccesses = overallHits + overallMisses;
2742810SN/A
2752810SN/A    // miss rate formulas
2764022SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
2774022SN/A        MemCmd cmd(access_idx);
2784022SN/A        const string &cstr = cmd.toString();
2792810SN/A
2802810SN/A        missRate[access_idx]
2812810SN/A            .name(name() + "." + cstr + "_miss_rate")
2822810SN/A            .desc("miss rate for " + cstr + " accesses")
2832810SN/A            .flags(total | nozero | nonan)
2842810SN/A            ;
2852810SN/A
2862810SN/A        missRate[access_idx] = misses[access_idx] / accesses[access_idx];
2872810SN/A    }
2882810SN/A
2892810SN/A    demandMissRate
2902810SN/A        .name(name() + ".demand_miss_rate")
2912810SN/A        .desc("miss rate for demand accesses")
2922810SN/A        .flags(total)
2932810SN/A        ;
2942810SN/A    demandMissRate = demandMisses / demandAccesses;
2952810SN/A
2962810SN/A    overallMissRate
2972810SN/A        .name(name() + ".overall_miss_rate")
2982810SN/A        .desc("miss rate for overall accesses")
2992810SN/A        .flags(total)
3002810SN/A        ;
3012810SN/A    overallMissRate = overallMisses / overallAccesses;
3022810SN/A
3032810SN/A    // miss latency formulas
3044022SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
3054022SN/A        MemCmd cmd(access_idx);
3064022SN/A        const string &cstr = cmd.toString();
3072810SN/A
3082810SN/A        avgMissLatency[access_idx]
3092810SN/A            .name(name() + "." + cstr + "_avg_miss_latency")
3102810SN/A            .desc("average " + cstr + " miss latency")
3112810SN/A            .flags(total | nozero | nonan)
3122810SN/A            ;
3132810SN/A
3142810SN/A        avgMissLatency[access_idx] =
3152810SN/A            missLatency[access_idx] / misses[access_idx];
3162810SN/A    }
3172810SN/A
3182810SN/A    demandAvgMissLatency
3192810SN/A        .name(name() + ".demand_avg_miss_latency")
3202810SN/A        .desc("average overall miss latency")
3212810SN/A        .flags(total)
3222810SN/A        ;
3232810SN/A    demandAvgMissLatency = demandMissLatency / demandMisses;
3242810SN/A
3252810SN/A    overallAvgMissLatency
3262810SN/A        .name(name() + ".overall_avg_miss_latency")
3272810SN/A        .desc("average overall miss latency")
3282810SN/A        .flags(total)
3292810SN/A        ;
3302810SN/A    overallAvgMissLatency = overallMissLatency / overallMisses;
3312810SN/A
3322810SN/A    blocked_cycles.init(NUM_BLOCKED_CAUSES);
3332810SN/A    blocked_cycles
3342810SN/A        .name(name() + ".blocked_cycles")
3352810SN/A        .desc("number of cycles access was blocked")
3362810SN/A        .subname(Blocked_NoMSHRs, "no_mshrs")
3372810SN/A        .subname(Blocked_NoTargets, "no_targets")
3382810SN/A        ;
3392810SN/A
3402810SN/A
3412810SN/A    blocked_causes.init(NUM_BLOCKED_CAUSES);
3422810SN/A    blocked_causes
3432810SN/A        .name(name() + ".blocked")
3442810SN/A        .desc("number of cycles access was blocked")
3452810SN/A        .subname(Blocked_NoMSHRs, "no_mshrs")
3462810SN/A        .subname(Blocked_NoTargets, "no_targets")
3472810SN/A        ;
3482810SN/A
3492810SN/A    avg_blocked
3502810SN/A        .name(name() + ".avg_blocked_cycles")
3512810SN/A        .desc("average number of cycles each access was blocked")
3522810SN/A        .subname(Blocked_NoMSHRs, "no_mshrs")
3532810SN/A        .subname(Blocked_NoTargets, "no_targets")
3542810SN/A        ;
3552810SN/A
3562810SN/A    avg_blocked = blocked_cycles / blocked_causes;
3572810SN/A
3582810SN/A    fastWrites
3592810SN/A        .name(name() + ".fast_writes")
3602810SN/A        .desc("number of fast writes performed")
3612810SN/A        ;
3622810SN/A
3632810SN/A    cacheCopies
3642810SN/A        .name(name() + ".cache_copies")
3652810SN/A        .desc("number of cache copies performed")
3662810SN/A        ;
3672826SN/A
3684626SN/A    writebacks
3694626SN/A        .init(maxThreadsPerCPU)
3704626SN/A        .name(name() + ".writebacks")
3714626SN/A        .desc("number of writebacks")
3724626SN/A        .flags(total)
3734626SN/A        ;
3744626SN/A
3754626SN/A    // MSHR statistics
3764626SN/A    // MSHR hit statistics
3774626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
3784626SN/A        MemCmd cmd(access_idx);
3794626SN/A        const string &cstr = cmd.toString();
3804626SN/A
3814626SN/A        mshr_hits[access_idx]
3824626SN/A            .init(maxThreadsPerCPU)
3834626SN/A            .name(name() + "." + cstr + "_mshr_hits")
3844626SN/A            .desc("number of " + cstr + " MSHR hits")
3854626SN/A            .flags(total | nozero | nonan)
3864626SN/A            ;
3874626SN/A    }
3884626SN/A
3894626SN/A    demandMshrHits
3904626SN/A        .name(name() + ".demand_mshr_hits")
3914626SN/A        .desc("number of demand (read+write) MSHR hits")
3924626SN/A        .flags(total)
3934626SN/A        ;
3944871SN/A    demandMshrHits = SUM_DEMAND(mshr_hits);
3954626SN/A
3964626SN/A    overallMshrHits
3974626SN/A        .name(name() + ".overall_mshr_hits")
3984626SN/A        .desc("number of overall MSHR hits")
3994626SN/A        .flags(total)
4004626SN/A        ;
4014871SN/A    overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
4024626SN/A
4034626SN/A    // MSHR miss statistics
4044626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
4054626SN/A        MemCmd cmd(access_idx);
4064626SN/A        const string &cstr = cmd.toString();
4074626SN/A
4084626SN/A        mshr_misses[access_idx]
4094626SN/A            .init(maxThreadsPerCPU)
4104626SN/A            .name(name() + "." + cstr + "_mshr_misses")
4114626SN/A            .desc("number of " + cstr + " MSHR misses")
4124626SN/A            .flags(total | nozero | nonan)
4134626SN/A            ;
4144626SN/A    }
4154626SN/A
4164626SN/A    demandMshrMisses
4174626SN/A        .name(name() + ".demand_mshr_misses")
4184626SN/A        .desc("number of demand (read+write) MSHR misses")
4194626SN/A        .flags(total)
4204626SN/A        ;
4214871SN/A    demandMshrMisses = SUM_DEMAND(mshr_misses);
4224626SN/A
4234626SN/A    overallMshrMisses
4244626SN/A        .name(name() + ".overall_mshr_misses")
4254626SN/A        .desc("number of overall MSHR misses")
4264626SN/A        .flags(total)
4274626SN/A        ;
4284871SN/A    overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
4294626SN/A
4304626SN/A    // MSHR miss latency statistics
4314626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
4324626SN/A        MemCmd cmd(access_idx);
4334626SN/A        const string &cstr = cmd.toString();
4344626SN/A
4354626SN/A        mshr_miss_latency[access_idx]
4364626SN/A            .init(maxThreadsPerCPU)
4374626SN/A            .name(name() + "." + cstr + "_mshr_miss_latency")
4384626SN/A            .desc("number of " + cstr + " MSHR miss cycles")
4394626SN/A            .flags(total | nozero | nonan)
4404626SN/A            ;
4414626SN/A    }
4424626SN/A
4434626SN/A    demandMshrMissLatency
4444626SN/A        .name(name() + ".demand_mshr_miss_latency")
4454626SN/A        .desc("number of demand (read+write) MSHR miss cycles")
4464626SN/A        .flags(total)
4474626SN/A        ;
4484871SN/A    demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
4494626SN/A
4504626SN/A    overallMshrMissLatency
4514626SN/A        .name(name() + ".overall_mshr_miss_latency")
4524626SN/A        .desc("number of overall MSHR miss cycles")
4534626SN/A        .flags(total)
4544626SN/A        ;
4554871SN/A    overallMshrMissLatency =
4564871SN/A        demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
4574626SN/A
4584626SN/A    // MSHR uncacheable statistics
4594626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
4604626SN/A        MemCmd cmd(access_idx);
4614626SN/A        const string &cstr = cmd.toString();
4624626SN/A
4634626SN/A        mshr_uncacheable[access_idx]
4644626SN/A            .init(maxThreadsPerCPU)
4654626SN/A            .name(name() + "." + cstr + "_mshr_uncacheable")
4664626SN/A            .desc("number of " + cstr + " MSHR uncacheable")
4674626SN/A            .flags(total | nozero | nonan)
4684626SN/A            ;
4694626SN/A    }
4704626SN/A
4714626SN/A    overallMshrUncacheable
4724626SN/A        .name(name() + ".overall_mshr_uncacheable_misses")
4734626SN/A        .desc("number of overall MSHR uncacheable misses")
4744626SN/A        .flags(total)
4754626SN/A        ;
4764871SN/A    overallMshrUncacheable =
4774871SN/A        SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
4784626SN/A
4794626SN/A    // MSHR miss latency statistics
4804626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
4814626SN/A        MemCmd cmd(access_idx);
4824626SN/A        const string &cstr = cmd.toString();
4834626SN/A
4844626SN/A        mshr_uncacheable_lat[access_idx]
4854626SN/A            .init(maxThreadsPerCPU)
4864626SN/A            .name(name() + "." + cstr + "_mshr_uncacheable_latency")
4874626SN/A            .desc("number of " + cstr + " MSHR uncacheable cycles")
4884626SN/A            .flags(total | nozero | nonan)
4894626SN/A            ;
4904626SN/A    }
4914626SN/A
4924626SN/A    overallMshrUncacheableLatency
4934626SN/A        .name(name() + ".overall_mshr_uncacheable_latency")
4944626SN/A        .desc("number of overall MSHR uncacheable cycles")
4954626SN/A        .flags(total)
4964626SN/A        ;
4974871SN/A    overallMshrUncacheableLatency =
4984871SN/A        SUM_DEMAND(mshr_uncacheable_lat) +
4994871SN/A        SUM_NON_DEMAND(mshr_uncacheable_lat);
5004626SN/A
5014626SN/A#if 0
5024626SN/A    // MSHR access formulas
5034626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
5044626SN/A        MemCmd cmd(access_idx);
5054626SN/A        const string &cstr = cmd.toString();
5064626SN/A
5074626SN/A        mshrAccesses[access_idx]
5084626SN/A            .name(name() + "." + cstr + "_mshr_accesses")
5094626SN/A            .desc("number of " + cstr + " mshr accesses(hits+misses)")
5104626SN/A            .flags(total | nozero | nonan)
5114626SN/A            ;
5124626SN/A        mshrAccesses[access_idx] =
5134626SN/A            mshr_hits[access_idx] + mshr_misses[access_idx]
5144626SN/A            + mshr_uncacheable[access_idx];
5154626SN/A    }
5164626SN/A
5174626SN/A    demandMshrAccesses
5184626SN/A        .name(name() + ".demand_mshr_accesses")
5194626SN/A        .desc("number of demand (read+write) mshr accesses")
5204626SN/A        .flags(total | nozero | nonan)
5214626SN/A        ;
5224626SN/A    demandMshrAccesses = demandMshrHits + demandMshrMisses;
5234626SN/A
5244626SN/A    overallMshrAccesses
5254626SN/A        .name(name() + ".overall_mshr_accesses")
5264626SN/A        .desc("number of overall (read+write) mshr accesses")
5274626SN/A        .flags(total | nozero | nonan)
5284626SN/A        ;
5294626SN/A    overallMshrAccesses = overallMshrHits + overallMshrMisses
5304626SN/A        + overallMshrUncacheable;
5314626SN/A#endif
5324626SN/A
5334626SN/A    // MSHR miss rate formulas
5344626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
5354626SN/A        MemCmd cmd(access_idx);
5364626SN/A        const string &cstr = cmd.toString();
5374626SN/A
5384626SN/A        mshrMissRate[access_idx]
5394626SN/A            .name(name() + "." + cstr + "_mshr_miss_rate")
5404626SN/A            .desc("mshr miss rate for " + cstr + " accesses")
5414626SN/A            .flags(total | nozero | nonan)
5424626SN/A            ;
5434626SN/A
5444626SN/A        mshrMissRate[access_idx] =
5454626SN/A            mshr_misses[access_idx] / accesses[access_idx];
5464626SN/A    }
5474626SN/A
5484626SN/A    demandMshrMissRate
5494626SN/A        .name(name() + ".demand_mshr_miss_rate")
5504626SN/A        .desc("mshr miss rate for demand accesses")
5514626SN/A        .flags(total)
5524626SN/A        ;
5534626SN/A    demandMshrMissRate = demandMshrMisses / demandAccesses;
5544626SN/A
5554626SN/A    overallMshrMissRate
5564626SN/A        .name(name() + ".overall_mshr_miss_rate")
5574626SN/A        .desc("mshr miss rate for overall accesses")
5584626SN/A        .flags(total)
5594626SN/A        ;
5604626SN/A    overallMshrMissRate = overallMshrMisses / overallAccesses;
5614626SN/A
5624626SN/A    // mshrMiss latency formulas
5634626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
5644626SN/A        MemCmd cmd(access_idx);
5654626SN/A        const string &cstr = cmd.toString();
5664626SN/A
5674626SN/A        avgMshrMissLatency[access_idx]
5684626SN/A            .name(name() + "." + cstr + "_avg_mshr_miss_latency")
5694626SN/A            .desc("average " + cstr + " mshr miss latency")
5704626SN/A            .flags(total | nozero | nonan)
5714626SN/A            ;
5724626SN/A
5734626SN/A        avgMshrMissLatency[access_idx] =
5744626SN/A            mshr_miss_latency[access_idx] / mshr_misses[access_idx];
5754626SN/A    }
5764626SN/A
5774626SN/A    demandAvgMshrMissLatency
5784626SN/A        .name(name() + ".demand_avg_mshr_miss_latency")
5794626SN/A        .desc("average overall mshr miss latency")
5804626SN/A        .flags(total)
5814626SN/A        ;
5824626SN/A    demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
5834626SN/A
5844626SN/A    overallAvgMshrMissLatency
5854626SN/A        .name(name() + ".overall_avg_mshr_miss_latency")
5864626SN/A        .desc("average overall mshr miss latency")
5874626SN/A        .flags(total)
5884626SN/A        ;
5894626SN/A    overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
5904626SN/A
5914626SN/A    // mshrUncacheable latency formulas
5924626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
5934626SN/A        MemCmd cmd(access_idx);
5944626SN/A        const string &cstr = cmd.toString();
5954626SN/A
5964626SN/A        avgMshrUncacheableLatency[access_idx]
5974626SN/A            .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
5984626SN/A            .desc("average " + cstr + " mshr uncacheable latency")
5994626SN/A            .flags(total | nozero | nonan)
6004626SN/A            ;
6014626SN/A
6024626SN/A        avgMshrUncacheableLatency[access_idx] =
6034626SN/A            mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
6044626SN/A    }
6054626SN/A
6064626SN/A    overallAvgMshrUncacheableLatency
6074626SN/A        .name(name() + ".overall_avg_mshr_uncacheable_latency")
6084626SN/A        .desc("average overall mshr uncacheable latency")
6094626SN/A        .flags(total)
6104626SN/A        ;
6114626SN/A    overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
6124626SN/A
6134626SN/A    mshr_cap_events
6144626SN/A        .init(maxThreadsPerCPU)
6154626SN/A        .name(name() + ".mshr_cap_events")
6164626SN/A        .desc("number of times MSHR cap was activated")
6174626SN/A        .flags(total)
6184626SN/A        ;
6194626SN/A
6204626SN/A    //software prefetching stats
6214626SN/A    soft_prefetch_mshr_full
6224626SN/A        .init(maxThreadsPerCPU)
6234626SN/A        .name(name() + ".soft_prefetch_mshr_full")
6244626SN/A        .desc("number of mshr full events for SW prefetching instrutions")
6254626SN/A        .flags(total)
6264626SN/A        ;
6274626SN/A
6284626SN/A    mshr_no_allocate_misses
6294626SN/A        .name(name() +".no_allocate_misses")
6304626SN/A        .desc("Number of misses that were no-allocate")
6314626SN/A        ;
6324626SN/A
6332810SN/A}
6343503SN/A
6353503SN/Aunsigned int
6363503SN/ABaseCache::drain(Event *de)
6373503SN/A{
6384626SN/A    int count = memSidePort->drain(de) + cpuSidePort->drain(de);
6394626SN/A
6403503SN/A    // Set status
6414626SN/A    if (count != 0) {
6423503SN/A        drainEvent = de;
6433503SN/A
6443503SN/A        changeState(SimObject::Draining);
6454626SN/A        return count;
6463503SN/A    }
6473503SN/A
6483503SN/A    changeState(SimObject::Drained);
6493503SN/A    return 0;
6503503SN/A}
651