mem_delay.cc revision 13784
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 6313784Sgabeblack@google.comPort & 6413784Sgabeblack@google.comMemDelay::getPort(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; 6813784Sgabeblack@google.com } else if (if_name == "slave") { 6912802Sandreas.sandberg@arm.com return slavePort; 7012802Sandreas.sandberg@arm.com } else { 7113784Sgabeblack@google.com return MemObject::getPort(if_name, idx); 7212802Sandreas.sandberg@arm.com } 7312802Sandreas.sandberg@arm.com} 7412802Sandreas.sandberg@arm.com 7512802Sandreas.sandberg@arm.combool 7612823Srmk35@cl.cam.ac.ukMemDelay::trySatisfyFunctional(PacketPtr pkt) 7712802Sandreas.sandberg@arm.com{ 7812823Srmk35@cl.cam.ac.uk return slavePort.trySatisfyFunctional(pkt) || 7912823Srmk35@cl.cam.ac.uk masterPort.trySatisfyFunctional(pkt); 8012802Sandreas.sandberg@arm.com} 8112802Sandreas.sandberg@arm.com 8212802Sandreas.sandberg@arm.comMemDelay::MasterPort::MasterPort(const std::string &_name, MemDelay &_parent) 8312802Sandreas.sandberg@arm.com : QueuedMasterPort(_name, &_parent, 8412802Sandreas.sandberg@arm.com _parent.reqQueue, _parent.snoopRespQueue), 8512802Sandreas.sandberg@arm.com parent(_parent) 8612802Sandreas.sandberg@arm.com{ 8712802Sandreas.sandberg@arm.com} 8812802Sandreas.sandberg@arm.com 8912802Sandreas.sandberg@arm.combool 9012802Sandreas.sandberg@arm.comMemDelay::MasterPort::recvTimingResp(PacketPtr pkt) 9112802Sandreas.sandberg@arm.com{ 9212802Sandreas.sandberg@arm.com const Tick when = curTick() + parent.delayResp(pkt); 9312802Sandreas.sandberg@arm.com 9412802Sandreas.sandberg@arm.com parent.slavePort.schedTimingResp(pkt, when); 9512802Sandreas.sandberg@arm.com 9612802Sandreas.sandberg@arm.com return true; 9712802Sandreas.sandberg@arm.com} 9812802Sandreas.sandberg@arm.com 9912802Sandreas.sandberg@arm.comvoid 10012802Sandreas.sandberg@arm.comMemDelay::MasterPort::recvFunctionalSnoop(PacketPtr pkt) 10112802Sandreas.sandberg@arm.com{ 10212823Srmk35@cl.cam.ac.uk if (parent.trySatisfyFunctional(pkt)) { 10312802Sandreas.sandberg@arm.com pkt->makeResponse(); 10412802Sandreas.sandberg@arm.com } else { 10512802Sandreas.sandberg@arm.com parent.slavePort.sendFunctionalSnoop(pkt); 10612802Sandreas.sandberg@arm.com } 10712802Sandreas.sandberg@arm.com} 10812802Sandreas.sandberg@arm.com 10912802Sandreas.sandberg@arm.comTick 11012802Sandreas.sandberg@arm.comMemDelay::MasterPort::recvAtomicSnoop(PacketPtr pkt) 11112802Sandreas.sandberg@arm.com{ 11212802Sandreas.sandberg@arm.com const Tick delay = parent.delaySnoopResp(pkt); 11312802Sandreas.sandberg@arm.com 11412802Sandreas.sandberg@arm.com return delay + parent.slavePort.sendAtomicSnoop(pkt); 11512802Sandreas.sandberg@arm.com} 11612802Sandreas.sandberg@arm.com 11712802Sandreas.sandberg@arm.comvoid 11812802Sandreas.sandberg@arm.comMemDelay::MasterPort::recvTimingSnoopReq(PacketPtr pkt) 11912802Sandreas.sandberg@arm.com{ 12012802Sandreas.sandberg@arm.com parent.slavePort.sendTimingSnoopReq(pkt); 12112802Sandreas.sandberg@arm.com} 12212802Sandreas.sandberg@arm.com 12312802Sandreas.sandberg@arm.com 12412802Sandreas.sandberg@arm.comMemDelay::SlavePort::SlavePort(const std::string &_name, MemDelay &_parent) 12512802Sandreas.sandberg@arm.com : QueuedSlavePort(_name, &_parent, _parent.respQueue), 12612802Sandreas.sandberg@arm.com parent(_parent) 12712802Sandreas.sandberg@arm.com{ 12812802Sandreas.sandberg@arm.com} 12912802Sandreas.sandberg@arm.com 13012802Sandreas.sandberg@arm.comTick 13112802Sandreas.sandberg@arm.comMemDelay::SlavePort::recvAtomic(PacketPtr pkt) 13212802Sandreas.sandberg@arm.com{ 13312802Sandreas.sandberg@arm.com const Tick delay = parent.delayReq(pkt) + parent.delayResp(pkt); 13412802Sandreas.sandberg@arm.com 13512802Sandreas.sandberg@arm.com return delay + parent.masterPort.sendAtomic(pkt); 13612802Sandreas.sandberg@arm.com} 13712802Sandreas.sandberg@arm.com 13812802Sandreas.sandberg@arm.combool 13912802Sandreas.sandberg@arm.comMemDelay::SlavePort::recvTimingReq(PacketPtr pkt) 14012802Sandreas.sandberg@arm.com{ 14112802Sandreas.sandberg@arm.com const Tick when = curTick() + parent.delayReq(pkt); 14212802Sandreas.sandberg@arm.com 14312802Sandreas.sandberg@arm.com parent.masterPort.schedTimingReq(pkt, when); 14412802Sandreas.sandberg@arm.com 14512802Sandreas.sandberg@arm.com return true; 14612802Sandreas.sandberg@arm.com} 14712802Sandreas.sandberg@arm.com 14812802Sandreas.sandberg@arm.comvoid 14912802Sandreas.sandberg@arm.comMemDelay::SlavePort::recvFunctional(PacketPtr pkt) 15012802Sandreas.sandberg@arm.com{ 15112823Srmk35@cl.cam.ac.uk if (parent.trySatisfyFunctional(pkt)) { 15212802Sandreas.sandberg@arm.com pkt->makeResponse(); 15312802Sandreas.sandberg@arm.com } else { 15412802Sandreas.sandberg@arm.com parent.masterPort.sendFunctional(pkt); 15512802Sandreas.sandberg@arm.com } 15612802Sandreas.sandberg@arm.com} 15712802Sandreas.sandberg@arm.com 15812802Sandreas.sandberg@arm.combool 15912802Sandreas.sandberg@arm.comMemDelay::SlavePort::recvTimingSnoopResp(PacketPtr pkt) 16012802Sandreas.sandberg@arm.com{ 16112802Sandreas.sandberg@arm.com const Tick when = curTick() + parent.delaySnoopResp(pkt); 16212802Sandreas.sandberg@arm.com 16312802Sandreas.sandberg@arm.com parent.masterPort.schedTimingSnoopResp(pkt, when); 16412802Sandreas.sandberg@arm.com 16512802Sandreas.sandberg@arm.com return true; 16612802Sandreas.sandberg@arm.com} 16712802Sandreas.sandberg@arm.com 16812802Sandreas.sandberg@arm.com 16912802Sandreas.sandberg@arm.com 17012802Sandreas.sandberg@arm.comSimpleMemDelay::SimpleMemDelay(const SimpleMemDelayParams *p) 17112802Sandreas.sandberg@arm.com : MemDelay(p), 17212802Sandreas.sandberg@arm.com readReqDelay(p->read_req), 17312802Sandreas.sandberg@arm.com readRespDelay(p->read_resp), 17412802Sandreas.sandberg@arm.com writeReqDelay(p->write_req), 17512802Sandreas.sandberg@arm.com writeRespDelay(p->write_resp) 17612802Sandreas.sandberg@arm.com{ 17712802Sandreas.sandberg@arm.com} 17812802Sandreas.sandberg@arm.com 17912802Sandreas.sandberg@arm.comTick 18012802Sandreas.sandberg@arm.comSimpleMemDelay::delayReq(PacketPtr pkt) 18112802Sandreas.sandberg@arm.com{ 18212802Sandreas.sandberg@arm.com if (pkt->isRead()) { 18312802Sandreas.sandberg@arm.com return readReqDelay; 18412802Sandreas.sandberg@arm.com } else if (pkt->isWrite()) { 18512802Sandreas.sandberg@arm.com return writeReqDelay; 18612802Sandreas.sandberg@arm.com } else { 18712802Sandreas.sandberg@arm.com return 0; 18812802Sandreas.sandberg@arm.com } 18912802Sandreas.sandberg@arm.com} 19012802Sandreas.sandberg@arm.com 19112802Sandreas.sandberg@arm.comTick 19212802Sandreas.sandberg@arm.comSimpleMemDelay::delayResp(PacketPtr pkt) 19312802Sandreas.sandberg@arm.com{ 19412802Sandreas.sandberg@arm.com if (pkt->isRead()) { 19512802Sandreas.sandberg@arm.com return readRespDelay; 19612802Sandreas.sandberg@arm.com } else if (pkt->isWrite()) { 19712802Sandreas.sandberg@arm.com return writeRespDelay; 19812802Sandreas.sandberg@arm.com } else { 19912802Sandreas.sandberg@arm.com return 0; 20012802Sandreas.sandberg@arm.com } 20112802Sandreas.sandberg@arm.com} 20212802Sandreas.sandberg@arm.com 20312802Sandreas.sandberg@arm.com 20412802Sandreas.sandberg@arm.comSimpleMemDelay * 20512802Sandreas.sandberg@arm.comSimpleMemDelayParams::create() 20612802Sandreas.sandberg@arm.com{ 20712802Sandreas.sandberg@arm.com return new SimpleMemDelay(this); 20812802Sandreas.sandberg@arm.com} 209