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