dramsim2.cc revision 11190
110066Sandreas.hansson@arm.com/*
210066Sandreas.hansson@arm.com * Copyright (c) 2013 ARM Limited
310066Sandreas.hansson@arm.com * All rights reserved
410066Sandreas.hansson@arm.com *
510066Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
610066Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
710066Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
810066Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
910066Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
1010066Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
1110066Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
1210066Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
1310066Sandreas.hansson@arm.com *
1410066Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
1510066Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
1610066Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
1710066Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
1810066Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
1910066Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
2010066Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
2110066Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
2210066Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
2310066Sandreas.hansson@arm.com * this software without specific prior written permission.
2410066Sandreas.hansson@arm.com *
2510066Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610066Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710066Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810066Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910066Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010066Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110066Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210066Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310066Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410066Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510066Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610066Sandreas.hansson@arm.com *
3710066Sandreas.hansson@arm.com * Authors: Andreas Hansson
3810066Sandreas.hansson@arm.com */
3910066Sandreas.hansson@arm.com
4010066Sandreas.hansson@arm.com#include "DRAMSim2/Callback.h"
4110066Sandreas.hansson@arm.com#include "base/callback.hh"
4210066Sandreas.hansson@arm.com#include "base/trace.hh"
4310066Sandreas.hansson@arm.com#include "debug/DRAMSim2.hh"
4410066Sandreas.hansson@arm.com#include "debug/Drain.hh"
4510066Sandreas.hansson@arm.com#include "mem/dramsim2.hh"
4610066Sandreas.hansson@arm.com#include "sim/system.hh"
4710066Sandreas.hansson@arm.com
4810066Sandreas.hansson@arm.comDRAMSim2::DRAMSim2(const Params* p) :
4910066Sandreas.hansson@arm.com    AbstractMemory(p),
5010066Sandreas.hansson@arm.com    port(name() + ".port", *this),
5110066Sandreas.hansson@arm.com    wrapper(p->deviceConfigFile, p->systemConfigFile, p->filePath,
5210066Sandreas.hansson@arm.com            p->traceFile, p->range.size() / 1024 / 1024, p->enableDebug),
5310296Sandreas.hansson@arm.com    retryReq(false), retryResp(false), startTick(0),
5410066Sandreas.hansson@arm.com    nbrOutstandingReads(0), nbrOutstandingWrites(0),
5510066Sandreas.hansson@arm.com    sendResponseEvent(this), tickEvent(this)
5610066Sandreas.hansson@arm.com{
5710066Sandreas.hansson@arm.com    DPRINTF(DRAMSim2,
5810066Sandreas.hansson@arm.com            "Instantiated DRAMSim2 with clock %d ns and queue size %d\n",
5910066Sandreas.hansson@arm.com            wrapper.clockPeriod(), wrapper.queueSize());
6010066Sandreas.hansson@arm.com
6110066Sandreas.hansson@arm.com    DRAMSim::TransactionCompleteCB* read_cb =
6210066Sandreas.hansson@arm.com        new DRAMSim::Callback<DRAMSim2, void, unsigned, uint64_t, uint64_t>(
6310066Sandreas.hansson@arm.com            this, &DRAMSim2::readComplete);
6410066Sandreas.hansson@arm.com    DRAMSim::TransactionCompleteCB* write_cb =
6510066Sandreas.hansson@arm.com        new DRAMSim::Callback<DRAMSim2, void, unsigned, uint64_t, uint64_t>(
6610066Sandreas.hansson@arm.com            this, &DRAMSim2::writeComplete);
6710066Sandreas.hansson@arm.com    wrapper.setCallbacks(read_cb, write_cb);
6810066Sandreas.hansson@arm.com
6910066Sandreas.hansson@arm.com    // Register a callback to compensate for the destructor not
7010066Sandreas.hansson@arm.com    // being called. The callback prints the DRAMSim2 stats.
7110066Sandreas.hansson@arm.com    Callback* cb = new MakeCallback<DRAMSim2Wrapper,
7210066Sandreas.hansson@arm.com        &DRAMSim2Wrapper::printStats>(wrapper);
7310066Sandreas.hansson@arm.com    registerExitCallback(cb);
7410066Sandreas.hansson@arm.com}
7510066Sandreas.hansson@arm.com
7610066Sandreas.hansson@arm.comvoid
7710066Sandreas.hansson@arm.comDRAMSim2::init()
7810066Sandreas.hansson@arm.com{
7910466Sandreas.hansson@arm.com    AbstractMemory::init();
8010466Sandreas.hansson@arm.com
8110066Sandreas.hansson@arm.com    if (!port.isConnected()) {
8210066Sandreas.hansson@arm.com        fatal("DRAMSim2 %s is unconnected!\n", name());
8310066Sandreas.hansson@arm.com    } else {
8410066Sandreas.hansson@arm.com        port.sendRangeChange();
8510066Sandreas.hansson@arm.com    }
8610066Sandreas.hansson@arm.com
8710066Sandreas.hansson@arm.com    if (system()->cacheLineSize() != wrapper.burstSize())
8810066Sandreas.hansson@arm.com        fatal("DRAMSim2 burst size %d does not match cache line size %d\n",
8910066Sandreas.hansson@arm.com              wrapper.burstSize(), system()->cacheLineSize());
9010066Sandreas.hansson@arm.com}
9110066Sandreas.hansson@arm.com
9210066Sandreas.hansson@arm.comvoid
9310066Sandreas.hansson@arm.comDRAMSim2::startup()
9410066Sandreas.hansson@arm.com{
9510296Sandreas.hansson@arm.com    startTick = curTick();
9610296Sandreas.hansson@arm.com
9710066Sandreas.hansson@arm.com    // kick off the clock ticks
9810066Sandreas.hansson@arm.com    schedule(tickEvent, clockEdge());
9910066Sandreas.hansson@arm.com}
10010066Sandreas.hansson@arm.com
10110066Sandreas.hansson@arm.comvoid
10210066Sandreas.hansson@arm.comDRAMSim2::sendResponse()
10310066Sandreas.hansson@arm.com{
10410066Sandreas.hansson@arm.com    assert(!retryResp);
10510066Sandreas.hansson@arm.com    assert(!responseQueue.empty());
10610066Sandreas.hansson@arm.com
10710066Sandreas.hansson@arm.com    DPRINTF(DRAMSim2, "Attempting to send response\n");
10810066Sandreas.hansson@arm.com
10910066Sandreas.hansson@arm.com    bool success = port.sendTimingResp(responseQueue.front());
11010066Sandreas.hansson@arm.com    if (success) {
11110066Sandreas.hansson@arm.com        responseQueue.pop_front();
11210066Sandreas.hansson@arm.com
11310066Sandreas.hansson@arm.com        DPRINTF(DRAMSim2, "Have %d read, %d write, %d responses outstanding\n",
11410066Sandreas.hansson@arm.com                nbrOutstandingReads, nbrOutstandingWrites,
11510066Sandreas.hansson@arm.com                responseQueue.size());
11610066Sandreas.hansson@arm.com
11710066Sandreas.hansson@arm.com        if (!responseQueue.empty() && !sendResponseEvent.scheduled())
11810066Sandreas.hansson@arm.com            schedule(sendResponseEvent, curTick());
11910066Sandreas.hansson@arm.com
12010913Sandreas.sandberg@arm.com        if (nbrOutstanding() == 0)
12110913Sandreas.sandberg@arm.com            signalDrainDone();
12210066Sandreas.hansson@arm.com    } else {
12310066Sandreas.hansson@arm.com        retryResp = true;
12410066Sandreas.hansson@arm.com
12510066Sandreas.hansson@arm.com        DPRINTF(DRAMSim2, "Waiting for response retry\n");
12610066Sandreas.hansson@arm.com
12710066Sandreas.hansson@arm.com        assert(!sendResponseEvent.scheduled());
12810066Sandreas.hansson@arm.com    }
12910066Sandreas.hansson@arm.com}
13010066Sandreas.hansson@arm.com
13110066Sandreas.hansson@arm.comunsigned int
13210066Sandreas.hansson@arm.comDRAMSim2::nbrOutstanding() const
13310066Sandreas.hansson@arm.com{
13410066Sandreas.hansson@arm.com    return nbrOutstandingReads + nbrOutstandingWrites + responseQueue.size();
13510066Sandreas.hansson@arm.com}
13610066Sandreas.hansson@arm.com
13710066Sandreas.hansson@arm.comvoid
13810066Sandreas.hansson@arm.comDRAMSim2::tick()
13910066Sandreas.hansson@arm.com{
14010066Sandreas.hansson@arm.com    wrapper.tick();
14110066Sandreas.hansson@arm.com
14210066Sandreas.hansson@arm.com    // is the connected port waiting for a retry, if so check the
14310066Sandreas.hansson@arm.com    // state and send a retry if conditions have changed
14410066Sandreas.hansson@arm.com    if (retryReq && nbrOutstanding() < wrapper.queueSize()) {
14510066Sandreas.hansson@arm.com        retryReq = false;
14610713Sandreas.hansson@arm.com        port.sendRetryReq();
14710066Sandreas.hansson@arm.com    }
14810066Sandreas.hansson@arm.com
14910066Sandreas.hansson@arm.com    schedule(tickEvent, curTick() + wrapper.clockPeriod() * SimClock::Int::ns);
15010066Sandreas.hansson@arm.com}
15110066Sandreas.hansson@arm.com
15210066Sandreas.hansson@arm.comTick
15310066Sandreas.hansson@arm.comDRAMSim2::recvAtomic(PacketPtr pkt)
15410066Sandreas.hansson@arm.com{
15510066Sandreas.hansson@arm.com    access(pkt);
15610066Sandreas.hansson@arm.com
15710066Sandreas.hansson@arm.com    // 50 ns is just an arbitrary value at this point
15810066Sandreas.hansson@arm.com    return pkt->memInhibitAsserted() ? 0 : 50000;
15910066Sandreas.hansson@arm.com}
16010066Sandreas.hansson@arm.com
16110066Sandreas.hansson@arm.comvoid
16210066Sandreas.hansson@arm.comDRAMSim2::recvFunctional(PacketPtr pkt)
16310066Sandreas.hansson@arm.com{
16410066Sandreas.hansson@arm.com    pkt->pushLabel(name());
16510066Sandreas.hansson@arm.com
16610066Sandreas.hansson@arm.com    functionalAccess(pkt);
16710066Sandreas.hansson@arm.com
16810066Sandreas.hansson@arm.com    // potentially update the packets in our response queue as well
16910066Sandreas.hansson@arm.com    for (auto i = responseQueue.begin(); i != responseQueue.end(); ++i)
17010066Sandreas.hansson@arm.com        pkt->checkFunctional(*i);
17110066Sandreas.hansson@arm.com
17210066Sandreas.hansson@arm.com    pkt->popLabel();
17310066Sandreas.hansson@arm.com}
17410066Sandreas.hansson@arm.com
17510066Sandreas.hansson@arm.combool
17610066Sandreas.hansson@arm.comDRAMSim2::recvTimingReq(PacketPtr pkt)
17710066Sandreas.hansson@arm.com{
17810066Sandreas.hansson@arm.com    // we should never see a new request while in retry
17910066Sandreas.hansson@arm.com    assert(!retryReq);
18010066Sandreas.hansson@arm.com
18110066Sandreas.hansson@arm.com    if (pkt->memInhibitAsserted()) {
18210066Sandreas.hansson@arm.com        // snooper will supply based on copy of packet
18310066Sandreas.hansson@arm.com        // still target's responsibility to delete packet
18411190Sandreas.hansson@arm.com        pendingDelete.reset(pkt);
18510066Sandreas.hansson@arm.com        return true;
18610066Sandreas.hansson@arm.com    }
18710066Sandreas.hansson@arm.com
18810066Sandreas.hansson@arm.com    // if we cannot accept we need to send a retry once progress can
18910066Sandreas.hansson@arm.com    // be made
19010066Sandreas.hansson@arm.com    bool can_accept = nbrOutstanding() < wrapper.queueSize();
19110066Sandreas.hansson@arm.com
19210066Sandreas.hansson@arm.com    // keep track of the transaction
19310066Sandreas.hansson@arm.com    if (pkt->isRead()) {
19410066Sandreas.hansson@arm.com        if (can_accept) {
19510066Sandreas.hansson@arm.com            outstandingReads[pkt->getAddr()].push(pkt);
19610066Sandreas.hansson@arm.com
19710066Sandreas.hansson@arm.com            // we count a transaction as outstanding until it has left the
19810066Sandreas.hansson@arm.com            // queue in the controller, and the response has been sent
19910066Sandreas.hansson@arm.com            // back, note that this will differ for reads and writes
20010066Sandreas.hansson@arm.com            ++nbrOutstandingReads;
20110066Sandreas.hansson@arm.com        }
20210066Sandreas.hansson@arm.com    } else if (pkt->isWrite()) {
20310066Sandreas.hansson@arm.com        if (can_accept) {
20410066Sandreas.hansson@arm.com            outstandingWrites[pkt->getAddr()].push(pkt);
20510066Sandreas.hansson@arm.com
20610066Sandreas.hansson@arm.com            ++nbrOutstandingWrites;
20710066Sandreas.hansson@arm.com
20810066Sandreas.hansson@arm.com            // perform the access for writes
20910066Sandreas.hansson@arm.com            accessAndRespond(pkt);
21010066Sandreas.hansson@arm.com        }
21110066Sandreas.hansson@arm.com    } else {
21210066Sandreas.hansson@arm.com        // keep it simple and just respond if necessary
21310066Sandreas.hansson@arm.com        accessAndRespond(pkt);
21410066Sandreas.hansson@arm.com        return true;
21510066Sandreas.hansson@arm.com    }
21610066Sandreas.hansson@arm.com
21710066Sandreas.hansson@arm.com    if (can_accept) {
21810066Sandreas.hansson@arm.com        // we should never have a situation when we think there is space,
21910066Sandreas.hansson@arm.com        // and there isn't
22010066Sandreas.hansson@arm.com        assert(wrapper.canAccept());
22110066Sandreas.hansson@arm.com
22210066Sandreas.hansson@arm.com        DPRINTF(DRAMSim2, "Enqueueing address %lld\n", pkt->getAddr());
22310066Sandreas.hansson@arm.com
22410066Sandreas.hansson@arm.com        // @todo what about the granularity here, implicit assumption that
22510066Sandreas.hansson@arm.com        // a transaction matches the burst size of the memory (which we
22610066Sandreas.hansson@arm.com        // cannot determine without parsing the ini file ourselves)
22710066Sandreas.hansson@arm.com        wrapper.enqueue(pkt->isWrite(), pkt->getAddr());
22810066Sandreas.hansson@arm.com
22910066Sandreas.hansson@arm.com        return true;
23010066Sandreas.hansson@arm.com    } else {
23110066Sandreas.hansson@arm.com        retryReq = true;
23210066Sandreas.hansson@arm.com        return false;
23310066Sandreas.hansson@arm.com    }
23410066Sandreas.hansson@arm.com}
23510066Sandreas.hansson@arm.com
23610066Sandreas.hansson@arm.comvoid
23710713Sandreas.hansson@arm.comDRAMSim2::recvRespRetry()
23810066Sandreas.hansson@arm.com{
23910066Sandreas.hansson@arm.com    DPRINTF(DRAMSim2, "Retrying\n");
24010066Sandreas.hansson@arm.com
24110066Sandreas.hansson@arm.com    assert(retryResp);
24210066Sandreas.hansson@arm.com    retryResp = false;
24310066Sandreas.hansson@arm.com    sendResponse();
24410066Sandreas.hansson@arm.com}
24510066Sandreas.hansson@arm.com
24610066Sandreas.hansson@arm.comvoid
24710066Sandreas.hansson@arm.comDRAMSim2::accessAndRespond(PacketPtr pkt)
24810066Sandreas.hansson@arm.com{
24910066Sandreas.hansson@arm.com    DPRINTF(DRAMSim2, "Access for address %lld\n", pkt->getAddr());
25010066Sandreas.hansson@arm.com
25110066Sandreas.hansson@arm.com    bool needsResponse = pkt->needsResponse();
25210066Sandreas.hansson@arm.com
25310066Sandreas.hansson@arm.com    // do the actual memory access which also turns the packet into a
25410066Sandreas.hansson@arm.com    // response
25510066Sandreas.hansson@arm.com    access(pkt);
25610066Sandreas.hansson@arm.com
25710066Sandreas.hansson@arm.com    // turn packet around to go back to requester if response expected
25810066Sandreas.hansson@arm.com    if (needsResponse) {
25910066Sandreas.hansson@arm.com        // access already turned the packet into a response
26010066Sandreas.hansson@arm.com        assert(pkt->isResponse());
26110721SMarco.Balboni@ARM.com        // Here we pay for xbar additional delay and to process the payload
26210721SMarco.Balboni@ARM.com        // of the packet.
26310721SMarco.Balboni@ARM.com        Tick time = curTick() + pkt->headerDelay + pkt->payloadDelay;
26410721SMarco.Balboni@ARM.com        // Reset the timings of the packet
26510694SMarco.Balboni@ARM.com        pkt->headerDelay = pkt->payloadDelay = 0;
26610066Sandreas.hansson@arm.com
26710066Sandreas.hansson@arm.com        DPRINTF(DRAMSim2, "Queuing response for address %lld\n",
26810066Sandreas.hansson@arm.com                pkt->getAddr());
26910066Sandreas.hansson@arm.com
27010066Sandreas.hansson@arm.com        // queue it to be sent back
27110066Sandreas.hansson@arm.com        responseQueue.push_back(pkt);
27210066Sandreas.hansson@arm.com
27310066Sandreas.hansson@arm.com        // if we are not already waiting for a retry, or are scheduled
27410066Sandreas.hansson@arm.com        // to send a response, schedule an event
27510066Sandreas.hansson@arm.com        if (!retryResp && !sendResponseEvent.scheduled())
27610721SMarco.Balboni@ARM.com            schedule(sendResponseEvent, time);
27710066Sandreas.hansson@arm.com    } else {
27811190Sandreas.hansson@arm.com        // queue the packet for deletion
27911190Sandreas.hansson@arm.com        pendingDelete.reset(pkt);
28010066Sandreas.hansson@arm.com    }
28110066Sandreas.hansson@arm.com}
28210066Sandreas.hansson@arm.com
28310066Sandreas.hansson@arm.comvoid DRAMSim2::readComplete(unsigned id, uint64_t addr, uint64_t cycle)
28410066Sandreas.hansson@arm.com{
28510296Sandreas.hansson@arm.com    assert(cycle == divCeil(curTick() - startTick,
28610066Sandreas.hansson@arm.com                            wrapper.clockPeriod() * SimClock::Int::ns));
28710066Sandreas.hansson@arm.com
28810066Sandreas.hansson@arm.com    DPRINTF(DRAMSim2, "Read to address %lld complete\n", addr);
28910066Sandreas.hansson@arm.com
29010066Sandreas.hansson@arm.com    // get the outstanding reads for the address in question
29110066Sandreas.hansson@arm.com    auto p = outstandingReads.find(addr);
29210066Sandreas.hansson@arm.com    assert(p != outstandingReads.end());
29310066Sandreas.hansson@arm.com
29410066Sandreas.hansson@arm.com    // first in first out, which is not necessarily true, but it is
29510066Sandreas.hansson@arm.com    // the best we can do at this point
29610066Sandreas.hansson@arm.com    PacketPtr pkt = p->second.front();
29710066Sandreas.hansson@arm.com    p->second.pop();
29810066Sandreas.hansson@arm.com
29910066Sandreas.hansson@arm.com    if (p->second.empty())
30010066Sandreas.hansson@arm.com        outstandingReads.erase(p);
30110066Sandreas.hansson@arm.com
30210066Sandreas.hansson@arm.com    // no need to check for drain here as the next call will add a
30310066Sandreas.hansson@arm.com    // response to the response queue straight away
30410066Sandreas.hansson@arm.com    assert(nbrOutstandingReads != 0);
30510066Sandreas.hansson@arm.com    --nbrOutstandingReads;
30610066Sandreas.hansson@arm.com
30710066Sandreas.hansson@arm.com    // perform the actual memory access
30810066Sandreas.hansson@arm.com    accessAndRespond(pkt);
30910066Sandreas.hansson@arm.com}
31010066Sandreas.hansson@arm.com
31110066Sandreas.hansson@arm.comvoid DRAMSim2::writeComplete(unsigned id, uint64_t addr, uint64_t cycle)
31210066Sandreas.hansson@arm.com{
31310296Sandreas.hansson@arm.com    assert(cycle == divCeil(curTick() - startTick,
31410066Sandreas.hansson@arm.com                            wrapper.clockPeriod() * SimClock::Int::ns));
31510066Sandreas.hansson@arm.com
31610066Sandreas.hansson@arm.com    DPRINTF(DRAMSim2, "Write to address %lld complete\n", addr);
31710066Sandreas.hansson@arm.com
31810066Sandreas.hansson@arm.com    // get the outstanding reads for the address in question
31910066Sandreas.hansson@arm.com    auto p = outstandingWrites.find(addr);
32010066Sandreas.hansson@arm.com    assert(p != outstandingWrites.end());
32110066Sandreas.hansson@arm.com
32210066Sandreas.hansson@arm.com    // we have already responded, and this is only to keep track of
32310066Sandreas.hansson@arm.com    // what is outstanding
32410066Sandreas.hansson@arm.com    p->second.pop();
32510066Sandreas.hansson@arm.com    if (p->second.empty())
32610066Sandreas.hansson@arm.com        outstandingWrites.erase(p);
32710066Sandreas.hansson@arm.com
32810066Sandreas.hansson@arm.com    assert(nbrOutstandingWrites != 0);
32910066Sandreas.hansson@arm.com    --nbrOutstandingWrites;
33010066Sandreas.hansson@arm.com
33110913Sandreas.sandberg@arm.com    if (nbrOutstanding() == 0)
33210913Sandreas.sandberg@arm.com        signalDrainDone();
33310066Sandreas.hansson@arm.com}
33410066Sandreas.hansson@arm.com
33510066Sandreas.hansson@arm.comBaseSlavePort&
33610066Sandreas.hansson@arm.comDRAMSim2::getSlavePort(const std::string &if_name, PortID idx)
33710066Sandreas.hansson@arm.com{
33810066Sandreas.hansson@arm.com    if (if_name != "port") {
33910066Sandreas.hansson@arm.com        return MemObject::getSlavePort(if_name, idx);
34010066Sandreas.hansson@arm.com    } else {
34110066Sandreas.hansson@arm.com        return port;
34210066Sandreas.hansson@arm.com    }
34310066Sandreas.hansson@arm.com}
34410066Sandreas.hansson@arm.com
34510921Sandreas.hansson@arm.comDrainState
34610913Sandreas.sandberg@arm.comDRAMSim2::drain()
34710066Sandreas.hansson@arm.com{
34810066Sandreas.hansson@arm.com    // check our outstanding reads and writes and if any they need to
34910066Sandreas.hansson@arm.com    // drain
35010913Sandreas.sandberg@arm.com    return nbrOutstanding() != 0 ? DrainState::Draining : DrainState::Drained;
35110066Sandreas.hansson@arm.com}
35210066Sandreas.hansson@arm.com
35310066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::MemoryPort(const std::string& _name,
35410066Sandreas.hansson@arm.com                                 DRAMSim2& _memory)
35510066Sandreas.hansson@arm.com    : SlavePort(_name, &_memory), memory(_memory)
35610066Sandreas.hansson@arm.com{ }
35710066Sandreas.hansson@arm.com
35810066Sandreas.hansson@arm.comAddrRangeList
35910066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::getAddrRanges() const
36010066Sandreas.hansson@arm.com{
36110066Sandreas.hansson@arm.com    AddrRangeList ranges;
36210066Sandreas.hansson@arm.com    ranges.push_back(memory.getAddrRange());
36310066Sandreas.hansson@arm.com    return ranges;
36410066Sandreas.hansson@arm.com}
36510066Sandreas.hansson@arm.com
36610066Sandreas.hansson@arm.comTick
36710066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvAtomic(PacketPtr pkt)
36810066Sandreas.hansson@arm.com{
36910066Sandreas.hansson@arm.com    return memory.recvAtomic(pkt);
37010066Sandreas.hansson@arm.com}
37110066Sandreas.hansson@arm.com
37210066Sandreas.hansson@arm.comvoid
37310066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvFunctional(PacketPtr pkt)
37410066Sandreas.hansson@arm.com{
37510066Sandreas.hansson@arm.com    memory.recvFunctional(pkt);
37610066Sandreas.hansson@arm.com}
37710066Sandreas.hansson@arm.com
37810066Sandreas.hansson@arm.combool
37910066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvTimingReq(PacketPtr pkt)
38010066Sandreas.hansson@arm.com{
38110066Sandreas.hansson@arm.com    // pass it to the memory controller
38210066Sandreas.hansson@arm.com    return memory.recvTimingReq(pkt);
38310066Sandreas.hansson@arm.com}
38410066Sandreas.hansson@arm.com
38510066Sandreas.hansson@arm.comvoid
38610713Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvRespRetry()
38710066Sandreas.hansson@arm.com{
38810713Sandreas.hansson@arm.com    memory.recvRespRetry();
38910066Sandreas.hansson@arm.com}
39010066Sandreas.hansson@arm.com
39110066Sandreas.hansson@arm.comDRAMSim2*
39210066Sandreas.hansson@arm.comDRAMSim2Params::create()
39310066Sandreas.hansson@arm.com{
39410066Sandreas.hansson@arm.com    return new DRAMSim2(this);
39510066Sandreas.hansson@arm.com}
396