dramsim2.cc revision 11793
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 4011793Sbrandon.potter@amd.com#include "mem/dramsim2.hh" 4111793Sbrandon.potter@amd.com 4210066Sandreas.hansson@arm.com#include "DRAMSim2/Callback.h" 4310066Sandreas.hansson@arm.com#include "base/callback.hh" 4410066Sandreas.hansson@arm.com#include "base/trace.hh" 4510066Sandreas.hansson@arm.com#include "debug/DRAMSim2.hh" 4610066Sandreas.hansson@arm.com#include "debug/Drain.hh" 4710066Sandreas.hansson@arm.com#include "sim/system.hh" 4810066Sandreas.hansson@arm.com 4910066Sandreas.hansson@arm.comDRAMSim2::DRAMSim2(const Params* p) : 5010066Sandreas.hansson@arm.com AbstractMemory(p), 5110066Sandreas.hansson@arm.com port(name() + ".port", *this), 5210066Sandreas.hansson@arm.com wrapper(p->deviceConfigFile, p->systemConfigFile, p->filePath, 5310066Sandreas.hansson@arm.com p->traceFile, p->range.size() / 1024 / 1024, p->enableDebug), 5410296Sandreas.hansson@arm.com retryReq(false), retryResp(false), startTick(0), 5510066Sandreas.hansson@arm.com nbrOutstandingReads(0), nbrOutstandingWrites(0), 5610066Sandreas.hansson@arm.com sendResponseEvent(this), tickEvent(this) 5710066Sandreas.hansson@arm.com{ 5810066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, 5910066Sandreas.hansson@arm.com "Instantiated DRAMSim2 with clock %d ns and queue size %d\n", 6010066Sandreas.hansson@arm.com wrapper.clockPeriod(), wrapper.queueSize()); 6110066Sandreas.hansson@arm.com 6210066Sandreas.hansson@arm.com DRAMSim::TransactionCompleteCB* read_cb = 6310066Sandreas.hansson@arm.com new DRAMSim::Callback<DRAMSim2, void, unsigned, uint64_t, uint64_t>( 6410066Sandreas.hansson@arm.com this, &DRAMSim2::readComplete); 6510066Sandreas.hansson@arm.com DRAMSim::TransactionCompleteCB* write_cb = 6610066Sandreas.hansson@arm.com new DRAMSim::Callback<DRAMSim2, void, unsigned, uint64_t, uint64_t>( 6710066Sandreas.hansson@arm.com this, &DRAMSim2::writeComplete); 6810066Sandreas.hansson@arm.com wrapper.setCallbacks(read_cb, write_cb); 6910066Sandreas.hansson@arm.com 7010066Sandreas.hansson@arm.com // Register a callback to compensate for the destructor not 7110066Sandreas.hansson@arm.com // being called. The callback prints the DRAMSim2 stats. 7210066Sandreas.hansson@arm.com Callback* cb = new MakeCallback<DRAMSim2Wrapper, 7310066Sandreas.hansson@arm.com &DRAMSim2Wrapper::printStats>(wrapper); 7410066Sandreas.hansson@arm.com registerExitCallback(cb); 7510066Sandreas.hansson@arm.com} 7610066Sandreas.hansson@arm.com 7710066Sandreas.hansson@arm.comvoid 7810066Sandreas.hansson@arm.comDRAMSim2::init() 7910066Sandreas.hansson@arm.com{ 8010466Sandreas.hansson@arm.com AbstractMemory::init(); 8110466Sandreas.hansson@arm.com 8210066Sandreas.hansson@arm.com if (!port.isConnected()) { 8310066Sandreas.hansson@arm.com fatal("DRAMSim2 %s is unconnected!\n", name()); 8410066Sandreas.hansson@arm.com } else { 8510066Sandreas.hansson@arm.com port.sendRangeChange(); 8610066Sandreas.hansson@arm.com } 8710066Sandreas.hansson@arm.com 8810066Sandreas.hansson@arm.com if (system()->cacheLineSize() != wrapper.burstSize()) 8910066Sandreas.hansson@arm.com fatal("DRAMSim2 burst size %d does not match cache line size %d\n", 9010066Sandreas.hansson@arm.com wrapper.burstSize(), system()->cacheLineSize()); 9110066Sandreas.hansson@arm.com} 9210066Sandreas.hansson@arm.com 9310066Sandreas.hansson@arm.comvoid 9410066Sandreas.hansson@arm.comDRAMSim2::startup() 9510066Sandreas.hansson@arm.com{ 9610296Sandreas.hansson@arm.com startTick = curTick(); 9710296Sandreas.hansson@arm.com 9810066Sandreas.hansson@arm.com // kick off the clock ticks 9910066Sandreas.hansson@arm.com schedule(tickEvent, clockEdge()); 10010066Sandreas.hansson@arm.com} 10110066Sandreas.hansson@arm.com 10210066Sandreas.hansson@arm.comvoid 10310066Sandreas.hansson@arm.comDRAMSim2::sendResponse() 10410066Sandreas.hansson@arm.com{ 10510066Sandreas.hansson@arm.com assert(!retryResp); 10610066Sandreas.hansson@arm.com assert(!responseQueue.empty()); 10710066Sandreas.hansson@arm.com 10810066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Attempting to send response\n"); 10910066Sandreas.hansson@arm.com 11010066Sandreas.hansson@arm.com bool success = port.sendTimingResp(responseQueue.front()); 11110066Sandreas.hansson@arm.com if (success) { 11210066Sandreas.hansson@arm.com responseQueue.pop_front(); 11310066Sandreas.hansson@arm.com 11410066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Have %d read, %d write, %d responses outstanding\n", 11510066Sandreas.hansson@arm.com nbrOutstandingReads, nbrOutstandingWrites, 11610066Sandreas.hansson@arm.com responseQueue.size()); 11710066Sandreas.hansson@arm.com 11810066Sandreas.hansson@arm.com if (!responseQueue.empty() && !sendResponseEvent.scheduled()) 11910066Sandreas.hansson@arm.com schedule(sendResponseEvent, curTick()); 12010066Sandreas.hansson@arm.com 12110913Sandreas.sandberg@arm.com if (nbrOutstanding() == 0) 12210913Sandreas.sandberg@arm.com signalDrainDone(); 12310066Sandreas.hansson@arm.com } else { 12410066Sandreas.hansson@arm.com retryResp = true; 12510066Sandreas.hansson@arm.com 12610066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Waiting for response retry\n"); 12710066Sandreas.hansson@arm.com 12810066Sandreas.hansson@arm.com assert(!sendResponseEvent.scheduled()); 12910066Sandreas.hansson@arm.com } 13010066Sandreas.hansson@arm.com} 13110066Sandreas.hansson@arm.com 13210066Sandreas.hansson@arm.comunsigned int 13310066Sandreas.hansson@arm.comDRAMSim2::nbrOutstanding() const 13410066Sandreas.hansson@arm.com{ 13510066Sandreas.hansson@arm.com return nbrOutstandingReads + nbrOutstandingWrites + responseQueue.size(); 13610066Sandreas.hansson@arm.com} 13710066Sandreas.hansson@arm.com 13810066Sandreas.hansson@arm.comvoid 13910066Sandreas.hansson@arm.comDRAMSim2::tick() 14010066Sandreas.hansson@arm.com{ 14110066Sandreas.hansson@arm.com wrapper.tick(); 14210066Sandreas.hansson@arm.com 14310066Sandreas.hansson@arm.com // is the connected port waiting for a retry, if so check the 14410066Sandreas.hansson@arm.com // state and send a retry if conditions have changed 14510066Sandreas.hansson@arm.com if (retryReq && nbrOutstanding() < wrapper.queueSize()) { 14610066Sandreas.hansson@arm.com retryReq = false; 14710713Sandreas.hansson@arm.com port.sendRetryReq(); 14810066Sandreas.hansson@arm.com } 14910066Sandreas.hansson@arm.com 15010066Sandreas.hansson@arm.com schedule(tickEvent, curTick() + wrapper.clockPeriod() * SimClock::Int::ns); 15110066Sandreas.hansson@arm.com} 15210066Sandreas.hansson@arm.com 15310066Sandreas.hansson@arm.comTick 15410066Sandreas.hansson@arm.comDRAMSim2::recvAtomic(PacketPtr pkt) 15510066Sandreas.hansson@arm.com{ 15610066Sandreas.hansson@arm.com access(pkt); 15710066Sandreas.hansson@arm.com 15810066Sandreas.hansson@arm.com // 50 ns is just an arbitrary value at this point 15911284Sandreas.hansson@arm.com return pkt->cacheResponding() ? 0 : 50000; 16010066Sandreas.hansson@arm.com} 16110066Sandreas.hansson@arm.com 16210066Sandreas.hansson@arm.comvoid 16310066Sandreas.hansson@arm.comDRAMSim2::recvFunctional(PacketPtr pkt) 16410066Sandreas.hansson@arm.com{ 16510066Sandreas.hansson@arm.com pkt->pushLabel(name()); 16610066Sandreas.hansson@arm.com 16710066Sandreas.hansson@arm.com functionalAccess(pkt); 16810066Sandreas.hansson@arm.com 16910066Sandreas.hansson@arm.com // potentially update the packets in our response queue as well 17010066Sandreas.hansson@arm.com for (auto i = responseQueue.begin(); i != responseQueue.end(); ++i) 17110066Sandreas.hansson@arm.com pkt->checkFunctional(*i); 17210066Sandreas.hansson@arm.com 17310066Sandreas.hansson@arm.com pkt->popLabel(); 17410066Sandreas.hansson@arm.com} 17510066Sandreas.hansson@arm.com 17610066Sandreas.hansson@arm.combool 17710066Sandreas.hansson@arm.comDRAMSim2::recvTimingReq(PacketPtr pkt) 17810066Sandreas.hansson@arm.com{ 17911284Sandreas.hansson@arm.com // if a cache is responding, sink the packet without further action 18011284Sandreas.hansson@arm.com if (pkt->cacheResponding()) { 18111190Sandreas.hansson@arm.com pendingDelete.reset(pkt); 18210066Sandreas.hansson@arm.com return true; 18310066Sandreas.hansson@arm.com } 18410066Sandreas.hansson@arm.com 18511192Sandreas.hansson@arm.com // we should not get a new request after committing to retry the 18611192Sandreas.hansson@arm.com // current one, but unfortunately the CPU violates this rule, so 18711192Sandreas.hansson@arm.com // simply ignore it for now 18811192Sandreas.hansson@arm.com if (retryReq) 18911192Sandreas.hansson@arm.com return false; 19011192Sandreas.hansson@arm.com 19110066Sandreas.hansson@arm.com // if we cannot accept we need to send a retry once progress can 19210066Sandreas.hansson@arm.com // be made 19310066Sandreas.hansson@arm.com bool can_accept = nbrOutstanding() < wrapper.queueSize(); 19410066Sandreas.hansson@arm.com 19510066Sandreas.hansson@arm.com // keep track of the transaction 19610066Sandreas.hansson@arm.com if (pkt->isRead()) { 19710066Sandreas.hansson@arm.com if (can_accept) { 19810066Sandreas.hansson@arm.com outstandingReads[pkt->getAddr()].push(pkt); 19910066Sandreas.hansson@arm.com 20010066Sandreas.hansson@arm.com // we count a transaction as outstanding until it has left the 20110066Sandreas.hansson@arm.com // queue in the controller, and the response has been sent 20210066Sandreas.hansson@arm.com // back, note that this will differ for reads and writes 20310066Sandreas.hansson@arm.com ++nbrOutstandingReads; 20410066Sandreas.hansson@arm.com } 20510066Sandreas.hansson@arm.com } else if (pkt->isWrite()) { 20610066Sandreas.hansson@arm.com if (can_accept) { 20710066Sandreas.hansson@arm.com outstandingWrites[pkt->getAddr()].push(pkt); 20810066Sandreas.hansson@arm.com 20910066Sandreas.hansson@arm.com ++nbrOutstandingWrites; 21010066Sandreas.hansson@arm.com 21110066Sandreas.hansson@arm.com // perform the access for writes 21210066Sandreas.hansson@arm.com accessAndRespond(pkt); 21310066Sandreas.hansson@arm.com } 21410066Sandreas.hansson@arm.com } else { 21510066Sandreas.hansson@arm.com // keep it simple and just respond if necessary 21610066Sandreas.hansson@arm.com accessAndRespond(pkt); 21710066Sandreas.hansson@arm.com return true; 21810066Sandreas.hansson@arm.com } 21910066Sandreas.hansson@arm.com 22010066Sandreas.hansson@arm.com if (can_accept) { 22110066Sandreas.hansson@arm.com // we should never have a situation when we think there is space, 22210066Sandreas.hansson@arm.com // and there isn't 22310066Sandreas.hansson@arm.com assert(wrapper.canAccept()); 22410066Sandreas.hansson@arm.com 22510066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Enqueueing address %lld\n", pkt->getAddr()); 22610066Sandreas.hansson@arm.com 22710066Sandreas.hansson@arm.com // @todo what about the granularity here, implicit assumption that 22810066Sandreas.hansson@arm.com // a transaction matches the burst size of the memory (which we 22910066Sandreas.hansson@arm.com // cannot determine without parsing the ini file ourselves) 23010066Sandreas.hansson@arm.com wrapper.enqueue(pkt->isWrite(), pkt->getAddr()); 23110066Sandreas.hansson@arm.com 23210066Sandreas.hansson@arm.com return true; 23310066Sandreas.hansson@arm.com } else { 23410066Sandreas.hansson@arm.com retryReq = true; 23510066Sandreas.hansson@arm.com return false; 23610066Sandreas.hansson@arm.com } 23710066Sandreas.hansson@arm.com} 23810066Sandreas.hansson@arm.com 23910066Sandreas.hansson@arm.comvoid 24010713Sandreas.hansson@arm.comDRAMSim2::recvRespRetry() 24110066Sandreas.hansson@arm.com{ 24210066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Retrying\n"); 24310066Sandreas.hansson@arm.com 24410066Sandreas.hansson@arm.com assert(retryResp); 24510066Sandreas.hansson@arm.com retryResp = false; 24610066Sandreas.hansson@arm.com sendResponse(); 24710066Sandreas.hansson@arm.com} 24810066Sandreas.hansson@arm.com 24910066Sandreas.hansson@arm.comvoid 25010066Sandreas.hansson@arm.comDRAMSim2::accessAndRespond(PacketPtr pkt) 25110066Sandreas.hansson@arm.com{ 25210066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Access for address %lld\n", pkt->getAddr()); 25310066Sandreas.hansson@arm.com 25410066Sandreas.hansson@arm.com bool needsResponse = pkt->needsResponse(); 25510066Sandreas.hansson@arm.com 25610066Sandreas.hansson@arm.com // do the actual memory access which also turns the packet into a 25710066Sandreas.hansson@arm.com // response 25810066Sandreas.hansson@arm.com access(pkt); 25910066Sandreas.hansson@arm.com 26010066Sandreas.hansson@arm.com // turn packet around to go back to requester if response expected 26110066Sandreas.hansson@arm.com if (needsResponse) { 26210066Sandreas.hansson@arm.com // access already turned the packet into a response 26310066Sandreas.hansson@arm.com assert(pkt->isResponse()); 26410721SMarco.Balboni@ARM.com // Here we pay for xbar additional delay and to process the payload 26510721SMarco.Balboni@ARM.com // of the packet. 26610721SMarco.Balboni@ARM.com Tick time = curTick() + pkt->headerDelay + pkt->payloadDelay; 26710721SMarco.Balboni@ARM.com // Reset the timings of the packet 26810694SMarco.Balboni@ARM.com pkt->headerDelay = pkt->payloadDelay = 0; 26910066Sandreas.hansson@arm.com 27010066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Queuing response for address %lld\n", 27110066Sandreas.hansson@arm.com pkt->getAddr()); 27210066Sandreas.hansson@arm.com 27310066Sandreas.hansson@arm.com // queue it to be sent back 27410066Sandreas.hansson@arm.com responseQueue.push_back(pkt); 27510066Sandreas.hansson@arm.com 27610066Sandreas.hansson@arm.com // if we are not already waiting for a retry, or are scheduled 27710066Sandreas.hansson@arm.com // to send a response, schedule an event 27810066Sandreas.hansson@arm.com if (!retryResp && !sendResponseEvent.scheduled()) 27910721SMarco.Balboni@ARM.com schedule(sendResponseEvent, time); 28010066Sandreas.hansson@arm.com } else { 28111190Sandreas.hansson@arm.com // queue the packet for deletion 28211190Sandreas.hansson@arm.com pendingDelete.reset(pkt); 28310066Sandreas.hansson@arm.com } 28410066Sandreas.hansson@arm.com} 28510066Sandreas.hansson@arm.com 28610066Sandreas.hansson@arm.comvoid DRAMSim2::readComplete(unsigned id, uint64_t addr, uint64_t cycle) 28710066Sandreas.hansson@arm.com{ 28810296Sandreas.hansson@arm.com assert(cycle == divCeil(curTick() - startTick, 28910066Sandreas.hansson@arm.com wrapper.clockPeriod() * SimClock::Int::ns)); 29010066Sandreas.hansson@arm.com 29110066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Read to address %lld complete\n", addr); 29210066Sandreas.hansson@arm.com 29310066Sandreas.hansson@arm.com // get the outstanding reads for the address in question 29410066Sandreas.hansson@arm.com auto p = outstandingReads.find(addr); 29510066Sandreas.hansson@arm.com assert(p != outstandingReads.end()); 29610066Sandreas.hansson@arm.com 29710066Sandreas.hansson@arm.com // first in first out, which is not necessarily true, but it is 29810066Sandreas.hansson@arm.com // the best we can do at this point 29910066Sandreas.hansson@arm.com PacketPtr pkt = p->second.front(); 30010066Sandreas.hansson@arm.com p->second.pop(); 30110066Sandreas.hansson@arm.com 30210066Sandreas.hansson@arm.com if (p->second.empty()) 30310066Sandreas.hansson@arm.com outstandingReads.erase(p); 30410066Sandreas.hansson@arm.com 30510066Sandreas.hansson@arm.com // no need to check for drain here as the next call will add a 30610066Sandreas.hansson@arm.com // response to the response queue straight away 30710066Sandreas.hansson@arm.com assert(nbrOutstandingReads != 0); 30810066Sandreas.hansson@arm.com --nbrOutstandingReads; 30910066Sandreas.hansson@arm.com 31010066Sandreas.hansson@arm.com // perform the actual memory access 31110066Sandreas.hansson@arm.com accessAndRespond(pkt); 31210066Sandreas.hansson@arm.com} 31310066Sandreas.hansson@arm.com 31410066Sandreas.hansson@arm.comvoid DRAMSim2::writeComplete(unsigned id, uint64_t addr, uint64_t cycle) 31510066Sandreas.hansson@arm.com{ 31610296Sandreas.hansson@arm.com assert(cycle == divCeil(curTick() - startTick, 31710066Sandreas.hansson@arm.com wrapper.clockPeriod() * SimClock::Int::ns)); 31810066Sandreas.hansson@arm.com 31910066Sandreas.hansson@arm.com DPRINTF(DRAMSim2, "Write to address %lld complete\n", addr); 32010066Sandreas.hansson@arm.com 32110066Sandreas.hansson@arm.com // get the outstanding reads for the address in question 32210066Sandreas.hansson@arm.com auto p = outstandingWrites.find(addr); 32310066Sandreas.hansson@arm.com assert(p != outstandingWrites.end()); 32410066Sandreas.hansson@arm.com 32510066Sandreas.hansson@arm.com // we have already responded, and this is only to keep track of 32610066Sandreas.hansson@arm.com // what is outstanding 32710066Sandreas.hansson@arm.com p->second.pop(); 32810066Sandreas.hansson@arm.com if (p->second.empty()) 32910066Sandreas.hansson@arm.com outstandingWrites.erase(p); 33010066Sandreas.hansson@arm.com 33110066Sandreas.hansson@arm.com assert(nbrOutstandingWrites != 0); 33210066Sandreas.hansson@arm.com --nbrOutstandingWrites; 33310066Sandreas.hansson@arm.com 33410913Sandreas.sandberg@arm.com if (nbrOutstanding() == 0) 33510913Sandreas.sandberg@arm.com signalDrainDone(); 33610066Sandreas.hansson@arm.com} 33710066Sandreas.hansson@arm.com 33810066Sandreas.hansson@arm.comBaseSlavePort& 33910066Sandreas.hansson@arm.comDRAMSim2::getSlavePort(const std::string &if_name, PortID idx) 34010066Sandreas.hansson@arm.com{ 34110066Sandreas.hansson@arm.com if (if_name != "port") { 34210066Sandreas.hansson@arm.com return MemObject::getSlavePort(if_name, idx); 34310066Sandreas.hansson@arm.com } else { 34410066Sandreas.hansson@arm.com return port; 34510066Sandreas.hansson@arm.com } 34610066Sandreas.hansson@arm.com} 34710066Sandreas.hansson@arm.com 34810921Sandreas.hansson@arm.comDrainState 34910913Sandreas.sandberg@arm.comDRAMSim2::drain() 35010066Sandreas.hansson@arm.com{ 35110066Sandreas.hansson@arm.com // check our outstanding reads and writes and if any they need to 35210066Sandreas.hansson@arm.com // drain 35310913Sandreas.sandberg@arm.com return nbrOutstanding() != 0 ? DrainState::Draining : DrainState::Drained; 35410066Sandreas.hansson@arm.com} 35510066Sandreas.hansson@arm.com 35610066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::MemoryPort(const std::string& _name, 35710066Sandreas.hansson@arm.com DRAMSim2& _memory) 35810066Sandreas.hansson@arm.com : SlavePort(_name, &_memory), memory(_memory) 35910066Sandreas.hansson@arm.com{ } 36010066Sandreas.hansson@arm.com 36110066Sandreas.hansson@arm.comAddrRangeList 36210066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::getAddrRanges() const 36310066Sandreas.hansson@arm.com{ 36410066Sandreas.hansson@arm.com AddrRangeList ranges; 36510066Sandreas.hansson@arm.com ranges.push_back(memory.getAddrRange()); 36610066Sandreas.hansson@arm.com return ranges; 36710066Sandreas.hansson@arm.com} 36810066Sandreas.hansson@arm.com 36910066Sandreas.hansson@arm.comTick 37010066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvAtomic(PacketPtr pkt) 37110066Sandreas.hansson@arm.com{ 37210066Sandreas.hansson@arm.com return memory.recvAtomic(pkt); 37310066Sandreas.hansson@arm.com} 37410066Sandreas.hansson@arm.com 37510066Sandreas.hansson@arm.comvoid 37610066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvFunctional(PacketPtr pkt) 37710066Sandreas.hansson@arm.com{ 37810066Sandreas.hansson@arm.com memory.recvFunctional(pkt); 37910066Sandreas.hansson@arm.com} 38010066Sandreas.hansson@arm.com 38110066Sandreas.hansson@arm.combool 38210066Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvTimingReq(PacketPtr pkt) 38310066Sandreas.hansson@arm.com{ 38410066Sandreas.hansson@arm.com // pass it to the memory controller 38510066Sandreas.hansson@arm.com return memory.recvTimingReq(pkt); 38610066Sandreas.hansson@arm.com} 38710066Sandreas.hansson@arm.com 38810066Sandreas.hansson@arm.comvoid 38910713Sandreas.hansson@arm.comDRAMSim2::MemoryPort::recvRespRetry() 39010066Sandreas.hansson@arm.com{ 39110713Sandreas.hansson@arm.com memory.recvRespRetry(); 39210066Sandreas.hansson@arm.com} 39310066Sandreas.hansson@arm.com 39410066Sandreas.hansson@arm.comDRAMSim2* 39510066Sandreas.hansson@arm.comDRAMSim2Params::create() 39610066Sandreas.hansson@arm.com{ 39710066Sandreas.hansson@arm.com return new DRAMSim2(this); 39810066Sandreas.hansson@arm.com} 399