CacheMemory.hh revision 11061
12810Srdreslin@umich.edu/*
212500Snikos.nikoleris@arm.com * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood
311051Sandreas.hansson@arm.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
411051Sandreas.hansson@arm.com * All rights reserved.
511051Sandreas.hansson@arm.com *
611051Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
711051Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
811051Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
911051Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
1011051Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
1111051Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
1211051Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
1311051Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
1411051Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
1511051Sandreas.hansson@arm.com * this software without specific prior written permission.
162810Srdreslin@umich.edu *
172810Srdreslin@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182810Srdreslin@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192810Srdreslin@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202810Srdreslin@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212810Srdreslin@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222810Srdreslin@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232810Srdreslin@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242810Srdreslin@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252810Srdreslin@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262810Srdreslin@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272810Srdreslin@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282810Srdreslin@umich.edu */
292810Srdreslin@umich.edu
302810Srdreslin@umich.edu#ifndef __MEM_RUBY_STRUCTURES_CACHEMEMORY_HH__
312810Srdreslin@umich.edu#define __MEM_RUBY_STRUCTURES_CACHEMEMORY_HH__
322810Srdreslin@umich.edu
332810Srdreslin@umich.edu#include <string>
342810Srdreslin@umich.edu#include <vector>
352810Srdreslin@umich.edu
362810Srdreslin@umich.edu#include "base/hashmap.hh"
372810Srdreslin@umich.edu#include "base/statistics.hh"
382810Srdreslin@umich.edu#include "mem/protocol/CacheRequestType.hh"
392810Srdreslin@umich.edu#include "mem/protocol/CacheResourceType.hh"
402810Srdreslin@umich.edu#include "mem/protocol/RubyRequest.hh"
412810Srdreslin@umich.edu#include "mem/ruby/common/DataBlock.hh"
4211051Sandreas.hansson@arm.com#include "mem/ruby/slicc_interface/AbstractCacheEntry.hh"
4311051Sandreas.hansson@arm.com#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh"
442810Srdreslin@umich.edu#include "mem/ruby/structures/AbstractReplacementPolicy.hh"
4511051Sandreas.hansson@arm.com#include "mem/ruby/structures/BankedArray.hh"
4611051Sandreas.hansson@arm.com#include "mem/ruby/system/CacheRecorder.hh"
4712349Snikos.nikoleris@arm.com#include "params/RubyCache.hh"
482810Srdreslin@umich.edu#include "sim/sim_object.hh"
492810Srdreslin@umich.edu
502810Srdreslin@umich.educlass CacheMemory : public SimObject
512810Srdreslin@umich.edu{
5211051Sandreas.hansson@arm.com  public:
532810Srdreslin@umich.edu    typedef RubyCacheParams Params;
542810Srdreslin@umich.edu    CacheMemory(const Params *p);
5511051Sandreas.hansson@arm.com    ~CacheMemory();
562810Srdreslin@umich.edu
5712724Snikos.nikoleris@arm.com    void init();
5812724Snikos.nikoleris@arm.com
5912724Snikos.nikoleris@arm.com    // Public Methods
6012334Sgabeblack@google.com    // perform a cache access and see if we hit or not.  Return true on a hit.
6112724Snikos.nikoleris@arm.com    bool tryCacheAccess(Addr address, RubyRequestType type,
6211051Sandreas.hansson@arm.com                        DataBlock*& data_ptr);
6311051Sandreas.hansson@arm.com
6411051Sandreas.hansson@arm.com    // similar to above, but doesn't require full access check
6511288Ssteve.reinhardt@amd.com    bool testCacheAccess(Addr address, RubyRequestType type,
6612724Snikos.nikoleris@arm.com                         DataBlock*& data_ptr);
6713223Sodanrc@yahoo.com.br
6811051Sandreas.hansson@arm.com    // tests to see if an address is present in the cache
6912724Snikos.nikoleris@arm.com    bool isTagPresent(Addr address) const;
7012724Snikos.nikoleris@arm.com
7112724Snikos.nikoleris@arm.com    // Returns true if there is:
7212724Snikos.nikoleris@arm.com    //   a) a tag match on this address or there is
7311051Sandreas.hansson@arm.com    //   b) an unused line in the same cache "way"
7411053Sandreas.hansson@arm.com    bool cacheAvail(Addr address) const;
7511053Sandreas.hansson@arm.com
7612724Snikos.nikoleris@arm.com    // find an unused entry and sets the tag appropriate for the address
7711051Sandreas.hansson@arm.com    AbstractCacheEntry* allocate(Addr address,
7811051Sandreas.hansson@arm.com                                 AbstractCacheEntry* new_entry, bool touch);
7911051Sandreas.hansson@arm.com    AbstractCacheEntry* allocate(Addr address, AbstractCacheEntry* new_entry)
8011051Sandreas.hansson@arm.com    {
8111601Sandreas.hansson@arm.com        return allocate(address, new_entry, true);
8211601Sandreas.hansson@arm.com    }
8311051Sandreas.hansson@arm.com    void allocateVoid(Addr address, AbstractCacheEntry* new_entry)
8412724Snikos.nikoleris@arm.com    {
8511051Sandreas.hansson@arm.com        allocate(address, new_entry, true);
8612724Snikos.nikoleris@arm.com    }
8711600Sandreas.hansson@arm.com
8811600Sandreas.hansson@arm.com    // Explicitly free up this address
8911051Sandreas.hansson@arm.com    void deallocate(Addr address);
9011051Sandreas.hansson@arm.com
9111051Sandreas.hansson@arm.com    // Returns with the physical address of the conflicting cache line
9211284Sandreas.hansson@arm.com    Addr cacheProbe(Addr address) const;
9311051Sandreas.hansson@arm.com
9411051Sandreas.hansson@arm.com    // looks an address up in the cache
9511051Sandreas.hansson@arm.com    AbstractCacheEntry* lookup(Addr address);
9611602Sandreas.hansson@arm.com    const AbstractCacheEntry* lookup(Addr address) const;
9711051Sandreas.hansson@arm.com
9811051Sandreas.hansson@arm.com    Cycles getTagLatency() const { return tagArray.getLatency(); }
9911284Sandreas.hansson@arm.com    Cycles getDataLatency() const { return dataArray.getLatency(); }
10011051Sandreas.hansson@arm.com
10111284Sandreas.hansson@arm.com    bool isBlockInvalid(int64_t cache_set, int64_t loc);
10211602Sandreas.hansson@arm.com    bool isBlockNotBusy(int64_t cache_set, int64_t loc);
10311051Sandreas.hansson@arm.com
10411051Sandreas.hansson@arm.com    // Hook for checkpointing the contents of the cache
10511284Sandreas.hansson@arm.com    void recordCacheContents(int cntrl, CacheRecorder* tr) const;
10611051Sandreas.hansson@arm.com
10711284Sandreas.hansson@arm.com    // Set this address to most recently used
10811284Sandreas.hansson@arm.com    void setMRU(Addr address);
10911284Sandreas.hansson@arm.com
11011051Sandreas.hansson@arm.com    // Functions for locking and unlocking cache lines corresponding to the
11111051Sandreas.hansson@arm.com    // provided address.  These are required for supporting atomic memory
11211051Sandreas.hansson@arm.com    // accesses.  These are to be used when only the address of the cache entry
11311284Sandreas.hansson@arm.com    // is available.  In case the entry itself is available. use the functions
11411284Sandreas.hansson@arm.com    // provided by the AbstractCacheEntry class.
11511284Sandreas.hansson@arm.com    void setLocked (Addr addr, int context);
11611284Sandreas.hansson@arm.com    void clearLocked (Addr addr);
11711051Sandreas.hansson@arm.com    bool isLocked (Addr addr, int context);
11811051Sandreas.hansson@arm.com
11911051Sandreas.hansson@arm.com    // Print cache contents
12011284Sandreas.hansson@arm.com    void print(std::ostream& out) const;
12111284Sandreas.hansson@arm.com    void printData(std::ostream& out) const;
12211284Sandreas.hansson@arm.com
12311197Sandreas.hansson@arm.com    void regStats();
12411601Sandreas.hansson@arm.com    bool checkResourceAvailable(CacheResourceType res, Addr addr);
12511601Sandreas.hansson@arm.com    void recordRequestType(CacheRequestType requestType, Addr addr);
12611601Sandreas.hansson@arm.com
12711601Sandreas.hansson@arm.com  public:
12811601Sandreas.hansson@arm.com    Stats::Scalar m_demand_hits;
12911601Sandreas.hansson@arm.com    Stats::Scalar m_demand_misses;
13011601Sandreas.hansson@arm.com    Stats::Formula m_demand_accesses;
13111601Sandreas.hansson@arm.com
13211197Sandreas.hansson@arm.com    Stats::Scalar m_sw_prefetches;
13311601Sandreas.hansson@arm.com    Stats::Scalar m_hw_prefetches;
13411601Sandreas.hansson@arm.com    Stats::Formula m_prefetches;
13511601Sandreas.hansson@arm.com
13611601Sandreas.hansson@arm.com    Stats::Vector m_accessModeType;
13711601Sandreas.hansson@arm.com
13811601Sandreas.hansson@arm.com    Stats::Scalar numDataArrayReads;
13911601Sandreas.hansson@arm.com    Stats::Scalar numDataArrayWrites;
14011051Sandreas.hansson@arm.com    Stats::Scalar numTagArrayReads;
14111051Sandreas.hansson@arm.com    Stats::Scalar numTagArrayWrites;
14211051Sandreas.hansson@arm.com
14311051Sandreas.hansson@arm.com    Stats::Scalar numTagArrayStalls;
14411051Sandreas.hansson@arm.com    Stats::Scalar numDataArrayStalls;
14511284Sandreas.hansson@arm.com
14611284Sandreas.hansson@arm.com    int getCacheSize() const { return m_cache_size; }
14711051Sandreas.hansson@arm.com    int getNumBlocks() const { return m_cache_num_sets * m_cache_assoc; }
14811051Sandreas.hansson@arm.com    Addr getAddressAtIdx(int idx) const;
14911051Sandreas.hansson@arm.com
15011051Sandreas.hansson@arm.com  private:
15111284Sandreas.hansson@arm.com    // convert a Address to its location in the cache
15211051Sandreas.hansson@arm.com    int64_t addressToCacheSet(Addr address) const;
15311051Sandreas.hansson@arm.com
15411051Sandreas.hansson@arm.com    // Given a cache tag: returns the index of the tag in a set.
15511051Sandreas.hansson@arm.com    // returns -1 if the tag is not found.
15611051Sandreas.hansson@arm.com    int findTagInSet(int64_t line, Addr tag) const;
15711051Sandreas.hansson@arm.com    int findTagInSetIgnorePermissions(int64_t cacheSet, Addr tag) const;
15811051Sandreas.hansson@arm.com
15911051Sandreas.hansson@arm.com    // Private copy constructor and assignment operator
16011051Sandreas.hansson@arm.com    CacheMemory(const CacheMemory& obj);
16111051Sandreas.hansson@arm.com    CacheMemory& operator=(const CacheMemory& obj);
16211051Sandreas.hansson@arm.com
16311051Sandreas.hansson@arm.com  private:
16411051Sandreas.hansson@arm.com    // Data Members (m_prefix)
16511051Sandreas.hansson@arm.com    bool m_is_instruction_only_cache;
16611051Sandreas.hansson@arm.com
16711051Sandreas.hansson@arm.com    // The first index is the # of cache lines.
16811051Sandreas.hansson@arm.com    // The second index is the the amount associativity.
16912724Snikos.nikoleris@arm.com    m5::hash_map<Addr, int> m_tag_index;
17012724Snikos.nikoleris@arm.com    std::vector<std::vector<AbstractCacheEntry*> > m_cache;
17112724Snikos.nikoleris@arm.com
17212724Snikos.nikoleris@arm.com    AbstractReplacementPolicy *m_replacementPolicy_ptr;
17312724Snikos.nikoleris@arm.com
17412724Snikos.nikoleris@arm.com    BankedArray dataArray;
17512724Snikos.nikoleris@arm.com    BankedArray tagArray;
17611051Sandreas.hansson@arm.com
17711051Sandreas.hansson@arm.com    int m_cache_size;
17811051Sandreas.hansson@arm.com    int m_cache_num_sets;
17911051Sandreas.hansson@arm.com    int m_cache_num_set_bits;
18012723Snikos.nikoleris@arm.com    int m_cache_assoc;
18111051Sandreas.hansson@arm.com    int m_start_index_bit;
18211051Sandreas.hansson@arm.com    bool m_resource_stalls;
18311484Snikos.nikoleris@arm.com};
18411051Sandreas.hansson@arm.com
18511051Sandreas.hansson@arm.comstd::ostream& operator<<(std::ostream& out, const CacheMemory& obj);
18611051Sandreas.hansson@arm.com
18711051Sandreas.hansson@arm.com#endif // __MEM_RUBY_STRUCTURES_CACHEMEMORY_HH__
18811051Sandreas.hansson@arm.com