dramsim2.cc revision 11192
12391SN/A/*
28931Sandreas.hansson@arm.com * Copyright (c) 2013 ARM Limited
37733SAli.Saidi@ARM.com * All rights reserved
47733SAli.Saidi@ARM.com *
57733SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall
67733SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual
77733SAli.Saidi@ARM.com * property including but not limited to intellectual property relating
87733SAli.Saidi@ARM.com * to a hardware implementation of the functionality of the software
97733SAli.Saidi@ARM.com * licensed hereunder.  You may use the software subject to the license
107733SAli.Saidi@ARM.com * terms below provided that you ensure that this notice is replicated
117733SAli.Saidi@ARM.com * unmodified and in its entirety in all distributions of the software,
127733SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form.
137733SAli.Saidi@ARM.com *
142391SN/A * Redistribution and use in source and binary forms, with or without
152391SN/A * modification, are permitted provided that the following conditions are
162391SN/A * met: redistributions of source code must retain the above copyright
172391SN/A * notice, this list of conditions and the following disclaimer;
182391SN/A * redistributions in binary form must reproduce the above copyright
192391SN/A * notice, this list of conditions and the following disclaimer in the
202391SN/A * documentation and/or other materials provided with the distribution;
212391SN/A * neither the name of the copyright holders nor the names of its
222391SN/A * contributors may be used to endorse or promote products derived from
232391SN/A * this software without specific prior written permission.
242391SN/A *
252391SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262391SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272391SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282391SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292391SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302391SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312391SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322391SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332391SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342391SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352391SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362665Ssaidi@eecs.umich.edu *
378931Sandreas.hansson@arm.com * Authors: Andreas Hansson
382391SN/A */
392391SN/A
409293Sandreas.hansson@arm.com#include "DRAMSim2/Callback.h"
419293Sandreas.hansson@arm.com#include "base/callback.hh"
429293Sandreas.hansson@arm.com#include "base/trace.hh"
439293Sandreas.hansson@arm.com#include "debug/DRAMSim2.hh"
449293Sandreas.hansson@arm.com#include "debug/Drain.hh"
459293Sandreas.hansson@arm.com#include "mem/dramsim2.hh"
469293Sandreas.hansson@arm.com#include "sim/system.hh"
479293Sandreas.hansson@arm.com
489293Sandreas.hansson@arm.comDRAMSim2::DRAMSim2(const Params* p) :
499293Sandreas.hansson@arm.com    AbstractMemory(p),
509293Sandreas.hansson@arm.com    port(name() + ".port", *this),
519293Sandreas.hansson@arm.com    wrapper(p->deviceConfigFile, p->systemConfigFile, p->filePath,
529293Sandreas.hansson@arm.com            p->traceFile, p->range.size() / 1024 / 1024, p->enableDebug),
539356Snilay@cs.wisc.edu    retryReq(false), retryResp(false), startTick(0),
548931Sandreas.hansson@arm.com    nbrOutstandingReads(0), nbrOutstandingWrites(0),
559293Sandreas.hansson@arm.com    sendResponseEvent(this), tickEvent(this)
569293Sandreas.hansson@arm.com{
572394SN/A    DPRINTF(DRAMSim2,
582394SN/A            "Instantiated DRAMSim2 with clock %d ns and queue size %d\n",
592391SN/A            wrapper.clockPeriod(), wrapper.queueSize());
602391SN/A
619293Sandreas.hansson@arm.com    DRAMSim::TransactionCompleteCB* read_cb =
629293Sandreas.hansson@arm.com        new DRAMSim::Callback<DRAMSim2, void, unsigned, uint64_t, uint64_t>(
639293Sandreas.hansson@arm.com            this, &DRAMSim2::readComplete);
642391SN/A    DRAMSim::TransactionCompleteCB* write_cb =
659293Sandreas.hansson@arm.com        new DRAMSim::Callback<DRAMSim2, void, unsigned, uint64_t, uint64_t>(
669293Sandreas.hansson@arm.com            this, &DRAMSim2::writeComplete);
678931Sandreas.hansson@arm.com    wrapper.setCallbacks(read_cb, write_cb);
688931Sandreas.hansson@arm.com
698931Sandreas.hansson@arm.com    // Register a callback to compensate for the destructor not
708931Sandreas.hansson@arm.com    // being called. The callback prints the DRAMSim2 stats.
718931Sandreas.hansson@arm.com    Callback* cb = new MakeCallback<DRAMSim2Wrapper,
722391SN/A        &DRAMSim2Wrapper::printStats>(wrapper);
738931Sandreas.hansson@arm.com    registerExitCallback(cb);
748931Sandreas.hansson@arm.com}
758931Sandreas.hansson@arm.com
768931Sandreas.hansson@arm.comvoid
778931Sandreas.hansson@arm.comDRAMSim2::init()
788931Sandreas.hansson@arm.com{
798931Sandreas.hansson@arm.com    AbstractMemory::init();
808931Sandreas.hansson@arm.com
819293Sandreas.hansson@arm.com    if (!port.isConnected()) {
829293Sandreas.hansson@arm.com        fatal("DRAMSim2 %s is unconnected!\n", name());
839293Sandreas.hansson@arm.com    } else {
849293Sandreas.hansson@arm.com        port.sendRangeChange();
859293Sandreas.hansson@arm.com    }
869293Sandreas.hansson@arm.com
879293Sandreas.hansson@arm.com    if (system()->cacheLineSize() != wrapper.burstSize())
889293Sandreas.hansson@arm.com        fatal("DRAMSim2 burst size %d does not match cache line size %d\n",
899293Sandreas.hansson@arm.com              wrapper.burstSize(), system()->cacheLineSize());
909293Sandreas.hansson@arm.com}
919293Sandreas.hansson@arm.com
929293Sandreas.hansson@arm.comvoid
939293Sandreas.hansson@arm.comDRAMSim2::startup()
949293Sandreas.hansson@arm.com{
958931Sandreas.hansson@arm.com    startTick = curTick();
969293Sandreas.hansson@arm.com
979293Sandreas.hansson@arm.com    // kick off the clock ticks
989404Sandreas.hansson@arm.com    schedule(tickEvent, clockEdge());
999404Sandreas.hansson@arm.com}
1009404Sandreas.hansson@arm.com
1019404Sandreas.hansson@arm.comvoid
1029293Sandreas.hansson@arm.comDRAMSim2::sendResponse()
1039293Sandreas.hansson@arm.com{
1049293Sandreas.hansson@arm.com    assert(!retryResp);
1059293Sandreas.hansson@arm.com    assert(!responseQueue.empty());
1069293Sandreas.hansson@arm.com
1079293Sandreas.hansson@arm.com    DPRINTF(DRAMSim2, "Attempting to send response\n");
1089404Sandreas.hansson@arm.com
1099404Sandreas.hansson@arm.com    bool success = port.sendTimingResp(responseQueue.front());
1109404Sandreas.hansson@arm.com    if (success) {
1119404Sandreas.hansson@arm.com        responseQueue.pop_front();
1129404Sandreas.hansson@arm.com
1139404Sandreas.hansson@arm.com        DPRINTF(DRAMSim2, "Have %d read, %d write, %d responses outstanding\n",
1149293Sandreas.hansson@arm.com                nbrOutstandingReads, nbrOutstandingWrites,
1159293Sandreas.hansson@arm.com                responseQueue.size());
1169293Sandreas.hansson@arm.com
1179293Sandreas.hansson@arm.com        if (!responseQueue.empty() && !sendResponseEvent.scheduled())
1189293Sandreas.hansson@arm.com            schedule(sendResponseEvent, curTick());
1199293Sandreas.hansson@arm.com
1209293Sandreas.hansson@arm.com        if (nbrOutstanding() == 0)
1219293Sandreas.hansson@arm.com            signalDrainDone();
1229411Sandreas.hansson@arm.com    } else {
1239411Sandreas.hansson@arm.com        retryResp = true;
1249411Sandreas.hansson@arm.com
1259411Sandreas.hansson@arm.com        DPRINTF(DRAMSim2, "Waiting for response retry\n");
1269293Sandreas.hansson@arm.com
1279411Sandreas.hansson@arm.com        assert(!sendResponseEvent.scheduled());
1289411Sandreas.hansson@arm.com    }
1299293Sandreas.hansson@arm.com}
1309293Sandreas.hansson@arm.com
1319293Sandreas.hansson@arm.comunsigned int
1329293Sandreas.hansson@arm.comDRAMSim2::nbrOutstanding() const
1339293Sandreas.hansson@arm.com{
1349293Sandreas.hansson@arm.com    return nbrOutstandingReads + nbrOutstandingWrites + responseQueue.size();
1359293Sandreas.hansson@arm.com}
1369405Sandreas.hansson@arm.com
1379405Sandreas.hansson@arm.comvoid
1389293Sandreas.hansson@arm.comDRAMSim2::tick()
1399293Sandreas.hansson@arm.com{
1409293Sandreas.hansson@arm.com    wrapper.tick();
1419293Sandreas.hansson@arm.com
1429293Sandreas.hansson@arm.com    // is the connected port waiting for a retry, if so check the
1439293Sandreas.hansson@arm.com    // state and send a retry if conditions have changed
1449404Sandreas.hansson@arm.com    if (retryReq && nbrOutstanding() < wrapper.queueSize()) {
1459404Sandreas.hansson@arm.com        retryReq = false;
1469404Sandreas.hansson@arm.com        port.sendRetryReq();
1479404Sandreas.hansson@arm.com    }
1489293Sandreas.hansson@arm.com
1499293Sandreas.hansson@arm.com    schedule(tickEvent, curTick() + wrapper.clockPeriod() * SimClock::Int::ns);
1509293Sandreas.hansson@arm.com}
1519293Sandreas.hansson@arm.com
1529293Sandreas.hansson@arm.comTick
1538931Sandreas.hansson@arm.comDRAMSim2::recvAtomic(PacketPtr pkt)
1549293Sandreas.hansson@arm.com{
1559293Sandreas.hansson@arm.com    access(pkt);
1569293Sandreas.hansson@arm.com
1579404Sandreas.hansson@arm.com    // 50 ns is just an arbitrary value at this point
1589404Sandreas.hansson@arm.com    return pkt->memInhibitAsserted() ? 0 : 50000;
1599404Sandreas.hansson@arm.com}
1609404Sandreas.hansson@arm.com
1619293Sandreas.hansson@arm.comvoid
1629404Sandreas.hansson@arm.comDRAMSim2::recvFunctional(PacketPtr pkt)
1639404Sandreas.hansson@arm.com{
1649405Sandreas.hansson@arm.com    pkt->pushLabel(name());
1659405Sandreas.hansson@arm.com
1669404Sandreas.hansson@arm.com    functionalAccess(pkt);
1679404Sandreas.hansson@arm.com
1688931Sandreas.hansson@arm.com    // potentially update the packets in our response queue as well
1698931Sandreas.hansson@arm.com    for (auto i = responseQueue.begin(); i != responseQueue.end(); ++i)
1708931Sandreas.hansson@arm.com        pkt->checkFunctional(*i);
1719293Sandreas.hansson@arm.com
1729293Sandreas.hansson@arm.com    pkt->popLabel();
1739293Sandreas.hansson@arm.com}
1749293Sandreas.hansson@arm.com
1759293Sandreas.hansson@arm.combool
1769293Sandreas.hansson@arm.comDRAMSim2::recvTimingReq(PacketPtr pkt)
1779293Sandreas.hansson@arm.com{
1789293Sandreas.hansson@arm.com    // sink inhibited packets without further action
1798931Sandreas.hansson@arm.com    if (pkt->memInhibitAsserted()) {
1808931Sandreas.hansson@arm.com        pendingDelete.reset(pkt);
1818931Sandreas.hansson@arm.com        return true;
1828931Sandreas.hansson@arm.com    }
1839405Sandreas.hansson@arm.com
1848931Sandreas.hansson@arm.com    // we should not get a new request after committing to retry the
1859235Sandreas.hansson@arm.com    // current one, but unfortunately the CPU violates this rule, so
1868931Sandreas.hansson@arm.com    // simply ignore it for now
1878931Sandreas.hansson@arm.com    if (retryReq)
1888931Sandreas.hansson@arm.com        return false;
1898931Sandreas.hansson@arm.com
1908931Sandreas.hansson@arm.com    // if we cannot accept we need to send a retry once progress can
1918931Sandreas.hansson@arm.com    // be made
1928851Sandreas.hansson@arm.com    bool can_accept = nbrOutstanding() < wrapper.queueSize();
1938851Sandreas.hansson@arm.com
1948931Sandreas.hansson@arm.com    // keep track of the transaction
1955477Snate@binkert.org    if (pkt->isRead()) {
1968931Sandreas.hansson@arm.com        if (can_accept) {
1978931Sandreas.hansson@arm.com            outstandingReads[pkt->getAddr()].push(pkt);
1988931Sandreas.hansson@arm.com
1997730SAli.Saidi@ARM.com            // we count a transaction as outstanding until it has left the
2008931Sandreas.hansson@arm.com            // queue in the controller, and the response has been sent
2018931Sandreas.hansson@arm.com            // back, note that this will differ for reads and writes
2028931Sandreas.hansson@arm.com            ++nbrOutstandingReads;
2038931Sandreas.hansson@arm.com        }
2048931Sandreas.hansson@arm.com    } else if (pkt->isWrite()) {
2058931Sandreas.hansson@arm.com        if (can_accept) {
2069413Sandreas.hansson@arm.com            outstandingWrites[pkt->getAddr()].push(pkt);
2079413Sandreas.hansson@arm.com
2089413Sandreas.hansson@arm.com            ++nbrOutstandingWrites;
2099413Sandreas.hansson@arm.com
2109413Sandreas.hansson@arm.com            // perform the access for writes
2119413Sandreas.hansson@arm.com            accessAndRespond(pkt);
2129413Sandreas.hansson@arm.com        }
2139413Sandreas.hansson@arm.com    } else {
2149413Sandreas.hansson@arm.com        // keep it simple and just respond if necessary
2159413Sandreas.hansson@arm.com        accessAndRespond(pkt);
2169413Sandreas.hansson@arm.com        return true;
2179413Sandreas.hansson@arm.com    }
2189413Sandreas.hansson@arm.com
2199413Sandreas.hansson@arm.com    if (can_accept) {
2209413Sandreas.hansson@arm.com        // we should never have a situation when we think there is space,
2219413Sandreas.hansson@arm.com        // and there isn't
2229413Sandreas.hansson@arm.com        assert(wrapper.canAccept());
2239413Sandreas.hansson@arm.com
2249413Sandreas.hansson@arm.com        DPRINTF(DRAMSim2, "Enqueueing address %lld\n", pkt->getAddr());
2258931Sandreas.hansson@arm.com
2267730SAli.Saidi@ARM.com        // @todo what about the granularity here, implicit assumption that
2272391SN/A        // a transaction matches the burst size of the memory (which we
2289413Sandreas.hansson@arm.com        // cannot determine without parsing the ini file ourselves)
2299413Sandreas.hansson@arm.com        wrapper.enqueue(pkt->isWrite(), pkt->getAddr());
2309413Sandreas.hansson@arm.com
2319413Sandreas.hansson@arm.com        return true;
2329413Sandreas.hansson@arm.com    } else {
2339413Sandreas.hansson@arm.com        retryReq = true;
2348931Sandreas.hansson@arm.com        return false;
2352391SN/A    }
2362391SN/A}
2372541SN/A
2388931Sandreas.hansson@arm.comvoid
2392541SN/ADRAMSim2::recvRespRetry()
2408931Sandreas.hansson@arm.com{
2418931Sandreas.hansson@arm.com    DPRINTF(DRAMSim2, "Retrying\n");
2429235Sandreas.hansson@arm.com
2438931Sandreas.hansson@arm.com    assert(retryResp);
2448931Sandreas.hansson@arm.com    retryResp = false;
2452391SN/A    sendResponse();
2462391SN/A}
2478719SAli.Saidi@ARM.com
2488931Sandreas.hansson@arm.comvoid
2498719SAli.Saidi@ARM.comDRAMSim2::accessAndRespond(PacketPtr pkt)
2508931Sandreas.hansson@arm.com{
2518931Sandreas.hansson@arm.com    DPRINTF(DRAMSim2, "Access for address %lld\n", pkt->getAddr());
2529235Sandreas.hansson@arm.com
2538931Sandreas.hansson@arm.com    bool needsResponse = pkt->needsResponse();
2548931Sandreas.hansson@arm.com
2558719SAli.Saidi@ARM.com    // do the actual memory access which also turns the packet into a
2569293Sandreas.hansson@arm.com    // response
2579293Sandreas.hansson@arm.com    access(pkt);
2589293Sandreas.hansson@arm.com
2599293Sandreas.hansson@arm.com    // turn packet around to go back to requester if response expected
2609293Sandreas.hansson@arm.com    if (needsResponse) {
2619293Sandreas.hansson@arm.com        // access already turned the packet into a response
2629293Sandreas.hansson@arm.com        assert(pkt->isResponse());
2639293Sandreas.hansson@arm.com        // Here we pay for xbar additional delay and to process the payload
2649293Sandreas.hansson@arm.com        // of the packet.
2659293Sandreas.hansson@arm.com        Tick time = curTick() + pkt->headerDelay + pkt->payloadDelay;
2669293Sandreas.hansson@arm.com        // Reset the timings of the packet
2679293Sandreas.hansson@arm.com        pkt->headerDelay = pkt->payloadDelay = 0;
2689293Sandreas.hansson@arm.com
2699293Sandreas.hansson@arm.com        DPRINTF(DRAMSim2, "Queuing response for address %lld\n",
2709293Sandreas.hansson@arm.com                pkt->getAddr());
2719293Sandreas.hansson@arm.com
2729293Sandreas.hansson@arm.com        // queue it to be sent back
2739293Sandreas.hansson@arm.com        responseQueue.push_back(pkt);
2749293Sandreas.hansson@arm.com
2759293Sandreas.hansson@arm.com        // if we are not already waiting for a retry, or are scheduled
2769293Sandreas.hansson@arm.com        // to send a response, schedule an event
2779293Sandreas.hansson@arm.com        if (!retryResp && !sendResponseEvent.scheduled())
2789293Sandreas.hansson@arm.com            schedule(sendResponseEvent, time);
2799293Sandreas.hansson@arm.com    } else {
2809293Sandreas.hansson@arm.com        // queue the packet for deletion
2819293Sandreas.hansson@arm.com        pendingDelete.reset(pkt);
2829293Sandreas.hansson@arm.com    }
2839293Sandreas.hansson@arm.com}
2849293Sandreas.hansson@arm.com
2859293Sandreas.hansson@arm.comvoid DRAMSim2::readComplete(unsigned id, uint64_t addr, uint64_t cycle)
2869293Sandreas.hansson@arm.com{
2879293Sandreas.hansson@arm.com    assert(cycle == divCeil(curTick() - startTick,
2889293Sandreas.hansson@arm.com                            wrapper.clockPeriod() * SimClock::Int::ns));
2899293Sandreas.hansson@arm.com
2909293Sandreas.hansson@arm.com    DPRINTF(DRAMSim2, "Read to address %lld complete\n", addr);
2919293Sandreas.hansson@arm.com
2929293Sandreas.hansson@arm.com    // get the outstanding reads for the address in question
2939293Sandreas.hansson@arm.com    auto p = outstandingReads.find(addr);
2949293Sandreas.hansson@arm.com    assert(p != outstandingReads.end());
2959293Sandreas.hansson@arm.com
2969386Sandreas.hansson@arm.com    // first in first out, which is not necessarily true, but it is
2979293Sandreas.hansson@arm.com    // the best we can do at this point
2989293Sandreas.hansson@arm.com    PacketPtr pkt = p->second.front();
2999293Sandreas.hansson@arm.com    p->second.pop();
3009293Sandreas.hansson@arm.com
3019293Sandreas.hansson@arm.com    if (p->second.empty())
3029293Sandreas.hansson@arm.com        outstandingReads.erase(p);
3039293Sandreas.hansson@arm.com
3049293Sandreas.hansson@arm.com    // no need to check for drain here as the next call will add a
3059293Sandreas.hansson@arm.com    // response to the response queue straight away
3069293Sandreas.hansson@arm.com    assert(nbrOutstandingReads != 0);
3079293Sandreas.hansson@arm.com    --nbrOutstandingReads;
3089293Sandreas.hansson@arm.com
3099293Sandreas.hansson@arm.com    // perform the actual memory access
3109293Sandreas.hansson@arm.com    accessAndRespond(pkt);
3119293Sandreas.hansson@arm.com}
3129293Sandreas.hansson@arm.com
3139293Sandreas.hansson@arm.comvoid DRAMSim2::writeComplete(unsigned id, uint64_t addr, uint64_t cycle)
3149293Sandreas.hansson@arm.com{
3159293Sandreas.hansson@arm.com    assert(cycle == divCeil(curTick() - startTick,
3169293Sandreas.hansson@arm.com                            wrapper.clockPeriod() * SimClock::Int::ns));
3179293Sandreas.hansson@arm.com
3189293Sandreas.hansson@arm.com    DPRINTF(DRAMSim2, "Write to address %lld complete\n", addr);
3199293Sandreas.hansson@arm.com
3209293Sandreas.hansson@arm.com    // get the outstanding reads for the address in question
3219293Sandreas.hansson@arm.com    auto p = outstandingWrites.find(addr);
3229293Sandreas.hansson@arm.com    assert(p != outstandingWrites.end());
3239293Sandreas.hansson@arm.com
3249293Sandreas.hansson@arm.com    // we have already responded, and this is only to keep track of
3259293Sandreas.hansson@arm.com    // what is outstanding
3269293Sandreas.hansson@arm.com    p->second.pop();
3279293Sandreas.hansson@arm.com    if (p->second.empty())
3289293Sandreas.hansson@arm.com        outstandingWrites.erase(p);
3299293Sandreas.hansson@arm.com
3309293Sandreas.hansson@arm.com    assert(nbrOutstandingWrites != 0);
3319293Sandreas.hansson@arm.com    --nbrOutstandingWrites;
3329293Sandreas.hansson@arm.com
3339293Sandreas.hansson@arm.com    if (nbrOutstanding() == 0)
3349293Sandreas.hansson@arm.com        signalDrainDone();
3359293Sandreas.hansson@arm.com}
3369293Sandreas.hansson@arm.com
3379293Sandreas.hansson@arm.comBaseSlavePort&
3389293Sandreas.hansson@arm.comDRAMSim2::getSlavePort(const std::string &if_name, PortID idx)
3399293Sandreas.hansson@arm.com{
3409293Sandreas.hansson@arm.com    if (if_name != "port") {
3419293Sandreas.hansson@arm.com        return MemObject::getSlavePort(if_name, idx);
3429293Sandreas.hansson@arm.com    } else {
3439293Sandreas.hansson@arm.com        return port;
3449293Sandreas.hansson@arm.com    }
3459293Sandreas.hansson@arm.com}
3469293Sandreas.hansson@arm.com
3479293Sandreas.hansson@arm.comDrainState
3489293Sandreas.hansson@arm.comDRAMSim2::drain()
3499293Sandreas.hansson@arm.com{
3509293Sandreas.hansson@arm.com    // check our outstanding reads and writes and if any they need to
3519293Sandreas.hansson@arm.com    // drain
3529293Sandreas.hansson@arm.com    return nbrOutstanding() != 0 ? DrainState::Draining : DrainState::Drained;
3539409Sandreas.hansson@arm.com}
3549409Sandreas.hansson@arm.com
3559293Sandreas.hansson@arm.comDRAMSim2::MemoryPort::MemoryPort(const std::string& _name,
3569293Sandreas.hansson@arm.com                                 DRAMSim2& _memory)
3579293Sandreas.hansson@arm.com    : SlavePort(_name, &_memory), memory(_memory)
3589293Sandreas.hansson@arm.com{ }
3599293Sandreas.hansson@arm.com
3609293Sandreas.hansson@arm.comAddrRangeList
3619293Sandreas.hansson@arm.comDRAMSim2::MemoryPort::getAddrRanges() const
3629293Sandreas.hansson@arm.com{
3639293Sandreas.hansson@arm.com    AddrRangeList ranges;
3649293Sandreas.hansson@arm.com    ranges.push_back(memory.getAddrRange());
3659293Sandreas.hansson@arm.com    return ranges;
3669293Sandreas.hansson@arm.com}
3679293Sandreas.hansson@arm.com
3689293Sandreas.hansson@arm.comTick
3699293Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvAtomic(PacketPtr pkt)
3709293Sandreas.hansson@arm.com{
3719293Sandreas.hansson@arm.com    return memory.recvAtomic(pkt);
3729293Sandreas.hansson@arm.com}
3739293Sandreas.hansson@arm.com
3749293Sandreas.hansson@arm.comvoid
3759293Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvFunctional(PacketPtr pkt)
3769293Sandreas.hansson@arm.com{
3779293Sandreas.hansson@arm.com    memory.recvFunctional(pkt);
3789293Sandreas.hansson@arm.com}
3799293Sandreas.hansson@arm.com
3809293Sandreas.hansson@arm.combool
3819293Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvTimingReq(PacketPtr pkt)
3829293Sandreas.hansson@arm.com{
3839293Sandreas.hansson@arm.com    // pass it to the memory controller
3849293Sandreas.hansson@arm.com    return memory.recvTimingReq(pkt);
3859293Sandreas.hansson@arm.com}
3869293Sandreas.hansson@arm.com
3879293Sandreas.hansson@arm.comvoid
3889293Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvRespRetry()
3899293Sandreas.hansson@arm.com{
3909293Sandreas.hansson@arm.com    memory.recvRespRetry();
3919293Sandreas.hansson@arm.com}
3929293Sandreas.hansson@arm.com
3939293Sandreas.hansson@arm.comDRAMSim2*
3949293Sandreas.hansson@arm.comDRAMSim2Params::create()
3959293Sandreas.hansson@arm.com{
3969293Sandreas.hansson@arm.com    return new DRAMSim2(this);
3979293Sandreas.hansson@arm.com}
3989293Sandreas.hansson@arm.com