simple_memobj.hh revision 12338
1/* 2 * Copyright (c) 2017 Jason Lowe-Power 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Jason Lowe-Power 29 */ 30 31#ifndef __LEARNING_GEM5_PART2_SIMPLE_MEMOBJ_HH__ 32#define __LEARNING_GEM5_PART2_SIMPLE_MEMOBJ_HH__ 33 34#include "mem/mem_object.hh" 35#include "params/SimpleMemobj.hh" 36 37/** 38 * A very simple memory object. Current implementation doesn't even cache 39 * anything it just forwards requests and responses. 40 * This memobj is fully blocking (not non-blocking). Only a single request can 41 * be outstanding at a time. 42 */ 43class SimpleMemobj : public MemObject 44{ 45 private: 46 47 /** 48 * Port on the CPU-side that receives requests. 49 * Mostly just forwards requests to the owner. 50 * Part of a vector of ports. One for each CPU port (e.g., data, inst) 51 */ 52 class CPUSidePort : public SlavePort 53 { 54 private: 55 /// The object that owns this object (SimpleMemobj) 56 SimpleMemobj *owner; 57 58 /// True if the port needs to send a retry req. 59 bool needRetry; 60 61 /// If we tried to send a packet and it was blocked, store it here 62 PacketPtr blockedPacket; 63 64 public: 65 /** 66 * Constructor. Just calls the superclass constructor. 67 */ 68 CPUSidePort(const std::string& name, SimpleMemobj *owner) : 69 SlavePort(name, owner), owner(owner), needRetry(false), 70 blockedPacket(nullptr) 71 { } 72 73 /** 74 * Send a packet across this port. This is called by the owner and 75 * all of the flow control is hanled in this function. 76 * 77 * @param packet to send. 78 */ 79 void sendPacket(PacketPtr pkt); 80 81 /** 82 * Get a list of the non-overlapping address ranges the owner is 83 * responsible for. All slave ports must override this function 84 * and return a populated list with at least one item. 85 * 86 * @return a list of ranges responded to 87 */ 88 AddrRangeList getAddrRanges() const override; 89 90 /** 91 * Send a retry to the peer port only if it is needed. This is called 92 * from the SimpleMemobj whenever it is unblocked. 93 */ 94 void trySendRetry(); 95 96 protected: 97 /** 98 * Receive an atomic request packet from the master port. 99 * No need to implement in this simple memobj. 100 */ 101 Tick recvAtomic(PacketPtr pkt) override 102 { panic("recvAtomic unimpl."); } 103 104 /** 105 * Receive a functional request packet from the master port. 106 * Performs a "debug" access updating/reading the data in place. 107 * 108 * @param packet the requestor sent. 109 */ 110 void recvFunctional(PacketPtr pkt) override; 111 112 /** 113 * Receive a timing request from the master port. 114 * 115 * @param the packet that the requestor sent 116 * @return whether this object can consume the packet. If false, we 117 * will call sendRetry() when we can try to receive this 118 * request again. 119 */ 120 bool recvTimingReq(PacketPtr pkt) override; 121 122 /** 123 * Called by the master port if sendTimingResp was called on this 124 * slave port (causing recvTimingResp to be called on the master 125 * port) and was unsuccesful. 126 */ 127 void recvRespRetry() override; 128 }; 129 130 /** 131 * Port on the memory-side that receives responses. 132 * Mostly just forwards requests to the owner 133 */ 134 class MemSidePort : public MasterPort 135 { 136 private: 137 /// The object that owns this object (SimpleMemobj) 138 SimpleMemobj *owner; 139 140 /// If we tried to send a packet and it was blocked, store it here 141 PacketPtr blockedPacket; 142 143 public: 144 /** 145 * Constructor. Just calls the superclass constructor. 146 */ 147 MemSidePort(const std::string& name, SimpleMemobj *owner) : 148 MasterPort(name, owner), owner(owner), blockedPacket(nullptr) 149 { } 150 151 /** 152 * Send a packet across this port. This is called by the owner and 153 * all of the flow control is hanled in this function. 154 * 155 * @param packet to send. 156 */ 157 void sendPacket(PacketPtr pkt); 158 159 protected: 160 /** 161 * Receive a timing response from the slave port. 162 */ 163 bool recvTimingResp(PacketPtr pkt) override; 164 165 /** 166 * Called by the slave port if sendTimingReq was called on this 167 * master port (causing recvTimingReq to be called on the slave 168 * port) and was unsuccesful. 169 */ 170 void recvReqRetry() override; 171 172 /** 173 * Called to receive an address range change from the peer slave 174 * port. The default implementation ignores the change and does 175 * nothing. Override this function in a derived class if the owner 176 * needs to be aware of the address ranges, e.g. in an 177 * interconnect component like a bus. 178 */ 179 void recvRangeChange() override; 180 }; 181 182 /** 183 * Handle the request from the CPU side 184 * 185 * @param requesting packet 186 * @return true if we can handle the request this cycle, false if the 187 * requestor needs to retry later 188 */ 189 bool handleRequest(PacketPtr pkt); 190 191 /** 192 * Handle the respone from the memory side 193 * 194 * @param responding packet 195 * @return true if we can handle the response this cycle, false if the 196 * responder needs to retry later 197 */ 198 bool handleResponse(PacketPtr pkt); 199 200 /** 201 * Handle a packet functionally. Update the data on a write and get the 202 * data on a read. 203 * 204 * @param packet to functionally handle 205 */ 206 void handleFunctional(PacketPtr pkt); 207 208 /** 209 * Return the address ranges this memobj is responsible for. Just use the 210 * same as the next upper level of the hierarchy. 211 * 212 * @return the address ranges this memobj is responsible for 213 */ 214 AddrRangeList getAddrRanges() const; 215 216 /** 217 * Tell the CPU side to ask for our memory ranges. 218 */ 219 void sendRangeChange(); 220 221 /// Instantiation of the CPU-side ports 222 CPUSidePort instPort; 223 CPUSidePort dataPort; 224 225 /// Instantiation of the memory-side port 226 MemSidePort memPort; 227 228 /// True if this is currently blocked waiting for a response. 229 bool blocked; 230 231 public: 232 233 /** constructor 234 */ 235 SimpleMemobj(SimpleMemobjParams *params); 236 237 /** 238 * Get a master port with a given name and index. This is used at 239 * binding time and returns a reference to a protocol-agnostic 240 * base master port. 241 * 242 * @param if_name Port name 243 * @param idx Index in the case of a VectorPort 244 * 245 * @return A reference to the given port 246 */ 247 BaseMasterPort& getMasterPort(const std::string& if_name, 248 PortID idx = InvalidPortID) override; 249 250 /** 251 * Get a slave port with a given name and index. This is used at 252 * binding time and returns a reference to a protocol-agnostic 253 * base master port. 254 * 255 * @param if_name Port name 256 * @param idx Index in the case of a VectorPort 257 * 258 * @return A reference to the given port 259 */ 260 BaseSlavePort& getSlavePort(const std::string& if_name, 261 PortID idx = InvalidPortID) override; 262}; 263 264 265#endif // __LEARNING_GEM5_PART2_SIMPLE_MEMOBJ_HH__ 266