gem5  v21.0.1.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
simple_cache.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/random.hh"
32 #include "debug/SimpleCache.hh"
33 #include "sim/system.hh"
34 
35 SimpleCache::SimpleCache(const SimpleCacheParams &params) :
36  ClockedObject(params),
37  latency(params.latency),
38  blockSize(params.system->cacheLineSize()),
39  capacity(params.size / blockSize),
40  memPort(params.name + ".mem_side", this),
41  blocked(false), originalPacket(nullptr), waitingPortId(-1), stats(this)
42 {
43  // Since the CPU side ports are a vector of ports, create an instance of
44  // the CPUSidePort for each connection. This member of params is
45  // automatically created depending on the name of the vector port and
46  // holds the number of connections to this port name
47  for (int i = 0; i < params.port_cpu_side_connection_count; ++i) {
48  cpuPorts.emplace_back(name() + csprintf(".cpu_side[%d]", i), i, this);
49  }
50 }
51 
52 Port &
53 SimpleCache::getPort(const std::string &if_name, PortID idx)
54 {
55  // This is the name from the Python SimObject declaration in SimpleCache.py
56  if (if_name == "mem_side") {
57  panic_if(idx != InvalidPortID,
58  "Mem side of simple cache not a vector port");
59  return memPort;
60  } else if (if_name == "cpu_side" && idx < cpuPorts.size()) {
61  // We should have already created all of the ports in the constructor
62  return cpuPorts[idx];
63  } else {
64  // pass it along to our super class
65  return ClockedObject::getPort(if_name, idx);
66  }
67 }
68 
69 void
71 {
72  // Note: This flow control is very simple since the cache is blocking.
73 
74  panic_if(blockedPacket != nullptr, "Should never try to send if blocked!");
75 
76  // If we can't send the packet across the port, store it for later.
77  DPRINTF(SimpleCache, "Sending %s to CPU\n", pkt->print());
78  if (!sendTimingResp(pkt)) {
79  DPRINTF(SimpleCache, "failed!\n");
80  blockedPacket = pkt;
81  }
82 }
83 
86 {
87  return owner->getAddrRanges();
88 }
89 
90 void
92 {
93  if (needRetry && blockedPacket == nullptr) {
94  // Only send a retry if the port is now completely free
95  needRetry = false;
96  DPRINTF(SimpleCache, "Sending retry req.\n");
97  sendRetryReq();
98  }
99 }
100 
101 void
103 {
104  // Just forward to the cache.
105  return owner->handleFunctional(pkt);
106 }
107 
108 bool
110 {
111  DPRINTF(SimpleCache, "Got request %s\n", pkt->print());
112 
113  if (blockedPacket || needRetry) {
114  // The cache may not be able to send a reply if this is blocked
115  DPRINTF(SimpleCache, "Request blocked\n");
116  needRetry = true;
117  return false;
118  }
119  // Just forward to the cache.
120  if (!owner->handleRequest(pkt, id)) {
121  DPRINTF(SimpleCache, "Request failed\n");
122  // stalling
123  needRetry = true;
124  return false;
125  } else {
126  DPRINTF(SimpleCache, "Request succeeded\n");
127  return true;
128  }
129 }
130 
131 void
133 {
134  // We should have a blocked packet if this function is called.
135  assert(blockedPacket != nullptr);
136 
137  // Grab the blocked packet.
138  PacketPtr pkt = blockedPacket;
139  blockedPacket = nullptr;
140 
141  DPRINTF(SimpleCache, "Retrying response pkt %s\n", pkt->print());
142  // Try to resend it. It's possible that it fails again.
143  sendPacket(pkt);
144 
145  // We may now be able to accept new packets
146  trySendRetry();
147 }
148 
149 void
151 {
152  // Note: This flow control is very simple since the cache is blocking.
153 
154  panic_if(blockedPacket != nullptr, "Should never try to send if blocked!");
155 
156  // If we can't send the packet across the port, store it for later.
157  if (!sendTimingReq(pkt)) {
158  blockedPacket = pkt;
159  }
160 }
161 
162 bool
164 {
165  // Just forward to the cache.
166  return owner->handleResponse(pkt);
167 }
168 
169 void
171 {
172  // We should have a blocked packet if this function is called.
173  assert(blockedPacket != nullptr);
174 
175  // Grab the blocked packet.
176  PacketPtr pkt = blockedPacket;
177  blockedPacket = nullptr;
178 
179  // Try to resend it. It's possible that it fails again.
180  sendPacket(pkt);
181 }
182 
183 void
185 {
186  owner->sendRangeChange();
187 }
188 
189 bool
191 {
192  if (blocked) {
193  // There is currently an outstanding request so we can't respond. Stall
194  return false;
195  }
196 
197  DPRINTF(SimpleCache, "Got request for addr %#x\n", pkt->getAddr());
198 
199  // This cache is now blocked waiting for the response to this packet.
200  blocked = true;
201 
202  // Store the port for when we get the response
203  assert(waitingPortId == -1);
204  waitingPortId = port_id;
205 
206  // Schedule an event after cache access latency to actually access
207  schedule(new EventFunctionWrapper([this, pkt]{ accessTiming(pkt); },
208  name() + ".accessEvent", true),
209  clockEdge(latency));
210 
211  return true;
212 }
213 
214 bool
216 {
217  assert(blocked);
218  DPRINTF(SimpleCache, "Got response for addr %#x\n", pkt->getAddr());
219 
220  // For now assume that inserts are off of the critical path and don't count
221  // for any added latency.
222  insert(pkt);
223 
225 
226  // If we had to upgrade the request packet to a full cache line, now we
227  // can use that packet to construct the response.
228  if (originalPacket != nullptr) {
229  DPRINTF(SimpleCache, "Copying data from new packet to old\n");
230  // We had to upgrade a previous packet. We can functionally deal with
231  // the cache access now. It better be a hit.
232  M5_VAR_USED bool hit = accessFunctional(originalPacket);
233  panic_if(!hit, "Should always hit after inserting");
235  delete pkt; // We may need to delay this, I'm not sure.
236  pkt = originalPacket;
237  originalPacket = nullptr;
238  } // else, pkt contains the data it needs
239 
240  sendResponse(pkt);
241 
242  return true;
243 }
244 
246 {
247  assert(blocked);
248  DPRINTF(SimpleCache, "Sending resp for addr %#x\n", pkt->getAddr());
249 
250  int port = waitingPortId;
251 
252  // The packet is now done. We're about to put it in the port, no need for
253  // this object to continue to stall.
254  // We need to free the resource before sending the packet in case the CPU
255  // tries to send another request immediately (e.g., in the same callchain).
256  blocked = false;
257  waitingPortId = -1;
258 
259  // Simply forward to the memory port
260  cpuPorts[port].sendPacket(pkt);
261 
262  // For each of the cpu ports, if it needs to send a retry, it should do it
263  // now since this memory object may be unblocked now.
264  for (auto& port : cpuPorts) {
265  port.trySendRetry();
266  }
267 }
268 
269 void
271 {
272  if (accessFunctional(pkt)) {
273  pkt->makeResponse();
274  } else {
275  memPort.sendFunctional(pkt);
276  }
277 }
278 
279 void
281 {
282  bool hit = accessFunctional(pkt);
283 
284  DPRINTF(SimpleCache, "%s for packet: %s\n", hit ? "Hit" : "Miss",
285  pkt->print());
286 
287  if (hit) {
288  // Respond to the CPU side
289  stats.hits++; // update stats
290  DDUMP(SimpleCache, pkt->getConstPtr<uint8_t>(), pkt->getSize());
291  pkt->makeResponse();
292  sendResponse(pkt);
293  } else {
294  stats.misses++; // update stats
295  missTime = curTick();
296  // Forward to the memory side.
297  // We can't directly forward the packet unless it is exactly the size
298  // of the cache line, and aligned. Check for that here.
299  Addr addr = pkt->getAddr();
300  Addr block_addr = pkt->getBlockAddr(blockSize);
301  unsigned size = pkt->getSize();
302  if (addr == block_addr && size == blockSize) {
303  // Aligned and block size. We can just forward.
304  DPRINTF(SimpleCache, "forwarding packet\n");
305  memPort.sendPacket(pkt);
306  } else {
307  DPRINTF(SimpleCache, "Upgrading packet to block size\n");
308  panic_if(addr - block_addr + size > blockSize,
309  "Cannot handle accesses that span multiple cache lines");
310  // Unaligned access to one cache block
311  assert(pkt->needsResponse());
312  MemCmd cmd;
313  if (pkt->isWrite() || pkt->isRead()) {
314  // Read the data from memory to write into the block.
315  // We'll write the data in the cache (i.e., a writeback cache)
316  cmd = MemCmd::ReadReq;
317  } else {
318  panic("Unknown packet type in upgrade size");
319  }
320 
321  // Create a new packet that is blockSize
322  PacketPtr new_pkt = new Packet(pkt->req, cmd, blockSize);
323  new_pkt->allocate();
324 
325  // Should now be block aligned
326  assert(new_pkt->getAddr() == new_pkt->getBlockAddr(blockSize));
327 
328  // Save the old packet
329  originalPacket = pkt;
330 
331  DPRINTF(SimpleCache, "forwarding packet\n");
332  memPort.sendPacket(new_pkt);
333  }
334  }
335 }
336 
337 bool
339 {
340  Addr block_addr = pkt->getBlockAddr(blockSize);
341  auto it = cacheStore.find(block_addr);
342  if (it != cacheStore.end()) {
343  if (pkt->isWrite()) {
344  // Write the data into the block in the cache
345  pkt->writeDataToBlock(it->second, blockSize);
346  } else if (pkt->isRead()) {
347  // Read the data out of the cache block into the packet
348  pkt->setDataFromBlock(it->second, blockSize);
349  } else {
350  panic("Unknown packet type!");
351  }
352  return true;
353  }
354  return false;
355 }
356 
357 void
359 {
360  // The packet should be aligned.
361  assert(pkt->getAddr() == pkt->getBlockAddr(blockSize));
362  // The address should not be in the cache
363  assert(cacheStore.find(pkt->getAddr()) == cacheStore.end());
364  // The pkt should be a response
365  assert(pkt->isResponse());
366 
367  if (cacheStore.size() >= capacity) {
368  // Select random thing to evict. This is a little convoluted since we
369  // are using a std::unordered_map. See http://bit.ly/2hrnLP2
370  int bucket, bucket_size;
371  do {
372  bucket = random_mt.random(0, (int)cacheStore.bucket_count() - 1);
373  } while ( (bucket_size = cacheStore.bucket_size(bucket)) == 0 );
374  auto block = std::next(cacheStore.begin(bucket),
375  random_mt.random(0, bucket_size - 1));
376 
377  DPRINTF(SimpleCache, "Removing addr %#x\n", block->first);
378 
379  // Write back the data.
380  // Create a new request-packet pair
381  RequestPtr req = std::make_shared<Request>(
382  block->first, blockSize, 0, 0);
383 
384  PacketPtr new_pkt = new Packet(req, MemCmd::WritebackDirty, blockSize);
385  new_pkt->dataDynamic(block->second); // This will be deleted later
386 
387  DPRINTF(SimpleCache, "Writing packet back %s\n", pkt->print());
388  // Send the write to memory
389  memPort.sendPacket(new_pkt);
390 
391  // Delete this entry
392  cacheStore.erase(block->first);
393  }
394 
395  DPRINTF(SimpleCache, "Inserting %s\n", pkt->print());
396  DDUMP(SimpleCache, pkt->getConstPtr<uint8_t>(), blockSize);
397 
398  // Allocate space for the cache block data
399  uint8_t *data = new uint8_t[blockSize];
400 
401  // Insert the data and address into the cache store
402  cacheStore[pkt->getAddr()] = data;
403 
404  // Write the data into the cache
406 }
407 
410 {
411  DPRINTF(SimpleCache, "Sending new ranges\n");
412  // Just use the same ranges as whatever is on the memory side.
413  return memPort.getAddrRanges();
414 }
415 
416 void
418 {
419  for (auto& port : cpuPorts) {
420  port.sendRangeChange();
421  }
422 }
423 
425  : Stats::Group(parent),
426  ADD_STAT(hits, UNIT_COUNT, "Number of hits"),
427  ADD_STAT(misses, UNIT_COUNT, "Number of misses"),
428  ADD_STAT(missLatency, UNIT_TICK, "Ticks for misses to the cache"),
429  ADD_STAT(hitRatio, UNIT_RATIO,
430  "The ratio of hits to the total accesses to the cache",
431  hits / (hits + misses))
432 {
433  missLatency.init(16); // number of buckets
434 }
SimpleCache::SimpleCacheStats::SimpleCacheStats
SimpleCacheStats(Stats::Group *parent)
Definition: simple_cache.cc:424
SimpleCache::SimpleCacheStats::hits
Stats::Scalar hits
Definition: simple_cache.hh:299
Packet::isResponse
bool isResponse() const
Definition: packet.hh:561
SimpleCache::getPort
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition: simple_cache.cc:53
system.hh
data
const char data[]
Definition: circlebuf.test.cc:47
Packet::getAddr
Addr getAddr() const
Definition: packet.hh:755
ResponsePort::sendTimingResp
bool sendTimingResp(PacketPtr pkt)
Attempt to send a timing response to the request port by calling its corresponding receive function.
Definition: port.hh:367
InvalidPortID
const PortID InvalidPortID
Definition: types.hh:244
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
SimpleCache::handleFunctional
void handleFunctional(PacketPtr pkt)
Handle a packet functionally.
Definition: simple_cache.cc:270
random.hh
Packet::isRead
bool isRead() const
Definition: packet.hh:557
MemCmd::ReadReq
@ ReadReq
Definition: packet.hh:83
UNIT_TICK
#define UNIT_TICK
Definition: units.hh:40
PortID
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:243
SimpleCache::getAddrRanges
AddrRangeList getAddrRanges() const
Return the address ranges this cache is responsible for.
Definition: simple_cache.cc:409
Stats::Group::Group
Group()=delete
RequestPort::getAddrRanges
AddrRangeList getAddrRanges() const
Get the address ranges of the connected responder port.
Definition: port.cc:148
RequestPtr
std::shared_ptr< Request > RequestPtr
Definition: request.hh:86
Packet::req
RequestPtr req
A pointer to the original request.
Definition: packet.hh:341
SimpleCache::MemSidePort::recvRangeChange
void recvRangeChange() override
Called to receive an address range change from the peer response port.
Definition: simple_cache.cc:184
SimpleCache::MemSidePort::sendPacket
void sendPacket(PacketPtr pkt)
Send a packet across this port.
Definition: simple_cache.cc:150
Packet::dataDynamic
void dataDynamic(T *p)
Set the data pointer to a value that should have delete [] called on it.
Definition: packet.hh:1146
Packet::getSize
unsigned getSize() const
Definition: packet.hh:765
RequestPort::sendFunctional
void sendFunctional(PacketPtr pkt) const
Send a functional request packet, where the data is instantly updated everywhere in the memory system...
Definition: port.hh:482
SimpleCache::handleResponse
bool handleResponse(PacketPtr pkt)
Handle the respone from the memory side.
Definition: simple_cache.cc:215
SimpleCache::cacheStore
std::unordered_map< Addr, uint8_t * > cacheStore
An incredibly simple cache storage. Maps block addresses to data.
Definition: simple_cache.hh:292
Packet::writeDataToBlock
void writeDataToBlock(uint8_t *blk_data, int blkSize) const
Copy data from the packet to the provided block pointer, which is aligned to the given block size.
Definition: packet.hh:1279
Packet::print
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
Definition: packet.cc:389
SimpleCache::capacity
const unsigned capacity
Number of blocks in the cache (size of cache / block size)
Definition: simple_cache.hh:270
ClockedObject
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
Definition: clocked_object.hh:231
Random::random
std::enable_if_t< std::is_integral< T >::value, T > random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
Definition: random.hh:86
EventFunctionWrapper
Definition: eventq.hh:1112
SimpleCache::handleRequest
bool handleRequest(PacketPtr pkt, int port_id)
Handle the request from the CPU side.
Definition: simple_cache.cc:190
SimpleCache::SimpleCacheStats::misses
Stats::Scalar misses
Definition: simple_cache.hh:300
random_mt
Random random_mt
Definition: random.cc:96
X86ISA::system
Bitfield< 15 > system
Definition: misc.hh:997
EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1016
SimpleCache::sendRangeChange
void sendRangeChange() const
Tell the CPU side to ask for our memory ranges.
Definition: simple_cache.cc:417
SimpleCache::CPUSidePort::blockedPacket
PacketPtr blockedPacket
If we tried to send a packet and it was blocked, store it here.
Definition: simple_cache.hh:67
MemCmd::WritebackDirty
@ WritebackDirty
Definition: packet.hh:89
SimpleCache::MemSidePort::recvReqRetry
void recvReqRetry() override
Called by the response port if sendTimingReq was called on this request port (causing recvTimingReq t...
Definition: simple_cache.cc:170
SimpleCache::insert
void insert(PacketPtr pkt)
Insert a block into the cache.
Definition: simple_cache.cc:358
SimpleCache::accessTiming
void accessTiming(PacketPtr pkt)
Access the cache for a timing access.
Definition: simple_cache.cc:280
SimObject::getPort
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Definition: sim_object.cc:120
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:71
MemCmd
Definition: packet.hh:72
Packet::getBlockAddr
Addr getBlockAddr(unsigned int blk_size) const
Definition: packet.hh:779
SimpleCache::stats
SimpleCache::SimpleCacheStats stats
SimpleCache::CPUSidePort::trySendRetry
void trySendRetry()
Send a retry to the peer port only if it is needed.
Definition: simple_cache.cc:91
Port
Ports are used to interface objects to each other.
Definition: port.hh:56
Packet::needsResponse
bool needsResponse() const
Definition: packet.hh:571
Clocked::clockEdge
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Definition: clocked_object.hh:174
Packet::setDataFromBlock
void setDataFromBlock(const uint8_t *blk_data, int blkSize)
Copy data into the packet from the provided block pointer, which is aligned to the given block size.
Definition: packet.hh:1245
SimpleCache::sendResponse
void sendResponse(PacketPtr pkt)
Send the packet to the CPU side.
Definition: simple_cache.cc:245
SimpleCache::latency
const Cycles latency
Latency to check the cache. Number of cycles for both hit and miss.
Definition: simple_cache.hh:264
SimpleCache
A very simple cache object.
Definition: simple_cache.hh:46
UNIT_COUNT
#define UNIT_COUNT
Definition: units.hh:49
ProbePoints::Packet
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:103
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:148
Packet::makeResponse
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
Definition: packet.hh:1005
name
const std::string & name()
Definition: trace.cc:48
SimpleCache::CPUSidePort::sendPacket
void sendPacket(PacketPtr pkt)
Send a packet across this port.
Definition: simple_cache.cc:70
DDUMP
#define DDUMP(x, data, count)
DPRINTF is a debugging trace facility that allows one to selectively enable tracing statements.
Definition: trace.hh:236
UNIT_RATIO
#define UNIT_RATIO
Definition: units.hh:48
X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:80
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:182
SimpleCache::MemSidePort::recvTimingResp
bool recvTimingResp(PacketPtr pkt) override
Receive a timing response from the response port.
Definition: simple_cache.cc:163
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:197
SimpleCache::missTime
Tick missTime
For tracking the miss latency.
Definition: simple_cache.hh:289
SimpleCache::originalPacket
PacketPtr originalPacket
Packet that we are currently handling.
Definition: simple_cache.hh:283
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:258
Stats::Group
Statistics container.
Definition: group.hh:87
Stats::DistBase::sample
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Definition: statistics.hh:1323
Packet::isWrite
bool isWrite() const
Definition: packet.hh:558
SimpleCache::CPUSidePort::recvTimingReq
bool recvTimingReq(PacketPtr pkt) override
Receive a timing request from the request port.
Definition: simple_cache.cc:109
SimpleCache::CPUSidePort::getAddrRanges
AddrRangeList getAddrRanges() const override
Get a list of the non-overlapping address ranges the owner is responsible for.
Definition: simple_cache.cc:85
Stats
Definition: statistics.cc:53
curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:43
SimpleCache::CPUSidePort::recvRespRetry
void recvRespRetry() override
Called by the request port if sendTimingResp was called on this response port (causing recvTimingResp...
Definition: simple_cache.cc:132
Stats::Histogram::init
Histogram & init(size_type size)
Set the parameters of this histogram.
Definition: statistics.hh:2153
SimObject::params
const Params & params() const
Definition: sim_object.hh:168
SimpleCache::SimpleCache
SimpleCache(const SimpleCacheParams &params)
constructor
Definition: simple_cache.cc:35
std::list< AddrRange >
Packet::allocate
void allocate()
Allocate memory for the packet.
Definition: packet.hh:1300
SimpleCache::cpuPorts
std::vector< CPUSidePort > cpuPorts
Instantiation of the CPU-side port.
Definition: simple_cache.hh:273
simple_cache.hh
SimpleCache::memPort
MemSidePort memPort
Instantiation of the memory-side port.
Definition: simple_cache.hh:276
SimpleCache::SimpleCacheStats::missLatency
Stats::Histogram missLatency
Definition: simple_cache.hh:301
Packet::getConstPtr
const T * getConstPtr() const
Definition: packet.hh:1167
csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:158
SimpleCache::waitingPortId
int waitingPortId
The port to send the response when we recieve it back.
Definition: simple_cache.hh:286
SimpleCache::blockSize
const unsigned blockSize
The block size for the cache.
Definition: simple_cache.hh:267
SimpleCache::accessFunctional
bool accessFunctional(PacketPtr pkt)
This is where we actually update / read from the cache.
Definition: simple_cache.cc:338
SimpleCache::CPUSidePort::recvFunctional
void recvFunctional(PacketPtr pkt) override
Receive a functional request packet from the request port.
Definition: simple_cache.cc:102
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
SimpleCache::blocked
bool blocked
True if this cache is currently blocked waiting for a response.
Definition: simple_cache.hh:279

Generated on Tue Jun 22 2021 15:28:29 for gem5 by doxygen 1.8.17