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

Generated on Thu May 28 2020 16:21:33 for gem5 by doxygen 1.8.13