mem_delay.cc revision 13892:0182a0601f66
12497SN/A/*
210719SMarco.Balboni@ARM.com * Copyright (c) 2018 ARM Limited
38711SN/A * All rights reserved
48711SN/A *
58711SN/A * The license below extends only to copyright in the software and shall
68711SN/A * not be construed as granting a license to any other intellectual
78711SN/A * property including but not limited to intellectual property relating
88711SN/A * to a hardware implementation of the functionality of the software
98711SN/A * licensed hereunder.  You may use the software subject to the license
108711SN/A * terms below provided that you ensure that this notice is replicated
118711SN/A * unmodified and in its entirety in all distributions of the software,
128711SN/A * modified or unmodified, in source code or in binary form.
138711SN/A *
142497SN/A * Redistribution and use in source and binary forms, with or without
152497SN/A * modification, are permitted provided that the following conditions are
162497SN/A * met: redistributions of source code must retain the above copyright
172497SN/A * notice, this list of conditions and the following disclaimer;
182497SN/A * redistributions in binary form must reproduce the above copyright
192497SN/A * notice, this list of conditions and the following disclaimer in the
202497SN/A * documentation and/or other materials provided with the distribution;
212497SN/A * neither the name of the copyright holders nor the names of its
222497SN/A * contributors may be used to endorse or promote products derived from
232497SN/A * this software without specific prior written permission.
242497SN/A *
252497SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262497SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272497SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282497SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292497SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302497SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312497SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322497SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332497SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342497SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352497SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362497SN/A *
372497SN/A * Authors: Andreas Sandberg
382497SN/A */
392665SN/A
402665SN/A#include "mem/mem_delay.hh"
418715SN/A
428922SN/A#include "params/MemDelay.hh"
432497SN/A#include "params/SimpleMemDelay.hh"
442497SN/A
452497SN/AMemDelay::MemDelay(const MemDelayParams *p)
462982SN/A    : ClockedObject(p),
4710405Sandreas.hansson@arm.com      masterPort(name() + "-master", *this),
482497SN/A      slavePort(name() + "-slave", *this),
492497SN/A      reqQueue(*this, masterPort),
502846SN/A      respQueue(*this, slavePort),
512548SN/A      snoopRespQueue(*this, masterPort)
5210405Sandreas.hansson@arm.com{
5310405Sandreas.hansson@arm.com}
5410405Sandreas.hansson@arm.com
559524SN/Avoid
562497SN/AMemDelay::init()
5710405Sandreas.hansson@arm.com{
5810719SMarco.Balboni@ARM.com    if (!slavePort.isConnected() || !masterPort.isConnected())
5910719SMarco.Balboni@ARM.com        fatal("Memory delay is not connected on both sides.\n");
607523SN/A}
618851SN/A
628948SN/A
638948SN/APort &
648851SN/AMemDelay::getPort(const std::string &if_name, PortID idx)
659095SN/A{
6610405Sandreas.hansson@arm.com    if (if_name == "master") {
678922SN/A        return masterPort;
689715SN/A    } else if (if_name == "slave") {
699715SN/A        return slavePort;
7010713Sandreas.hansson@arm.com    } else {
7110713Sandreas.hansson@arm.com        return ClockedObject::getPort(if_name, idx);
728851SN/A    }
738851SN/A}
748948SN/A
758948SN/Abool
768915SN/AMemDelay::trySatisfyFunctional(PacketPtr pkt)
779031SN/A{
789095SN/A    return slavePort.trySatisfyFunctional(pkt) ||
7910405Sandreas.hansson@arm.com        masterPort.trySatisfyFunctional(pkt);
809036SN/A}
818922SN/A
829715SN/AMemDelay::MasterPort::MasterPort(const std::string &_name, MemDelay &_parent)
839715SN/A    : QueuedMasterPort(_name, &_parent,
8410713Sandreas.hansson@arm.com                       _parent.reqQueue, _parent.snoopRespQueue),
8510713Sandreas.hansson@arm.com      parent(_parent)
8610713Sandreas.hansson@arm.com{
878915SN/A}
888915SN/A
898948SN/Abool
908851SN/AMemDelay::MasterPort::recvTimingResp(PacketPtr pkt)
919095SN/A{
9210888Sandreas.hansson@arm.com    const Tick when = curTick() + parent.delayResp(pkt);
938922SN/A
949715SN/A    parent.slavePort.schedTimingResp(pkt, when);
959715SN/A
969716SN/A    return true;
978851SN/A}
988851SN/A
9910402SN/Avoid
10010402SN/AMemDelay::MasterPort::recvFunctionalSnoop(PacketPtr pkt)
10110402SN/A{
1027523SN/A    if (parent.trySatisfyFunctional(pkt)) {
1037523SN/A        pkt->makeResponse();
1047523SN/A    } else {
10510405Sandreas.hansson@arm.com        parent.slavePort.sendFunctionalSnoop(pkt);
1069715SN/A    }
10710405Sandreas.hansson@arm.com}
10810405Sandreas.hansson@arm.com
10910405Sandreas.hansson@arm.comTick
11010405Sandreas.hansson@arm.comMemDelay::MasterPort::recvAtomicSnoop(PacketPtr pkt)
11110405Sandreas.hansson@arm.com{
11210405Sandreas.hansson@arm.com    const Tick delay = parent.delaySnoopResp(pkt);
11310405Sandreas.hansson@arm.com
11410405Sandreas.hansson@arm.com    return delay + parent.slavePort.sendAtomicSnoop(pkt);
1159715SN/A}
1169715SN/A
1172568SN/Avoid
11810405Sandreas.hansson@arm.comMemDelay::MasterPort::recvTimingSnoopReq(PacketPtr pkt)
1192568SN/A{
1209278SN/A    parent.slavePort.sendTimingSnoopReq(pkt);
12110405Sandreas.hansson@arm.com}
1229278SN/A
1238948SN/A
1248948SN/AMemDelay::SlavePort::SlavePort(const std::string &_name, MemDelay &_parent)
12510405Sandreas.hansson@arm.com    : QueuedSlavePort(_name, &_parent, _parent.respQueue),
1269088SN/A      parent(_parent)
12710405Sandreas.hansson@arm.com{
12810405Sandreas.hansson@arm.com}
12910405Sandreas.hansson@arm.com
13010405Sandreas.hansson@arm.comTick
1318711SN/AMemDelay::SlavePort::recvAtomic(PacketPtr pkt)
1328711SN/A{
1332568SN/A    const Tick delay = parent.delayReq(pkt) + parent.delayResp(pkt);
1349036SN/A
13510405Sandreas.hansson@arm.com    return delay + parent.masterPort.sendAtomic(pkt);
1363244SN/A}
1373244SN/A
1388948SN/Abool
13910405Sandreas.hansson@arm.comMemDelay::SlavePort::recvTimingReq(PacketPtr pkt)
1403244SN/A{
14110883Sali.jafri@arm.com    const Tick when = curTick() + parent.delayReq(pkt);
14210883Sali.jafri@arm.com
14310883Sali.jafri@arm.com    parent.masterPort.schedTimingReq(pkt, when);
14410883Sali.jafri@arm.com
14510883Sali.jafri@arm.com    return true;
14610883Sali.jafri@arm.com}
1478975SN/A
1489032SN/Avoid
1493244SN/AMemDelay::SlavePort::recvFunctional(PacketPtr pkt)
1509091SN/A{
1519091SN/A    if (parent.trySatisfyFunctional(pkt)) {
15210656Sandreas.hansson@arm.com        pkt->makeResponse();
15310656Sandreas.hansson@arm.com    } else {
15410656Sandreas.hansson@arm.com        parent.masterPort.sendFunctional(pkt);
15510656Sandreas.hansson@arm.com    }
1569091SN/A}
1579612SN/A
1589712SN/Abool
1599612SN/AMemDelay::SlavePort::recvTimingSnoopResp(PacketPtr pkt)
16010405Sandreas.hansson@arm.com{
1619033SN/A    const Tick when = curTick() + parent.delaySnoopResp(pkt);
1629715SN/A
16310405Sandreas.hansson@arm.com    parent.masterPort.schedTimingSnoopResp(pkt, when);
1648949SN/A
1653244SN/A    return true;
1663244SN/A}
1673244SN/A
16810405Sandreas.hansson@arm.com
1699091SN/A
1709091SN/ASimpleMemDelay::SimpleMemDelay(const SimpleMemDelayParams *p)
1715197SN/A    : MemDelay(p),
1729712SN/A      readReqDelay(p->read_req),
1739712SN/A      readRespDelay(p->read_resp),
1749712SN/A      writeReqDelay(p->write_req),
1759712SN/A      writeRespDelay(p->write_resp)
1769712SN/A{
17710719SMarco.Balboni@ARM.com}
17810719SMarco.Balboni@ARM.com
17910719SMarco.Balboni@ARM.comTick
18010719SMarco.Balboni@ARM.comSimpleMemDelay::delayReq(PacketPtr pkt)
18110719SMarco.Balboni@ARM.com{
18210719SMarco.Balboni@ARM.com    if (pkt->isRead()) {
18310719SMarco.Balboni@ARM.com        return readReqDelay;
18410719SMarco.Balboni@ARM.com    } else if (pkt->isWrite()) {
18510719SMarco.Balboni@ARM.com        return writeReqDelay;
18610719SMarco.Balboni@ARM.com    } else {
18710719SMarco.Balboni@ARM.com        return 0;
1884912SN/A    }
18910821Sandreas.hansson@arm.com}
19011127Sandreas.hansson@arm.com
19111127Sandreas.hansson@arm.comTick
1928979SN/ASimpleMemDelay::delayResp(PacketPtr pkt)
1938979SN/A{
19410402SN/A    if (pkt->isRead()) {
19510402SN/A        return readRespDelay;
19610402SN/A    } else if (pkt->isWrite()) {
19711126Sandreas.hansson@arm.com        return writeRespDelay;
19811126Sandreas.hansson@arm.com    } else {
19911126Sandreas.hansson@arm.com        return 0;
20010719SMarco.Balboni@ARM.com    }
20110405Sandreas.hansson@arm.com}
20210402SN/A
20310402SN/A
20410402SN/ASimpleMemDelay *
20510402SN/ASimpleMemDelayParams::create()
20610402SN/A{
20710402SN/A    return new SimpleMemDelay(this);
20810402SN/A}
20911127Sandreas.hansson@arm.com