2 * Copyright (c) 2013,2016,2018 ARM Limited
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
14 * Copyright (c) 2003-2005 The Regents of The University of Michigan
15 * All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 * Authors: Erik Hallnor
46 * Definitions of BaseTags.
49 #include "mem/cache/tags/base.hh"
53 #include "base/types.hh"
54 #include "mem/cache/base.hh"
55 #include "mem/cache/tags/indexing_policies/base.hh"
56 #include "mem/request.hh"
57 #include "sim/core.hh"
58 #include "sim/sim_exit.hh"
59 #include "sim/system.hh"
61 BaseTags::BaseTags(const Params
*p
)
62 : ClockedObject(p
), blkSize(p
->block_size
), blkMask(blkSize
- 1),
64 lookupLatency(p
->tag_latency
),
65 accessLatency(p
->sequential_access
?
66 p
->tag_latency
+ p
->data_latency
:
67 std::max(p
->tag_latency
, p
->data_latency
)),
68 cache(nullptr), indexingPolicy(p
->indexing_policy
),
69 warmupBound((p
->warmup_percentage
/100.0) * (p
->size
/ p
->block_size
)),
70 warmedUp(false), numBlocks(p
->size
/ p
->block_size
),
71 dataBlks(new uint8_t[p
->size
]) // Allocate data storage in one big chunk
76 BaseTags::setCache(BaseCache
*_cache
)
83 BaseTags::findBlockBySetAndWay(int set
, int way
) const
85 return indexingPolicy
->getEntry(set
, way
);
89 BaseTags::findBlock(Addr addr
, bool is_secure
) const
92 Addr tag
= extractTag(addr
);
94 // Find possible entries that may contain the given address
95 const std::vector
<ReplaceableEntry
*> entries
=
96 indexingPolicy
->getPossibleEntries(addr
);
99 for (const auto& location
: entries
) {
100 CacheBlk
* blk
= static_cast<CacheBlk
*>(location
);
101 if ((blk
->tag
== tag
) && blk
->isValid() &&
102 (blk
->isSecure() == is_secure
)) {
107 // Did not find block
112 BaseTags::insertBlock(const Addr addr
, const bool is_secure
,
113 const int src_master_ID
, const uint32_t task_ID
,
116 assert(!blk
->isValid());
118 // Previous block, if existed, has been removed, and now we have
119 // to insert the new one
120 // Deal with what we are bringing in
121 assert(src_master_ID
< cache
->system
->maxMasters());
122 occupancies
[src_master_ID
]++;
124 // Insert block with tag, src master id and task id
125 blk
->insert(extractTag(addr
), is_secure
, src_master_ID
, task_ID
);
127 // Check if cache warm up is done
128 if (!warmedUp
&& tagsInUse
.value() >= warmupBound
) {
130 warmupCycle
= curTick();
133 // We only need to write into one tag and one data block.
139 BaseTags::extractTag(const Addr addr
) const
141 return indexingPolicy
->extractTag(addr
);
145 BaseTags::cleanupRefsVisitor(CacheBlk
&blk
)
148 totalRefs
+= blk
.refCount
;
154 BaseTags::cleanupRefs()
156 forEachBlk([this](CacheBlk
&blk
) { cleanupRefsVisitor(blk
); });
160 BaseTags::computeStatsVisitor(CacheBlk
&blk
)
163 assert(blk
.task_id
< ContextSwitchTaskId::NumTaskId
);
164 occupanciesTaskId
[blk
.task_id
]++;
165 assert(blk
.tickInserted
<= curTick());
166 Tick age
= curTick() - blk
.tickInserted
;
169 if (age
/ SimClock::Int::us
< 10) { // <10us
171 } else if (age
/ SimClock::Int::us
< 100) { // <100us
173 } else if (age
/ SimClock::Int::ms
< 1) { // <1ms
175 } else if (age
/ SimClock::Int::ms
< 10) { // <10ms
178 age_index
= 4; // >10ms
180 ageTaskId
[blk
.task_id
][age_index
]++;
185 BaseTags::computeStats()
187 for (unsigned i
= 0; i
< ContextSwitchTaskId::NumTaskId
; ++i
) {
188 occupanciesTaskId
[i
] = 0;
189 for (unsigned j
= 0; j
< 5; ++j
) {
194 forEachBlk([this](CacheBlk
&blk
) { computeStatsVisitor(blk
); });
202 auto print_blk
= [&str
](CacheBlk
&blk
) {
204 str
+= csprintf("\tBlock: %s\n", blk
.print());
206 forEachBlk(print_blk
);
209 str
= "no valid tags\n";
217 ClockedObject::regStats();
219 using namespace Stats
;
222 .name(name() + ".tagsinuse")
223 .desc("Cycle average of tags in use")
227 .name(name() + ".total_refs")
228 .desc("Total number of references to valid blocks.")
232 .name(name() + ".sampled_refs")
233 .desc("Sample count of references to valid blocks.")
237 .name(name() + ".avg_refs")
238 .desc("Average number of references to valid blocks.")
241 avgRefs
= totalRefs
/sampledRefs
;
244 .name(name() + ".warmup_cycle")
245 .desc("Cycle when the warmup percentage was hit.")
249 .init(cache
->system
->maxMasters())
250 .name(name() + ".occ_blocks")
251 .desc("Average occupied blocks per requestor")
252 .flags(nozero
| nonan
)
254 for (int i
= 0; i
< cache
->system
->maxMasters(); i
++) {
255 occupancies
.subname(i
, cache
->system
->getMasterName(i
));
259 .name(name() + ".occ_percent")
260 .desc("Average percentage of cache occupancy")
261 .flags(nozero
| total
)
263 for (int i
= 0; i
< cache
->system
->maxMasters(); i
++) {
264 avgOccs
.subname(i
, cache
->system
->getMasterName(i
));
267 avgOccs
= occupancies
/ Stats::constant(numBlocks
);
270 .init(ContextSwitchTaskId::NumTaskId
)
271 .name(name() + ".occ_task_id_blocks")
272 .desc("Occupied blocks per task id")
273 .flags(nozero
| nonan
)
277 .init(ContextSwitchTaskId::NumTaskId
, 5)
278 .name(name() + ".age_task_id_blocks")
279 .desc("Occupied blocks per task id")
280 .flags(nozero
| nonan
)
284 .name(name() + ".occ_task_id_percent")
285 .desc("Percentage of cache occupancy per task id")
289 percentOccsTaskId
= occupanciesTaskId
/ Stats::constant(numBlocks
);
292 .name(name() + ".tag_accesses")
293 .desc("Number of tag accesses")
297 .name(name() + ".data_accesses")
298 .desc("Number of data accesses")
301 registerDumpCallback(new BaseTagsDumpCallback(this));
302 registerExitCallback(new BaseTagsCallback(this));