gem5  v20.0.0.2
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 
30 
31 #include "base/trace.hh"
32 #include "debug/SimpleMemobj.hh"
33 
34 SimpleMemobj::SimpleMemobj(SimpleMemobjParams *params) :
35  SimObject(params),
36  instPort(params->name + ".inst_port", this),
37  dataPort(params->name + ".data_port", this),
38  memPort(params->name + ".mem_side", this),
39  blocked(false)
40 {
41 }
42 
43 Port &
44 SimpleMemobj::getPort(const std::string &if_name, PortID idx)
45 {
46  panic_if(idx != InvalidPortID, "This object doesn't support vector ports");
47 
48  // This is the name from the Python SimObject declaration (SimpleMemobj.py)
49  if (if_name == "mem_side") {
50  return memPort;
51  } else if (if_name == "inst_port") {
52  return instPort;
53  } else if (if_name == "data_port") {
54  return dataPort;
55  } else {
56  // pass it along to our super class
57  return SimObject::getPort(if_name, idx);
58  }
59 }
60 
61 void
63 {
64  // Note: This flow control is very simple since the memobj is blocking.
65 
66  panic_if(blockedPacket != nullptr, "Should never try to send if blocked!");
67 
68  // If we can't send the packet across the port, store it for later.
69  if (!sendTimingResp(pkt)) {
70  blockedPacket = pkt;
71  }
72 }
73 
76 {
77  return owner->getAddrRanges();
78 }
79 
80 void
82 {
83  if (needRetry && blockedPacket == nullptr) {
84  // Only send a retry if the port is now completely free
85  needRetry = false;
86  DPRINTF(SimpleMemobj, "Sending retry req for %d\n", id);
87  sendRetryReq();
88  }
89 }
90 
91 void
93 {
94  // Just forward to the memobj.
95  return owner->handleFunctional(pkt);
96 }
97 
98 bool
100 {
101  // Just forward to the memobj.
102  if (!owner->handleRequest(pkt)) {
103  needRetry = true;
104  return false;
105  } else {
106  return true;
107  }
108 }
109 
110 void
112 {
113  // We should have a blocked packet if this function is called.
114  assert(blockedPacket != nullptr);
115 
116  // Grab the blocked packet.
117  PacketPtr pkt = blockedPacket;
118  blockedPacket = nullptr;
119 
120  // Try to resend it. It's possible that it fails again.
121  sendPacket(pkt);
122 }
123 
124 void
126 {
127  // Note: This flow control is very simple since the memobj is blocking.
128 
129  panic_if(blockedPacket != nullptr, "Should never try to send if blocked!");
130 
131  // If we can't send the packet across the port, store it for later.
132  if (!sendTimingReq(pkt)) {
133  blockedPacket = pkt;
134  }
135 }
136 
137 bool
139 {
140  // Just forward to the memobj.
141  return owner->handleResponse(pkt);
142 }
143 
144 void
146 {
147  // We should have a blocked packet if this function is called.
148  assert(blockedPacket != nullptr);
149 
150  // Grab the blocked packet.
151  PacketPtr pkt = blockedPacket;
152  blockedPacket = nullptr;
153 
154  // Try to resend it. It's possible that it fails again.
155  sendPacket(pkt);
156 }
157 
158 void
160 {
161  owner->sendRangeChange();
162 }
163 
164 bool
166 {
167  if (blocked) {
168  // There is currently an outstanding request. Stall.
169  return false;
170  }
171 
172  DPRINTF(SimpleMemobj, "Got request for addr %#x\n", pkt->getAddr());
173 
174  // This memobj is now blocked waiting for the response to this packet.
175  blocked = true;
176 
177  // Simply forward to the memory port
178  memPort.sendPacket(pkt);
179 
180  return true;
181 }
182 
183 bool
185 {
186  assert(blocked);
187  DPRINTF(SimpleMemobj, "Got response for addr %#x\n", pkt->getAddr());
188 
189  // The packet is now done. We're about to put it in the port, no need for
190  // this object to continue to stall.
191  // We need to free the resource before sending the packet in case the CPU
192  // tries to send another request immediately (e.g., in the same callchain).
193  blocked = false;
194 
195  // Simply forward to the memory port
196  if (pkt->req->isInstFetch()) {
197  instPort.sendPacket(pkt);
198  } else {
199  dataPort.sendPacket(pkt);
200  }
201 
202  // For each of the cpu ports, if it needs to send a retry, it should do it
203  // now since this memory object may be unblocked now.
206 
207  return true;
208 }
209 
210 void
212 {
213  // Just pass this on to the memory side to handle for now.
214  memPort.sendFunctional(pkt);
215 }
216 
219 {
220  DPRINTF(SimpleMemobj, "Sending new ranges\n");
221  // Just use the same ranges as whatever is on the memory side.
222  return memPort.getAddrRanges();
223 }
224 
225 void
227 {
230 }
231 
232 
233 
235 SimpleMemobjParams::create()
236 {
237  return new SimpleMemobj(this);
238 }
bool handleResponse(PacketPtr pkt)
Handle the respone from the memory side.
#define DPRINTF(x,...)
Definition: trace.hh:222
Ports are used to interface objects to each other.
Definition: port.hh:56
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:282
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:50
const PortID InvalidPortID
Definition: types.hh:236
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:321
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Definition: sim_object.cc:123
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:720
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:249
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:89
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:435
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:235
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:181
Abstract superclass for simulation objects.
Definition: sim_object.hh:92
void recvRespRetry() override
Called by the master port if sendTimingResp was called on this slave port (causing recvTimingResp to ...

Generated on Mon Jun 8 2020 15:45:11 for gem5 by doxygen 1.8.13