Deleted Added
sdiff udiff text old ( 12338:ae907b0a57c2 ) new ( 13784:1941dc118243 )
full compact
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__