base.cc revision 13217
12SN/A/*
21762SN/A * Copyright (c) 2013,2016,2018 ARM Limited
32SN/A * All rights reserved.
42SN/A *
52SN/A * The license below extends only to copyright in the software and shall
62SN/A * not be construed as granting a license to any other intellectual
72SN/A * property including but not limited to intellectual property relating
82SN/A * to a hardware implementation of the functionality of the software
92SN/A * licensed hereunder.  You may use the software subject to the license
102SN/A * terms below provided that you ensure that this notice is replicated
112SN/A * unmodified and in its entirety in all distributions of the software,
122SN/A * modified or unmodified, in source code or in binary form.
132SN/A *
142SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
152SN/A * All rights reserved.
162SN/A *
172SN/A * Redistribution and use in source and binary forms, with or without
182SN/A * modification, are permitted provided that the following conditions are
192SN/A * met: redistributions of source code must retain the above copyright
202SN/A * notice, this list of conditions and the following disclaimer;
212SN/A * redistributions in binary form must reproduce the above copyright
222SN/A * notice, this list of conditions and the following disclaimer in the
232SN/A * documentation and/or other materials provided with the distribution;
242SN/A * neither the name of the copyright holders nor the names of its
252SN/A * contributors may be used to endorse or promote products derived from
262SN/A * this software without specific prior written permission.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292665Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
321388SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
361191SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
371191SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
381191SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
391388SN/A *
405529Snate@binkert.org * Authors: Erik Hallnor
411717SN/A *          Ron Dreslinski
422651Ssaidi@eecs.umich.edu */
432680Sktlim@umich.edu
441977SN/A/**
455529Snate@binkert.org * @file
463144Shsul@eecs.umich.edu * Definitions of BaseTags.
472190SN/A */
4856SN/A
492190SN/A#include "mem/cache/tags/base.hh"
502SN/A
512359SN/A#include <cassert>
522359SN/A
532359SN/A#include "base/types.hh"
542SN/A#include "mem/cache/base.hh"
552SN/A#include "mem/request.hh"
562SN/A#include "sim/core.hh"
572SN/A#include "sim/sim_exit.hh"
582SN/A#include "sim/system.hh"
592SN/A
602SN/ABaseTags::BaseTags(const Params *p)
612SN/A    : ClockedObject(p), blkSize(p->block_size), blkMask(blkSize - 1),
622SN/A      size(p->size),
635606Snate@binkert.org      lookupLatency(p->tag_latency),
645606Snate@binkert.org      accessLatency(p->sequential_access ?
655606Snate@binkert.org                    p->tag_latency + p->data_latency :
663126Sktlim@umich.edu                    std::max(p->tag_latency, p->data_latency)),
673126Sktlim@umich.edu      cache(nullptr),
685606Snate@binkert.org      warmupBound((p->warmup_percentage/100.0) * (p->size / p->block_size)),
693126Sktlim@umich.edu      warmedUp(false), numBlocks(p->size / p->block_size),
703126Sktlim@umich.edu      dataBlks(new uint8_t[p->size]) // Allocate data storage in one big chunk
712356SN/A{
722356SN/A}
732356SN/A
742367SN/Avoid
752356SN/ABaseTags::setCache(BaseCache *_cache)
765100Ssaidi@eecs.umich.edu{
772367SN/A    assert(!cache);
782356SN/A    cache = _cache;
792356SN/A}
802356SN/A
812367SN/Astd::vector<ReplaceableEntry*>
822367SN/ABaseTags::getPossibleLocations(const Addr addr) const
832367SN/A{
842367SN/A    panic("Unimplemented getPossibleLocations for tags subclass");
852356SN/A}
865606Snate@binkert.org
872356SN/ACacheBlk*
882356SN/ABaseTags::findBlock(Addr addr, bool is_secure) const
892356SN/A{
905336Shines@cs.fsu.edu    // Extract block tag
912356SN/A    Addr tag = extractTag(addr);
924873Sstever@eecs.umich.edu
932356SN/A    // Find possible locations for the given address
942356SN/A    const std::vector<ReplaceableEntry*> locations =
951858SN/A        getPossibleLocations(addr);
961400SN/A
975712Shsul@eecs.umich.edu    // Search for block
985712Shsul@eecs.umich.edu    for (const auto& location : locations) {
995529Snate@binkert.org        CacheBlk* blk = static_cast<CacheBlk*>(location);
1003661Srdreslin@umich.edu        if ((blk->tag == tag) && blk->isValid() &&
1012SN/A            (blk->isSecure() == is_secure)) {
1021400SN/A            return blk;
1035712Shsul@eecs.umich.edu        }
1045529Snate@binkert.org    }
1053661Srdreslin@umich.edu
1062SN/A    // Did not find block
1072SN/A    return nullptr;
1082359SN/A}
1091062SN/A
1105712Shsul@eecs.umich.eduvoid
1115712Shsul@eecs.umich.eduBaseTags::insertBlock(const Addr addr, const bool is_secure,
1125712Shsul@eecs.umich.edu                      const int src_master_ID, const uint32_t task_ID,
1135712Shsul@eecs.umich.edu                      CacheBlk *blk)
1145712Shsul@eecs.umich.edu{
1152SN/A    assert(!blk->isValid());
1162SN/A
1172SN/A    // Previous block, if existed, has been removed, and now we have
1185712Shsul@eecs.umich.edu    // to insert the new one
1195712Shsul@eecs.umich.edu    // Deal with what we are bringing in
1202SN/A    assert(src_master_ID < cache->system->maxMasters());
1212SN/A    occupancies[src_master_ID]++;
1222SN/A
1232SN/A    // Insert block with tag, src master id and task id
1241354SN/A    blk->insert(extractTag(addr), is_secure, src_master_ID, task_ID);
1252SN/A
126503SN/A    // Check if cache warm up is done
1272SN/A    if (!warmedUp && tagsInUse.value() >= warmupBound) {
1282SN/A        warmedUp = true;
1292SN/A        warmupCycle = curTick();
1302SN/A    }
1315606Snate@binkert.org
1325606Snate@binkert.org    // We only need to write into one tag and one data block.
1335606Snate@binkert.org    tagAccesses += 1;
1345606Snate@binkert.org    dataAccesses += 1;
1355606Snate@binkert.org}
1365606Snate@binkert.org
1375606Snate@binkert.orgvoid
1382SN/ABaseTags::cleanupRefsVisitor(CacheBlk &blk)
1391400SN/A{
1405606Snate@binkert.org    if (blk.isValid()) {
1415606Snate@binkert.org        totalRefs += blk.refCount;
1422SN/A        ++sampledRefs;
1432SN/A    }
1442SN/A}
1452SN/A
1462SN/Avoid
1475606Snate@binkert.orgBaseTags::cleanupRefs()
1485606Snate@binkert.org{
1495606Snate@binkert.org    forEachBlk([this](CacheBlk &blk) { cleanupRefsVisitor(blk); });
1505606Snate@binkert.org}
1512SN/A
1522SN/Avoid
153124SN/ABaseTags::computeStatsVisitor(CacheBlk &blk)
1541354SN/A{
155124SN/A    if (blk.isValid()) {
156124SN/A        assert(blk.task_id < ContextSwitchTaskId::NumTaskId);
157124SN/A        occupanciesTaskId[blk.task_id]++;
158124SN/A        assert(blk.tickInserted <= curTick());
159124SN/A        Tick age = curTick() - blk.tickInserted;
160124SN/A
1615606Snate@binkert.org        int age_index;
1625606Snate@binkert.org        if (age / SimClock::Int::us < 10) { // <10us
1635606Snate@binkert.org            age_index = 0;
1645606Snate@binkert.org        } else if (age / SimClock::Int::us < 100) { // <100us
1655606Snate@binkert.org            age_index = 1;
1665606Snate@binkert.org        } else if (age / SimClock::Int::ms < 1) { // <1ms
1675606Snate@binkert.org            age_index = 2;
168124SN/A        } else if (age / SimClock::Int::ms < 10) { // <10ms
1691400SN/A            age_index = 3;
1705606Snate@binkert.org        } else
171124SN/A            age_index = 4; // >10ms
172124SN/A
173124SN/A        ageTaskId[blk.task_id][age_index]++;
174124SN/A    }
175124SN/A}
1765606Snate@binkert.org
1775606Snate@binkert.orgvoid
1785606Snate@binkert.orgBaseTags::computeStats()
1795606Snate@binkert.org{
180124SN/A    for (unsigned i = 0; i < ContextSwitchTaskId::NumTaskId; ++i) {
181124SN/A        occupanciesTaskId[i] = 0;
1821191SN/A        for (unsigned j = 0; j < 5; ++j) {
1835529Snate@binkert.org            ageTaskId[i][j] = 0;
1841388SN/A        }
1851191SN/A    }
1865529Snate@binkert.org
1871191SN/A    forEachBlk([this](CacheBlk &blk) { computeStatsVisitor(blk); });
1885529Snate@binkert.org}
1891191SN/A
1901191SN/Astd::string
1915606Snate@binkert.orgBaseTags::print()
1925606Snate@binkert.org{
1935606Snate@binkert.org    std::string str;
1941191SN/A
1951191SN/A    auto print_blk = [&str](CacheBlk &blk) {
1961917SN/A        if (blk.isValid())
1975810Sgblack@eecs.umich.edu            str += csprintf("\tset: %d way: %d %s\n", blk.set, blk.way,
1985810Sgblack@eecs.umich.edu                            blk.print());
1991917SN/A    };
2005529Snate@binkert.org    forEachBlk(print_blk);
2015529Snate@binkert.org
2021917SN/A    if (str.empty())
2035529Snate@binkert.org        str = "no valid tags\n";
2041917SN/A
2051191SN/A    return str;
2061191SN/A}
2071191SN/A
2081191SN/Avoid
2091191SN/ABaseTags::regStats()
2101191SN/A{
2111191SN/A    ClockedObject::regStats();
2121191SN/A
2131191SN/A    using namespace Stats;
2141191SN/A
2151191SN/A    tagsInUse
2161129SN/A        .name(name() + ".tagsinuse")
2171129SN/A        .desc("Cycle average of tags in use")
2181129SN/A        ;
2195529Snate@binkert.org
2202680Sktlim@umich.edu    totalRefs
2211129SN/A        .name(name() + ".total_refs")
222180SN/A        .desc("Total number of references to valid blocks.")
2232SN/A        ;
2241917SN/A
2251917SN/A    sampledRefs
2261917SN/A        .name(name() + ".sampled_refs")
2275529Snate@binkert.org        .desc("Sample count of references to valid blocks.")
2285606Snate@binkert.org        ;
2291917SN/A
2302356SN/A    avgRefs
2315529Snate@binkert.org        .name(name() + ".avg_refs")
2325606Snate@binkert.org        .desc("Average number of references to valid blocks.")
2335606Snate@binkert.org        ;
2345606Snate@binkert.org
2352356SN/A    avgRefs = totalRefs/sampledRefs;
2361917SN/A
2371917SN/A    warmupCycle
2381917SN/A        .name(name() + ".warmup_cycle")
2391917SN/A        .desc("Cycle when the warmup percentage was hit.")
2402SN/A        ;
2412SN/A
242729SN/A    occupancies
243707SN/A        .init(cache->system->maxMasters())
244707SN/A        .name(name() + ".occ_blocks")
245707SN/A        .desc("Average occupied blocks per requestor")
246707SN/A        .flags(nozero | nonan)
247707SN/A        ;
248707SN/A    for (int i = 0; i < cache->system->maxMasters(); i++) {
2492680Sktlim@umich.edu        occupancies.subname(i, cache->system->getMasterName(i));
2502SN/A    }
2512SN/A
2522SN/A    avgOccs
2532SN/A        .name(name() + ".occ_percent")
2542680Sktlim@umich.edu        .desc("Average percentage of cache occupancy")
2552SN/A        .flags(nozero | total)
2562SN/A        ;
2572680Sktlim@umich.edu    for (int i = 0; i < cache->system->maxMasters(); i++) {
2582190SN/A        avgOccs.subname(i, cache->system->getMasterName(i));
2592190SN/A    }
2602190SN/A
2612SN/A    avgOccs = occupancies / Stats::constant(numBlocks);
2622SN/A
2633495Sktlim@umich.edu    occupanciesTaskId
2643495Sktlim@umich.edu        .init(ContextSwitchTaskId::NumTaskId)
2653495Sktlim@umich.edu        .name(name() + ".occ_task_id_blocks")
2663661Srdreslin@umich.edu        .desc("Occupied blocks per task id")
2673495Sktlim@umich.edu        .flags(nozero | nonan)
2683661Srdreslin@umich.edu        ;
2693495Sktlim@umich.edu
2703495Sktlim@umich.edu    ageTaskId
2713495Sktlim@umich.edu        .init(ContextSwitchTaskId::NumTaskId, 5)
2723495Sktlim@umich.edu        .name(name() + ".age_task_id_blocks")
2733495Sktlim@umich.edu        .desc("Occupied blocks per task id")
2743495Sktlim@umich.edu        .flags(nozero | nonan)
2753495Sktlim@umich.edu        ;
2764599Sacolyte@umich.edu
2774599Sacolyte@umich.edu    percentOccsTaskId
2783661Srdreslin@umich.edu        .name(name() + ".occ_task_id_percent")
2793495Sktlim@umich.edu        .desc("Percentage of cache occupancy per task id")
2803495Sktlim@umich.edu        .flags(nozero)
2813495Sktlim@umich.edu        ;
2823495Sktlim@umich.edu
283180SN/A    percentOccsTaskId = occupanciesTaskId / Stats::constant(numBlocks);
284180SN/A
2852680Sktlim@umich.edu    tagAccesses
286180SN/A        .name(name() + ".tag_accesses")
2872680Sktlim@umich.edu        .desc("Number of tag accesses")
2882680Sktlim@umich.edu        ;
2892378SN/A
2905718Shsul@eecs.umich.edu    dataAccesses
2915718Shsul@eecs.umich.edu        .name(name() + ".data_accesses")
2925718Shsul@eecs.umich.edu        .desc("Number of data accesses")
2935718Shsul@eecs.umich.edu        ;
2945718Shsul@eecs.umich.edu
2955718Shsul@eecs.umich.edu    registerDumpCallback(new BaseTagsDumpCallback(this));
2965718Shsul@eecs.umich.edu    registerExitCallback(new BaseTagsCallback(this));
2975718Shsul@eecs.umich.edu}
2985718Shsul@eecs.umich.edu