base.cc (9263:066099902102) base.cc (9288:3d6da8559605)
1/*
2 * Copyright (c) 2012 ARM Limited
3 * All rights reserved.
4 *
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.
13 *
14 * Copyright (c) 2003-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
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.
27 *
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.
39 *
40 * Authors: Erik Hallnor
41 */
42
43/**
44 * @file
45 * Definition of BaseCache functions.
46 */
47
48#include "cpu/base.hh"
49#include "cpu/smt.hh"
50#include "debug/Cache.hh"
51#include "debug/Drain.hh"
52#include "mem/cache/base.hh"
53#include "mem/cache/mshr.hh"
54#include "sim/full_system.hh"
55
56using namespace std;
57
58BaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name,
59 BaseCache *_cache,
60 const std::string &_label)
61 : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label),
62 blocked(false), mustSendRetry(false), sendRetryEvent(this)
63{
64}
65
66BaseCache::BaseCache(const Params *p)
67 : MemObject(p),
68 mshrQueue("MSHRs", p->mshrs, 4, MSHRQueue_MSHRs),
69 writeBuffer("write buffer", p->write_buffers, p->mshrs+1000,
70 MSHRQueue_WriteBuffer),
71 blkSize(p->block_size),
72 hitLatency(p->hit_latency),
73 responseLatency(p->response_latency),
74 numTarget(p->tgts_per_mshr),
75 forwardSnoops(p->forward_snoops),
76 isTopLevel(p->is_top_level),
77 blocked(0),
78 noTargetMSHR(NULL),
79 missCount(p->max_miss_count),
80 drainEvent(NULL),
81 addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()),
82 system(p->system)
83{
1/*
2 * Copyright (c) 2012 ARM Limited
3 * All rights reserved.
4 *
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.
13 *
14 * Copyright (c) 2003-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
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.
27 *
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.
39 *
40 * Authors: Erik Hallnor
41 */
42
43/**
44 * @file
45 * Definition of BaseCache functions.
46 */
47
48#include "cpu/base.hh"
49#include "cpu/smt.hh"
50#include "debug/Cache.hh"
51#include "debug/Drain.hh"
52#include "mem/cache/base.hh"
53#include "mem/cache/mshr.hh"
54#include "sim/full_system.hh"
55
56using namespace std;
57
58BaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name,
59 BaseCache *_cache,
60 const std::string &_label)
61 : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label),
62 blocked(false), mustSendRetry(false), sendRetryEvent(this)
63{
64}
65
66BaseCache::BaseCache(const Params *p)
67 : MemObject(p),
68 mshrQueue("MSHRs", p->mshrs, 4, MSHRQueue_MSHRs),
69 writeBuffer("write buffer", p->write_buffers, p->mshrs+1000,
70 MSHRQueue_WriteBuffer),
71 blkSize(p->block_size),
72 hitLatency(p->hit_latency),
73 responseLatency(p->response_latency),
74 numTarget(p->tgts_per_mshr),
75 forwardSnoops(p->forward_snoops),
76 isTopLevel(p->is_top_level),
77 blocked(0),
78 noTargetMSHR(NULL),
79 missCount(p->max_miss_count),
80 drainEvent(NULL),
81 addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()),
82 system(p->system)
83{
84 // ensure the clock is not running at an unreasonable clock speed
85 if (clock == 1)
86 panic("Cache %s has a cycle time of 1 tick. Specify a clock.\n",
87 name());
84}
85
86void
87BaseCache::CacheSlavePort::setBlocked()
88{
89 assert(!blocked);
90 DPRINTF(CachePort, "Cache port %s blocking new requests\n", name());
91 blocked = true;
92}
93
94void
95BaseCache::CacheSlavePort::clearBlocked()
96{
97 assert(blocked);
98 DPRINTF(CachePort, "Cache port %s accepting new requests\n", name());
99 blocked = false;
100 if (mustSendRetry) {
101 DPRINTF(CachePort, "Cache port %s sending retry\n", name());
102 mustSendRetry = false;
103 // @TODO: need to find a better time (next bus cycle?)
104 owner.schedule(sendRetryEvent, curTick() + 1);
105 }
106}
107
108
109void
110BaseCache::init()
111{
112 if (!cpuSidePort->isConnected() || !memSidePort->isConnected())
113 fatal("Cache ports on %s are not connected\n", name());
114 cpuSidePort->sendRangeChange();
115}
116
117MasterPort &
118BaseCache::getMasterPort(const std::string &if_name, int idx)
119{
120 if (if_name == "mem_side") {
121 return *memSidePort;
122 } else {
123 return MemObject::getMasterPort(if_name, idx);
124 }
125}
126
127SlavePort &
128BaseCache::getSlavePort(const std::string &if_name, int idx)
129{
130 if (if_name == "cpu_side") {
131 return *cpuSidePort;
132 } else {
133 return MemObject::getSlavePort(if_name, idx);
134 }
135}
136
137void
138BaseCache::regStats()
139{
140 using namespace Stats;
141
142 // Hit statistics
143 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
144 MemCmd cmd(access_idx);
145 const string &cstr = cmd.toString();
146
147 hits[access_idx]
148 .init(system->maxMasters())
149 .name(name() + "." + cstr + "_hits")
150 .desc("number of " + cstr + " hits")
151 .flags(total | nozero | nonan)
152 ;
153 for (int i = 0; i < system->maxMasters(); i++) {
154 hits[access_idx].subname(i, system->getMasterName(i));
155 }
156 }
157
158// These macros make it easier to sum the right subset of commands and
159// to change the subset of commands that are considered "demand" vs
160// "non-demand"
161#define SUM_DEMAND(s) \
162 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
163
164// should writebacks be included here? prior code was inconsistent...
165#define SUM_NON_DEMAND(s) \
166 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
167
168 demandHits
169 .name(name() + ".demand_hits")
170 .desc("number of demand (read+write) hits")
171 .flags(total | nozero | nonan)
172 ;
173 demandHits = SUM_DEMAND(hits);
174 for (int i = 0; i < system->maxMasters(); i++) {
175 demandHits.subname(i, system->getMasterName(i));
176 }
177
178 overallHits
179 .name(name() + ".overall_hits")
180 .desc("number of overall hits")
181 .flags(total | nozero | nonan)
182 ;
183 overallHits = demandHits + SUM_NON_DEMAND(hits);
184 for (int i = 0; i < system->maxMasters(); i++) {
185 overallHits.subname(i, system->getMasterName(i));
186 }
187
188 // Miss statistics
189 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
190 MemCmd cmd(access_idx);
191 const string &cstr = cmd.toString();
192
193 misses[access_idx]
194 .init(system->maxMasters())
195 .name(name() + "." + cstr + "_misses")
196 .desc("number of " + cstr + " misses")
197 .flags(total | nozero | nonan)
198 ;
199 for (int i = 0; i < system->maxMasters(); i++) {
200 misses[access_idx].subname(i, system->getMasterName(i));
201 }
202 }
203
204 demandMisses
205 .name(name() + ".demand_misses")
206 .desc("number of demand (read+write) misses")
207 .flags(total | nozero | nonan)
208 ;
209 demandMisses = SUM_DEMAND(misses);
210 for (int i = 0; i < system->maxMasters(); i++) {
211 demandMisses.subname(i, system->getMasterName(i));
212 }
213
214 overallMisses
215 .name(name() + ".overall_misses")
216 .desc("number of overall misses")
217 .flags(total | nozero | nonan)
218 ;
219 overallMisses = demandMisses + SUM_NON_DEMAND(misses);
220 for (int i = 0; i < system->maxMasters(); i++) {
221 overallMisses.subname(i, system->getMasterName(i));
222 }
223
224 // Miss latency statistics
225 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
226 MemCmd cmd(access_idx);
227 const string &cstr = cmd.toString();
228
229 missLatency[access_idx]
230 .init(system->maxMasters())
231 .name(name() + "." + cstr + "_miss_latency")
232 .desc("number of " + cstr + " miss cycles")
233 .flags(total | nozero | nonan)
234 ;
235 for (int i = 0; i < system->maxMasters(); i++) {
236 missLatency[access_idx].subname(i, system->getMasterName(i));
237 }
238 }
239
240 demandMissLatency
241 .name(name() + ".demand_miss_latency")
242 .desc("number of demand (read+write) miss cycles")
243 .flags(total | nozero | nonan)
244 ;
245 demandMissLatency = SUM_DEMAND(missLatency);
246 for (int i = 0; i < system->maxMasters(); i++) {
247 demandMissLatency.subname(i, system->getMasterName(i));
248 }
249
250 overallMissLatency
251 .name(name() + ".overall_miss_latency")
252 .desc("number of overall miss cycles")
253 .flags(total | nozero | nonan)
254 ;
255 overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
256 for (int i = 0; i < system->maxMasters(); i++) {
257 overallMissLatency.subname(i, system->getMasterName(i));
258 }
259
260 // access formulas
261 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
262 MemCmd cmd(access_idx);
263 const string &cstr = cmd.toString();
264
265 accesses[access_idx]
266 .name(name() + "." + cstr + "_accesses")
267 .desc("number of " + cstr + " accesses(hits+misses)")
268 .flags(total | nozero | nonan)
269 ;
270 accesses[access_idx] = hits[access_idx] + misses[access_idx];
271
272 for (int i = 0; i < system->maxMasters(); i++) {
273 accesses[access_idx].subname(i, system->getMasterName(i));
274 }
275 }
276
277 demandAccesses
278 .name(name() + ".demand_accesses")
279 .desc("number of demand (read+write) accesses")
280 .flags(total | nozero | nonan)
281 ;
282 demandAccesses = demandHits + demandMisses;
283 for (int i = 0; i < system->maxMasters(); i++) {
284 demandAccesses.subname(i, system->getMasterName(i));
285 }
286
287 overallAccesses
288 .name(name() + ".overall_accesses")
289 .desc("number of overall (read+write) accesses")
290 .flags(total | nozero | nonan)
291 ;
292 overallAccesses = overallHits + overallMisses;
293 for (int i = 0; i < system->maxMasters(); i++) {
294 overallAccesses.subname(i, system->getMasterName(i));
295 }
296
297 // miss rate formulas
298 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
299 MemCmd cmd(access_idx);
300 const string &cstr = cmd.toString();
301
302 missRate[access_idx]
303 .name(name() + "." + cstr + "_miss_rate")
304 .desc("miss rate for " + cstr + " accesses")
305 .flags(total | nozero | nonan)
306 ;
307 missRate[access_idx] = misses[access_idx] / accesses[access_idx];
308
309 for (int i = 0; i < system->maxMasters(); i++) {
310 missRate[access_idx].subname(i, system->getMasterName(i));
311 }
312 }
313
314 demandMissRate
315 .name(name() + ".demand_miss_rate")
316 .desc("miss rate for demand accesses")
317 .flags(total | nozero | nonan)
318 ;
319 demandMissRate = demandMisses / demandAccesses;
320 for (int i = 0; i < system->maxMasters(); i++) {
321 demandMissRate.subname(i, system->getMasterName(i));
322 }
323
324 overallMissRate
325 .name(name() + ".overall_miss_rate")
326 .desc("miss rate for overall accesses")
327 .flags(total | nozero | nonan)
328 ;
329 overallMissRate = overallMisses / overallAccesses;
330 for (int i = 0; i < system->maxMasters(); i++) {
331 overallMissRate.subname(i, system->getMasterName(i));
332 }
333
334 // miss latency formulas
335 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
336 MemCmd cmd(access_idx);
337 const string &cstr = cmd.toString();
338
339 avgMissLatency[access_idx]
340 .name(name() + "." + cstr + "_avg_miss_latency")
341 .desc("average " + cstr + " miss latency")
342 .flags(total | nozero | nonan)
343 ;
344 avgMissLatency[access_idx] =
345 missLatency[access_idx] / misses[access_idx];
346
347 for (int i = 0; i < system->maxMasters(); i++) {
348 avgMissLatency[access_idx].subname(i, system->getMasterName(i));
349 }
350 }
351
352 demandAvgMissLatency
353 .name(name() + ".demand_avg_miss_latency")
354 .desc("average overall miss latency")
355 .flags(total | nozero | nonan)
356 ;
357 demandAvgMissLatency = demandMissLatency / demandMisses;
358 for (int i = 0; i < system->maxMasters(); i++) {
359 demandAvgMissLatency.subname(i, system->getMasterName(i));
360 }
361
362 overallAvgMissLatency
363 .name(name() + ".overall_avg_miss_latency")
364 .desc("average overall miss latency")
365 .flags(total | nozero | nonan)
366 ;
367 overallAvgMissLatency = overallMissLatency / overallMisses;
368 for (int i = 0; i < system->maxMasters(); i++) {
369 overallAvgMissLatency.subname(i, system->getMasterName(i));
370 }
371
372 blocked_cycles.init(NUM_BLOCKED_CAUSES);
373 blocked_cycles
374 .name(name() + ".blocked_cycles")
375 .desc("number of cycles access was blocked")
376 .subname(Blocked_NoMSHRs, "no_mshrs")
377 .subname(Blocked_NoTargets, "no_targets")
378 ;
379
380
381 blocked_causes.init(NUM_BLOCKED_CAUSES);
382 blocked_causes
383 .name(name() + ".blocked")
384 .desc("number of cycles access was blocked")
385 .subname(Blocked_NoMSHRs, "no_mshrs")
386 .subname(Blocked_NoTargets, "no_targets")
387 ;
388
389 avg_blocked
390 .name(name() + ".avg_blocked_cycles")
391 .desc("average number of cycles each access was blocked")
392 .subname(Blocked_NoMSHRs, "no_mshrs")
393 .subname(Blocked_NoTargets, "no_targets")
394 ;
395
396 avg_blocked = blocked_cycles / blocked_causes;
397
398 fastWrites
399 .name(name() + ".fast_writes")
400 .desc("number of fast writes performed")
401 ;
402
403 cacheCopies
404 .name(name() + ".cache_copies")
405 .desc("number of cache copies performed")
406 ;
407
408 writebacks
409 .init(system->maxMasters())
410 .name(name() + ".writebacks")
411 .desc("number of writebacks")
412 .flags(total | nozero | nonan)
413 ;
414 for (int i = 0; i < system->maxMasters(); i++) {
415 writebacks.subname(i, system->getMasterName(i));
416 }
417
418 // MSHR statistics
419 // MSHR hit statistics
420 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
421 MemCmd cmd(access_idx);
422 const string &cstr = cmd.toString();
423
424 mshr_hits[access_idx]
425 .init(system->maxMasters())
426 .name(name() + "." + cstr + "_mshr_hits")
427 .desc("number of " + cstr + " MSHR hits")
428 .flags(total | nozero | nonan)
429 ;
430 for (int i = 0; i < system->maxMasters(); i++) {
431 mshr_hits[access_idx].subname(i, system->getMasterName(i));
432 }
433 }
434
435 demandMshrHits
436 .name(name() + ".demand_mshr_hits")
437 .desc("number of demand (read+write) MSHR hits")
438 .flags(total | nozero | nonan)
439 ;
440 demandMshrHits = SUM_DEMAND(mshr_hits);
441 for (int i = 0; i < system->maxMasters(); i++) {
442 demandMshrHits.subname(i, system->getMasterName(i));
443 }
444
445 overallMshrHits
446 .name(name() + ".overall_mshr_hits")
447 .desc("number of overall MSHR hits")
448 .flags(total | nozero | nonan)
449 ;
450 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
451 for (int i = 0; i < system->maxMasters(); i++) {
452 overallMshrHits.subname(i, system->getMasterName(i));
453 }
454
455 // MSHR miss statistics
456 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
457 MemCmd cmd(access_idx);
458 const string &cstr = cmd.toString();
459
460 mshr_misses[access_idx]
461 .init(system->maxMasters())
462 .name(name() + "." + cstr + "_mshr_misses")
463 .desc("number of " + cstr + " MSHR misses")
464 .flags(total | nozero | nonan)
465 ;
466 for (int i = 0; i < system->maxMasters(); i++) {
467 mshr_misses[access_idx].subname(i, system->getMasterName(i));
468 }
469 }
470
471 demandMshrMisses
472 .name(name() + ".demand_mshr_misses")
473 .desc("number of demand (read+write) MSHR misses")
474 .flags(total | nozero | nonan)
475 ;
476 demandMshrMisses = SUM_DEMAND(mshr_misses);
477 for (int i = 0; i < system->maxMasters(); i++) {
478 demandMshrMisses.subname(i, system->getMasterName(i));
479 }
480
481 overallMshrMisses
482 .name(name() + ".overall_mshr_misses")
483 .desc("number of overall MSHR misses")
484 .flags(total | nozero | nonan)
485 ;
486 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
487 for (int i = 0; i < system->maxMasters(); i++) {
488 overallMshrMisses.subname(i, system->getMasterName(i));
489 }
490
491 // MSHR miss latency statistics
492 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
493 MemCmd cmd(access_idx);
494 const string &cstr = cmd.toString();
495
496 mshr_miss_latency[access_idx]
497 .init(system->maxMasters())
498 .name(name() + "." + cstr + "_mshr_miss_latency")
499 .desc("number of " + cstr + " MSHR miss cycles")
500 .flags(total | nozero | nonan)
501 ;
502 for (int i = 0; i < system->maxMasters(); i++) {
503 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
504 }
505 }
506
507 demandMshrMissLatency
508 .name(name() + ".demand_mshr_miss_latency")
509 .desc("number of demand (read+write) MSHR miss cycles")
510 .flags(total | nozero | nonan)
511 ;
512 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
513 for (int i = 0; i < system->maxMasters(); i++) {
514 demandMshrMissLatency.subname(i, system->getMasterName(i));
515 }
516
517 overallMshrMissLatency
518 .name(name() + ".overall_mshr_miss_latency")
519 .desc("number of overall MSHR miss cycles")
520 .flags(total | nozero | nonan)
521 ;
522 overallMshrMissLatency =
523 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
524 for (int i = 0; i < system->maxMasters(); i++) {
525 overallMshrMissLatency.subname(i, system->getMasterName(i));
526 }
527
528 // MSHR uncacheable statistics
529 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
530 MemCmd cmd(access_idx);
531 const string &cstr = cmd.toString();
532
533 mshr_uncacheable[access_idx]
534 .init(system->maxMasters())
535 .name(name() + "." + cstr + "_mshr_uncacheable")
536 .desc("number of " + cstr + " MSHR uncacheable")
537 .flags(total | nozero | nonan)
538 ;
539 for (int i = 0; i < system->maxMasters(); i++) {
540 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
541 }
542 }
543
544 overallMshrUncacheable
545 .name(name() + ".overall_mshr_uncacheable_misses")
546 .desc("number of overall MSHR uncacheable misses")
547 .flags(total | nozero | nonan)
548 ;
549 overallMshrUncacheable =
550 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
551 for (int i = 0; i < system->maxMasters(); i++) {
552 overallMshrUncacheable.subname(i, system->getMasterName(i));
553 }
554
555 // MSHR miss latency statistics
556 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
557 MemCmd cmd(access_idx);
558 const string &cstr = cmd.toString();
559
560 mshr_uncacheable_lat[access_idx]
561 .init(system->maxMasters())
562 .name(name() + "." + cstr + "_mshr_uncacheable_latency")
563 .desc("number of " + cstr + " MSHR uncacheable cycles")
564 .flags(total | nozero | nonan)
565 ;
566 for (int i = 0; i < system->maxMasters(); i++) {
567 mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i));
568 }
569 }
570
571 overallMshrUncacheableLatency
572 .name(name() + ".overall_mshr_uncacheable_latency")
573 .desc("number of overall MSHR uncacheable cycles")
574 .flags(total | nozero | nonan)
575 ;
576 overallMshrUncacheableLatency =
577 SUM_DEMAND(mshr_uncacheable_lat) +
578 SUM_NON_DEMAND(mshr_uncacheable_lat);
579 for (int i = 0; i < system->maxMasters(); i++) {
580 overallMshrUncacheableLatency.subname(i, system->getMasterName(i));
581 }
582
583#if 0
584 // MSHR access formulas
585 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
586 MemCmd cmd(access_idx);
587 const string &cstr = cmd.toString();
588
589 mshrAccesses[access_idx]
590 .name(name() + "." + cstr + "_mshr_accesses")
591 .desc("number of " + cstr + " mshr accesses(hits+misses)")
592 .flags(total | nozero | nonan)
593 ;
594 mshrAccesses[access_idx] =
595 mshr_hits[access_idx] + mshr_misses[access_idx]
596 + mshr_uncacheable[access_idx];
597 }
598
599 demandMshrAccesses
600 .name(name() + ".demand_mshr_accesses")
601 .desc("number of demand (read+write) mshr accesses")
602 .flags(total | nozero | nonan)
603 ;
604 demandMshrAccesses = demandMshrHits + demandMshrMisses;
605
606 overallMshrAccesses
607 .name(name() + ".overall_mshr_accesses")
608 .desc("number of overall (read+write) mshr accesses")
609 .flags(total | nozero | nonan)
610 ;
611 overallMshrAccesses = overallMshrHits + overallMshrMisses
612 + overallMshrUncacheable;
613#endif
614
615 // MSHR miss rate formulas
616 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
617 MemCmd cmd(access_idx);
618 const string &cstr = cmd.toString();
619
620 mshrMissRate[access_idx]
621 .name(name() + "." + cstr + "_mshr_miss_rate")
622 .desc("mshr miss rate for " + cstr + " accesses")
623 .flags(total | nozero | nonan)
624 ;
625 mshrMissRate[access_idx] =
626 mshr_misses[access_idx] / accesses[access_idx];
627
628 for (int i = 0; i < system->maxMasters(); i++) {
629 mshrMissRate[access_idx].subname(i, system->getMasterName(i));
630 }
631 }
632
633 demandMshrMissRate
634 .name(name() + ".demand_mshr_miss_rate")
635 .desc("mshr miss rate for demand accesses")
636 .flags(total | nozero | nonan)
637 ;
638 demandMshrMissRate = demandMshrMisses / demandAccesses;
639 for (int i = 0; i < system->maxMasters(); i++) {
640 demandMshrMissRate.subname(i, system->getMasterName(i));
641 }
642
643 overallMshrMissRate
644 .name(name() + ".overall_mshr_miss_rate")
645 .desc("mshr miss rate for overall accesses")
646 .flags(total | nozero | nonan)
647 ;
648 overallMshrMissRate = overallMshrMisses / overallAccesses;
649 for (int i = 0; i < system->maxMasters(); i++) {
650 overallMshrMissRate.subname(i, system->getMasterName(i));
651 }
652
653 // mshrMiss latency formulas
654 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
655 MemCmd cmd(access_idx);
656 const string &cstr = cmd.toString();
657
658 avgMshrMissLatency[access_idx]
659 .name(name() + "." + cstr + "_avg_mshr_miss_latency")
660 .desc("average " + cstr + " mshr miss latency")
661 .flags(total | nozero | nonan)
662 ;
663 avgMshrMissLatency[access_idx] =
664 mshr_miss_latency[access_idx] / mshr_misses[access_idx];
665
666 for (int i = 0; i < system->maxMasters(); i++) {
667 avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i));
668 }
669 }
670
671 demandAvgMshrMissLatency
672 .name(name() + ".demand_avg_mshr_miss_latency")
673 .desc("average overall mshr miss latency")
674 .flags(total | nozero | nonan)
675 ;
676 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
677 for (int i = 0; i < system->maxMasters(); i++) {
678 demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
679 }
680
681 overallAvgMshrMissLatency
682 .name(name() + ".overall_avg_mshr_miss_latency")
683 .desc("average overall mshr miss latency")
684 .flags(total | nozero | nonan)
685 ;
686 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
687 for (int i = 0; i < system->maxMasters(); i++) {
688 overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
689 }
690
691 // mshrUncacheable latency formulas
692 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
693 MemCmd cmd(access_idx);
694 const string &cstr = cmd.toString();
695
696 avgMshrUncacheableLatency[access_idx]
697 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
698 .desc("average " + cstr + " mshr uncacheable latency")
699 .flags(total | nozero | nonan)
700 ;
701 avgMshrUncacheableLatency[access_idx] =
702 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
703
704 for (int i = 0; i < system->maxMasters(); i++) {
705 avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i));
706 }
707 }
708
709 overallAvgMshrUncacheableLatency
710 .name(name() + ".overall_avg_mshr_uncacheable_latency")
711 .desc("average overall mshr uncacheable latency")
712 .flags(total | nozero | nonan)
713 ;
714 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
715 for (int i = 0; i < system->maxMasters(); i++) {
716 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
717 }
718
719 mshr_cap_events
720 .init(system->maxMasters())
721 .name(name() + ".mshr_cap_events")
722 .desc("number of times MSHR cap was activated")
723 .flags(total | nozero | nonan)
724 ;
725 for (int i = 0; i < system->maxMasters(); i++) {
726 mshr_cap_events.subname(i, system->getMasterName(i));
727 }
728
729 //software prefetching stats
730 soft_prefetch_mshr_full
731 .init(system->maxMasters())
732 .name(name() + ".soft_prefetch_mshr_full")
733 .desc("number of mshr full events for SW prefetching instrutions")
734 .flags(total | nozero | nonan)
735 ;
736 for (int i = 0; i < system->maxMasters(); i++) {
737 soft_prefetch_mshr_full.subname(i, system->getMasterName(i));
738 }
739
740 mshr_no_allocate_misses
741 .name(name() +".no_allocate_misses")
742 .desc("Number of misses that were no-allocate")
743 ;
744
745}
746
747unsigned int
748BaseCache::drain(Event *de)
749{
750 int count = memSidePort->drain(de) + cpuSidePort->drain(de);
751
752 // Set status
753 if (count != 0) {
754 drainEvent = de;
755
756 changeState(SimObject::Draining);
757 DPRINTF(Drain, "Cache not drained\n");
758 return count;
759 }
760
761 changeState(SimObject::Drained);
762 return 0;
763}
88}
89
90void
91BaseCache::CacheSlavePort::setBlocked()
92{
93 assert(!blocked);
94 DPRINTF(CachePort, "Cache port %s blocking new requests\n", name());
95 blocked = true;
96}
97
98void
99BaseCache::CacheSlavePort::clearBlocked()
100{
101 assert(blocked);
102 DPRINTF(CachePort, "Cache port %s accepting new requests\n", name());
103 blocked = false;
104 if (mustSendRetry) {
105 DPRINTF(CachePort, "Cache port %s sending retry\n", name());
106 mustSendRetry = false;
107 // @TODO: need to find a better time (next bus cycle?)
108 owner.schedule(sendRetryEvent, curTick() + 1);
109 }
110}
111
112
113void
114BaseCache::init()
115{
116 if (!cpuSidePort->isConnected() || !memSidePort->isConnected())
117 fatal("Cache ports on %s are not connected\n", name());
118 cpuSidePort->sendRangeChange();
119}
120
121MasterPort &
122BaseCache::getMasterPort(const std::string &if_name, int idx)
123{
124 if (if_name == "mem_side") {
125 return *memSidePort;
126 } else {
127 return MemObject::getMasterPort(if_name, idx);
128 }
129}
130
131SlavePort &
132BaseCache::getSlavePort(const std::string &if_name, int idx)
133{
134 if (if_name == "cpu_side") {
135 return *cpuSidePort;
136 } else {
137 return MemObject::getSlavePort(if_name, idx);
138 }
139}
140
141void
142BaseCache::regStats()
143{
144 using namespace Stats;
145
146 // Hit statistics
147 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
148 MemCmd cmd(access_idx);
149 const string &cstr = cmd.toString();
150
151 hits[access_idx]
152 .init(system->maxMasters())
153 .name(name() + "." + cstr + "_hits")
154 .desc("number of " + cstr + " hits")
155 .flags(total | nozero | nonan)
156 ;
157 for (int i = 0; i < system->maxMasters(); i++) {
158 hits[access_idx].subname(i, system->getMasterName(i));
159 }
160 }
161
162// These macros make it easier to sum the right subset of commands and
163// to change the subset of commands that are considered "demand" vs
164// "non-demand"
165#define SUM_DEMAND(s) \
166 (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
167
168// should writebacks be included here? prior code was inconsistent...
169#define SUM_NON_DEMAND(s) \
170 (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
171
172 demandHits
173 .name(name() + ".demand_hits")
174 .desc("number of demand (read+write) hits")
175 .flags(total | nozero | nonan)
176 ;
177 demandHits = SUM_DEMAND(hits);
178 for (int i = 0; i < system->maxMasters(); i++) {
179 demandHits.subname(i, system->getMasterName(i));
180 }
181
182 overallHits
183 .name(name() + ".overall_hits")
184 .desc("number of overall hits")
185 .flags(total | nozero | nonan)
186 ;
187 overallHits = demandHits + SUM_NON_DEMAND(hits);
188 for (int i = 0; i < system->maxMasters(); i++) {
189 overallHits.subname(i, system->getMasterName(i));
190 }
191
192 // Miss statistics
193 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
194 MemCmd cmd(access_idx);
195 const string &cstr = cmd.toString();
196
197 misses[access_idx]
198 .init(system->maxMasters())
199 .name(name() + "." + cstr + "_misses")
200 .desc("number of " + cstr + " misses")
201 .flags(total | nozero | nonan)
202 ;
203 for (int i = 0; i < system->maxMasters(); i++) {
204 misses[access_idx].subname(i, system->getMasterName(i));
205 }
206 }
207
208 demandMisses
209 .name(name() + ".demand_misses")
210 .desc("number of demand (read+write) misses")
211 .flags(total | nozero | nonan)
212 ;
213 demandMisses = SUM_DEMAND(misses);
214 for (int i = 0; i < system->maxMasters(); i++) {
215 demandMisses.subname(i, system->getMasterName(i));
216 }
217
218 overallMisses
219 .name(name() + ".overall_misses")
220 .desc("number of overall misses")
221 .flags(total | nozero | nonan)
222 ;
223 overallMisses = demandMisses + SUM_NON_DEMAND(misses);
224 for (int i = 0; i < system->maxMasters(); i++) {
225 overallMisses.subname(i, system->getMasterName(i));
226 }
227
228 // Miss latency statistics
229 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
230 MemCmd cmd(access_idx);
231 const string &cstr = cmd.toString();
232
233 missLatency[access_idx]
234 .init(system->maxMasters())
235 .name(name() + "." + cstr + "_miss_latency")
236 .desc("number of " + cstr + " miss cycles")
237 .flags(total | nozero | nonan)
238 ;
239 for (int i = 0; i < system->maxMasters(); i++) {
240 missLatency[access_idx].subname(i, system->getMasterName(i));
241 }
242 }
243
244 demandMissLatency
245 .name(name() + ".demand_miss_latency")
246 .desc("number of demand (read+write) miss cycles")
247 .flags(total | nozero | nonan)
248 ;
249 demandMissLatency = SUM_DEMAND(missLatency);
250 for (int i = 0; i < system->maxMasters(); i++) {
251 demandMissLatency.subname(i, system->getMasterName(i));
252 }
253
254 overallMissLatency
255 .name(name() + ".overall_miss_latency")
256 .desc("number of overall miss cycles")
257 .flags(total | nozero | nonan)
258 ;
259 overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
260 for (int i = 0; i < system->maxMasters(); i++) {
261 overallMissLatency.subname(i, system->getMasterName(i));
262 }
263
264 // access formulas
265 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
266 MemCmd cmd(access_idx);
267 const string &cstr = cmd.toString();
268
269 accesses[access_idx]
270 .name(name() + "." + cstr + "_accesses")
271 .desc("number of " + cstr + " accesses(hits+misses)")
272 .flags(total | nozero | nonan)
273 ;
274 accesses[access_idx] = hits[access_idx] + misses[access_idx];
275
276 for (int i = 0; i < system->maxMasters(); i++) {
277 accesses[access_idx].subname(i, system->getMasterName(i));
278 }
279 }
280
281 demandAccesses
282 .name(name() + ".demand_accesses")
283 .desc("number of demand (read+write) accesses")
284 .flags(total | nozero | nonan)
285 ;
286 demandAccesses = demandHits + demandMisses;
287 for (int i = 0; i < system->maxMasters(); i++) {
288 demandAccesses.subname(i, system->getMasterName(i));
289 }
290
291 overallAccesses
292 .name(name() + ".overall_accesses")
293 .desc("number of overall (read+write) accesses")
294 .flags(total | nozero | nonan)
295 ;
296 overallAccesses = overallHits + overallMisses;
297 for (int i = 0; i < system->maxMasters(); i++) {
298 overallAccesses.subname(i, system->getMasterName(i));
299 }
300
301 // miss rate formulas
302 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
303 MemCmd cmd(access_idx);
304 const string &cstr = cmd.toString();
305
306 missRate[access_idx]
307 .name(name() + "." + cstr + "_miss_rate")
308 .desc("miss rate for " + cstr + " accesses")
309 .flags(total | nozero | nonan)
310 ;
311 missRate[access_idx] = misses[access_idx] / accesses[access_idx];
312
313 for (int i = 0; i < system->maxMasters(); i++) {
314 missRate[access_idx].subname(i, system->getMasterName(i));
315 }
316 }
317
318 demandMissRate
319 .name(name() + ".demand_miss_rate")
320 .desc("miss rate for demand accesses")
321 .flags(total | nozero | nonan)
322 ;
323 demandMissRate = demandMisses / demandAccesses;
324 for (int i = 0; i < system->maxMasters(); i++) {
325 demandMissRate.subname(i, system->getMasterName(i));
326 }
327
328 overallMissRate
329 .name(name() + ".overall_miss_rate")
330 .desc("miss rate for overall accesses")
331 .flags(total | nozero | nonan)
332 ;
333 overallMissRate = overallMisses / overallAccesses;
334 for (int i = 0; i < system->maxMasters(); i++) {
335 overallMissRate.subname(i, system->getMasterName(i));
336 }
337
338 // miss latency formulas
339 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
340 MemCmd cmd(access_idx);
341 const string &cstr = cmd.toString();
342
343 avgMissLatency[access_idx]
344 .name(name() + "." + cstr + "_avg_miss_latency")
345 .desc("average " + cstr + " miss latency")
346 .flags(total | nozero | nonan)
347 ;
348 avgMissLatency[access_idx] =
349 missLatency[access_idx] / misses[access_idx];
350
351 for (int i = 0; i < system->maxMasters(); i++) {
352 avgMissLatency[access_idx].subname(i, system->getMasterName(i));
353 }
354 }
355
356 demandAvgMissLatency
357 .name(name() + ".demand_avg_miss_latency")
358 .desc("average overall miss latency")
359 .flags(total | nozero | nonan)
360 ;
361 demandAvgMissLatency = demandMissLatency / demandMisses;
362 for (int i = 0; i < system->maxMasters(); i++) {
363 demandAvgMissLatency.subname(i, system->getMasterName(i));
364 }
365
366 overallAvgMissLatency
367 .name(name() + ".overall_avg_miss_latency")
368 .desc("average overall miss latency")
369 .flags(total | nozero | nonan)
370 ;
371 overallAvgMissLatency = overallMissLatency / overallMisses;
372 for (int i = 0; i < system->maxMasters(); i++) {
373 overallAvgMissLatency.subname(i, system->getMasterName(i));
374 }
375
376 blocked_cycles.init(NUM_BLOCKED_CAUSES);
377 blocked_cycles
378 .name(name() + ".blocked_cycles")
379 .desc("number of cycles access was blocked")
380 .subname(Blocked_NoMSHRs, "no_mshrs")
381 .subname(Blocked_NoTargets, "no_targets")
382 ;
383
384
385 blocked_causes.init(NUM_BLOCKED_CAUSES);
386 blocked_causes
387 .name(name() + ".blocked")
388 .desc("number of cycles access was blocked")
389 .subname(Blocked_NoMSHRs, "no_mshrs")
390 .subname(Blocked_NoTargets, "no_targets")
391 ;
392
393 avg_blocked
394 .name(name() + ".avg_blocked_cycles")
395 .desc("average number of cycles each access was blocked")
396 .subname(Blocked_NoMSHRs, "no_mshrs")
397 .subname(Blocked_NoTargets, "no_targets")
398 ;
399
400 avg_blocked = blocked_cycles / blocked_causes;
401
402 fastWrites
403 .name(name() + ".fast_writes")
404 .desc("number of fast writes performed")
405 ;
406
407 cacheCopies
408 .name(name() + ".cache_copies")
409 .desc("number of cache copies performed")
410 ;
411
412 writebacks
413 .init(system->maxMasters())
414 .name(name() + ".writebacks")
415 .desc("number of writebacks")
416 .flags(total | nozero | nonan)
417 ;
418 for (int i = 0; i < system->maxMasters(); i++) {
419 writebacks.subname(i, system->getMasterName(i));
420 }
421
422 // MSHR statistics
423 // MSHR hit statistics
424 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
425 MemCmd cmd(access_idx);
426 const string &cstr = cmd.toString();
427
428 mshr_hits[access_idx]
429 .init(system->maxMasters())
430 .name(name() + "." + cstr + "_mshr_hits")
431 .desc("number of " + cstr + " MSHR hits")
432 .flags(total | nozero | nonan)
433 ;
434 for (int i = 0; i < system->maxMasters(); i++) {
435 mshr_hits[access_idx].subname(i, system->getMasterName(i));
436 }
437 }
438
439 demandMshrHits
440 .name(name() + ".demand_mshr_hits")
441 .desc("number of demand (read+write) MSHR hits")
442 .flags(total | nozero | nonan)
443 ;
444 demandMshrHits = SUM_DEMAND(mshr_hits);
445 for (int i = 0; i < system->maxMasters(); i++) {
446 demandMshrHits.subname(i, system->getMasterName(i));
447 }
448
449 overallMshrHits
450 .name(name() + ".overall_mshr_hits")
451 .desc("number of overall MSHR hits")
452 .flags(total | nozero | nonan)
453 ;
454 overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
455 for (int i = 0; i < system->maxMasters(); i++) {
456 overallMshrHits.subname(i, system->getMasterName(i));
457 }
458
459 // MSHR miss statistics
460 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
461 MemCmd cmd(access_idx);
462 const string &cstr = cmd.toString();
463
464 mshr_misses[access_idx]
465 .init(system->maxMasters())
466 .name(name() + "." + cstr + "_mshr_misses")
467 .desc("number of " + cstr + " MSHR misses")
468 .flags(total | nozero | nonan)
469 ;
470 for (int i = 0; i < system->maxMasters(); i++) {
471 mshr_misses[access_idx].subname(i, system->getMasterName(i));
472 }
473 }
474
475 demandMshrMisses
476 .name(name() + ".demand_mshr_misses")
477 .desc("number of demand (read+write) MSHR misses")
478 .flags(total | nozero | nonan)
479 ;
480 demandMshrMisses = SUM_DEMAND(mshr_misses);
481 for (int i = 0; i < system->maxMasters(); i++) {
482 demandMshrMisses.subname(i, system->getMasterName(i));
483 }
484
485 overallMshrMisses
486 .name(name() + ".overall_mshr_misses")
487 .desc("number of overall MSHR misses")
488 .flags(total | nozero | nonan)
489 ;
490 overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
491 for (int i = 0; i < system->maxMasters(); i++) {
492 overallMshrMisses.subname(i, system->getMasterName(i));
493 }
494
495 // MSHR miss latency statistics
496 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
497 MemCmd cmd(access_idx);
498 const string &cstr = cmd.toString();
499
500 mshr_miss_latency[access_idx]
501 .init(system->maxMasters())
502 .name(name() + "." + cstr + "_mshr_miss_latency")
503 .desc("number of " + cstr + " MSHR miss cycles")
504 .flags(total | nozero | nonan)
505 ;
506 for (int i = 0; i < system->maxMasters(); i++) {
507 mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
508 }
509 }
510
511 demandMshrMissLatency
512 .name(name() + ".demand_mshr_miss_latency")
513 .desc("number of demand (read+write) MSHR miss cycles")
514 .flags(total | nozero | nonan)
515 ;
516 demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
517 for (int i = 0; i < system->maxMasters(); i++) {
518 demandMshrMissLatency.subname(i, system->getMasterName(i));
519 }
520
521 overallMshrMissLatency
522 .name(name() + ".overall_mshr_miss_latency")
523 .desc("number of overall MSHR miss cycles")
524 .flags(total | nozero | nonan)
525 ;
526 overallMshrMissLatency =
527 demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
528 for (int i = 0; i < system->maxMasters(); i++) {
529 overallMshrMissLatency.subname(i, system->getMasterName(i));
530 }
531
532 // MSHR uncacheable statistics
533 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
534 MemCmd cmd(access_idx);
535 const string &cstr = cmd.toString();
536
537 mshr_uncacheable[access_idx]
538 .init(system->maxMasters())
539 .name(name() + "." + cstr + "_mshr_uncacheable")
540 .desc("number of " + cstr + " MSHR uncacheable")
541 .flags(total | nozero | nonan)
542 ;
543 for (int i = 0; i < system->maxMasters(); i++) {
544 mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
545 }
546 }
547
548 overallMshrUncacheable
549 .name(name() + ".overall_mshr_uncacheable_misses")
550 .desc("number of overall MSHR uncacheable misses")
551 .flags(total | nozero | nonan)
552 ;
553 overallMshrUncacheable =
554 SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
555 for (int i = 0; i < system->maxMasters(); i++) {
556 overallMshrUncacheable.subname(i, system->getMasterName(i));
557 }
558
559 // MSHR miss latency statistics
560 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
561 MemCmd cmd(access_idx);
562 const string &cstr = cmd.toString();
563
564 mshr_uncacheable_lat[access_idx]
565 .init(system->maxMasters())
566 .name(name() + "." + cstr + "_mshr_uncacheable_latency")
567 .desc("number of " + cstr + " MSHR uncacheable cycles")
568 .flags(total | nozero | nonan)
569 ;
570 for (int i = 0; i < system->maxMasters(); i++) {
571 mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i));
572 }
573 }
574
575 overallMshrUncacheableLatency
576 .name(name() + ".overall_mshr_uncacheable_latency")
577 .desc("number of overall MSHR uncacheable cycles")
578 .flags(total | nozero | nonan)
579 ;
580 overallMshrUncacheableLatency =
581 SUM_DEMAND(mshr_uncacheable_lat) +
582 SUM_NON_DEMAND(mshr_uncacheable_lat);
583 for (int i = 0; i < system->maxMasters(); i++) {
584 overallMshrUncacheableLatency.subname(i, system->getMasterName(i));
585 }
586
587#if 0
588 // MSHR access formulas
589 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
590 MemCmd cmd(access_idx);
591 const string &cstr = cmd.toString();
592
593 mshrAccesses[access_idx]
594 .name(name() + "." + cstr + "_mshr_accesses")
595 .desc("number of " + cstr + " mshr accesses(hits+misses)")
596 .flags(total | nozero | nonan)
597 ;
598 mshrAccesses[access_idx] =
599 mshr_hits[access_idx] + mshr_misses[access_idx]
600 + mshr_uncacheable[access_idx];
601 }
602
603 demandMshrAccesses
604 .name(name() + ".demand_mshr_accesses")
605 .desc("number of demand (read+write) mshr accesses")
606 .flags(total | nozero | nonan)
607 ;
608 demandMshrAccesses = demandMshrHits + demandMshrMisses;
609
610 overallMshrAccesses
611 .name(name() + ".overall_mshr_accesses")
612 .desc("number of overall (read+write) mshr accesses")
613 .flags(total | nozero | nonan)
614 ;
615 overallMshrAccesses = overallMshrHits + overallMshrMisses
616 + overallMshrUncacheable;
617#endif
618
619 // MSHR miss rate formulas
620 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
621 MemCmd cmd(access_idx);
622 const string &cstr = cmd.toString();
623
624 mshrMissRate[access_idx]
625 .name(name() + "." + cstr + "_mshr_miss_rate")
626 .desc("mshr miss rate for " + cstr + " accesses")
627 .flags(total | nozero | nonan)
628 ;
629 mshrMissRate[access_idx] =
630 mshr_misses[access_idx] / accesses[access_idx];
631
632 for (int i = 0; i < system->maxMasters(); i++) {
633 mshrMissRate[access_idx].subname(i, system->getMasterName(i));
634 }
635 }
636
637 demandMshrMissRate
638 .name(name() + ".demand_mshr_miss_rate")
639 .desc("mshr miss rate for demand accesses")
640 .flags(total | nozero | nonan)
641 ;
642 demandMshrMissRate = demandMshrMisses / demandAccesses;
643 for (int i = 0; i < system->maxMasters(); i++) {
644 demandMshrMissRate.subname(i, system->getMasterName(i));
645 }
646
647 overallMshrMissRate
648 .name(name() + ".overall_mshr_miss_rate")
649 .desc("mshr miss rate for overall accesses")
650 .flags(total | nozero | nonan)
651 ;
652 overallMshrMissRate = overallMshrMisses / overallAccesses;
653 for (int i = 0; i < system->maxMasters(); i++) {
654 overallMshrMissRate.subname(i, system->getMasterName(i));
655 }
656
657 // mshrMiss latency formulas
658 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
659 MemCmd cmd(access_idx);
660 const string &cstr = cmd.toString();
661
662 avgMshrMissLatency[access_idx]
663 .name(name() + "." + cstr + "_avg_mshr_miss_latency")
664 .desc("average " + cstr + " mshr miss latency")
665 .flags(total | nozero | nonan)
666 ;
667 avgMshrMissLatency[access_idx] =
668 mshr_miss_latency[access_idx] / mshr_misses[access_idx];
669
670 for (int i = 0; i < system->maxMasters(); i++) {
671 avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i));
672 }
673 }
674
675 demandAvgMshrMissLatency
676 .name(name() + ".demand_avg_mshr_miss_latency")
677 .desc("average overall mshr miss latency")
678 .flags(total | nozero | nonan)
679 ;
680 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
681 for (int i = 0; i < system->maxMasters(); i++) {
682 demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
683 }
684
685 overallAvgMshrMissLatency
686 .name(name() + ".overall_avg_mshr_miss_latency")
687 .desc("average overall mshr miss latency")
688 .flags(total | nozero | nonan)
689 ;
690 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
691 for (int i = 0; i < system->maxMasters(); i++) {
692 overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
693 }
694
695 // mshrUncacheable latency formulas
696 for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
697 MemCmd cmd(access_idx);
698 const string &cstr = cmd.toString();
699
700 avgMshrUncacheableLatency[access_idx]
701 .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
702 .desc("average " + cstr + " mshr uncacheable latency")
703 .flags(total | nozero | nonan)
704 ;
705 avgMshrUncacheableLatency[access_idx] =
706 mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
707
708 for (int i = 0; i < system->maxMasters(); i++) {
709 avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i));
710 }
711 }
712
713 overallAvgMshrUncacheableLatency
714 .name(name() + ".overall_avg_mshr_uncacheable_latency")
715 .desc("average overall mshr uncacheable latency")
716 .flags(total | nozero | nonan)
717 ;
718 overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
719 for (int i = 0; i < system->maxMasters(); i++) {
720 overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
721 }
722
723 mshr_cap_events
724 .init(system->maxMasters())
725 .name(name() + ".mshr_cap_events")
726 .desc("number of times MSHR cap was activated")
727 .flags(total | nozero | nonan)
728 ;
729 for (int i = 0; i < system->maxMasters(); i++) {
730 mshr_cap_events.subname(i, system->getMasterName(i));
731 }
732
733 //software prefetching stats
734 soft_prefetch_mshr_full
735 .init(system->maxMasters())
736 .name(name() + ".soft_prefetch_mshr_full")
737 .desc("number of mshr full events for SW prefetching instrutions")
738 .flags(total | nozero | nonan)
739 ;
740 for (int i = 0; i < system->maxMasters(); i++) {
741 soft_prefetch_mshr_full.subname(i, system->getMasterName(i));
742 }
743
744 mshr_no_allocate_misses
745 .name(name() +".no_allocate_misses")
746 .desc("Number of misses that were no-allocate")
747 ;
748
749}
750
751unsigned int
752BaseCache::drain(Event *de)
753{
754 int count = memSidePort->drain(de) + cpuSidePort->drain(de);
755
756 // Set status
757 if (count != 0) {
758 drainEvent = de;
759
760 changeState(SimObject::Draining);
761 DPRINTF(Drain, "Cache not drained\n");
762 return count;
763 }
764
765 changeState(SimObject::Drained);
766 return 0;
767}