gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
simple_memobj.cc
Go to the documentation of this file.
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 
32 
33 #include "debug/SimpleMemobj.hh"
34 
35 SimpleMemobj::SimpleMemobj(SimpleMemobjParams *params) :
36  SimObject(params),
37  instPort(params->name + ".inst_port", this),
38  dataPort(params->name + ".data_port", this),
39  memPort(params->name + ".mem_side", this),
40  blocked(false)
41 {
42 }
43 
44 Port &
45 SimpleMemobj::getPort(const std::string &if_name, PortID idx)
46 {
47  panic_if(idx != InvalidPortID, "This object doesn't support vector ports");
48 
49  // This is the name from the Python SimObject declaration (SimpleMemobj.py)
50  if (if_name == "mem_side") {
51  return memPort;
52  } else if (if_name == "inst_port") {
53  return instPort;
54  } else if (if_name == "data_port") {
55  return dataPort;
56  } else {
57  // pass it along to our super class
58  return SimObject::getPort(if_name, idx);
59  }
60 }
61 
62 void
64 {
65  // Note: This flow control is very simple since the memobj is blocking.
66 
67  panic_if(blockedPacket != nullptr, "Should never try to send if blocked!");
68 
69  // If we can't send the packet across the port, store it for later.
70  if (!sendTimingResp(pkt)) {
71  blockedPacket = pkt;
72  }
73 }
74 
77 {
78  return owner->getAddrRanges();
79 }
80 
81 void
83 {
84  if (needRetry && blockedPacket == nullptr) {
85  // Only send a retry if the port is now completely free
86  needRetry = false;
87  DPRINTF(SimpleMemobj, "Sending retry req for %d\n", id);
88  sendRetryReq();
89  }
90 }
91 
92 void
94 {
95  // Just forward to the memobj.
96  return owner->handleFunctional(pkt);
97 }
98 
99 bool
101 {
102  // Just forward to the memobj.
103  if (!owner->handleRequest(pkt)) {
104  needRetry = true;
105  return false;
106  } else {
107  return true;
108  }
109 }
110 
111 void
113 {
114  // We should have a blocked packet if this function is called.
115  assert(blockedPacket != nullptr);
116 
117  // Grab the blocked packet.
118  PacketPtr pkt = blockedPacket;
119  blockedPacket = nullptr;
120 
121  // Try to resend it. It's possible that it fails again.
122  sendPacket(pkt);
123 }
124 
125 void
127 {
128  // Note: This flow control is very simple since the memobj is blocking.
129 
130  panic_if(blockedPacket != nullptr, "Should never try to send if blocked!");
131 
132  // If we can't send the packet across the port, store it for later.
133  if (!sendTimingReq(pkt)) {
134  blockedPacket = pkt;
135  }
136 }
137 
138 bool
140 {
141  // Just forward to the memobj.
142  return owner->handleResponse(pkt);
143 }
144 
145 void
147 {
148  // We should have a blocked packet if this function is called.
149  assert(blockedPacket != nullptr);
150 
151  // Grab the blocked packet.
152  PacketPtr pkt = blockedPacket;
153  blockedPacket = nullptr;
154 
155  // Try to resend it. It's possible that it fails again.
156  sendPacket(pkt);
157 }
158 
159 void
161 {
162  owner->sendRangeChange();
163 }
164 
165 bool
167 {
168  if (blocked) {
169  // There is currently an outstanding request. Stall.
170  return false;
171  }
172 
173  DPRINTF(SimpleMemobj, "Got request for addr %#x\n", pkt->getAddr());
174 
175  // This memobj is now blocked waiting for the response to this packet.
176  blocked = true;
177 
178  // Simply forward to the memory port
179  memPort.sendPacket(pkt);
180 
181  return true;
182 }
183 
184 bool
186 {
187  assert(blocked);
188  DPRINTF(SimpleMemobj, "Got response for addr %#x\n", pkt->getAddr());
189 
190  // The packet is now done. We're about to put it in the port, no need for
191  // this object to continue to stall.
192  // We need to free the resource before sending the packet in case the CPU
193  // tries to send another request immediately (e.g., in the same callchain).
194  blocked = false;
195 
196  // Simply forward to the memory port
197  if (pkt->req->isInstFetch()) {
198  instPort.sendPacket(pkt);
199  } else {
200  dataPort.sendPacket(pkt);
201  }
202 
203  // For each of the cpu ports, if it needs to send a retry, it should do it
204  // now since this memory object may be unblocked now.
207 
208  return true;
209 }
210 
211 void
213 {
214  // Just pass this on to the memory side to handle for now.
215  memPort.sendFunctional(pkt);
216 }
217 
220 {
221  DPRINTF(SimpleMemobj, "Sending new ranges\n");
222  // Just use the same ranges as whatever is on the memory side.
223  return memPort.getAddrRanges();
224 }
225 
226 void
228 {
231 }
232 
233 
234 
236 SimpleMemobjParams::create()
237 {
238  return new SimpleMemobj(this);
239 }
bool handleResponse(PacketPtr pkt)
Handle the respone from the memory side.
#define DPRINTF(x,...)
Definition: trace.hh:229
Ports are used to interface objects to each other.
Definition: port.hh:60
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Definition: sim_object.cc:126
bool recvTimingReq(PacketPtr pkt) override
Receive a timing request from the master port.
void sendRangeChange() const
Called by the owner to send a range change.
Definition: port.hh:286
AddrRangeList getAddrRanges() const override
Get a list of the non-overlapping address ranges the owner is responsible for.
const std::string & name()
Definition: trace.cc:54
const PortID InvalidPortID
Definition: types.hh:238
void recvRangeChange() override
Called to receive an address range change from the peer slave port.
CPUSidePort dataPort
AddrRangeList getAddrRanges() const
Return the address ranges this memobj is responsible for.
SimpleMemobj(SimpleMemobjParams *params)
constructor
bool recvTimingResp(PacketPtr pkt) override
Receive a timing response from the slave port.
void sendPacket(PacketPtr pkt)
Send a packet across this port.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
RequestPtr req
A pointer to the original request.
Definition: packet.hh:327
bool blocked
True if this is currently blocked waiting for a response.
void sendRangeChange()
Tell the CPU side to ask for our memory ranges.
Addr getAddr() const
Definition: packet.hh:726
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:255
bool handleRequest(PacketPtr pkt)
Handle the request from the CPU side.
A very simple memory object.
void sendPacket(PacketPtr pkt)
Send a packet across this port.
AddrRangeList getAddrRanges() const
Get the address ranges of the connected slave port.
Definition: port.cc:93
CPUSidePort instPort
Instantiation of the CPU-side ports.
void handleFunctional(PacketPtr pkt)
Handle a packet functionally.
void trySendRetry()
Send a retry to the peer port only if it is needed.
MemSidePort memPort
Instantiation of the memory-side port.
void sendFunctional(PacketPtr pkt) const
Send a functional request packet, where the data is instantly updated everywhere in the memory system...
Definition: port.hh:439
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:237
void recvReqRetry() override
Called by the slave port if sendTimingReq was called on this master port (causing recvTimingReq to be...
void recvFunctional(PacketPtr pkt) override
Receive a functional request packet from the master port.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:185
Abstract superclass for simulation objects.
Definition: sim_object.hh:96
void recvRespRetry() override
Called by the master port if sendTimingResp was called on this slave port (causing recvTimingResp to ...

Generated on Fri Feb 28 2020 16:27:01 for gem5 by doxygen 1.8.13