dramsim2.cc revision 10405:7a618c07e663
12817Sksewell@umich.edu/*
27763SAli.Saidi@ARM.com * Copyright (c) 2013 ARM Limited
37763SAli.Saidi@ARM.com * All rights reserved
47763SAli.Saidi@ARM.com *
57763SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall
67763SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual
77763SAli.Saidi@ARM.com * property including but not limited to intellectual property relating
87763SAli.Saidi@ARM.com * to a hardware implementation of the functionality of the software
97763SAli.Saidi@ARM.com * licensed hereunder.  You may use the software subject to the license
107763SAli.Saidi@ARM.com * terms below provided that you ensure that this notice is replicated
117763SAli.Saidi@ARM.com * unmodified and in its entirety in all distributions of the software,
127763SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form.
137763SAli.Saidi@ARM.com *
142817Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without
152817Sksewell@umich.edu * modification, are permitted provided that the following conditions are
162817Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
172817Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
182817Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
192817Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
202817Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
212817Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
222817Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
232817Sksewell@umich.edu * this software without specific prior written permission.
242817Sksewell@umich.edu *
252817Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262817Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272817Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282817Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292817Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302817Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312817Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322817Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332817Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342817Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352817Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362817Sksewell@umich.edu *
372817Sksewell@umich.edu * Authors: Andreas Hansson
382817Sksewell@umich.edu */
392817Sksewell@umich.edu
402817Sksewell@umich.edu#include "DRAMSim2/Callback.h"
412817Sksewell@umich.edu#include "base/callback.hh"
422817Sksewell@umich.edu#include "base/trace.hh"
432817Sksewell@umich.edu#include "debug/DRAMSim2.hh"
446329Sgblack@eecs.umich.edu#include "debug/Drain.hh"
456658Snate@binkert.org#include "mem/dramsim2.hh"
462817Sksewell@umich.edu#include "sim/system.hh"
472834Sksewell@umich.edu
482817Sksewell@umich.eduDRAMSim2::DRAMSim2(const Params* p) :
492817Sksewell@umich.edu    AbstractMemory(p),
502817Sksewell@umich.edu    port(name() + ".port", *this),
512817Sksewell@umich.edu    wrapper(p->deviceConfigFile, p->systemConfigFile, p->filePath,
525499Ssaidi@eecs.umich.edu            p->traceFile, p->range.size() / 1024 / 1024, p->enableDebug),
532817Sksewell@umich.edu    retryReq(false), retryResp(false), startTick(0),
545499Ssaidi@eecs.umich.edu    nbrOutstandingReads(0), nbrOutstandingWrites(0),
552817Sksewell@umich.edu    drainManager(NULL),
562817Sksewell@umich.edu    sendResponseEvent(this), tickEvent(this)
572817Sksewell@umich.edu{
582817Sksewell@umich.edu    DPRINTF(DRAMSim2,
592817Sksewell@umich.edu            "Instantiated DRAMSim2 with clock %d ns and queue size %d\n",
602817Sksewell@umich.edu            wrapper.clockPeriod(), wrapper.queueSize());
613126Sktlim@umich.edu
622817Sksewell@umich.edu    DRAMSim::TransactionCompleteCB* read_cb =
632817Sksewell@umich.edu        new DRAMSim::Callback<DRAMSim2, void, unsigned, uint64_t, uint64_t>(
642817Sksewell@umich.edu            this, &DRAMSim2::readComplete);
652817Sksewell@umich.edu    DRAMSim::TransactionCompleteCB* write_cb =
662817Sksewell@umich.edu        new DRAMSim::Callback<DRAMSim2, void, unsigned, uint64_t, uint64_t>(
672817Sksewell@umich.edu            this, &DRAMSim2::writeComplete);
682817Sksewell@umich.edu    wrapper.setCallbacks(read_cb, write_cb);
692817Sksewell@umich.edu
707467Stjones1@inf.ed.ac.uk    // Register a callback to compensate for the destructor not
712817Sksewell@umich.edu    // being called. The callback prints the DRAMSim2 stats.
727467Stjones1@inf.ed.ac.uk    Callback* cb = new MakeCallback<DRAMSim2Wrapper,
732817Sksewell@umich.edu        &DRAMSim2Wrapper::printStats>(wrapper);
742817Sksewell@umich.edu    registerExitCallback(cb);
752817Sksewell@umich.edu}
762817Sksewell@umich.edu
772817Sksewell@umich.eduvoid
782817Sksewell@umich.eduDRAMSim2::init()
795714Shsul@eecs.umich.edu{
805715Shsul@eecs.umich.edu    if (!port.isConnected()) {
812817Sksewell@umich.edu        fatal("DRAMSim2 %s is unconnected!\n", name());
822817Sksewell@umich.edu    } else {
832817Sksewell@umich.edu        port.sendRangeChange();
842817Sksewell@umich.edu    }
852817Sksewell@umich.edu
862817Sksewell@umich.edu    if (system()->cacheLineSize() != wrapper.burstSize())
872817Sksewell@umich.edu        fatal("DRAMSim2 burst size %d does not match cache line size %d\n",
882817Sksewell@umich.edu              wrapper.burstSize(), system()->cacheLineSize());
892817Sksewell@umich.edu}
902817Sksewell@umich.edu
912817Sksewell@umich.eduvoid
922817Sksewell@umich.eduDRAMSim2::startup()
932817Sksewell@umich.edu{
942817Sksewell@umich.edu    startTick = curTick();
952817Sksewell@umich.edu
962817Sksewell@umich.edu    // kick off the clock ticks
972817Sksewell@umich.edu    schedule(tickEvent, clockEdge());
982817Sksewell@umich.edu}
992817Sksewell@umich.edu
1002817Sksewell@umich.eduvoid
1016029Ssteve.reinhardt@amd.comDRAMSim2::sendResponse()
1022817Sksewell@umich.edu{
1032817Sksewell@umich.edu    assert(!retryResp);
1042817Sksewell@umich.edu    assert(!responseQueue.empty());
1052817Sksewell@umich.edu
1062817Sksewell@umich.edu    DPRINTF(DRAMSim2, "Attempting to send response\n");
1072817Sksewell@umich.edu
1082817Sksewell@umich.edu    bool success = port.sendTimingResp(responseQueue.front());
1092817Sksewell@umich.edu    if (success) {
1102817Sksewell@umich.edu        responseQueue.pop_front();
1112875Sksewell@umich.edu
1125715Shsul@eecs.umich.edu        DPRINTF(DRAMSim2, "Have %d read, %d write, %d responses outstanding\n",
1132817Sksewell@umich.edu                nbrOutstandingReads, nbrOutstandingWrites,
1142817Sksewell@umich.edu                responseQueue.size());
1152817Sksewell@umich.edu
1162817Sksewell@umich.edu        if (!responseQueue.empty() && !sendResponseEvent.scheduled())
1172817Sksewell@umich.edu            schedule(sendResponseEvent, curTick());
1182817Sksewell@umich.edu
1192817Sksewell@umich.edu        // check if we were asked to drain and if we are now done
1202817Sksewell@umich.edu        if (drainManager && nbrOutstanding() == 0) {
1212817Sksewell@umich.edu            drainManager->signalDrainDone();
1222817Sksewell@umich.edu            drainManager = NULL;
1232817Sksewell@umich.edu        }
1245715Shsul@eecs.umich.edu    } else {
1252817Sksewell@umich.edu        retryResp = true;
1262817Sksewell@umich.edu
1272817Sksewell@umich.edu        DPRINTF(DRAMSim2, "Waiting for response retry\n");
1282817Sksewell@umich.edu
1295250Sksewell@umich.edu        assert(!sendResponseEvent.scheduled());
1302817Sksewell@umich.edu    }
1312875Sksewell@umich.edu}
1325715Shsul@eecs.umich.edu
1332817Sksewell@umich.eduunsigned int
1342817Sksewell@umich.eduDRAMSim2::nbrOutstanding() const
1352817Sksewell@umich.edu{
1362817Sksewell@umich.edu    return nbrOutstandingReads + nbrOutstandingWrites + responseQueue.size();
1372817Sksewell@umich.edu}
1382817Sksewell@umich.edu
1392817Sksewell@umich.eduvoid
1402817Sksewell@umich.eduDRAMSim2::tick()
1412817Sksewell@umich.edu{
1422817Sksewell@umich.edu    wrapper.tick();
1432817Sksewell@umich.edu
1445704Snate@binkert.org    // is the connected port waiting for a retry, if so check the
1452817Sksewell@umich.edu    // state and send a retry if conditions have changed
1462817Sksewell@umich.edu    if (retryReq && nbrOutstanding() < wrapper.queueSize()) {
1472817Sksewell@umich.edu        retryReq = false;
1482817Sksewell@umich.edu        port.sendRetry();
1492817Sksewell@umich.edu    }
1502817Sksewell@umich.edu
1515715Shsul@eecs.umich.edu    schedule(tickEvent, curTick() + wrapper.clockPeriod() * SimClock::Int::ns);
1522817Sksewell@umich.edu}
1532817Sksewell@umich.edu
1542817Sksewell@umich.eduTick
1552817Sksewell@umich.eduDRAMSim2::recvAtomic(PacketPtr pkt)
1565250Sksewell@umich.edu{
1572817Sksewell@umich.edu    access(pkt);
1582875Sksewell@umich.edu
1595715Shsul@eecs.umich.edu    // 50 ns is just an arbitrary value at this point
1602817Sksewell@umich.edu    return pkt->memInhibitAsserted() ? 0 : 50000;
1612817Sksewell@umich.edu}
1622817Sksewell@umich.edu
1632817Sksewell@umich.eduvoid
1642817Sksewell@umich.eduDRAMSim2::recvFunctional(PacketPtr pkt)
1655715Shsul@eecs.umich.edu{
1662817Sksewell@umich.edu    pkt->pushLabel(name());
1672817Sksewell@umich.edu
1682817Sksewell@umich.edu    functionalAccess(pkt);
1692817Sksewell@umich.edu
1702817Sksewell@umich.edu    // potentially update the packets in our response queue as well
1712817Sksewell@umich.edu    for (auto i = responseQueue.begin(); i != responseQueue.end(); ++i)
1722817Sksewell@umich.edu        pkt->checkFunctional(*i);
1733548Sgblack@eecs.umich.edu
1742817Sksewell@umich.edu    pkt->popLabel();
1752817Sksewell@umich.edu}
1762817Sksewell@umich.edu
1772817Sksewell@umich.edubool
1782817Sksewell@umich.eduDRAMSim2::recvTimingReq(PacketPtr pkt)
1792817Sksewell@umich.edu{
1802817Sksewell@umich.edu    // we should never see a new request while in retry
1812817Sksewell@umich.edu    assert(!retryReq);
1822817Sksewell@umich.edu
1832817Sksewell@umich.edu    // @todo temporary hack to deal with memory corruption issues until
1842817Sksewell@umich.edu    // 4-phase transactions are complete
1852817Sksewell@umich.edu    for (int x = 0; x < pendingDelete.size(); x++)
1862817Sksewell@umich.edu        delete pendingDelete[x];
1872817Sksewell@umich.edu    pendingDelete.clear();
1882817Sksewell@umich.edu
1892817Sksewell@umich.edu    if (pkt->memInhibitAsserted()) {
1902817Sksewell@umich.edu        // snooper will supply based on copy of packet
1912817Sksewell@umich.edu        // still target's responsibility to delete packet
1922817Sksewell@umich.edu        pendingDelete.push_back(pkt);
1932817Sksewell@umich.edu        return true;
1942817Sksewell@umich.edu    }
1952817Sksewell@umich.edu
1962817Sksewell@umich.edu    // if we cannot accept we need to send a retry once progress can
1972817Sksewell@umich.edu    // be made
1982817Sksewell@umich.edu    bool can_accept = nbrOutstanding() < wrapper.queueSize();
1992817Sksewell@umich.edu
2002817Sksewell@umich.edu    // keep track of the transaction
2012817Sksewell@umich.edu    if (pkt->isRead()) {
2022817Sksewell@umich.edu        if (can_accept) {
2032817Sksewell@umich.edu            outstandingReads[pkt->getAddr()].push(pkt);
2042817Sksewell@umich.edu
2052817Sksewell@umich.edu            // we count a transaction as outstanding until it has left the
2062817Sksewell@umich.edu            // queue in the controller, and the response has been sent
2072817Sksewell@umich.edu            // back, note that this will differ for reads and writes
2082817Sksewell@umich.edu            ++nbrOutstandingReads;
2092817Sksewell@umich.edu        }
2102817Sksewell@umich.edu    } else if (pkt->isWrite()) {
2112817Sksewell@umich.edu        if (can_accept) {
2122817Sksewell@umich.edu            outstandingWrites[pkt->getAddr()].push(pkt);
2132817Sksewell@umich.edu
2142817Sksewell@umich.edu            ++nbrOutstandingWrites;
2152817Sksewell@umich.edu
2162817Sksewell@umich.edu            // perform the access for writes
2172817Sksewell@umich.edu            accessAndRespond(pkt);
2183126Sktlim@umich.edu        }
2193126Sktlim@umich.edu    } else {
2203126Sktlim@umich.edu        // keep it simple and just respond if necessary
2212817Sksewell@umich.edu        accessAndRespond(pkt);
2222817Sksewell@umich.edu        return true;
2232817Sksewell@umich.edu    }
2242817Sksewell@umich.edu
2253126Sktlim@umich.edu    if (can_accept) {
2263126Sktlim@umich.edu        // we should never have a situation when we think there is space,
2273126Sktlim@umich.edu        // and there isn't
2282817Sksewell@umich.edu        assert(wrapper.canAccept());
2292817Sksewell@umich.edu
2302817Sksewell@umich.edu        DPRINTF(DRAMSim2, "Enqueueing address %lld\n", pkt->getAddr());
2312817Sksewell@umich.edu
2322817Sksewell@umich.edu        // @todo what about the granularity here, implicit assumption that
2332817Sksewell@umich.edu        // a transaction matches the burst size of the memory (which we
2342817Sksewell@umich.edu        // cannot determine without parsing the ini file ourselves)
2352817Sksewell@umich.edu        wrapper.enqueue(pkt->isWrite(), pkt->getAddr());
2366221Snate@binkert.org
2372817Sksewell@umich.edu        return true;
2382817Sksewell@umich.edu    } else {
2392817Sksewell@umich.edu        retryReq = true;
2402817Sksewell@umich.edu        return false;
2412817Sksewell@umich.edu    }
2422817Sksewell@umich.edu}
2432817Sksewell@umich.edu
2442817Sksewell@umich.eduvoid
2452817Sksewell@umich.eduDRAMSim2::recvRetry()
2462817Sksewell@umich.edu{
2472817Sksewell@umich.edu    DPRINTF(DRAMSim2, "Retrying\n");
2482817Sksewell@umich.edu
2492817Sksewell@umich.edu    assert(retryResp);
2502817Sksewell@umich.edu    retryResp = false;
2512817Sksewell@umich.edu    sendResponse();
2522817Sksewell@umich.edu}
2532817Sksewell@umich.edu
2542817Sksewell@umich.eduvoid
2552817Sksewell@umich.eduDRAMSim2::accessAndRespond(PacketPtr pkt)
2562817Sksewell@umich.edu{
2572817Sksewell@umich.edu    DPRINTF(DRAMSim2, "Access for address %lld\n", pkt->getAddr());
2582817Sksewell@umich.edu
2592986Sgblack@eecs.umich.edu    bool needsResponse = pkt->needsResponse();
2602817Sksewell@umich.edu
2615258Sksewell@umich.edu    // do the actual memory access which also turns the packet into a
2625258Sksewell@umich.edu    // response
2637720Sgblack@eecs.umich.edu    access(pkt);
2642817Sksewell@umich.edu
2652817Sksewell@umich.edu    // turn packet around to go back to requester if response expected
2662817Sksewell@umich.edu    if (needsResponse) {
2672817Sksewell@umich.edu        // access already turned the packet into a response
2682817Sksewell@umich.edu        assert(pkt->isResponse());
2692817Sksewell@umich.edu
2702817Sksewell@umich.edu        // @todo someone should pay for this
2712817Sksewell@umich.edu        pkt->firstWordDelay = pkt->lastWordDelay = 0;
2727763SAli.Saidi@ARM.com
2737763SAli.Saidi@ARM.com        DPRINTF(DRAMSim2, "Queuing response for address %lld\n",
2747763SAli.Saidi@ARM.com                pkt->getAddr());
2752817Sksewell@umich.edu
2762817Sksewell@umich.edu        // queue it to be sent back
2772817Sksewell@umich.edu        responseQueue.push_back(pkt);
2782817Sksewell@umich.edu
2792817Sksewell@umich.edu        // if we are not already waiting for a retry, or are scheduled
2806313Sgblack@eecs.umich.edu        // to send a response, schedule an event
2815715Shsul@eecs.umich.edu        if (!retryResp && !sendResponseEvent.scheduled())
2822817Sksewell@umich.edu            schedule(sendResponseEvent, curTick());
2832817Sksewell@umich.edu    } else {
2842817Sksewell@umich.edu        // @todo the packet is going to be deleted, and the DRAMPacket
2852986Sgblack@eecs.umich.edu        // is still having a pointer to it
2862817Sksewell@umich.edu        pendingDelete.push_back(pkt);
2872817Sksewell@umich.edu    }
2886313Sgblack@eecs.umich.edu}
2896314Sgblack@eecs.umich.edu
2902817Sksewell@umich.eduvoid DRAMSim2::readComplete(unsigned id, uint64_t addr, uint64_t cycle)
2912817Sksewell@umich.edu{
2922817Sksewell@umich.edu    assert(cycle == divCeil(curTick() - startTick,
2932986Sgblack@eecs.umich.edu                            wrapper.clockPeriod() * SimClock::Int::ns));
2942817Sksewell@umich.edu
2952817Sksewell@umich.edu    DPRINTF(DRAMSim2, "Read to address %lld complete\n", addr);
2966313Sgblack@eecs.umich.edu
2975715Shsul@eecs.umich.edu    // get the outstanding reads for the address in question
2982817Sksewell@umich.edu    auto p = outstandingReads.find(addr);
2992817Sksewell@umich.edu    assert(p != outstandingReads.end());
3002817Sksewell@umich.edu
3012817Sksewell@umich.edu    // first in first out, which is not necessarily true, but it is
3022817Sksewell@umich.edu    // the best we can do at this point
3032817Sksewell@umich.edu    PacketPtr pkt = p->second.front();
3046313Sgblack@eecs.umich.edu    p->second.pop();
3055715Shsul@eecs.umich.edu
3062817Sksewell@umich.edu    if (p->second.empty())
3072817Sksewell@umich.edu        outstandingReads.erase(p);
3082817Sksewell@umich.edu
3095715Shsul@eecs.umich.edu    // no need to check for drain here as the next call will add a
3102817Sksewell@umich.edu    // response to the response queue straight away
3112817Sksewell@umich.edu    assert(nbrOutstandingReads != 0);
3122817Sksewell@umich.edu    --nbrOutstandingReads;
3132817Sksewell@umich.edu
3142817Sksewell@umich.edu    // perform the actual memory access
3152817Sksewell@umich.edu    accessAndRespond(pkt);
3162817Sksewell@umich.edu}
3176313Sgblack@eecs.umich.edu
3186314Sgblack@eecs.umich.eduvoid DRAMSim2::writeComplete(unsigned id, uint64_t addr, uint64_t cycle)
3192817Sksewell@umich.edu{
3202817Sksewell@umich.edu    assert(cycle == divCeil(curTick() - startTick,
3215715Shsul@eecs.umich.edu                            wrapper.clockPeriod() * SimClock::Int::ns));
3222817Sksewell@umich.edu
3232817Sksewell@umich.edu    DPRINTF(DRAMSim2, "Write to address %lld complete\n", addr);
3242817Sksewell@umich.edu
3252817Sksewell@umich.edu    // get the outstanding reads for the address in question
3262817Sksewell@umich.edu    auto p = outstandingWrites.find(addr);
3272817Sksewell@umich.edu    assert(p != outstandingWrites.end());
3282817Sksewell@umich.edu
3296313Sgblack@eecs.umich.edu    // we have already responded, and this is only to keep track of
3305715Shsul@eecs.umich.edu    // what is outstanding
3312817Sksewell@umich.edu    p->second.pop();
3322817Sksewell@umich.edu    if (p->second.empty())
3332817Sksewell@umich.edu        outstandingWrites.erase(p);
3345715Shsul@eecs.umich.edu
3352817Sksewell@umich.edu    assert(nbrOutstandingWrites != 0);
3362817Sksewell@umich.edu    --nbrOutstandingWrites;
3372817Sksewell@umich.edu
3382817Sksewell@umich.edu    // check if we were asked to drain and if we are now done
3392817Sksewell@umich.edu    if (drainManager && nbrOutstanding() == 0) {
3407720Sgblack@eecs.umich.edu        drainManager->signalDrainDone();
3412817Sksewell@umich.edu        drainManager = NULL;
3427720Sgblack@eecs.umich.edu    }
3435258Sksewell@umich.edu}
3445258Sksewell@umich.edu
3455258Sksewell@umich.eduBaseSlavePort&
3465715Shsul@eecs.umich.eduDRAMSim2::getSlavePort(const std::string &if_name, PortID idx)
3475258Sksewell@umich.edu{
3485258Sksewell@umich.edu    if (if_name != "port") {
3495258Sksewell@umich.edu        return MemObject::getSlavePort(if_name, idx);
3505258Sksewell@umich.edu    } else {
3516313Sgblack@eecs.umich.edu        return port;
3526313Sgblack@eecs.umich.edu    }
3536313Sgblack@eecs.umich.edu}
3546313Sgblack@eecs.umich.edu
3556313Sgblack@eecs.umich.eduunsigned int
3566313Sgblack@eecs.umich.eduDRAMSim2::drain(DrainManager* dm)
3576313Sgblack@eecs.umich.edu{
3586313Sgblack@eecs.umich.edu    // check our outstanding reads and writes and if any they need to
3596313Sgblack@eecs.umich.edu    // drain
3606313Sgblack@eecs.umich.edu    if (nbrOutstanding() != 0) {
3616313Sgblack@eecs.umich.edu        setDrainState(Drainable::Draining);
3626313Sgblack@eecs.umich.edu        drainManager = dm;
3636313Sgblack@eecs.umich.edu        return 1;
3646313Sgblack@eecs.umich.edu    } else {
3655258Sksewell@umich.edu        setDrainState(Drainable::Drained);
3664172Ssaidi@eecs.umich.edu        return 0;
3672817Sksewell@umich.edu    }
3685715Shsul@eecs.umich.edu}
3692817Sksewell@umich.edu
3702817Sksewell@umich.eduDRAMSim2::MemoryPort::MemoryPort(const std::string& _name,
3712817Sksewell@umich.edu                                 DRAMSim2& _memory)
3725715Shsul@eecs.umich.edu    : SlavePort(_name, &_memory), memory(_memory)
3732817Sksewell@umich.edu{ }
3742817Sksewell@umich.edu
3752817Sksewell@umich.eduAddrRangeList
3762817Sksewell@umich.eduDRAMSim2::MemoryPort::getAddrRanges() const
3773468Sgblack@eecs.umich.edu{
3784172Ssaidi@eecs.umich.edu    AddrRangeList ranges;
3792817Sksewell@umich.edu    ranges.push_back(memory.getAddrRange());
3802817Sksewell@umich.edu    return ranges;
3815715Shsul@eecs.umich.edu}
3822817Sksewell@umich.edu
3832817Sksewell@umich.eduTick
3842817Sksewell@umich.eduDRAMSim2::MemoryPort::recvAtomic(PacketPtr pkt)
3855715Shsul@eecs.umich.edu{
3862817Sksewell@umich.edu    return memory.recvAtomic(pkt);
3872817Sksewell@umich.edu}
3882817Sksewell@umich.edu
389void
390DRAMSim2::MemoryPort::recvFunctional(PacketPtr pkt)
391{
392    memory.recvFunctional(pkt);
393}
394
395bool
396DRAMSim2::MemoryPort::recvTimingReq(PacketPtr pkt)
397{
398    // pass it to the memory controller
399    return memory.recvTimingReq(pkt);
400}
401
402void
403DRAMSim2::MemoryPort::recvRetry()
404{
405    memory.recvRetry();
406}
407
408DRAMSim2*
409DRAMSim2Params::create()
410{
411    return new DRAMSim2(this);
412}
413