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