mem_delay.cc revision 12823
112802Sandreas.sandberg@arm.com/* 212802Sandreas.sandberg@arm.com * Copyright (c) 2018 ARM Limited 312802Sandreas.sandberg@arm.com * All rights reserved 412802Sandreas.sandberg@arm.com * 512802Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 612802Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 712802Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 812802Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 912802Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 1012802Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 1112802Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 1212802Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 1312802Sandreas.sandberg@arm.com * 1412802Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 1512802Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 1612802Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 1712802Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 1812802Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1912802Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 2012802Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 2112802Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 2212802Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 2312802Sandreas.sandberg@arm.com * this software without specific prior written permission. 2412802Sandreas.sandberg@arm.com * 2512802Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2612802Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2712802Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2812802Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2912802Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3012802Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3112802Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3212802Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3312802Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3412802Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3512802Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3612802Sandreas.sandberg@arm.com * 3712802Sandreas.sandberg@arm.com * Authors: Andreas Sandberg 3812802Sandreas.sandberg@arm.com */ 3912802Sandreas.sandberg@arm.com 4012802Sandreas.sandberg@arm.com#include "mem/mem_delay.hh" 4112802Sandreas.sandberg@arm.com 4212802Sandreas.sandberg@arm.com#include "params/MemDelay.hh" 4312802Sandreas.sandberg@arm.com#include "params/SimpleMemDelay.hh" 4412802Sandreas.sandberg@arm.com 4512802Sandreas.sandberg@arm.comMemDelay::MemDelay(const MemDelayParams *p) 4612802Sandreas.sandberg@arm.com : MemObject(p), 4712802Sandreas.sandberg@arm.com masterPort(name() + "-master", *this), 4812802Sandreas.sandberg@arm.com slavePort(name() + "-slave", *this), 4912802Sandreas.sandberg@arm.com reqQueue(*this, masterPort), 5012802Sandreas.sandberg@arm.com respQueue(*this, slavePort), 5112802Sandreas.sandberg@arm.com snoopRespQueue(*this, masterPort) 5212802Sandreas.sandberg@arm.com{ 5312802Sandreas.sandberg@arm.com} 5412802Sandreas.sandberg@arm.com 5512802Sandreas.sandberg@arm.comvoid 5612802Sandreas.sandberg@arm.comMemDelay::init() 5712802Sandreas.sandberg@arm.com{ 5812802Sandreas.sandberg@arm.com if (!slavePort.isConnected() || !masterPort.isConnected()) 5912802Sandreas.sandberg@arm.com fatal("Memory delay is not connected on both sides.\n"); 6012802Sandreas.sandberg@arm.com} 6112802Sandreas.sandberg@arm.com 6212802Sandreas.sandberg@arm.com 6312802Sandreas.sandberg@arm.comBaseMasterPort& 6412802Sandreas.sandberg@arm.comMemDelay::getMasterPort(const std::string& if_name, PortID idx) 6512802Sandreas.sandberg@arm.com{ 6612802Sandreas.sandberg@arm.com if (if_name == "master") { 6712802Sandreas.sandberg@arm.com return masterPort; 6812802Sandreas.sandberg@arm.com } else { 6912802Sandreas.sandberg@arm.com return MemObject::getMasterPort(if_name, idx); 7012802Sandreas.sandberg@arm.com } 7112802Sandreas.sandberg@arm.com} 7212802Sandreas.sandberg@arm.com 7312802Sandreas.sandberg@arm.comBaseSlavePort& 7412802Sandreas.sandberg@arm.comMemDelay::getSlavePort(const std::string& if_name, PortID idx) 7512802Sandreas.sandberg@arm.com{ 7612802Sandreas.sandberg@arm.com if (if_name == "slave") { 7712802Sandreas.sandberg@arm.com return slavePort; 7812802Sandreas.sandberg@arm.com } else { 7912802Sandreas.sandberg@arm.com return MemObject::getSlavePort(if_name, idx); 8012802Sandreas.sandberg@arm.com } 8112802Sandreas.sandberg@arm.com} 8212802Sandreas.sandberg@arm.com 8312802Sandreas.sandberg@arm.combool 8412823Srmk35@cl.cam.ac.ukMemDelay::trySatisfyFunctional(PacketPtr pkt) 8512802Sandreas.sandberg@arm.com{ 8612823Srmk35@cl.cam.ac.uk return slavePort.trySatisfyFunctional(pkt) || 8712823Srmk35@cl.cam.ac.uk masterPort.trySatisfyFunctional(pkt); 8812802Sandreas.sandberg@arm.com} 8912802Sandreas.sandberg@arm.com 9012802Sandreas.sandberg@arm.comMemDelay::MasterPort::MasterPort(const std::string &_name, MemDelay &_parent) 9112802Sandreas.sandberg@arm.com : QueuedMasterPort(_name, &_parent, 9212802Sandreas.sandberg@arm.com _parent.reqQueue, _parent.snoopRespQueue), 9312802Sandreas.sandberg@arm.com parent(_parent) 9412802Sandreas.sandberg@arm.com{ 9512802Sandreas.sandberg@arm.com} 9612802Sandreas.sandberg@arm.com 9712802Sandreas.sandberg@arm.combool 9812802Sandreas.sandberg@arm.comMemDelay::MasterPort::recvTimingResp(PacketPtr pkt) 9912802Sandreas.sandberg@arm.com{ 10012802Sandreas.sandberg@arm.com const Tick when = curTick() + parent.delayResp(pkt); 10112802Sandreas.sandberg@arm.com 10212802Sandreas.sandberg@arm.com parent.slavePort.schedTimingResp(pkt, when); 10312802Sandreas.sandberg@arm.com 10412802Sandreas.sandberg@arm.com return true; 10512802Sandreas.sandberg@arm.com} 10612802Sandreas.sandberg@arm.com 10712802Sandreas.sandberg@arm.comvoid 10812802Sandreas.sandberg@arm.comMemDelay::MasterPort::recvFunctionalSnoop(PacketPtr pkt) 10912802Sandreas.sandberg@arm.com{ 11012823Srmk35@cl.cam.ac.uk if (parent.trySatisfyFunctional(pkt)) { 11112802Sandreas.sandberg@arm.com pkt->makeResponse(); 11212802Sandreas.sandberg@arm.com } else { 11312802Sandreas.sandberg@arm.com parent.slavePort.sendFunctionalSnoop(pkt); 11412802Sandreas.sandberg@arm.com } 11512802Sandreas.sandberg@arm.com} 11612802Sandreas.sandberg@arm.com 11712802Sandreas.sandberg@arm.comTick 11812802Sandreas.sandberg@arm.comMemDelay::MasterPort::recvAtomicSnoop(PacketPtr pkt) 11912802Sandreas.sandberg@arm.com{ 12012802Sandreas.sandberg@arm.com const Tick delay = parent.delaySnoopResp(pkt); 12112802Sandreas.sandberg@arm.com 12212802Sandreas.sandberg@arm.com return delay + parent.slavePort.sendAtomicSnoop(pkt); 12312802Sandreas.sandberg@arm.com} 12412802Sandreas.sandberg@arm.com 12512802Sandreas.sandberg@arm.comvoid 12612802Sandreas.sandberg@arm.comMemDelay::MasterPort::recvTimingSnoopReq(PacketPtr pkt) 12712802Sandreas.sandberg@arm.com{ 12812802Sandreas.sandberg@arm.com parent.slavePort.sendTimingSnoopReq(pkt); 12912802Sandreas.sandberg@arm.com} 13012802Sandreas.sandberg@arm.com 13112802Sandreas.sandberg@arm.com 13212802Sandreas.sandberg@arm.comMemDelay::SlavePort::SlavePort(const std::string &_name, MemDelay &_parent) 13312802Sandreas.sandberg@arm.com : QueuedSlavePort(_name, &_parent, _parent.respQueue), 13412802Sandreas.sandberg@arm.com parent(_parent) 13512802Sandreas.sandberg@arm.com{ 13612802Sandreas.sandberg@arm.com} 13712802Sandreas.sandberg@arm.com 13812802Sandreas.sandberg@arm.comTick 13912802Sandreas.sandberg@arm.comMemDelay::SlavePort::recvAtomic(PacketPtr pkt) 14012802Sandreas.sandberg@arm.com{ 14112802Sandreas.sandberg@arm.com const Tick delay = parent.delayReq(pkt) + parent.delayResp(pkt); 14212802Sandreas.sandberg@arm.com 14312802Sandreas.sandberg@arm.com return delay + parent.masterPort.sendAtomic(pkt); 14412802Sandreas.sandberg@arm.com} 14512802Sandreas.sandberg@arm.com 14612802Sandreas.sandberg@arm.combool 14712802Sandreas.sandberg@arm.comMemDelay::SlavePort::recvTimingReq(PacketPtr pkt) 14812802Sandreas.sandberg@arm.com{ 14912802Sandreas.sandberg@arm.com const Tick when = curTick() + parent.delayReq(pkt); 15012802Sandreas.sandberg@arm.com 15112802Sandreas.sandberg@arm.com parent.masterPort.schedTimingReq(pkt, when); 15212802Sandreas.sandberg@arm.com 15312802Sandreas.sandberg@arm.com return true; 15412802Sandreas.sandberg@arm.com} 15512802Sandreas.sandberg@arm.com 15612802Sandreas.sandberg@arm.comvoid 15712802Sandreas.sandberg@arm.comMemDelay::SlavePort::recvFunctional(PacketPtr pkt) 15812802Sandreas.sandberg@arm.com{ 15912823Srmk35@cl.cam.ac.uk if (parent.trySatisfyFunctional(pkt)) { 16012802Sandreas.sandberg@arm.com pkt->makeResponse(); 16112802Sandreas.sandberg@arm.com } else { 16212802Sandreas.sandberg@arm.com parent.masterPort.sendFunctional(pkt); 16312802Sandreas.sandberg@arm.com } 16412802Sandreas.sandberg@arm.com} 16512802Sandreas.sandberg@arm.com 16612802Sandreas.sandberg@arm.combool 16712802Sandreas.sandberg@arm.comMemDelay::SlavePort::recvTimingSnoopResp(PacketPtr pkt) 16812802Sandreas.sandberg@arm.com{ 16912802Sandreas.sandberg@arm.com const Tick when = curTick() + parent.delaySnoopResp(pkt); 17012802Sandreas.sandberg@arm.com 17112802Sandreas.sandberg@arm.com parent.masterPort.schedTimingSnoopResp(pkt, when); 17212802Sandreas.sandberg@arm.com 17312802Sandreas.sandberg@arm.com return true; 17412802Sandreas.sandberg@arm.com} 17512802Sandreas.sandberg@arm.com 17612802Sandreas.sandberg@arm.com 17712802Sandreas.sandberg@arm.com 17812802Sandreas.sandberg@arm.comSimpleMemDelay::SimpleMemDelay(const SimpleMemDelayParams *p) 17912802Sandreas.sandberg@arm.com : MemDelay(p), 18012802Sandreas.sandberg@arm.com readReqDelay(p->read_req), 18112802Sandreas.sandberg@arm.com readRespDelay(p->read_resp), 18212802Sandreas.sandberg@arm.com writeReqDelay(p->write_req), 18312802Sandreas.sandberg@arm.com writeRespDelay(p->write_resp) 18412802Sandreas.sandberg@arm.com{ 18512802Sandreas.sandberg@arm.com} 18612802Sandreas.sandberg@arm.com 18712802Sandreas.sandberg@arm.comTick 18812802Sandreas.sandberg@arm.comSimpleMemDelay::delayReq(PacketPtr pkt) 18912802Sandreas.sandberg@arm.com{ 19012802Sandreas.sandberg@arm.com if (pkt->isRead()) { 19112802Sandreas.sandberg@arm.com return readReqDelay; 19212802Sandreas.sandberg@arm.com } else if (pkt->isWrite()) { 19312802Sandreas.sandberg@arm.com return writeReqDelay; 19412802Sandreas.sandberg@arm.com } else { 19512802Sandreas.sandberg@arm.com return 0; 19612802Sandreas.sandberg@arm.com } 19712802Sandreas.sandberg@arm.com} 19812802Sandreas.sandberg@arm.com 19912802Sandreas.sandberg@arm.comTick 20012802Sandreas.sandberg@arm.comSimpleMemDelay::delayResp(PacketPtr pkt) 20112802Sandreas.sandberg@arm.com{ 20212802Sandreas.sandberg@arm.com if (pkt->isRead()) { 20312802Sandreas.sandberg@arm.com return readRespDelay; 20412802Sandreas.sandberg@arm.com } else if (pkt->isWrite()) { 20512802Sandreas.sandberg@arm.com return writeRespDelay; 20612802Sandreas.sandberg@arm.com } else { 20712802Sandreas.sandberg@arm.com return 0; 20812802Sandreas.sandberg@arm.com } 20912802Sandreas.sandberg@arm.com} 21012802Sandreas.sandberg@arm.com 21112802Sandreas.sandberg@arm.com 21212802Sandreas.sandberg@arm.comSimpleMemDelay * 21312802Sandreas.sandberg@arm.comSimpleMemDelayParams::create() 21412802Sandreas.sandberg@arm.com{ 21512802Sandreas.sandberg@arm.com return new SimpleMemDelay(this); 21612802Sandreas.sandberg@arm.com} 217