base.hh revision 13223
1955SN/A/*
2955SN/A * Copyright (c) 2012-2014,2016-2018 ARM Limited
31762SN/A * All rights reserved.
4955SN/A *
5955SN/A * The license below extends only to copyright in the software and shall
6955SN/A * not be construed as granting a license to any other intellectual
7955SN/A * property including but not limited to intellectual property relating
8955SN/A * to a hardware implementation of the functionality of the software
9955SN/A * licensed hereunder.  You may use the software subject to the license
10955SN/A * terms below provided that you ensure that this notice is replicated
11955SN/A * unmodified and in its entirety in all distributions of the software,
12955SN/A * modified or unmodified, in source code or in binary form.
13955SN/A *
14955SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
15955SN/A * All rights reserved.
16955SN/A *
17955SN/A * Redistribution and use in source and binary forms, with or without
18955SN/A * modification, are permitted provided that the following conditions are
19955SN/A * met: redistributions of source code must retain the above copyright
20955SN/A * notice, this list of conditions and the following disclaimer;
21955SN/A * redistributions in binary form must reproduce the above copyright
22955SN/A * notice, this list of conditions and the following disclaimer in the
23955SN/A * documentation and/or other materials provided with the distribution;
24955SN/A * neither the name of the copyright holders nor the names of its
25955SN/A * contributors may be used to endorse or promote products derived from
26955SN/A * this software without specific prior written permission.
27955SN/A *
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
30955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352632Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362632Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372632Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382632Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39955SN/A *
402632Sstever@eecs.umich.edu * Authors: Erik Hallnor
412632Sstever@eecs.umich.edu *          Ron Dreslinski
422761Sstever@eecs.umich.edu */
432632Sstever@eecs.umich.edu
442632Sstever@eecs.umich.edu/**
452632Sstever@eecs.umich.edu * @file
462761Sstever@eecs.umich.edu * Declaration of a common base class for cache tagstore objects.
472761Sstever@eecs.umich.edu */
482761Sstever@eecs.umich.edu
492632Sstever@eecs.umich.edu#ifndef __MEM_CACHE_TAGS_BASE_HH__
502632Sstever@eecs.umich.edu#define __MEM_CACHE_TAGS_BASE_HH__
512761Sstever@eecs.umich.edu
522761Sstever@eecs.umich.edu#include <cassert>
532761Sstever@eecs.umich.edu#include <functional>
542761Sstever@eecs.umich.edu#include <string>
552761Sstever@eecs.umich.edu
562632Sstever@eecs.umich.edu#include "base/callback.hh"
572632Sstever@eecs.umich.edu#include "base/logging.hh"
582632Sstever@eecs.umich.edu#include "base/statistics.hh"
592632Sstever@eecs.umich.edu#include "base/types.hh"
602632Sstever@eecs.umich.edu#include "mem/cache/cache_blk.hh"
612632Sstever@eecs.umich.edu#include "params/BaseTags.hh"
622632Sstever@eecs.umich.edu#include "sim/clocked_object.hh"
63955SN/A
64955SN/Aclass BaseCache;
65955SN/Aclass IndexingPolicy;
66955SN/Aclass ReplaceableEntry;
67955SN/A
685396Ssaidi@eecs.umich.edu/**
694202Sbinkertn@umich.edu * A common base class of Cache tagstore objects.
705342Sstever@gmail.com */
71955SN/Aclass BaseTags : public ClockedObject
725273Sstever@gmail.com{
735273Sstever@gmail.com  protected:
742656Sstever@eecs.umich.edu    /** The block size of the cache. */
752656Sstever@eecs.umich.edu    const unsigned blkSize;
762656Sstever@eecs.umich.edu    /** Mask out all bits that aren't part of the block offset. */
772656Sstever@eecs.umich.edu    const Addr blkMask;
782656Sstever@eecs.umich.edu    /** The size of the cache. */
792656Sstever@eecs.umich.edu    const unsigned size;
802656Sstever@eecs.umich.edu    /** The tag lookup latency of the cache. */
812653Sstever@eecs.umich.edu    const Cycles lookupLatency;
825227Ssaidi@eecs.umich.edu    /**
835227Ssaidi@eecs.umich.edu     * The total access latency of the cache. This latency
845227Ssaidi@eecs.umich.edu     * is different depending on the cache access mode
855227Ssaidi@eecs.umich.edu     * (parallel or sequential)
865396Ssaidi@eecs.umich.edu     */
875396Ssaidi@eecs.umich.edu    const Cycles accessLatency;
885396Ssaidi@eecs.umich.edu    /** Pointer to the parent cache. */
895396Ssaidi@eecs.umich.edu    BaseCache *cache;
905396Ssaidi@eecs.umich.edu
915396Ssaidi@eecs.umich.edu    /** Indexing policy */
925396Ssaidi@eecs.umich.edu    BaseIndexingPolicy *indexingPolicy;
935396Ssaidi@eecs.umich.edu
945588Ssaidi@eecs.umich.edu    /**
955396Ssaidi@eecs.umich.edu     * The number of tags that need to be touched to meet the warmup
965396Ssaidi@eecs.umich.edu     * percentage.
975396Ssaidi@eecs.umich.edu     */
985396Ssaidi@eecs.umich.edu    const unsigned warmupBound;
995396Ssaidi@eecs.umich.edu    /** Marked true when the cache is warmed up. */
1005396Ssaidi@eecs.umich.edu    bool warmedUp;
1015396Ssaidi@eecs.umich.edu
1025396Ssaidi@eecs.umich.edu    /** the number of blocks in the cache */
1035396Ssaidi@eecs.umich.edu    const unsigned numBlocks;
1045396Ssaidi@eecs.umich.edu
1055396Ssaidi@eecs.umich.edu    /** The data blocks, 1 per cache block. */
1065396Ssaidi@eecs.umich.edu    std::unique_ptr<uint8_t[]> dataBlks;
1075396Ssaidi@eecs.umich.edu
1085396Ssaidi@eecs.umich.edu    // Statistics
1095396Ssaidi@eecs.umich.edu    /**
1105396Ssaidi@eecs.umich.edu     * TODO: It would be good if these stats were acquired after warmup.
1115396Ssaidi@eecs.umich.edu     * @addtogroup CacheStatistics
1125396Ssaidi@eecs.umich.edu     * @{
1135396Ssaidi@eecs.umich.edu     */
1145396Ssaidi@eecs.umich.edu
1155396Ssaidi@eecs.umich.edu    /** Per cycle average of the number of tags that hold valid data. */
1165396Ssaidi@eecs.umich.edu    Stats::Average tagsInUse;
1175396Ssaidi@eecs.umich.edu
1185396Ssaidi@eecs.umich.edu    /** The total number of references to a block before it is replaced. */
1195396Ssaidi@eecs.umich.edu    Stats::Scalar totalRefs;
1205396Ssaidi@eecs.umich.edu
1215396Ssaidi@eecs.umich.edu    /**
1225396Ssaidi@eecs.umich.edu     * The number of reference counts sampled. This is different from
1235396Ssaidi@eecs.umich.edu     * replacements because we sample all the valid blocks when the simulator
1245396Ssaidi@eecs.umich.edu     * exits.
1255396Ssaidi@eecs.umich.edu     */
1265396Ssaidi@eecs.umich.edu    Stats::Scalar sampledRefs;
1275396Ssaidi@eecs.umich.edu
1285396Ssaidi@eecs.umich.edu    /**
1295396Ssaidi@eecs.umich.edu     * Average number of references to a block before is was replaced.
1305396Ssaidi@eecs.umich.edu     * @todo This should change to an average stat once we have them.
1315396Ssaidi@eecs.umich.edu     */
1325396Ssaidi@eecs.umich.edu    Stats::Formula avgRefs;
1335396Ssaidi@eecs.umich.edu
1345396Ssaidi@eecs.umich.edu    /** The cycle that the warmup percentage was hit. 0 on failure. */
1355396Ssaidi@eecs.umich.edu    Stats::Scalar warmupCycle;
1365396Ssaidi@eecs.umich.edu
1375396Ssaidi@eecs.umich.edu    /** Average occupancy of each requestor using the cache */
1385396Ssaidi@eecs.umich.edu    Stats::AverageVector occupancies;
1395396Ssaidi@eecs.umich.edu
1405396Ssaidi@eecs.umich.edu    /** Average occ % of each requestor using the cache */
1415396Ssaidi@eecs.umich.edu    Stats::Formula avgOccs;
1425396Ssaidi@eecs.umich.edu
1435396Ssaidi@eecs.umich.edu    /** Occupancy of each context/cpu using the cache */
1445396Ssaidi@eecs.umich.edu    Stats::Vector occupanciesTaskId;
1455396Ssaidi@eecs.umich.edu
1465396Ssaidi@eecs.umich.edu    /** Occupancy of each context/cpu using the cache */
1474781Snate@binkert.org    Stats::Vector2d ageTaskId;
1481852SN/A
149955SN/A    /** Occ % of each context/cpu using the cache */
150955SN/A    Stats::Formula percentOccsTaskId;
151955SN/A
1523717Sstever@eecs.umich.edu    /** Number of tags consulted over all accesses. */
1533716Sstever@eecs.umich.edu    Stats::Scalar tagAccesses;
154955SN/A    /** Number of data blocks consulted over all accesses. */
1551533SN/A    Stats::Scalar dataAccesses;
1563716Sstever@eecs.umich.edu
1571533SN/A    /**
1584678Snate@binkert.org     * @}
1594678Snate@binkert.org     */
1604678Snate@binkert.org
1614678Snate@binkert.org    /**
1624678Snate@binkert.org     * Set the parent cache back pointer.
1634678Snate@binkert.org     *
1644678Snate@binkert.org     * @param _cache Pointer to parent cache.
1654678Snate@binkert.org     */
1664678Snate@binkert.org    void setCache(BaseCache *_cache);
1674678Snate@binkert.org
1684678Snate@binkert.org  public:
1694678Snate@binkert.org    typedef BaseTagsParams Params;
1704678Snate@binkert.org    BaseTags(const Params *p);
1714678Snate@binkert.org
1724678Snate@binkert.org    /**
1734678Snate@binkert.org     * Destructor.
1744678Snate@binkert.org     */
1754678Snate@binkert.org    virtual ~BaseTags() {}
1764678Snate@binkert.org
1774678Snate@binkert.org    /**
1784678Snate@binkert.org     * Initialize blocks and set the parent cache back pointer.
1794973Ssaidi@eecs.umich.edu     *
1804678Snate@binkert.org     * @param _cache Pointer to parent cache.
1814678Snate@binkert.org     */
1824678Snate@binkert.org    virtual void init(BaseCache *_cache) = 0;
1834678Snate@binkert.org
1844678Snate@binkert.org    /**
1854678Snate@binkert.org     * Register local statistics.
186955SN/A     */
187955SN/A    void regStats();
1882632Sstever@eecs.umich.edu
1892632Sstever@eecs.umich.edu    /**
190955SN/A     * Average in the reference count for valid blocks when the simulation
191955SN/A     * exits.
192955SN/A     */
193955SN/A    void cleanupRefs();
1942632Sstever@eecs.umich.edu
195955SN/A    /**
1962632Sstever@eecs.umich.edu     * Computes stats just prior to dump event
1972632Sstever@eecs.umich.edu     */
1982632Sstever@eecs.umich.edu    void computeStats();
1992632Sstever@eecs.umich.edu
2002632Sstever@eecs.umich.edu    /**
2012632Sstever@eecs.umich.edu     * Print all tags used
2022632Sstever@eecs.umich.edu     */
2032632Sstever@eecs.umich.edu    std::string print();
2042632Sstever@eecs.umich.edu
2052632Sstever@eecs.umich.edu    /**
2062632Sstever@eecs.umich.edu     * Finds the block in the cache without touching it.
2072632Sstever@eecs.umich.edu     *
2082632Sstever@eecs.umich.edu     * @param addr The address to look for.
2093718Sstever@eecs.umich.edu     * @param is_secure True if the target memory space is secure.
2103718Sstever@eecs.umich.edu     * @return Pointer to the cache block.
2113718Sstever@eecs.umich.edu     */
2123718Sstever@eecs.umich.edu    virtual CacheBlk *findBlock(Addr addr, bool is_secure) const;
2133718Sstever@eecs.umich.edu
2143718Sstever@eecs.umich.edu    /**
2153718Sstever@eecs.umich.edu     * Find a block given set and way.
2163718Sstever@eecs.umich.edu     *
2173718Sstever@eecs.umich.edu     * @param set The set of the block.
2183718Sstever@eecs.umich.edu     * @param way The way of the block.
2193718Sstever@eecs.umich.edu     * @return The block.
2203718Sstever@eecs.umich.edu     */
2213718Sstever@eecs.umich.edu    virtual ReplaceableEntry* findBlockBySetAndWay(int set, int way) const;
2222634Sstever@eecs.umich.edu
2232634Sstever@eecs.umich.edu    /**
2242632Sstever@eecs.umich.edu     * Align an address to the block size.
2252638Sstever@eecs.umich.edu     * @param addr the address to align.
2262632Sstever@eecs.umich.edu     * @return The block address.
2272632Sstever@eecs.umich.edu     */
2282632Sstever@eecs.umich.edu    Addr blkAlign(Addr addr) const
2292632Sstever@eecs.umich.edu    {
2302632Sstever@eecs.umich.edu        return addr & ~blkMask;
2312632Sstever@eecs.umich.edu    }
2321858SN/A
2333716Sstever@eecs.umich.edu    /**
2342638Sstever@eecs.umich.edu     * Calculate the block offset of an address.
2352638Sstever@eecs.umich.edu     * @param addr the address to get the offset of.
2362638Sstever@eecs.umich.edu     * @return the block offset.
2372638Sstever@eecs.umich.edu     */
2382638Sstever@eecs.umich.edu    int extractBlkOffset(Addr addr) const
2392638Sstever@eecs.umich.edu    {
2402638Sstever@eecs.umich.edu        return (addr & blkMask);
2413716Sstever@eecs.umich.edu    }
2422634Sstever@eecs.umich.edu
2432634Sstever@eecs.umich.edu    /**
244955SN/A     * Limit the allocation for the cache ways.
2455341Sstever@gmail.com     * @param ways The maximum number of ways available for replacement.
2465341Sstever@gmail.com     */
2475341Sstever@gmail.com    virtual void setWayAllocationMax(int ways)
2485341Sstever@gmail.com    {
249955SN/A        panic("This tag class does not implement way allocation limit!\n");
250955SN/A    }
251955SN/A
252955SN/A    /**
253955SN/A     * Get the way allocation mask limit.
254955SN/A     * @return The maximum number of ways available for replacement.
255955SN/A     */
2561858SN/A    virtual int getWayAllocationMax() const
2571858SN/A    {
2582632Sstever@eecs.umich.edu        panic("This tag class does not implement way allocation limit!\n");
259955SN/A        return -1;
2604494Ssaidi@eecs.umich.edu    }
2614494Ssaidi@eecs.umich.edu
2623716Sstever@eecs.umich.edu    /**
2631105SN/A     * This function updates the tags when a block is invalidated
2642667Sstever@eecs.umich.edu     *
2652667Sstever@eecs.umich.edu     * @param blk A valid block to invalidate.
2662667Sstever@eecs.umich.edu     */
2672667Sstever@eecs.umich.edu    virtual void invalidate(CacheBlk *blk)
2682667Sstever@eecs.umich.edu    {
2692667Sstever@eecs.umich.edu        assert(blk);
2701869SN/A        assert(blk->isValid());
2711869SN/A
2721869SN/A        occupancies[blk->srcMasterId]--;
2731869SN/A        totalRefs += blk->refCount;
2741869SN/A        sampledRefs++;
2751065SN/A
2765341Sstever@gmail.com        blk->invalidate();
2775341Sstever@gmail.com    }
2785341Sstever@gmail.com
2795341Sstever@gmail.com    /**
2805341Sstever@gmail.com     * Find replacement victim based on address. If the address requires
2815341Sstever@gmail.com     * blocks to be evicted, their locations are listed for eviction. If a
2825341Sstever@gmail.com     * conventional cache is being used, the list only contains the victim.
2835341Sstever@gmail.com     * However, if using sector or compressed caches, the victim is one of
2845341Sstever@gmail.com     * the blocks to be evicted, but its location is the only one that will
2855341Sstever@gmail.com     * be assigned to the newly allocated block associated to this address.
2865341Sstever@gmail.com     * @sa insertBlock
2875341Sstever@gmail.com     *
2885341Sstever@gmail.com     * @param addr Address to find a victim for.
2895341Sstever@gmail.com     * @param is_secure True if the target memory space is secure.
2905341Sstever@gmail.com     * @param evict_blks Cache blocks to be evicted.
2915341Sstever@gmail.com     * @return Cache block to be replaced.
2925341Sstever@gmail.com     */
2935341Sstever@gmail.com    virtual CacheBlk* findVictim(Addr addr, const bool is_secure,
2945341Sstever@gmail.com                                 std::vector<CacheBlk*>& evict_blks) const = 0;
2955341Sstever@gmail.com
2965341Sstever@gmail.com    virtual CacheBlk* accessBlock(Addr addr, bool is_secure, Cycles &lat) = 0;
2975341Sstever@gmail.com
2985341Sstever@gmail.com    /**
2995341Sstever@gmail.com     * Generate the tag from the given address.
3005341Sstever@gmail.com     *
3015341Sstever@gmail.com     * @param addr The address to get the tag from.
3025341Sstever@gmail.com     * @return The tag of the address.
3035397Ssaidi@eecs.umich.edu     */
3045397Ssaidi@eecs.umich.edu    virtual Addr extractTag(const Addr addr) const;
3055341Sstever@gmail.com
3065341Sstever@gmail.com    /**
3075341Sstever@gmail.com     * Insert the new block into the cache and update stats.
3085341Sstever@gmail.com     *
3095341Sstever@gmail.com     * @param addr Address of the block.
3105341Sstever@gmail.com     * @param is_secure Whether the block is in secure space or not.
3115341Sstever@gmail.com     * @param src_master_ID The source requestor ID.
3125341Sstever@gmail.com     * @param task_ID The new task ID.
3135341Sstever@gmail.com     * @param blk The block to update.
3145341Sstever@gmail.com     */
3155341Sstever@gmail.com    virtual void insertBlock(const Addr addr, const bool is_secure,
3165341Sstever@gmail.com                             const int src_master_ID, const uint32_t task_ID,
3175341Sstever@gmail.com                             CacheBlk *blk);
3185341Sstever@gmail.com
3195341Sstever@gmail.com    /**
3205341Sstever@gmail.com     * Regenerate the block address.
3215341Sstever@gmail.com     *
3225341Sstever@gmail.com     * @param block The block.
3235341Sstever@gmail.com     * @return the block address.
3245341Sstever@gmail.com     */
3255341Sstever@gmail.com    virtual Addr regenerateBlkAddr(const CacheBlk* blk) const = 0;
3265341Sstever@gmail.com
3275742Snate@binkert.org    /**
3285341Sstever@gmail.com     * Visit each block in the tags and apply a visitor
3295742Snate@binkert.org     *
3305742Snate@binkert.org     * The visitor should be a std::function that takes a cache block
3315742Snate@binkert.org     * reference as its parameter.
3325341Sstever@gmail.com     *
3335742Snate@binkert.org     * @param visitor Visitor to call on each block.
3345742Snate@binkert.org     */
3355341Sstever@gmail.com    virtual void forEachBlk(std::function<void(CacheBlk &)> visitor) = 0;
3362632Sstever@eecs.umich.edu
3375199Sstever@gmail.com    /**
3384781Snate@binkert.org     * Find if any of the blocks satisfies a condition
3394781Snate@binkert.org     *
3405550Snate@binkert.org     * The visitor should be a std::function that takes a cache block
3414781Snate@binkert.org     * reference as its parameter. The visitor will terminate the
3424781Snate@binkert.org     * traversal early if the condition is satisfied.
3433918Ssaidi@eecs.umich.edu     *
3444781Snate@binkert.org     * @param visitor Visitor to call on each block.
3454781Snate@binkert.org     */
3463940Ssaidi@eecs.umich.edu    virtual bool anyBlk(std::function<bool(CacheBlk &)> visitor) = 0;
3473942Ssaidi@eecs.umich.edu
3483940Ssaidi@eecs.umich.edu  private:
3493918Ssaidi@eecs.umich.edu    /**
3503918Ssaidi@eecs.umich.edu     * Update the reference stats using data from the input block
351955SN/A     *
3521858SN/A     * @param blk The input block
3533918Ssaidi@eecs.umich.edu     */
3543918Ssaidi@eecs.umich.edu    void cleanupRefsVisitor(CacheBlk &blk);
3553918Ssaidi@eecs.umich.edu
3563918Ssaidi@eecs.umich.edu    /**
3575571Snate@binkert.org     * Update the occupancy and age stats using data from the input block
3583940Ssaidi@eecs.umich.edu     *
3593940Ssaidi@eecs.umich.edu     * @param blk The input block
3603918Ssaidi@eecs.umich.edu     */
3613918Ssaidi@eecs.umich.edu    void computeStatsVisitor(CacheBlk &blk);
3623918Ssaidi@eecs.umich.edu};
3633918Ssaidi@eecs.umich.edu
3643918Ssaidi@eecs.umich.educlass BaseTagsCallback : public Callback
3653918Ssaidi@eecs.umich.edu{
3663918Ssaidi@eecs.umich.edu    BaseTags *tags;
3673918Ssaidi@eecs.umich.edu  public:
3683918Ssaidi@eecs.umich.edu    BaseTagsCallback(BaseTags *t) : tags(t) {}
3693940Ssaidi@eecs.umich.edu    virtual void process() { tags->cleanupRefs(); };
3703918Ssaidi@eecs.umich.edu};
3713918Ssaidi@eecs.umich.edu
3725397Ssaidi@eecs.umich.educlass BaseTagsDumpCallback : public Callback
3735397Ssaidi@eecs.umich.edu{
3745397Ssaidi@eecs.umich.edu    BaseTags *tags;
3755708Ssaidi@eecs.umich.edu  public:
3765708Ssaidi@eecs.umich.edu    BaseTagsDumpCallback(BaseTags *t) : tags(t) {}
3775708Ssaidi@eecs.umich.edu    virtual void process() { tags->computeStats(); };
3785708Ssaidi@eecs.umich.edu};
3795708Ssaidi@eecs.umich.edu
3805397Ssaidi@eecs.umich.edu#endif //__MEM_CACHE_TAGS_BASE_HH__
3811851SN/A