1/* 2 * Copyright (c) 2018 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Andreas Sandberg 38 */ 39 40#ifndef __MEM_MEM_DELAY_HH__ 41#define __MEM_MEM_DELAY_HH__ 42 43#include "mem/qport.hh" 44#include "sim/clocked_object.hh" 45 46struct MemDelayParams; 47struct SimpleMemDelayParams; 48 49/** 50 * This abstract component provides a mechanism to delay 51 * packets. It can be spliced between arbitrary ports of the memory 52 * system and delays packets that pass through it. 53 * 54 * Specialisations of this abstract class should override at least one 55 * of delayReq, delayResp, deleySnoopReq, delaySnoopResp. These 56 * methods receive a PacketPtr as their argument and return a delay in 57 * Ticks. The base class implements an infinite buffer to hold delayed 58 * packets until they are ready. The intention is to use this 59 * component for rapid prototyping of other memory system components 60 * that introduce a packet processing delays. 61 * 62 * NOTE: Packets may be reordered if the delays aren't constant. 63 */ 64class MemDelay : public ClockedObject 65{ 66 67 public: 68 MemDelay(const MemDelayParams *params); 69 70 void init() override; 71 72 protected: // Port interface 73 Port &getPort(const std::string &if_name, 74 PortID idx=InvalidPortID) override; 75 76 class MasterPort : public QueuedMasterPort 77 { 78 public: 79 MasterPort(const std::string &_name, MemDelay &_parent); 80 81 protected: 82 bool recvTimingResp(PacketPtr pkt) override; 83 84 void recvFunctionalSnoop(PacketPtr pkt) override; 85 86 Tick recvAtomicSnoop(PacketPtr pkt) override; 87 88 void recvTimingSnoopReq(PacketPtr pkt) override; 89 90 void recvRangeChange() override { 91 parent.slavePort.sendRangeChange(); 92 } 93 94 bool isSnooping() const override { 95 return parent.slavePort.isSnooping(); 96 } 97 98 private: 99 MemDelay& parent; 100 }; 101 102 class SlavePort : public QueuedSlavePort 103 { 104 public: 105 SlavePort(const std::string &_name, MemDelay &_parent); 106 107 protected: 108 Tick recvAtomic(PacketPtr pkt) override; 109 bool recvTimingReq(PacketPtr pkt) override; 110 void recvFunctional(PacketPtr pkt) override; 111 bool recvTimingSnoopResp(PacketPtr pkt) override; 112 113 AddrRangeList getAddrRanges() const override { 114 return parent.masterPort.getAddrRanges(); 115 } 116 117 bool tryTiming(PacketPtr pkt) override { return true; } 118 119 private: 120 121 MemDelay& parent; 122 123 }; 124 125 bool trySatisfyFunctional(PacketPtr pkt); 126 127 MasterPort masterPort; 128 SlavePort slavePort; 129 130 ReqPacketQueue reqQueue; 131 RespPacketQueue respQueue; 132 SnoopRespPacketQueue snoopRespQueue; 133 134 protected: 135 /** 136 * Delay a request by some number of ticks. 137 * 138 * @return Ticks to delay packet. 139 */ 140 virtual Tick delayReq(PacketPtr pkt) { return 0; } 141 142 /** 143 * Delay a response by some number of ticks. 144 * 145 * @return Ticks to delay packet. 146 */ 147 virtual Tick delayResp(PacketPtr pkt) { return 0; } 148 149 /** 150 * Delay a snoop response by some number of ticks. 151 * 152 * @return Ticks to delay packet. 153 */ 154 virtual Tick delaySnoopResp(PacketPtr pkt) { return 0; } 155}; 156 157/** 158 * Delay packets by a constant time. Delays can be specified 159 * separately for read requests, read responses, write requests, and 160 * write responses. 161 * 162 * This class does not delay snoops or requests/responses that are 163 * neither reads or writes. 164 */ 165class SimpleMemDelay : public MemDelay 166{ 167 public: 168 SimpleMemDelay(const SimpleMemDelayParams *params); 169 170 protected: 171 Tick delayReq(PacketPtr pkt) override; 172 Tick delayResp(PacketPtr pkt) override; 173 174 protected: // Params 175 const Tick readReqDelay; 176 const Tick readRespDelay; 177 178 const Tick writeReqDelay; 179 const Tick writeRespDelay; 180}; 181 182#endif //__MEM_MEM_DELAY_HH__ 183