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