base.cc revision 9795
12810SN/A/*
29614Srene.dejong@arm.com * Copyright (c) 2012-2013 ARM Limited
38856Sandreas.hansson@arm.com * All rights reserved.
48856Sandreas.hansson@arm.com *
58856Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
68856Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
78856Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
88856Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
98856Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
108856Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
118856Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
128856Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
138856Sandreas.hansson@arm.com *
142810SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
152810SN/A * All rights reserved.
162810SN/A *
172810SN/A * Redistribution and use in source and binary forms, with or without
182810SN/A * modification, are permitted provided that the following conditions are
192810SN/A * met: redistributions of source code must retain the above copyright
202810SN/A * notice, this list of conditions and the following disclaimer;
212810SN/A * redistributions in binary form must reproduce the above copyright
222810SN/A * notice, this list of conditions and the following disclaimer in the
232810SN/A * documentation and/or other materials provided with the distribution;
242810SN/A * neither the name of the copyright holders nor the names of its
252810SN/A * contributors may be used to endorse or promote products derived from
262810SN/A * this software without specific prior written permission.
272810SN/A *
282810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392810SN/A *
402810SN/A * Authors: Erik Hallnor
412810SN/A */
422810SN/A
432810SN/A/**
442810SN/A * @file
452810SN/A * Definition of BaseCache functions.
462810SN/A */
472810SN/A
483348SN/A#include "cpu/base.hh"
493348SN/A#include "cpu/smt.hh"
508232Snate@binkert.org#include "debug/Cache.hh"
519152Satgutier@umich.edu#include "debug/Drain.hh"
529795Sandreas.hansson@arm.com#include "mem/cache/tags/fa_lru.hh"
539795Sandreas.hansson@arm.com#include "mem/cache/tags/lru.hh"
545338Sstever@gmail.com#include "mem/cache/base.hh"
559795Sandreas.hansson@arm.com#include "mem/cache/cache.hh"
565338Sstever@gmail.com#include "mem/cache/mshr.hh"
578786Sgblack@eecs.umich.edu#include "sim/full_system.hh"
582810SN/A
592810SN/Ausing namespace std;
602810SN/A
618856Sandreas.hansson@arm.comBaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name,
628856Sandreas.hansson@arm.com                                          BaseCache *_cache,
638856Sandreas.hansson@arm.com                                          const std::string &_label)
648922Swilliam.wang@arm.com    : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label),
658914Sandreas.hansson@arm.com      blocked(false), mustSendRetry(false), sendRetryEvent(this)
668856Sandreas.hansson@arm.com{
678856Sandreas.hansson@arm.com}
684475SN/A
695034SN/ABaseCache::BaseCache(const Params *p)
705034SN/A    : MemObject(p),
715314SN/A      mshrQueue("MSHRs", p->mshrs, 4, MSHRQueue_MSHRs),
725314SN/A      writeBuffer("write buffer", p->write_buffers, p->mshrs+1000,
734628SN/A                  MSHRQueue_WriteBuffer),
745034SN/A      blkSize(p->block_size),
759263Smrinmoy.ghosh@arm.com      hitLatency(p->hit_latency),
769263Smrinmoy.ghosh@arm.com      responseLatency(p->response_latency),
775034SN/A      numTarget(p->tgts_per_mshr),
786122SSteve.Reinhardt@amd.com      forwardSnoops(p->forward_snoops),
798134SAli.Saidi@ARM.com      isTopLevel(p->is_top_level),
804626SN/A      blocked(0),
814626SN/A      noTargetMSHR(NULL),
825034SN/A      missCount(p->max_miss_count),
838883SAli.Saidi@ARM.com      addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()),
848833Sdam.sunwoo@arm.com      system(p->system)
854458SN/A{
862810SN/A}
872810SN/A
883013SN/Avoid
898856Sandreas.hansson@arm.comBaseCache::CacheSlavePort::setBlocked()
902810SN/A{
913013SN/A    assert(!blocked);
928856Sandreas.hansson@arm.com    DPRINTF(CachePort, "Cache port %s blocking new requests\n", name());
932810SN/A    blocked = true;
949614Srene.dejong@arm.com    // if we already scheduled a retry in this cycle, but it has not yet
959614Srene.dejong@arm.com    // happened, cancel it
969614Srene.dejong@arm.com    if (sendRetryEvent.scheduled()) {
979614Srene.dejong@arm.com       owner.deschedule(sendRetryEvent);
989614Srene.dejong@arm.com       DPRINTF(CachePort, "Cache port %s deschedule retry\n", name());
999614Srene.dejong@arm.com       mustSendRetry = true;
1009614Srene.dejong@arm.com    }
1012810SN/A}
1022810SN/A
1032810SN/Avoid
1048856Sandreas.hansson@arm.comBaseCache::CacheSlavePort::clearBlocked()
1052810SN/A{
1063013SN/A    assert(blocked);
1078856Sandreas.hansson@arm.com    DPRINTF(CachePort, "Cache port %s accepting new requests\n", name());
1083013SN/A    blocked = false;
1098856Sandreas.hansson@arm.com    if (mustSendRetry) {
1108856Sandreas.hansson@arm.com        DPRINTF(CachePort, "Cache port %s sending retry\n", name());
1112897SN/A        mustSendRetry = false;
1124666SN/A        // @TODO: need to find a better time (next bus cycle?)
1138922Swilliam.wang@arm.com        owner.schedule(sendRetryEvent, curTick() + 1);
1142897SN/A    }
1152810SN/A}
1162810SN/A
1172844SN/A
1182810SN/Avoid
1192858SN/ABaseCache::init()
1202858SN/A{
1218856Sandreas.hansson@arm.com    if (!cpuSidePort->isConnected() || !memSidePort->isConnected())
1228922Swilliam.wang@arm.com        fatal("Cache ports on %s are not connected\n", name());
1238711Sandreas.hansson@arm.com    cpuSidePort->sendRangeChange();
1242858SN/A}
1252858SN/A
1269294Sandreas.hansson@arm.comBaseMasterPort &
1279294Sandreas.hansson@arm.comBaseCache::getMasterPort(const std::string &if_name, PortID idx)
1288922Swilliam.wang@arm.com{
1298922Swilliam.wang@arm.com    if (if_name == "mem_side") {
1308922Swilliam.wang@arm.com        return *memSidePort;
1318922Swilliam.wang@arm.com    }  else {
1328922Swilliam.wang@arm.com        return MemObject::getMasterPort(if_name, idx);
1338922Swilliam.wang@arm.com    }
1348922Swilliam.wang@arm.com}
1358922Swilliam.wang@arm.com
1369294Sandreas.hansson@arm.comBaseSlavePort &
1379294Sandreas.hansson@arm.comBaseCache::getSlavePort(const std::string &if_name, PortID idx)
1388922Swilliam.wang@arm.com{
1398922Swilliam.wang@arm.com    if (if_name == "cpu_side") {
1408922Swilliam.wang@arm.com        return *cpuSidePort;
1418922Swilliam.wang@arm.com    } else {
1428922Swilliam.wang@arm.com        return MemObject::getSlavePort(if_name, idx);
1438922Swilliam.wang@arm.com    }
1448922Swilliam.wang@arm.com}
1454628SN/A
1462858SN/Avoid
1472810SN/ABaseCache::regStats()
1482810SN/A{
1492810SN/A    using namespace Stats;
1502810SN/A
1512810SN/A    // Hit statistics
1524022SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
1534022SN/A        MemCmd cmd(access_idx);
1544022SN/A        const string &cstr = cmd.toString();
1552810SN/A
1562810SN/A        hits[access_idx]
1578833Sdam.sunwoo@arm.com            .init(system->maxMasters())
1582810SN/A            .name(name() + "." + cstr + "_hits")
1592810SN/A            .desc("number of " + cstr + " hits")
1602810SN/A            .flags(total | nozero | nonan)
1612810SN/A            ;
1628833Sdam.sunwoo@arm.com        for (int i = 0; i < system->maxMasters(); i++) {
1638833Sdam.sunwoo@arm.com            hits[access_idx].subname(i, system->getMasterName(i));
1648833Sdam.sunwoo@arm.com        }
1652810SN/A    }
1662810SN/A
1674871SN/A// These macros make it easier to sum the right subset of commands and
1684871SN/A// to change the subset of commands that are considered "demand" vs
1694871SN/A// "non-demand"
1704871SN/A#define SUM_DEMAND(s) \
1714871SN/A    (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
1724871SN/A
1734871SN/A// should writebacks be included here?  prior code was inconsistent...
1744871SN/A#define SUM_NON_DEMAND(s) \
1754871SN/A    (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
1764871SN/A
1772810SN/A    demandHits
1782810SN/A        .name(name() + ".demand_hits")
1792810SN/A        .desc("number of demand (read+write) hits")
1808833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
1812810SN/A        ;
1824871SN/A    demandHits = SUM_DEMAND(hits);
1838833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
1848833Sdam.sunwoo@arm.com        demandHits.subname(i, system->getMasterName(i));
1858833Sdam.sunwoo@arm.com    }
1862810SN/A
1872810SN/A    overallHits
1882810SN/A        .name(name() + ".overall_hits")
1892810SN/A        .desc("number of overall hits")
1908833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
1912810SN/A        ;
1924871SN/A    overallHits = demandHits + SUM_NON_DEMAND(hits);
1938833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
1948833Sdam.sunwoo@arm.com        overallHits.subname(i, system->getMasterName(i));
1958833Sdam.sunwoo@arm.com    }
1962810SN/A
1972810SN/A    // Miss statistics
1984022SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
1994022SN/A        MemCmd cmd(access_idx);
2004022SN/A        const string &cstr = cmd.toString();
2012810SN/A
2022810SN/A        misses[access_idx]
2038833Sdam.sunwoo@arm.com            .init(system->maxMasters())
2042810SN/A            .name(name() + "." + cstr + "_misses")
2052810SN/A            .desc("number of " + cstr + " misses")
2062810SN/A            .flags(total | nozero | nonan)
2072810SN/A            ;
2088833Sdam.sunwoo@arm.com        for (int i = 0; i < system->maxMasters(); i++) {
2098833Sdam.sunwoo@arm.com            misses[access_idx].subname(i, system->getMasterName(i));
2108833Sdam.sunwoo@arm.com        }
2112810SN/A    }
2122810SN/A
2132810SN/A    demandMisses
2142810SN/A        .name(name() + ".demand_misses")
2152810SN/A        .desc("number of demand (read+write) misses")
2168833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
2172810SN/A        ;
2184871SN/A    demandMisses = SUM_DEMAND(misses);
2198833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
2208833Sdam.sunwoo@arm.com        demandMisses.subname(i, system->getMasterName(i));
2218833Sdam.sunwoo@arm.com    }
2222810SN/A
2232810SN/A    overallMisses
2242810SN/A        .name(name() + ".overall_misses")
2252810SN/A        .desc("number of overall misses")
2268833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
2272810SN/A        ;
2284871SN/A    overallMisses = demandMisses + SUM_NON_DEMAND(misses);
2298833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
2308833Sdam.sunwoo@arm.com        overallMisses.subname(i, system->getMasterName(i));
2318833Sdam.sunwoo@arm.com    }
2322810SN/A
2332810SN/A    // Miss latency statistics
2344022SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
2354022SN/A        MemCmd cmd(access_idx);
2364022SN/A        const string &cstr = cmd.toString();
2372810SN/A
2382810SN/A        missLatency[access_idx]
2398833Sdam.sunwoo@arm.com            .init(system->maxMasters())
2402810SN/A            .name(name() + "." + cstr + "_miss_latency")
2412810SN/A            .desc("number of " + cstr + " miss cycles")
2422810SN/A            .flags(total | nozero | nonan)
2432810SN/A            ;
2448833Sdam.sunwoo@arm.com        for (int i = 0; i < system->maxMasters(); i++) {
2458833Sdam.sunwoo@arm.com            missLatency[access_idx].subname(i, system->getMasterName(i));
2468833Sdam.sunwoo@arm.com        }
2472810SN/A    }
2482810SN/A
2492810SN/A    demandMissLatency
2502810SN/A        .name(name() + ".demand_miss_latency")
2512810SN/A        .desc("number of demand (read+write) miss cycles")
2528833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
2532810SN/A        ;
2544871SN/A    demandMissLatency = SUM_DEMAND(missLatency);
2558833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
2568833Sdam.sunwoo@arm.com        demandMissLatency.subname(i, system->getMasterName(i));
2578833Sdam.sunwoo@arm.com    }
2582810SN/A
2592810SN/A    overallMissLatency
2602810SN/A        .name(name() + ".overall_miss_latency")
2612810SN/A        .desc("number of overall miss cycles")
2628833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
2632810SN/A        ;
2644871SN/A    overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
2658833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
2668833Sdam.sunwoo@arm.com        overallMissLatency.subname(i, system->getMasterName(i));
2678833Sdam.sunwoo@arm.com    }
2682810SN/A
2692810SN/A    // access formulas
2704022SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
2714022SN/A        MemCmd cmd(access_idx);
2724022SN/A        const string &cstr = cmd.toString();
2732810SN/A
2742810SN/A        accesses[access_idx]
2752810SN/A            .name(name() + "." + cstr + "_accesses")
2762810SN/A            .desc("number of " + cstr + " accesses(hits+misses)")
2772810SN/A            .flags(total | nozero | nonan)
2782810SN/A            ;
2798833Sdam.sunwoo@arm.com        accesses[access_idx] = hits[access_idx] + misses[access_idx];
2802810SN/A
2818833Sdam.sunwoo@arm.com        for (int i = 0; i < system->maxMasters(); i++) {
2828833Sdam.sunwoo@arm.com            accesses[access_idx].subname(i, system->getMasterName(i));
2838833Sdam.sunwoo@arm.com        }
2842810SN/A    }
2852810SN/A
2862810SN/A    demandAccesses
2872810SN/A        .name(name() + ".demand_accesses")
2882810SN/A        .desc("number of demand (read+write) accesses")
2898833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
2902810SN/A        ;
2912810SN/A    demandAccesses = demandHits + demandMisses;
2928833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
2938833Sdam.sunwoo@arm.com        demandAccesses.subname(i, system->getMasterName(i));
2948833Sdam.sunwoo@arm.com    }
2952810SN/A
2962810SN/A    overallAccesses
2972810SN/A        .name(name() + ".overall_accesses")
2982810SN/A        .desc("number of overall (read+write) accesses")
2998833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
3002810SN/A        ;
3012810SN/A    overallAccesses = overallHits + overallMisses;
3028833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
3038833Sdam.sunwoo@arm.com        overallAccesses.subname(i, system->getMasterName(i));
3048833Sdam.sunwoo@arm.com    }
3052810SN/A
3062810SN/A    // miss rate formulas
3074022SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
3084022SN/A        MemCmd cmd(access_idx);
3094022SN/A        const string &cstr = cmd.toString();
3102810SN/A
3112810SN/A        missRate[access_idx]
3122810SN/A            .name(name() + "." + cstr + "_miss_rate")
3132810SN/A            .desc("miss rate for " + cstr + " accesses")
3142810SN/A            .flags(total | nozero | nonan)
3152810SN/A            ;
3168833Sdam.sunwoo@arm.com        missRate[access_idx] = misses[access_idx] / accesses[access_idx];
3172810SN/A
3188833Sdam.sunwoo@arm.com        for (int i = 0; i < system->maxMasters(); i++) {
3198833Sdam.sunwoo@arm.com            missRate[access_idx].subname(i, system->getMasterName(i));
3208833Sdam.sunwoo@arm.com        }
3212810SN/A    }
3222810SN/A
3232810SN/A    demandMissRate
3242810SN/A        .name(name() + ".demand_miss_rate")
3252810SN/A        .desc("miss rate for demand accesses")
3268833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
3272810SN/A        ;
3282810SN/A    demandMissRate = demandMisses / demandAccesses;
3298833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
3308833Sdam.sunwoo@arm.com        demandMissRate.subname(i, system->getMasterName(i));
3318833Sdam.sunwoo@arm.com    }
3322810SN/A
3332810SN/A    overallMissRate
3342810SN/A        .name(name() + ".overall_miss_rate")
3352810SN/A        .desc("miss rate for overall accesses")
3368833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
3372810SN/A        ;
3382810SN/A    overallMissRate = overallMisses / overallAccesses;
3398833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
3408833Sdam.sunwoo@arm.com        overallMissRate.subname(i, system->getMasterName(i));
3418833Sdam.sunwoo@arm.com    }
3422810SN/A
3432810SN/A    // miss latency formulas
3444022SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
3454022SN/A        MemCmd cmd(access_idx);
3464022SN/A        const string &cstr = cmd.toString();
3472810SN/A
3482810SN/A        avgMissLatency[access_idx]
3492810SN/A            .name(name() + "." + cstr + "_avg_miss_latency")
3502810SN/A            .desc("average " + cstr + " miss latency")
3512810SN/A            .flags(total | nozero | nonan)
3522810SN/A            ;
3532810SN/A        avgMissLatency[access_idx] =
3542810SN/A            missLatency[access_idx] / misses[access_idx];
3558833Sdam.sunwoo@arm.com
3568833Sdam.sunwoo@arm.com        for (int i = 0; i < system->maxMasters(); i++) {
3578833Sdam.sunwoo@arm.com            avgMissLatency[access_idx].subname(i, system->getMasterName(i));
3588833Sdam.sunwoo@arm.com        }
3592810SN/A    }
3602810SN/A
3612810SN/A    demandAvgMissLatency
3622810SN/A        .name(name() + ".demand_avg_miss_latency")
3632810SN/A        .desc("average overall miss latency")
3648833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
3652810SN/A        ;
3662810SN/A    demandAvgMissLatency = demandMissLatency / demandMisses;
3678833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
3688833Sdam.sunwoo@arm.com        demandAvgMissLatency.subname(i, system->getMasterName(i));
3698833Sdam.sunwoo@arm.com    }
3702810SN/A
3712810SN/A    overallAvgMissLatency
3722810SN/A        .name(name() + ".overall_avg_miss_latency")
3732810SN/A        .desc("average overall miss latency")
3748833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
3752810SN/A        ;
3762810SN/A    overallAvgMissLatency = overallMissLatency / overallMisses;
3778833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
3788833Sdam.sunwoo@arm.com        overallAvgMissLatency.subname(i, system->getMasterName(i));
3798833Sdam.sunwoo@arm.com    }
3802810SN/A
3812810SN/A    blocked_cycles.init(NUM_BLOCKED_CAUSES);
3822810SN/A    blocked_cycles
3832810SN/A        .name(name() + ".blocked_cycles")
3842810SN/A        .desc("number of cycles access was blocked")
3852810SN/A        .subname(Blocked_NoMSHRs, "no_mshrs")
3862810SN/A        .subname(Blocked_NoTargets, "no_targets")
3872810SN/A        ;
3882810SN/A
3892810SN/A
3902810SN/A    blocked_causes.init(NUM_BLOCKED_CAUSES);
3912810SN/A    blocked_causes
3922810SN/A        .name(name() + ".blocked")
3932810SN/A        .desc("number of cycles access was blocked")
3942810SN/A        .subname(Blocked_NoMSHRs, "no_mshrs")
3952810SN/A        .subname(Blocked_NoTargets, "no_targets")
3962810SN/A        ;
3972810SN/A
3982810SN/A    avg_blocked
3992810SN/A        .name(name() + ".avg_blocked_cycles")
4002810SN/A        .desc("average number of cycles each access was blocked")
4012810SN/A        .subname(Blocked_NoMSHRs, "no_mshrs")
4022810SN/A        .subname(Blocked_NoTargets, "no_targets")
4032810SN/A        ;
4042810SN/A
4052810SN/A    avg_blocked = blocked_cycles / blocked_causes;
4062810SN/A
4072810SN/A    fastWrites
4082810SN/A        .name(name() + ".fast_writes")
4092810SN/A        .desc("number of fast writes performed")
4102810SN/A        ;
4112810SN/A
4122810SN/A    cacheCopies
4132810SN/A        .name(name() + ".cache_copies")
4142810SN/A        .desc("number of cache copies performed")
4152810SN/A        ;
4162826SN/A
4174626SN/A    writebacks
4188833Sdam.sunwoo@arm.com        .init(system->maxMasters())
4194626SN/A        .name(name() + ".writebacks")
4204626SN/A        .desc("number of writebacks")
4218833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
4224626SN/A        ;
4238833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
4248833Sdam.sunwoo@arm.com        writebacks.subname(i, system->getMasterName(i));
4258833Sdam.sunwoo@arm.com    }
4264626SN/A
4274626SN/A    // MSHR statistics
4284626SN/A    // MSHR hit statistics
4294626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
4304626SN/A        MemCmd cmd(access_idx);
4314626SN/A        const string &cstr = cmd.toString();
4324626SN/A
4334626SN/A        mshr_hits[access_idx]
4348833Sdam.sunwoo@arm.com            .init(system->maxMasters())
4354626SN/A            .name(name() + "." + cstr + "_mshr_hits")
4364626SN/A            .desc("number of " + cstr + " MSHR hits")
4374626SN/A            .flags(total | nozero | nonan)
4384626SN/A            ;
4398833Sdam.sunwoo@arm.com        for (int i = 0; i < system->maxMasters(); i++) {
4408833Sdam.sunwoo@arm.com            mshr_hits[access_idx].subname(i, system->getMasterName(i));
4418833Sdam.sunwoo@arm.com        }
4424626SN/A    }
4434626SN/A
4444626SN/A    demandMshrHits
4454626SN/A        .name(name() + ".demand_mshr_hits")
4464626SN/A        .desc("number of demand (read+write) MSHR hits")
4478833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
4484626SN/A        ;
4494871SN/A    demandMshrHits = SUM_DEMAND(mshr_hits);
4508833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
4518833Sdam.sunwoo@arm.com        demandMshrHits.subname(i, system->getMasterName(i));
4528833Sdam.sunwoo@arm.com    }
4534626SN/A
4544626SN/A    overallMshrHits
4554626SN/A        .name(name() + ".overall_mshr_hits")
4564626SN/A        .desc("number of overall MSHR hits")
4578833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
4584626SN/A        ;
4594871SN/A    overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
4608833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
4618833Sdam.sunwoo@arm.com        overallMshrHits.subname(i, system->getMasterName(i));
4628833Sdam.sunwoo@arm.com    }
4634626SN/A
4644626SN/A    // MSHR miss statistics
4654626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
4664626SN/A        MemCmd cmd(access_idx);
4674626SN/A        const string &cstr = cmd.toString();
4684626SN/A
4694626SN/A        mshr_misses[access_idx]
4708833Sdam.sunwoo@arm.com            .init(system->maxMasters())
4714626SN/A            .name(name() + "." + cstr + "_mshr_misses")
4724626SN/A            .desc("number of " + cstr + " MSHR misses")
4734626SN/A            .flags(total | nozero | nonan)
4744626SN/A            ;
4758833Sdam.sunwoo@arm.com        for (int i = 0; i < system->maxMasters(); i++) {
4768833Sdam.sunwoo@arm.com            mshr_misses[access_idx].subname(i, system->getMasterName(i));
4778833Sdam.sunwoo@arm.com        }
4784626SN/A    }
4794626SN/A
4804626SN/A    demandMshrMisses
4814626SN/A        .name(name() + ".demand_mshr_misses")
4824626SN/A        .desc("number of demand (read+write) MSHR misses")
4838833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
4844626SN/A        ;
4854871SN/A    demandMshrMisses = SUM_DEMAND(mshr_misses);
4868833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
4878833Sdam.sunwoo@arm.com        demandMshrMisses.subname(i, system->getMasterName(i));
4888833Sdam.sunwoo@arm.com    }
4894626SN/A
4904626SN/A    overallMshrMisses
4914626SN/A        .name(name() + ".overall_mshr_misses")
4924626SN/A        .desc("number of overall MSHR misses")
4938833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
4944626SN/A        ;
4954871SN/A    overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
4968833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
4978833Sdam.sunwoo@arm.com        overallMshrMisses.subname(i, system->getMasterName(i));
4988833Sdam.sunwoo@arm.com    }
4994626SN/A
5004626SN/A    // MSHR miss latency statistics
5014626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
5024626SN/A        MemCmd cmd(access_idx);
5034626SN/A        const string &cstr = cmd.toString();
5044626SN/A
5054626SN/A        mshr_miss_latency[access_idx]
5068833Sdam.sunwoo@arm.com            .init(system->maxMasters())
5074626SN/A            .name(name() + "." + cstr + "_mshr_miss_latency")
5084626SN/A            .desc("number of " + cstr + " MSHR miss cycles")
5094626SN/A            .flags(total | nozero | nonan)
5104626SN/A            ;
5118833Sdam.sunwoo@arm.com        for (int i = 0; i < system->maxMasters(); i++) {
5128833Sdam.sunwoo@arm.com            mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
5138833Sdam.sunwoo@arm.com        }
5144626SN/A    }
5154626SN/A
5164626SN/A    demandMshrMissLatency
5174626SN/A        .name(name() + ".demand_mshr_miss_latency")
5184626SN/A        .desc("number of demand (read+write) MSHR miss cycles")
5198833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
5204626SN/A        ;
5214871SN/A    demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
5228833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
5238833Sdam.sunwoo@arm.com        demandMshrMissLatency.subname(i, system->getMasterName(i));
5248833Sdam.sunwoo@arm.com    }
5254626SN/A
5264626SN/A    overallMshrMissLatency
5274626SN/A        .name(name() + ".overall_mshr_miss_latency")
5284626SN/A        .desc("number of overall MSHR miss cycles")
5298833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
5304626SN/A        ;
5314871SN/A    overallMshrMissLatency =
5324871SN/A        demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
5338833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
5348833Sdam.sunwoo@arm.com        overallMshrMissLatency.subname(i, system->getMasterName(i));
5358833Sdam.sunwoo@arm.com    }
5364626SN/A
5374626SN/A    // MSHR uncacheable statistics
5384626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
5394626SN/A        MemCmd cmd(access_idx);
5404626SN/A        const string &cstr = cmd.toString();
5414626SN/A
5424626SN/A        mshr_uncacheable[access_idx]
5438833Sdam.sunwoo@arm.com            .init(system->maxMasters())
5444626SN/A            .name(name() + "." + cstr + "_mshr_uncacheable")
5454626SN/A            .desc("number of " + cstr + " MSHR uncacheable")
5464626SN/A            .flags(total | nozero | nonan)
5474626SN/A            ;
5488833Sdam.sunwoo@arm.com        for (int i = 0; i < system->maxMasters(); i++) {
5498833Sdam.sunwoo@arm.com            mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
5508833Sdam.sunwoo@arm.com        }
5514626SN/A    }
5524626SN/A
5534626SN/A    overallMshrUncacheable
5544626SN/A        .name(name() + ".overall_mshr_uncacheable_misses")
5554626SN/A        .desc("number of overall MSHR uncacheable misses")
5568833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
5574626SN/A        ;
5584871SN/A    overallMshrUncacheable =
5594871SN/A        SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
5608833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
5618833Sdam.sunwoo@arm.com        overallMshrUncacheable.subname(i, system->getMasterName(i));
5628833Sdam.sunwoo@arm.com    }
5634626SN/A
5644626SN/A    // MSHR miss latency statistics
5654626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
5664626SN/A        MemCmd cmd(access_idx);
5674626SN/A        const string &cstr = cmd.toString();
5684626SN/A
5694626SN/A        mshr_uncacheable_lat[access_idx]
5708833Sdam.sunwoo@arm.com            .init(system->maxMasters())
5714626SN/A            .name(name() + "." + cstr + "_mshr_uncacheable_latency")
5724626SN/A            .desc("number of " + cstr + " MSHR uncacheable cycles")
5734626SN/A            .flags(total | nozero | nonan)
5744626SN/A            ;
5758833Sdam.sunwoo@arm.com        for (int i = 0; i < system->maxMasters(); i++) {
5768833Sdam.sunwoo@arm.com            mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i));
5778833Sdam.sunwoo@arm.com        }
5784626SN/A    }
5794626SN/A
5804626SN/A    overallMshrUncacheableLatency
5814626SN/A        .name(name() + ".overall_mshr_uncacheable_latency")
5824626SN/A        .desc("number of overall MSHR uncacheable cycles")
5838833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
5844626SN/A        ;
5854871SN/A    overallMshrUncacheableLatency =
5864871SN/A        SUM_DEMAND(mshr_uncacheable_lat) +
5874871SN/A        SUM_NON_DEMAND(mshr_uncacheable_lat);
5888833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
5898833Sdam.sunwoo@arm.com        overallMshrUncacheableLatency.subname(i, system->getMasterName(i));
5908833Sdam.sunwoo@arm.com    }
5914626SN/A
5924626SN/A#if 0
5934626SN/A    // MSHR access formulas
5944626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
5954626SN/A        MemCmd cmd(access_idx);
5964626SN/A        const string &cstr = cmd.toString();
5974626SN/A
5984626SN/A        mshrAccesses[access_idx]
5994626SN/A            .name(name() + "." + cstr + "_mshr_accesses")
6004626SN/A            .desc("number of " + cstr + " mshr accesses(hits+misses)")
6014626SN/A            .flags(total | nozero | nonan)
6024626SN/A            ;
6034626SN/A        mshrAccesses[access_idx] =
6044626SN/A            mshr_hits[access_idx] + mshr_misses[access_idx]
6054626SN/A            + mshr_uncacheable[access_idx];
6064626SN/A    }
6074626SN/A
6084626SN/A    demandMshrAccesses
6094626SN/A        .name(name() + ".demand_mshr_accesses")
6104626SN/A        .desc("number of demand (read+write) mshr accesses")
6114626SN/A        .flags(total | nozero | nonan)
6124626SN/A        ;
6134626SN/A    demandMshrAccesses = demandMshrHits + demandMshrMisses;
6144626SN/A
6154626SN/A    overallMshrAccesses
6164626SN/A        .name(name() + ".overall_mshr_accesses")
6174626SN/A        .desc("number of overall (read+write) mshr accesses")
6184626SN/A        .flags(total | nozero | nonan)
6194626SN/A        ;
6204626SN/A    overallMshrAccesses = overallMshrHits + overallMshrMisses
6214626SN/A        + overallMshrUncacheable;
6224626SN/A#endif
6234626SN/A
6244626SN/A    // MSHR miss rate formulas
6254626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
6264626SN/A        MemCmd cmd(access_idx);
6274626SN/A        const string &cstr = cmd.toString();
6284626SN/A
6294626SN/A        mshrMissRate[access_idx]
6304626SN/A            .name(name() + "." + cstr + "_mshr_miss_rate")
6314626SN/A            .desc("mshr miss rate for " + cstr + " accesses")
6324626SN/A            .flags(total | nozero | nonan)
6334626SN/A            ;
6344626SN/A        mshrMissRate[access_idx] =
6354626SN/A            mshr_misses[access_idx] / accesses[access_idx];
6368833Sdam.sunwoo@arm.com
6378833Sdam.sunwoo@arm.com        for (int i = 0; i < system->maxMasters(); i++) {
6388833Sdam.sunwoo@arm.com            mshrMissRate[access_idx].subname(i, system->getMasterName(i));
6398833Sdam.sunwoo@arm.com        }
6404626SN/A    }
6414626SN/A
6424626SN/A    demandMshrMissRate
6434626SN/A        .name(name() + ".demand_mshr_miss_rate")
6444626SN/A        .desc("mshr miss rate for demand accesses")
6458833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
6464626SN/A        ;
6474626SN/A    demandMshrMissRate = demandMshrMisses / demandAccesses;
6488833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
6498833Sdam.sunwoo@arm.com        demandMshrMissRate.subname(i, system->getMasterName(i));
6508833Sdam.sunwoo@arm.com    }
6514626SN/A
6524626SN/A    overallMshrMissRate
6534626SN/A        .name(name() + ".overall_mshr_miss_rate")
6544626SN/A        .desc("mshr miss rate for overall accesses")
6558833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
6564626SN/A        ;
6574626SN/A    overallMshrMissRate = overallMshrMisses / overallAccesses;
6588833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
6598833Sdam.sunwoo@arm.com        overallMshrMissRate.subname(i, system->getMasterName(i));
6608833Sdam.sunwoo@arm.com    }
6614626SN/A
6624626SN/A    // mshrMiss latency formulas
6634626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
6644626SN/A        MemCmd cmd(access_idx);
6654626SN/A        const string &cstr = cmd.toString();
6664626SN/A
6674626SN/A        avgMshrMissLatency[access_idx]
6684626SN/A            .name(name() + "." + cstr + "_avg_mshr_miss_latency")
6694626SN/A            .desc("average " + cstr + " mshr miss latency")
6704626SN/A            .flags(total | nozero | nonan)
6714626SN/A            ;
6724626SN/A        avgMshrMissLatency[access_idx] =
6734626SN/A            mshr_miss_latency[access_idx] / mshr_misses[access_idx];
6748833Sdam.sunwoo@arm.com
6758833Sdam.sunwoo@arm.com        for (int i = 0; i < system->maxMasters(); i++) {
6768833Sdam.sunwoo@arm.com            avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i));
6778833Sdam.sunwoo@arm.com        }
6784626SN/A    }
6794626SN/A
6804626SN/A    demandAvgMshrMissLatency
6814626SN/A        .name(name() + ".demand_avg_mshr_miss_latency")
6824626SN/A        .desc("average overall mshr miss latency")
6838833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
6844626SN/A        ;
6854626SN/A    demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
6868833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
6878833Sdam.sunwoo@arm.com        demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
6888833Sdam.sunwoo@arm.com    }
6894626SN/A
6904626SN/A    overallAvgMshrMissLatency
6914626SN/A        .name(name() + ".overall_avg_mshr_miss_latency")
6924626SN/A        .desc("average overall mshr miss latency")
6938833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
6944626SN/A        ;
6954626SN/A    overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
6968833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
6978833Sdam.sunwoo@arm.com        overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
6988833Sdam.sunwoo@arm.com    }
6994626SN/A
7004626SN/A    // mshrUncacheable latency formulas
7014626SN/A    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
7024626SN/A        MemCmd cmd(access_idx);
7034626SN/A        const string &cstr = cmd.toString();
7044626SN/A
7054626SN/A        avgMshrUncacheableLatency[access_idx]
7064626SN/A            .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
7074626SN/A            .desc("average " + cstr + " mshr uncacheable latency")
7084626SN/A            .flags(total | nozero | nonan)
7094626SN/A            ;
7104626SN/A        avgMshrUncacheableLatency[access_idx] =
7114626SN/A            mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
7128833Sdam.sunwoo@arm.com
7138833Sdam.sunwoo@arm.com        for (int i = 0; i < system->maxMasters(); i++) {
7148833Sdam.sunwoo@arm.com            avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i));
7158833Sdam.sunwoo@arm.com        }
7164626SN/A    }
7174626SN/A
7184626SN/A    overallAvgMshrUncacheableLatency
7194626SN/A        .name(name() + ".overall_avg_mshr_uncacheable_latency")
7204626SN/A        .desc("average overall mshr uncacheable latency")
7218833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
7224626SN/A        ;
7234626SN/A    overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
7248833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
7258833Sdam.sunwoo@arm.com        overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
7268833Sdam.sunwoo@arm.com    }
7274626SN/A
7284626SN/A    mshr_cap_events
7298833Sdam.sunwoo@arm.com        .init(system->maxMasters())
7304626SN/A        .name(name() + ".mshr_cap_events")
7314626SN/A        .desc("number of times MSHR cap was activated")
7328833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
7334626SN/A        ;
7348833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
7358833Sdam.sunwoo@arm.com        mshr_cap_events.subname(i, system->getMasterName(i));
7368833Sdam.sunwoo@arm.com    }
7374626SN/A
7384626SN/A    //software prefetching stats
7394626SN/A    soft_prefetch_mshr_full
7408833Sdam.sunwoo@arm.com        .init(system->maxMasters())
7414626SN/A        .name(name() + ".soft_prefetch_mshr_full")
7424626SN/A        .desc("number of mshr full events for SW prefetching instrutions")
7438833Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
7444626SN/A        ;
7458833Sdam.sunwoo@arm.com    for (int i = 0; i < system->maxMasters(); i++) {
7468833Sdam.sunwoo@arm.com        soft_prefetch_mshr_full.subname(i, system->getMasterName(i));
7478833Sdam.sunwoo@arm.com    }
7484626SN/A
7494626SN/A    mshr_no_allocate_misses
7504626SN/A        .name(name() +".no_allocate_misses")
7514626SN/A        .desc("Number of misses that were no-allocate")
7524626SN/A        ;
7534626SN/A
7542810SN/A}
7553503SN/A
7563503SN/Aunsigned int
7579342SAndreas.Sandberg@arm.comBaseCache::drain(DrainManager *dm)
7583503SN/A{
7599347SAndreas.Sandberg@arm.com    int count = memSidePort->drain(dm) + cpuSidePort->drain(dm) +
7609347SAndreas.Sandberg@arm.com        mshrQueue.drain(dm) + writeBuffer.drain(dm);
7614626SN/A
7623503SN/A    // Set status
7634626SN/A    if (count != 0) {
7649342SAndreas.Sandberg@arm.com        setDrainState(Drainable::Draining);
7659152Satgutier@umich.edu        DPRINTF(Drain, "Cache not drained\n");
7664626SN/A        return count;
7673503SN/A    }
7683503SN/A
7699342SAndreas.Sandberg@arm.com    setDrainState(Drainable::Drained);
7703503SN/A    return 0;
7713503SN/A}
7729795Sandreas.hansson@arm.com
7739795Sandreas.hansson@arm.comBaseCache *
7749795Sandreas.hansson@arm.comBaseCacheParams::create()
7759795Sandreas.hansson@arm.com{
7769795Sandreas.hansson@arm.com    int numSets = size / (assoc * block_size);
7779795Sandreas.hansson@arm.com
7789795Sandreas.hansson@arm.com    if (numSets == 1) {
7799795Sandreas.hansson@arm.com        FALRU *tags = new FALRU(block_size, size, hit_latency);
7809795Sandreas.hansson@arm.com        return new Cache<FALRU>(this, tags);
7819795Sandreas.hansson@arm.com    } else {
7829795Sandreas.hansson@arm.com        LRU *tags = new LRU(numSets, block_size, assoc, hit_latency);
7839795Sandreas.hansson@arm.com        return new Cache<LRU>(this, tags);
7849795Sandreas.hansson@arm.com    }
7859795Sandreas.hansson@arm.com}
786