base.cc revision 4628
12686Sksewell@umich.edu/*
22686Sksewell@umich.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan
32686Sksewell@umich.edu * All rights reserved.
42686Sksewell@umich.edu *
52686Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without
62686Sksewell@umich.edu * modification, are permitted provided that the following conditions are
72686Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
82686Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
92686Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
102686Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
112686Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
122686Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
132686Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
142686Sksewell@umich.edu * this software without specific prior written permission.
152686Sksewell@umich.edu *
162686Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172686Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182686Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192686Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202686Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212686Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222686Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232686Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242686Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252686Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262686Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272706Sksewell@umich.edu *
282706Sksewell@umich.edu * Authors: Erik Hallnor
292686Sksewell@umich.edu */
302686Sksewell@umich.edu
314661Sksewell@umich.edu/**
322686Sksewell@umich.edu * @file
334661Sksewell@umich.edu * Definition of BaseCache functions.
344661Sksewell@umich.edu */
354661Sksewell@umich.edu
364661Sksewell@umich.edu#include "cpu/base.hh"
374661Sksewell@umich.edu#include "cpu/smt.hh"
384661Sksewell@umich.edu#include "mem/cache/base_cache.hh"
392980Sgblack@eecs.umich.edu#include "mem/cache/miss/mshr.hh"
402686Sksewell@umich.edu
412686Sksewell@umich.eduusing namespace std;
424661Sksewell@umich.edu
432686Sksewell@umich.eduBaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache)
442686Sksewell@umich.edu    : SimpleTimingPort(_name, _cache), cache(_cache), otherPort(NULL),
452686Sksewell@umich.edu      blocked(false), waitingOnRetry(false), mustSendRetry(false),
462686Sksewell@umich.edu      requestCauses(0)
472686Sksewell@umich.edu{
482686Sksewell@umich.edu}
492686Sksewell@umich.edu
502686Sksewell@umich.edu
512686Sksewell@umich.eduBaseCache::BaseCache(const std::string &name, Params &params)
522686Sksewell@umich.edu    : MemObject(name),
532686Sksewell@umich.edu      mshrQueue(params.numMSHRs, 4, MSHRQueue_MSHRs),
542686Sksewell@umich.edu      writeBuffer(params.numWriteBuffers, params.numMSHRs+1000,
552686Sksewell@umich.edu                  MSHRQueue_WriteBuffer),
562686Sksewell@umich.edu      blkSize(params.blkSize),
572686Sksewell@umich.edu      numTarget(params.numTargets),
582686Sksewell@umich.edu      blocked(0),
592686Sksewell@umich.edu      noTargetMSHR(NULL),
602686Sksewell@umich.edu      missCount(params.maxMisses),
612686Sksewell@umich.edu      drainEvent(NULL)
622686Sksewell@umich.edu{
632686Sksewell@umich.edu}
642686Sksewell@umich.edu
652686Sksewell@umich.edu
662686Sksewell@umich.eduvoid
672686Sksewell@umich.eduBaseCache::CachePort::recvStatusChange(Port::Status status)
682686Sksewell@umich.edu{
692686Sksewell@umich.edu    if (status == Port::RangeChange) {
702686Sksewell@umich.edu        otherPort->sendStatusChange(Port::RangeChange);
712686Sksewell@umich.edu    }
722686Sksewell@umich.edu}
732686Sksewell@umich.edu
742686Sksewell@umich.eduint
752686Sksewell@umich.eduBaseCache::CachePort::deviceBlockSize()
762686Sksewell@umich.edu{
772686Sksewell@umich.edu    return cache->getBlockSize();
782686Sksewell@umich.edu}
792686Sksewell@umich.edu
802686Sksewell@umich.edu
812686Sksewell@umich.eduvoid
822686Sksewell@umich.eduBaseCache::CachePort::checkAndSendFunctional(PacketPtr pkt)
832686Sksewell@umich.edu{
842686Sksewell@umich.edu    checkFunctional(pkt);
852686Sksewell@umich.edu    if (pkt->result != Packet::Success)
862686Sksewell@umich.edu        sendFunctional(pkt);
872686Sksewell@umich.edu}
882686Sksewell@umich.edu
892686Sksewell@umich.edu
902686Sksewell@umich.edubool
912686Sksewell@umich.eduBaseCache::CachePort::recvRetryCommon()
922686Sksewell@umich.edu{
932686Sksewell@umich.edu    assert(waitingOnRetry);
942686Sksewell@umich.edu    waitingOnRetry = false;
952686Sksewell@umich.edu    return false;
962686Sksewell@umich.edu}
972686Sksewell@umich.edu
982686Sksewell@umich.edu
992686Sksewell@umich.eduvoid
1002686Sksewell@umich.eduBaseCache::CachePort::setBlocked()
1012686Sksewell@umich.edu{
1022686Sksewell@umich.edu    assert(!blocked);
1032686Sksewell@umich.edu    DPRINTF(Cache, "Cache Blocking\n");
1042686Sksewell@umich.edu    blocked = true;
1052686Sksewell@umich.edu    //Clear the retry flag
1062686Sksewell@umich.edu    mustSendRetry = false;
1072686Sksewell@umich.edu}
1082686Sksewell@umich.edu
1092686Sksewell@umich.eduvoid
1102686Sksewell@umich.eduBaseCache::CachePort::clearBlocked()
1112686Sksewell@umich.edu{
1122686Sksewell@umich.edu    assert(blocked);
1132686Sksewell@umich.edu    DPRINTF(Cache, "Cache Unblocking\n");
1142686Sksewell@umich.edu    blocked = false;
1152686Sksewell@umich.edu    if (mustSendRetry)
1162686Sksewell@umich.edu    {
1172686Sksewell@umich.edu        DPRINTF(Cache, "Cache Sending Retry\n");
1182686Sksewell@umich.edu        mustSendRetry = false;
1192686Sksewell@umich.edu        sendRetry();
1202686Sksewell@umich.edu    }
1212686Sksewell@umich.edu}
1222686Sksewell@umich.edu
1232686Sksewell@umich.edu
1242686Sksewell@umich.eduvoid
1252686Sksewell@umich.eduBaseCache::init()
1262686Sksewell@umich.edu{
1272686Sksewell@umich.edu    if (!cpuSidePort || !memSidePort)
1282686Sksewell@umich.edu        panic("Cache not hooked up on both sides\n");
1292686Sksewell@umich.edu    cpuSidePort->sendStatusChange(Port::RangeChange);
1302686Sksewell@umich.edu}
1312686Sksewell@umich.edu
1322686Sksewell@umich.edu
1332686Sksewell@umich.eduvoid
1342686Sksewell@umich.eduBaseCache::regStats()
1352686Sksewell@umich.edu{
1362686Sksewell@umich.edu    using namespace Stats;
1372686Sksewell@umich.edu
1382686Sksewell@umich.edu    // Hit statistics
1392686Sksewell@umich.edu    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
1402686Sksewell@umich.edu        MemCmd cmd(access_idx);
1412686Sksewell@umich.edu        const string &cstr = cmd.toString();
1422686Sksewell@umich.edu
1432686Sksewell@umich.edu        hits[access_idx]
1442686Sksewell@umich.edu            .init(maxThreadsPerCPU)
1452686Sksewell@umich.edu            .name(name() + "." + cstr + "_hits")
1462686Sksewell@umich.edu            .desc("number of " + cstr + " hits")
1472686Sksewell@umich.edu            .flags(total | nozero | nonan)
1482686Sksewell@umich.edu            ;
1492686Sksewell@umich.edu    }
1502686Sksewell@umich.edu
1512686Sksewell@umich.edu    demandHits
1522686Sksewell@umich.edu        .name(name() + ".demand_hits")
1532686Sksewell@umich.edu        .desc("number of demand (read+write) hits")
1542686Sksewell@umich.edu        .flags(total)
1552686Sksewell@umich.edu        ;
1562686Sksewell@umich.edu    demandHits = hits[MemCmd::ReadReq] + hits[MemCmd::WriteReq];
1572686Sksewell@umich.edu
1582686Sksewell@umich.edu    overallHits
1592686Sksewell@umich.edu        .name(name() + ".overall_hits")
1602686Sksewell@umich.edu        .desc("number of overall hits")
1612686Sksewell@umich.edu        .flags(total)
1622686Sksewell@umich.edu        ;
1632686Sksewell@umich.edu    overallHits = demandHits + hits[MemCmd::SoftPFReq] + hits[MemCmd::HardPFReq]
1642686Sksewell@umich.edu        + hits[MemCmd::Writeback];
1652686Sksewell@umich.edu
1662686Sksewell@umich.edu    // Miss statistics
1672686Sksewell@umich.edu    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
1682686Sksewell@umich.edu        MemCmd cmd(access_idx);
1692686Sksewell@umich.edu        const string &cstr = cmd.toString();
1702686Sksewell@umich.edu
1712686Sksewell@umich.edu        misses[access_idx]
1722686Sksewell@umich.edu            .init(maxThreadsPerCPU)
1732686Sksewell@umich.edu            .name(name() + "." + cstr + "_misses")
1742686Sksewell@umich.edu            .desc("number of " + cstr + " misses")
1752686Sksewell@umich.edu            .flags(total | nozero | nonan)
1762686Sksewell@umich.edu            ;
1772686Sksewell@umich.edu    }
1782686Sksewell@umich.edu
1792686Sksewell@umich.edu    demandMisses
1802686Sksewell@umich.edu        .name(name() + ".demand_misses")
1812686Sksewell@umich.edu        .desc("number of demand (read+write) misses")
1822686Sksewell@umich.edu        .flags(total)
1832686Sksewell@umich.edu        ;
1842686Sksewell@umich.edu    demandMisses = misses[MemCmd::ReadReq] + misses[MemCmd::WriteReq];
1852686Sksewell@umich.edu
1862686Sksewell@umich.edu    overallMisses
1872686Sksewell@umich.edu        .name(name() + ".overall_misses")
1882686Sksewell@umich.edu        .desc("number of overall misses")
1892686Sksewell@umich.edu        .flags(total)
1902686Sksewell@umich.edu        ;
1912686Sksewell@umich.edu    overallMisses = demandMisses + misses[MemCmd::SoftPFReq] +
1922686Sksewell@umich.edu        misses[MemCmd::HardPFReq] + misses[MemCmd::Writeback];
1932686Sksewell@umich.edu
1942686Sksewell@umich.edu    // Miss latency statistics
1952686Sksewell@umich.edu    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
1962686Sksewell@umich.edu        MemCmd cmd(access_idx);
1972686Sksewell@umich.edu        const string &cstr = cmd.toString();
1982686Sksewell@umich.edu
1992686Sksewell@umich.edu        missLatency[access_idx]
2002686Sksewell@umich.edu            .init(maxThreadsPerCPU)
2012686Sksewell@umich.edu            .name(name() + "." + cstr + "_miss_latency")
2022686Sksewell@umich.edu            .desc("number of " + cstr + " miss cycles")
2032686Sksewell@umich.edu            .flags(total | nozero | nonan)
2042686Sksewell@umich.edu            ;
2052686Sksewell@umich.edu    }
2064661Sksewell@umich.edu
2074661Sksewell@umich.edu    demandMissLatency
2084661Sksewell@umich.edu        .name(name() + ".demand_miss_latency")
2094661Sksewell@umich.edu        .desc("number of demand (read+write) miss cycles")
2104661Sksewell@umich.edu        .flags(total)
2114661Sksewell@umich.edu        ;
212    demandMissLatency = missLatency[MemCmd::ReadReq] + missLatency[MemCmd::WriteReq];
213
214    overallMissLatency
215        .name(name() + ".overall_miss_latency")
216        .desc("number of overall miss cycles")
217        .flags(total)
218        ;
219    overallMissLatency = demandMissLatency + missLatency[MemCmd::SoftPFReq] +
220        missLatency[MemCmd::HardPFReq];
221
222    // access formulas
223    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
224        MemCmd cmd(access_idx);
225        const string &cstr = cmd.toString();
226
227        accesses[access_idx]
228            .name(name() + "." + cstr + "_accesses")
229            .desc("number of " + cstr + " accesses(hits+misses)")
230            .flags(total | nozero | nonan)
231            ;
232
233        accesses[access_idx] = hits[access_idx] + misses[access_idx];
234    }
235
236    demandAccesses
237        .name(name() + ".demand_accesses")
238        .desc("number of demand (read+write) accesses")
239        .flags(total)
240        ;
241    demandAccesses = demandHits + demandMisses;
242
243    overallAccesses
244        .name(name() + ".overall_accesses")
245        .desc("number of overall (read+write) accesses")
246        .flags(total)
247        ;
248    overallAccesses = overallHits + overallMisses;
249
250    // miss rate formulas
251    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
252        MemCmd cmd(access_idx);
253        const string &cstr = cmd.toString();
254
255        missRate[access_idx]
256            .name(name() + "." + cstr + "_miss_rate")
257            .desc("miss rate for " + cstr + " accesses")
258            .flags(total | nozero | nonan)
259            ;
260
261        missRate[access_idx] = misses[access_idx] / accesses[access_idx];
262    }
263
264    demandMissRate
265        .name(name() + ".demand_miss_rate")
266        .desc("miss rate for demand accesses")
267        .flags(total)
268        ;
269    demandMissRate = demandMisses / demandAccesses;
270
271    overallMissRate
272        .name(name() + ".overall_miss_rate")
273        .desc("miss rate for overall accesses")
274        .flags(total)
275        ;
276    overallMissRate = overallMisses / overallAccesses;
277
278    // miss latency formulas
279    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
280        MemCmd cmd(access_idx);
281        const string &cstr = cmd.toString();
282
283        avgMissLatency[access_idx]
284            .name(name() + "." + cstr + "_avg_miss_latency")
285            .desc("average " + cstr + " miss latency")
286            .flags(total | nozero | nonan)
287            ;
288
289        avgMissLatency[access_idx] =
290            missLatency[access_idx] / misses[access_idx];
291    }
292
293    demandAvgMissLatency
294        .name(name() + ".demand_avg_miss_latency")
295        .desc("average overall miss latency")
296        .flags(total)
297        ;
298    demandAvgMissLatency = demandMissLatency / demandMisses;
299
300    overallAvgMissLatency
301        .name(name() + ".overall_avg_miss_latency")
302        .desc("average overall miss latency")
303        .flags(total)
304        ;
305    overallAvgMissLatency = overallMissLatency / overallMisses;
306
307    blocked_cycles.init(NUM_BLOCKED_CAUSES);
308    blocked_cycles
309        .name(name() + ".blocked_cycles")
310        .desc("number of cycles access was blocked")
311        .subname(Blocked_NoMSHRs, "no_mshrs")
312        .subname(Blocked_NoTargets, "no_targets")
313        ;
314
315
316    blocked_causes.init(NUM_BLOCKED_CAUSES);
317    blocked_causes
318        .name(name() + ".blocked")
319        .desc("number of cycles access was blocked")
320        .subname(Blocked_NoMSHRs, "no_mshrs")
321        .subname(Blocked_NoTargets, "no_targets")
322        ;
323
324    avg_blocked
325        .name(name() + ".avg_blocked_cycles")
326        .desc("average number of cycles each access was blocked")
327        .subname(Blocked_NoMSHRs, "no_mshrs")
328        .subname(Blocked_NoTargets, "no_targets")
329        ;
330
331    avg_blocked = blocked_cycles / blocked_causes;
332
333    fastWrites
334        .name(name() + ".fast_writes")
335        .desc("number of fast writes performed")
336        ;
337
338    cacheCopies
339        .name(name() + ".cache_copies")
340        .desc("number of cache copies performed")
341        ;
342
343    writebacks
344        .init(maxThreadsPerCPU)
345        .name(name() + ".writebacks")
346        .desc("number of writebacks")
347        .flags(total)
348        ;
349
350    // MSHR statistics
351    // MSHR hit statistics
352    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
353        MemCmd cmd(access_idx);
354        const string &cstr = cmd.toString();
355
356        mshr_hits[access_idx]
357            .init(maxThreadsPerCPU)
358            .name(name() + "." + cstr + "_mshr_hits")
359            .desc("number of " + cstr + " MSHR hits")
360            .flags(total | nozero | nonan)
361            ;
362    }
363
364    demandMshrHits
365        .name(name() + ".demand_mshr_hits")
366        .desc("number of demand (read+write) MSHR hits")
367        .flags(total)
368        ;
369    demandMshrHits = mshr_hits[MemCmd::ReadReq] + mshr_hits[MemCmd::WriteReq];
370
371    overallMshrHits
372        .name(name() + ".overall_mshr_hits")
373        .desc("number of overall MSHR hits")
374        .flags(total)
375        ;
376    overallMshrHits = demandMshrHits + mshr_hits[MemCmd::SoftPFReq] +
377        mshr_hits[MemCmd::HardPFReq];
378
379    // MSHR miss statistics
380    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
381        MemCmd cmd(access_idx);
382        const string &cstr = cmd.toString();
383
384        mshr_misses[access_idx]
385            .init(maxThreadsPerCPU)
386            .name(name() + "." + cstr + "_mshr_misses")
387            .desc("number of " + cstr + " MSHR misses")
388            .flags(total | nozero | nonan)
389            ;
390    }
391
392    demandMshrMisses
393        .name(name() + ".demand_mshr_misses")
394        .desc("number of demand (read+write) MSHR misses")
395        .flags(total)
396        ;
397    demandMshrMisses = mshr_misses[MemCmd::ReadReq] + mshr_misses[MemCmd::WriteReq];
398
399    overallMshrMisses
400        .name(name() + ".overall_mshr_misses")
401        .desc("number of overall MSHR misses")
402        .flags(total)
403        ;
404    overallMshrMisses = demandMshrMisses + mshr_misses[MemCmd::SoftPFReq] +
405        mshr_misses[MemCmd::HardPFReq];
406
407    // MSHR miss latency statistics
408    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
409        MemCmd cmd(access_idx);
410        const string &cstr = cmd.toString();
411
412        mshr_miss_latency[access_idx]
413            .init(maxThreadsPerCPU)
414            .name(name() + "." + cstr + "_mshr_miss_latency")
415            .desc("number of " + cstr + " MSHR miss cycles")
416            .flags(total | nozero | nonan)
417            ;
418    }
419
420    demandMshrMissLatency
421        .name(name() + ".demand_mshr_miss_latency")
422        .desc("number of demand (read+write) MSHR miss cycles")
423        .flags(total)
424        ;
425    demandMshrMissLatency = mshr_miss_latency[MemCmd::ReadReq]
426        + mshr_miss_latency[MemCmd::WriteReq];
427
428    overallMshrMissLatency
429        .name(name() + ".overall_mshr_miss_latency")
430        .desc("number of overall MSHR miss cycles")
431        .flags(total)
432        ;
433    overallMshrMissLatency = demandMshrMissLatency +
434        mshr_miss_latency[MemCmd::SoftPFReq] + mshr_miss_latency[MemCmd::HardPFReq];
435
436    // MSHR uncacheable statistics
437    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
438        MemCmd cmd(access_idx);
439        const string &cstr = cmd.toString();
440
441        mshr_uncacheable[access_idx]
442            .init(maxThreadsPerCPU)
443            .name(name() + "." + cstr + "_mshr_uncacheable")
444            .desc("number of " + cstr + " MSHR uncacheable")
445            .flags(total | nozero | nonan)
446            ;
447    }
448
449    overallMshrUncacheable
450        .name(name() + ".overall_mshr_uncacheable_misses")
451        .desc("number of overall MSHR uncacheable misses")
452        .flags(total)
453        ;
454    overallMshrUncacheable = mshr_uncacheable[MemCmd::ReadReq]
455        + mshr_uncacheable[MemCmd::WriteReq] + mshr_uncacheable[MemCmd::SoftPFReq]
456        + mshr_uncacheable[MemCmd::HardPFReq];
457
458    // MSHR miss latency statistics
459    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
460        MemCmd cmd(access_idx);
461        const string &cstr = cmd.toString();
462
463        mshr_uncacheable_lat[access_idx]
464            .init(maxThreadsPerCPU)
465            .name(name() + "." + cstr + "_mshr_uncacheable_latency")
466            .desc("number of " + cstr + " MSHR uncacheable cycles")
467            .flags(total | nozero | nonan)
468            ;
469    }
470
471    overallMshrUncacheableLatency
472        .name(name() + ".overall_mshr_uncacheable_latency")
473        .desc("number of overall MSHR uncacheable cycles")
474        .flags(total)
475        ;
476    overallMshrUncacheableLatency = mshr_uncacheable_lat[MemCmd::ReadReq]
477        + mshr_uncacheable_lat[MemCmd::WriteReq]
478        + mshr_uncacheable_lat[MemCmd::SoftPFReq]
479        + mshr_uncacheable_lat[MemCmd::HardPFReq];
480
481#if 0
482    // MSHR access formulas
483    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
484        MemCmd cmd(access_idx);
485        const string &cstr = cmd.toString();
486
487        mshrAccesses[access_idx]
488            .name(name() + "." + cstr + "_mshr_accesses")
489            .desc("number of " + cstr + " mshr accesses(hits+misses)")
490            .flags(total | nozero | nonan)
491            ;
492        mshrAccesses[access_idx] =
493            mshr_hits[access_idx] + mshr_misses[access_idx]
494            + mshr_uncacheable[access_idx];
495    }
496
497    demandMshrAccesses
498        .name(name() + ".demand_mshr_accesses")
499        .desc("number of demand (read+write) mshr accesses")
500        .flags(total | nozero | nonan)
501        ;
502    demandMshrAccesses = demandMshrHits + demandMshrMisses;
503
504    overallMshrAccesses
505        .name(name() + ".overall_mshr_accesses")
506        .desc("number of overall (read+write) mshr accesses")
507        .flags(total | nozero | nonan)
508        ;
509    overallMshrAccesses = overallMshrHits + overallMshrMisses
510        + overallMshrUncacheable;
511#endif
512
513    // MSHR miss rate formulas
514    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
515        MemCmd cmd(access_idx);
516        const string &cstr = cmd.toString();
517
518        mshrMissRate[access_idx]
519            .name(name() + "." + cstr + "_mshr_miss_rate")
520            .desc("mshr miss rate for " + cstr + " accesses")
521            .flags(total | nozero | nonan)
522            ;
523
524        mshrMissRate[access_idx] =
525            mshr_misses[access_idx] / accesses[access_idx];
526    }
527
528    demandMshrMissRate
529        .name(name() + ".demand_mshr_miss_rate")
530        .desc("mshr miss rate for demand accesses")
531        .flags(total)
532        ;
533    demandMshrMissRate = demandMshrMisses / demandAccesses;
534
535    overallMshrMissRate
536        .name(name() + ".overall_mshr_miss_rate")
537        .desc("mshr miss rate for overall accesses")
538        .flags(total)
539        ;
540    overallMshrMissRate = overallMshrMisses / overallAccesses;
541
542    // mshrMiss latency formulas
543    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
544        MemCmd cmd(access_idx);
545        const string &cstr = cmd.toString();
546
547        avgMshrMissLatency[access_idx]
548            .name(name() + "." + cstr + "_avg_mshr_miss_latency")
549            .desc("average " + cstr + " mshr miss latency")
550            .flags(total | nozero | nonan)
551            ;
552
553        avgMshrMissLatency[access_idx] =
554            mshr_miss_latency[access_idx] / mshr_misses[access_idx];
555    }
556
557    demandAvgMshrMissLatency
558        .name(name() + ".demand_avg_mshr_miss_latency")
559        .desc("average overall mshr miss latency")
560        .flags(total)
561        ;
562    demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
563
564    overallAvgMshrMissLatency
565        .name(name() + ".overall_avg_mshr_miss_latency")
566        .desc("average overall mshr miss latency")
567        .flags(total)
568        ;
569    overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
570
571    // mshrUncacheable latency formulas
572    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
573        MemCmd cmd(access_idx);
574        const string &cstr = cmd.toString();
575
576        avgMshrUncacheableLatency[access_idx]
577            .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
578            .desc("average " + cstr + " mshr uncacheable latency")
579            .flags(total | nozero | nonan)
580            ;
581
582        avgMshrUncacheableLatency[access_idx] =
583            mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
584    }
585
586    overallAvgMshrUncacheableLatency
587        .name(name() + ".overall_avg_mshr_uncacheable_latency")
588        .desc("average overall mshr uncacheable latency")
589        .flags(total)
590        ;
591    overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
592
593    mshr_cap_events
594        .init(maxThreadsPerCPU)
595        .name(name() + ".mshr_cap_events")
596        .desc("number of times MSHR cap was activated")
597        .flags(total)
598        ;
599
600    //software prefetching stats
601    soft_prefetch_mshr_full
602        .init(maxThreadsPerCPU)
603        .name(name() + ".soft_prefetch_mshr_full")
604        .desc("number of mshr full events for SW prefetching instrutions")
605        .flags(total)
606        ;
607
608    mshr_no_allocate_misses
609        .name(name() +".no_allocate_misses")
610        .desc("Number of misses that were no-allocate")
611        ;
612
613}
614
615unsigned int
616BaseCache::drain(Event *de)
617{
618    int count = memSidePort->drain(de) + cpuSidePort->drain(de);
619
620    // Set status
621    if (count != 0) {
622        drainEvent = de;
623
624        changeState(SimObject::Draining);
625        return count;
626    }
627
628    changeState(SimObject::Drained);
629    return 0;
630}
631