base.hh revision 13219
12810SN/A/*
212728Snikos.nikoleris@arm.com * Copyright (c) 2012-2014,2016-2018 ARM Limited
39347SAndreas.Sandberg@arm.com * All rights reserved.
49347SAndreas.Sandberg@arm.com *
59347SAndreas.Sandberg@arm.com * The license below extends only to copyright in the software and shall
69347SAndreas.Sandberg@arm.com * not be construed as granting a license to any other intellectual
79347SAndreas.Sandberg@arm.com * property including but not limited to intellectual property relating
89347SAndreas.Sandberg@arm.com * to a hardware implementation of the functionality of the software
99347SAndreas.Sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
109347SAndreas.Sandberg@arm.com * terms below provided that you ensure that this notice is replicated
119347SAndreas.Sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
129347SAndreas.Sandberg@arm.com * modified or unmodified, in source code or in binary form.
139347SAndreas.Sandberg@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 *          Ron Dreslinski
422810SN/A */
432810SN/A
442810SN/A/**
452810SN/A * @file
462810SN/A * Declaration of a common base class for cache tagstore objects.
472810SN/A */
482810SN/A
4912492Sodanrc@yahoo.com.br#ifndef __MEM_CACHE_TAGS_BASE_HH__
5012492Sodanrc@yahoo.com.br#define __MEM_CACHE_TAGS_BASE_HH__
512810SN/A
5212727Snikos.nikoleris@arm.com#include <cassert>
5312728Snikos.nikoleris@arm.com#include <functional>
542810SN/A#include <string>
558229Snate@binkert.org
568229Snate@binkert.org#include "base/callback.hh"
5712727Snikos.nikoleris@arm.com#include "base/logging.hh"
582810SN/A#include "base/statistics.hh"
5912727Snikos.nikoleris@arm.com#include "base/types.hh"
6010815Sdavid.guillen@arm.com#include "mem/cache/blk.hh"
619796Sprakash.ramrakhyani@arm.com#include "params/BaseTags.hh"
629796Sprakash.ramrakhyani@arm.com#include "sim/clocked_object.hh"
632810SN/A
642810SN/Aclass BaseCache;
6513219Sodanrc@yahoo.com.brclass IndexingPolicy;
6612773Sodanrc@yahoo.com.brclass ReplaceableEntry;
672810SN/A
682810SN/A/**
692810SN/A * A common base class of Cache tagstore objects.
702810SN/A */
719796Sprakash.ramrakhyani@arm.comclass BaseTags : public ClockedObject
722810SN/A{
732810SN/A  protected:
749796Sprakash.ramrakhyani@arm.com    /** The block size of the cache. */
759796Sprakash.ramrakhyani@arm.com    const unsigned blkSize;
7611893Snikos.nikoleris@arm.com    /** Mask out all bits that aren't part of the block offset. */
7711893Snikos.nikoleris@arm.com    const Addr blkMask;
789796Sprakash.ramrakhyani@arm.com    /** The size of the cache. */
799796Sprakash.ramrakhyani@arm.com    const unsigned size;
8011722Ssophiane.senni@gmail.com    /** The tag lookup latency of the cache. */
8111722Ssophiane.senni@gmail.com    const Cycles lookupLatency;
8211722Ssophiane.senni@gmail.com    /**
8311722Ssophiane.senni@gmail.com     * The total access latency of the cache. This latency
8411722Ssophiane.senni@gmail.com     * is different depending on the cache access mode
8511722Ssophiane.senni@gmail.com     * (parallel or sequential)
8611722Ssophiane.senni@gmail.com     */
8710693SMarco.Balboni@ARM.com    const Cycles accessLatency;
882810SN/A    /** Pointer to the parent cache. */
892810SN/A    BaseCache *cache;
902810SN/A
9113219Sodanrc@yahoo.com.br    /** Indexing policy */
9213219Sodanrc@yahoo.com.br    BaseIndexingPolicy *indexingPolicy;
9313219Sodanrc@yahoo.com.br
942810SN/A    /**
952810SN/A     * The number of tags that need to be touched to meet the warmup
962810SN/A     * percentage.
972810SN/A     */
9812513Sodanrc@yahoo.com.br    const unsigned warmupBound;
992810SN/A    /** Marked true when the cache is warmed up. */
1002810SN/A    bool warmedUp;
1012810SN/A
1026978SLisa.Hsu@amd.com    /** the number of blocks in the cache */
10312553Snikos.nikoleris@arm.com    const unsigned numBlocks;
1046978SLisa.Hsu@amd.com
10512629Sodanrc@yahoo.com.br    /** The data blocks, 1 per cache block. */
10612629Sodanrc@yahoo.com.br    std::unique_ptr<uint8_t[]> dataBlks;
10712629Sodanrc@yahoo.com.br
1082810SN/A    // Statistics
1092810SN/A    /**
11012513Sodanrc@yahoo.com.br     * TODO: It would be good if these stats were acquired after warmup.
1112810SN/A     * @addtogroup CacheStatistics
1122810SN/A     * @{
1132810SN/A     */
1142810SN/A
1152810SN/A    /** Per cycle average of the number of tags that hold valid data. */
1165999Snate@binkert.org    Stats::Average tagsInUse;
1172810SN/A
1182810SN/A    /** The total number of references to a block before it is replaced. */
1195999Snate@binkert.org    Stats::Scalar totalRefs;
1202810SN/A
1212810SN/A    /**
1222810SN/A     * The number of reference counts sampled. This is different from
1232810SN/A     * replacements because we sample all the valid blocks when the simulator
1242810SN/A     * exits.
1252810SN/A     */
1265999Snate@binkert.org    Stats::Scalar sampledRefs;
1272810SN/A
1282810SN/A    /**
1292810SN/A     * Average number of references to a block before is was replaced.
1302810SN/A     * @todo This should change to an average stat once we have them.
1312810SN/A     */
1322810SN/A    Stats::Formula avgRefs;
1332810SN/A
13412513Sodanrc@yahoo.com.br    /** The cycle that the warmup percentage was hit. 0 on failure. */
1355999Snate@binkert.org    Stats::Scalar warmupCycle;
1366978SLisa.Hsu@amd.com
1378833Sdam.sunwoo@arm.com    /** Average occupancy of each requestor using the cache */
1386978SLisa.Hsu@amd.com    Stats::AverageVector occupancies;
1396978SLisa.Hsu@amd.com
1408833Sdam.sunwoo@arm.com    /** Average occ % of each requestor using the cache */
1416978SLisa.Hsu@amd.com    Stats::Formula avgOccs;
1426978SLisa.Hsu@amd.com
14310024Sdam.sunwoo@arm.com    /** Occupancy of each context/cpu using the cache */
14410024Sdam.sunwoo@arm.com    Stats::Vector occupanciesTaskId;
14510024Sdam.sunwoo@arm.com
14610024Sdam.sunwoo@arm.com    /** Occupancy of each context/cpu using the cache */
14710024Sdam.sunwoo@arm.com    Stats::Vector2d ageTaskId;
14810024Sdam.sunwoo@arm.com
14910024Sdam.sunwoo@arm.com    /** Occ % of each context/cpu using the cache */
15010024Sdam.sunwoo@arm.com    Stats::Formula percentOccsTaskId;
15110024Sdam.sunwoo@arm.com
15210025Stimothy.jones@arm.com    /** Number of tags consulted over all accesses. */
15310025Stimothy.jones@arm.com    Stats::Scalar tagAccesses;
15410025Stimothy.jones@arm.com    /** Number of data blocks consulted over all accesses. */
15510025Stimothy.jones@arm.com    Stats::Scalar dataAccesses;
15610025Stimothy.jones@arm.com
1572810SN/A    /**
1582810SN/A     * @}
1592810SN/A     */
1602810SN/A
16113216Sodanrc@yahoo.com.br    /**
16213216Sodanrc@yahoo.com.br     * Set the parent cache back pointer.
16313216Sodanrc@yahoo.com.br     *
16413216Sodanrc@yahoo.com.br     * @param _cache Pointer to parent cache.
16513216Sodanrc@yahoo.com.br     */
16613216Sodanrc@yahoo.com.br    void setCache(BaseCache *_cache);
16713216Sodanrc@yahoo.com.br
1682810SN/A  public:
1699796Sprakash.ramrakhyani@arm.com    typedef BaseTagsParams Params;
1709796Sprakash.ramrakhyani@arm.com    BaseTags(const Params *p);
1712810SN/A
1722810SN/A    /**
1732810SN/A     * Destructor.
1742810SN/A     */
1752810SN/A    virtual ~BaseTags() {}
1762810SN/A
1772810SN/A    /**
17813216Sodanrc@yahoo.com.br     * Initialize blocks and set the parent cache back pointer.
17913216Sodanrc@yahoo.com.br     *
1802810SN/A     * @param _cache Pointer to parent cache.
1812810SN/A     */
18213216Sodanrc@yahoo.com.br    virtual void init(BaseCache *_cache) = 0;
1832810SN/A
1842810SN/A    /**
1859796Sprakash.ramrakhyani@arm.com     * Register local statistics.
1862810SN/A     */
1879796Sprakash.ramrakhyani@arm.com    void regStats();
1882810SN/A
1892810SN/A    /**
1902810SN/A     * Average in the reference count for valid blocks when the simulation
1912810SN/A     * exits.
1922810SN/A     */
19312728Snikos.nikoleris@arm.com    void cleanupRefs();
1947612SGene.Wu@arm.com
1957612SGene.Wu@arm.com    /**
19610024Sdam.sunwoo@arm.com     * Computes stats just prior to dump event
19710024Sdam.sunwoo@arm.com     */
19812728Snikos.nikoleris@arm.com    void computeStats();
19910024Sdam.sunwoo@arm.com
20010024Sdam.sunwoo@arm.com    /**
2019663Suri.wiener@arm.com     * Print all tags used
2029663Suri.wiener@arm.com     */
20312728Snikos.nikoleris@arm.com    std::string print();
20410815Sdavid.guillen@arm.com
20510815Sdavid.guillen@arm.com    /**
20613217Sodanrc@yahoo.com.br     * Finds the block in the cache without touching it.
20713217Sodanrc@yahoo.com.br     *
20813217Sodanrc@yahoo.com.br     * @param addr The address to look for.
20913217Sodanrc@yahoo.com.br     * @param is_secure True if the target memory space is secure.
21013217Sodanrc@yahoo.com.br     * @return Pointer to the cache block.
21110815Sdavid.guillen@arm.com     */
21213217Sodanrc@yahoo.com.br    virtual CacheBlk *findBlock(Addr addr, bool is_secure) const;
21310815Sdavid.guillen@arm.com
21410815Sdavid.guillen@arm.com    /**
21512743Sodanrc@yahoo.com.br     * Find a block given set and way.
21612743Sodanrc@yahoo.com.br     *
21712743Sodanrc@yahoo.com.br     * @param set The set of the block.
21812743Sodanrc@yahoo.com.br     * @param way The way of the block.
21912743Sodanrc@yahoo.com.br     * @return The block.
22012743Sodanrc@yahoo.com.br     */
22113219Sodanrc@yahoo.com.br    virtual ReplaceableEntry* findBlockBySetAndWay(int set, int way) const;
22212743Sodanrc@yahoo.com.br
22312743Sodanrc@yahoo.com.br    /**
22411893Snikos.nikoleris@arm.com     * Align an address to the block size.
22511893Snikos.nikoleris@arm.com     * @param addr the address to align.
22611893Snikos.nikoleris@arm.com     * @return The block address.
22711893Snikos.nikoleris@arm.com     */
22811893Snikos.nikoleris@arm.com    Addr blkAlign(Addr addr) const
22911893Snikos.nikoleris@arm.com    {
23011893Snikos.nikoleris@arm.com        return addr & ~blkMask;
23111893Snikos.nikoleris@arm.com    }
23211893Snikos.nikoleris@arm.com
23311893Snikos.nikoleris@arm.com    /**
23410815Sdavid.guillen@arm.com     * Calculate the block offset of an address.
23510815Sdavid.guillen@arm.com     * @param addr the address to get the offset of.
23610815Sdavid.guillen@arm.com     * @return the block offset.
23710815Sdavid.guillen@arm.com     */
23810815Sdavid.guillen@arm.com    int extractBlkOffset(Addr addr) const
23910815Sdavid.guillen@arm.com    {
24011893Snikos.nikoleris@arm.com        return (addr & blkMask);
24110815Sdavid.guillen@arm.com    }
24210815Sdavid.guillen@arm.com
24310941Sdavid.guillen@arm.com    /**
24410941Sdavid.guillen@arm.com     * Limit the allocation for the cache ways.
24510941Sdavid.guillen@arm.com     * @param ways The maximum number of ways available for replacement.
24610941Sdavid.guillen@arm.com     */
24710941Sdavid.guillen@arm.com    virtual void setWayAllocationMax(int ways)
24810941Sdavid.guillen@arm.com    {
24910941Sdavid.guillen@arm.com        panic("This tag class does not implement way allocation limit!\n");
25010941Sdavid.guillen@arm.com    }
25110941Sdavid.guillen@arm.com
25210941Sdavid.guillen@arm.com    /**
25310941Sdavid.guillen@arm.com     * Get the way allocation mask limit.
25410941Sdavid.guillen@arm.com     * @return The maximum number of ways available for replacement.
25510941Sdavid.guillen@arm.com     */
25610941Sdavid.guillen@arm.com    virtual int getWayAllocationMax() const
25710941Sdavid.guillen@arm.com    {
25810941Sdavid.guillen@arm.com        panic("This tag class does not implement way allocation limit!\n");
25910941Sdavid.guillen@arm.com        return -1;
26010941Sdavid.guillen@arm.com    }
26110941Sdavid.guillen@arm.com
26212566Snikos.nikoleris@arm.com    /**
26312704Snikos.nikoleris@arm.com     * This function updates the tags when a block is invalidated
26412704Snikos.nikoleris@arm.com     *
26512704Snikos.nikoleris@arm.com     * @param blk A valid block to invalidate.
26612566Snikos.nikoleris@arm.com     */
26712566Snikos.nikoleris@arm.com    virtual void invalidate(CacheBlk *blk)
26812566Snikos.nikoleris@arm.com    {
26912566Snikos.nikoleris@arm.com        assert(blk);
27012566Snikos.nikoleris@arm.com        assert(blk->isValid());
27112704Snikos.nikoleris@arm.com
27212566Snikos.nikoleris@arm.com        occupancies[blk->srcMasterId]--;
27312704Snikos.nikoleris@arm.com        totalRefs += blk->refCount;
27412704Snikos.nikoleris@arm.com        sampledRefs++;
27512704Snikos.nikoleris@arm.com
27612704Snikos.nikoleris@arm.com        blk->invalidate();
27712566Snikos.nikoleris@arm.com    }
27810815Sdavid.guillen@arm.com
27912600Sodanrc@yahoo.com.br    /**
28012744Sodanrc@yahoo.com.br     * Find replacement victim based on address. If the address requires
28112744Sodanrc@yahoo.com.br     * blocks to be evicted, their locations are listed for eviction. If a
28212744Sodanrc@yahoo.com.br     * conventional cache is being used, the list only contains the victim.
28312744Sodanrc@yahoo.com.br     * However, if using sector or compressed caches, the victim is one of
28412744Sodanrc@yahoo.com.br     * the blocks to be evicted, but its location is the only one that will
28512744Sodanrc@yahoo.com.br     * be assigned to the newly allocated block associated to this address.
28612744Sodanrc@yahoo.com.br     * @sa insertBlock
28712600Sodanrc@yahoo.com.br     *
28812600Sodanrc@yahoo.com.br     * @param addr Address to find a victim for.
28912746Sodanrc@yahoo.com.br     * @param is_secure True if the target memory space is secure.
29012744Sodanrc@yahoo.com.br     * @param evict_blks Cache blocks to be evicted.
29112600Sodanrc@yahoo.com.br     * @return Cache block to be replaced.
29212600Sodanrc@yahoo.com.br     */
29312746Sodanrc@yahoo.com.br    virtual CacheBlk* findVictim(Addr addr, const bool is_secure,
29412746Sodanrc@yahoo.com.br                                 std::vector<CacheBlk*>& evict_blks) const = 0;
29512600Sodanrc@yahoo.com.br
29611870Snikos.nikoleris@arm.com    virtual CacheBlk* accessBlock(Addr addr, bool is_secure, Cycles &lat) = 0;
29710815Sdavid.guillen@arm.com
29813219Sodanrc@yahoo.com.br    /**
29913219Sodanrc@yahoo.com.br     * Generate the tag from the given address.
30013219Sodanrc@yahoo.com.br     *
30113219Sodanrc@yahoo.com.br     * @param addr The address to get the tag from.
30213219Sodanrc@yahoo.com.br     * @return The tag of the address.
30313219Sodanrc@yahoo.com.br     */
30413219Sodanrc@yahoo.com.br    virtual Addr extractTag(const Addr addr) const;
30510815Sdavid.guillen@arm.com
30612636Sodanrc@yahoo.com.br    /**
30712636Sodanrc@yahoo.com.br     * Insert the new block into the cache and update stats.
30812636Sodanrc@yahoo.com.br     *
30913215Sodanrc@yahoo.com.br     * @param addr Address of the block.
31013215Sodanrc@yahoo.com.br     * @param is_secure Whether the block is in secure space or not.
31113215Sodanrc@yahoo.com.br     * @param src_master_ID The source requestor ID.
31213215Sodanrc@yahoo.com.br     * @param task_ID The new task ID.
31312636Sodanrc@yahoo.com.br     * @param blk The block to update.
31412636Sodanrc@yahoo.com.br     */
31513215Sodanrc@yahoo.com.br    virtual void insertBlock(const Addr addr, const bool is_secure,
31613215Sodanrc@yahoo.com.br                             const int src_master_ID, const uint32_t task_ID,
31713215Sodanrc@yahoo.com.br                             CacheBlk *blk);
31810815Sdavid.guillen@arm.com
31912574Sodanrc@yahoo.com.br    /**
32012574Sodanrc@yahoo.com.br     * Regenerate the block address.
32112574Sodanrc@yahoo.com.br     *
32212574Sodanrc@yahoo.com.br     * @param block The block.
32312574Sodanrc@yahoo.com.br     * @return the block address.
32412574Sodanrc@yahoo.com.br     */
32512574Sodanrc@yahoo.com.br    virtual Addr regenerateBlkAddr(const CacheBlk* blk) const = 0;
32610815Sdavid.guillen@arm.com
32712728Snikos.nikoleris@arm.com    /**
32812728Snikos.nikoleris@arm.com     * Visit each block in the tags and apply a visitor
32912728Snikos.nikoleris@arm.com     *
33012728Snikos.nikoleris@arm.com     * The visitor should be a std::function that takes a cache block
33112728Snikos.nikoleris@arm.com     * reference as its parameter.
33212728Snikos.nikoleris@arm.com     *
33312728Snikos.nikoleris@arm.com     * @param visitor Visitor to call on each block.
33412728Snikos.nikoleris@arm.com     */
33512728Snikos.nikoleris@arm.com    virtual void forEachBlk(std::function<void(CacheBlk &)> visitor) = 0;
33612728Snikos.nikoleris@arm.com
33712728Snikos.nikoleris@arm.com    /**
33812728Snikos.nikoleris@arm.com     * Find if any of the blocks satisfies a condition
33912728Snikos.nikoleris@arm.com     *
34012728Snikos.nikoleris@arm.com     * The visitor should be a std::function that takes a cache block
34112728Snikos.nikoleris@arm.com     * reference as its parameter. The visitor will terminate the
34212728Snikos.nikoleris@arm.com     * traversal early if the condition is satisfied.
34312728Snikos.nikoleris@arm.com     *
34412728Snikos.nikoleris@arm.com     * @param visitor Visitor to call on each block.
34512728Snikos.nikoleris@arm.com     */
34612728Snikos.nikoleris@arm.com    virtual bool anyBlk(std::function<bool(CacheBlk &)> visitor) = 0;
34712728Snikos.nikoleris@arm.com
34812728Snikos.nikoleris@arm.com  private:
34912728Snikos.nikoleris@arm.com    /**
35012728Snikos.nikoleris@arm.com     * Update the reference stats using data from the input block
35112728Snikos.nikoleris@arm.com     *
35212728Snikos.nikoleris@arm.com     * @param blk The input block
35312728Snikos.nikoleris@arm.com     */
35412728Snikos.nikoleris@arm.com    void cleanupRefsVisitor(CacheBlk &blk);
35512728Snikos.nikoleris@arm.com
35612728Snikos.nikoleris@arm.com    /**
35712728Snikos.nikoleris@arm.com     * Update the occupancy and age stats using data from the input block
35812728Snikos.nikoleris@arm.com     *
35912728Snikos.nikoleris@arm.com     * @param blk The input block
36012728Snikos.nikoleris@arm.com     */
36112728Snikos.nikoleris@arm.com    void computeStatsVisitor(CacheBlk &blk);
3622810SN/A};
3632810SN/A
3642810SN/Aclass BaseTagsCallback : public Callback
3652810SN/A{
3662810SN/A    BaseTags *tags;
3672810SN/A  public:
3682810SN/A    BaseTagsCallback(BaseTags *t) : tags(t) {}
3692810SN/A    virtual void process() { tags->cleanupRefs(); };
3702810SN/A};
3712810SN/A
37210024Sdam.sunwoo@arm.comclass BaseTagsDumpCallback : public Callback
37310024Sdam.sunwoo@arm.com{
37410024Sdam.sunwoo@arm.com    BaseTags *tags;
37510024Sdam.sunwoo@arm.com  public:
37610024Sdam.sunwoo@arm.com    BaseTagsDumpCallback(BaseTags *t) : tags(t) {}
37710024Sdam.sunwoo@arm.com    virtual void process() { tags->computeStats(); };
37810024Sdam.sunwoo@arm.com};
37910024Sdam.sunwoo@arm.com
38012492Sodanrc@yahoo.com.br#endif //__MEM_CACHE_TAGS_BASE_HH__
381