gem5  v20.1.0.0
RubySystem.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 ARM Limited
3  * All rights reserved.
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 1999-2011 Mark D. Hill and David A. Wood
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  */
40 
42 
43 #include <fcntl.h>
44 #include <zlib.h>
45 
46 #include <cstdio>
47 #include <list>
48 
49 #include "base/intmath.hh"
50 #include "base/statistics.hh"
51 #include "debug/RubyCacheTrace.hh"
52 #include "debug/RubySystem.hh"
57 #include "mem/simple_mem.hh"
58 #include "sim/eventq.hh"
59 #include "sim/simulate.hh"
60 #include "sim/system.hh"
61 
62 using namespace std;
63 
68 bool RubySystem::m_warmup_enabled = false;
69 // To look forward to allowing multiple RubySystem instances, track the number
70 // of RubySystems that need to be warmed up on checkpoint restore.
73 
75  : ClockedObject(p), m_access_backing_store(p->access_backing_store),
76  m_cache_recorder(NULL)
77 {
78  m_randomization = p->randomization;
79 
80  m_block_size_bytes = p->block_size_bytes;
83  m_memory_size_bits = p->memory_size_bits;
84 
85  // Resize to the size of different machine types
86  m_abstract_controls.resize(MachineType_NUM);
87 
88  // Collate the statistics before they are printed.
90  // Create the profiler
91  m_profiler = new Profiler(p, this);
92  m_phys_mem = p->phys_mem;
93 }
94 
95 void
97 {
98  m_networks.emplace_back(network_ptr);
99 }
100 
101 void
103 {
104  m_abs_cntrl_vec.push_back(cntrl);
105 
106  MachineID id = cntrl->getMachineID();
107  m_abstract_controls[id.getType()][id.getNum()] = cntrl;
108 }
109 
110 void
112 {
113  int network_id = -1;
114  for (int idx = 0; idx < m_networks.size(); ++idx) {
115  if (m_networks[idx].get() == network) {
116  network_id = idx;
117  }
118  }
119 
120  fatal_if(network_id < 0, "Could not add MachineID %s. Network not found",
121  MachineIDToString(mach_id).c_str());
122 
123  machineToNetwork.insert(std::make_pair(mach_id, network_id));
124 }
125 
126 // This registers all requestor IDs in the system for functional reads. This
127 // should be called in init() since requestor IDs are obtained in a SimObject's
128 // constructor and there are functional reads/writes between init() and
129 // startup().
130 void
132 {
133  // Create the map for RequestorID to network node. This is done in init()
134  // because all RequestorIDs must be obtained in the constructor and
135  // AbstractControllers are registered in their constructor. This is done
136  // in two steps: (1) Add all of the AbstractControllers. Since we don't
137  // have a mapping of RequestorID to MachineID this is the easiest way to
138  // filter out AbstractControllers from non-Ruby requestors. (2) Go through
139  // the system's list of RequestorIDs and add missing RequestorIDs to
140  // network 0 (the default).
141  for (auto& cntrl : m_abs_cntrl_vec) {
142  RequestorID id = cntrl->getRequestorId();
143  MachineID mach_id = cntrl->getMachineID();
144 
145  // These are setup in Network constructor and should exist
146  fatal_if(!machineToNetwork.count(mach_id),
147  "No machineID %s. Does not belong to a Ruby network?",
148  MachineIDToString(mach_id).c_str());
149 
150  auto network_id = machineToNetwork[mach_id];
151  requestorToNetwork.insert(std::make_pair(id, network_id));
152 
153  // Create helper vectors for each network to iterate over.
154  netCntrls[network_id].push_back(cntrl);
155  }
156 
157  // Default all other requestor IDs to network 0
158  for (auto id = 0; id < params()->system->maxRequestors(); ++id) {
159  if (!requestorToNetwork.count(id)) {
160  requestorToNetwork.insert(std::make_pair(id, 0));
161  }
162  }
163 }
164 
166 {
167  delete m_profiler;
168 }
169 
170 void
171 RubySystem::makeCacheRecorder(uint8_t *uncompressed_trace,
172  uint64_t cache_trace_size,
173  uint64_t block_size_bytes)
174 {
175  vector<Sequencer*> sequencer_map;
176  Sequencer* sequencer_ptr = NULL;
177 
178  for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) {
179  sequencer_map.push_back(m_abs_cntrl_vec[cntrl]->getCPUSequencer());
180  if (sequencer_ptr == NULL) {
181  sequencer_ptr = sequencer_map[cntrl];
182  }
183  }
184 
185  assert(sequencer_ptr != NULL);
186 
187  for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) {
188  if (sequencer_map[cntrl] == NULL) {
189  sequencer_map[cntrl] = sequencer_ptr;
190  }
191  }
192 
193  // Remove the old CacheRecorder if it's still hanging about.
194  if (m_cache_recorder != NULL) {
195  delete m_cache_recorder;
196  }
197 
198  // Create the CacheRecorder and record the cache trace
199  m_cache_recorder = new CacheRecorder(uncompressed_trace, cache_trace_size,
200  sequencer_map, block_size_bytes);
201 }
202 
203 void
205 {
206  m_cooldown_enabled = true;
207 
208  // Make the trace so we know what to write back.
209  DPRINTF(RubyCacheTrace, "Recording Cache Trace\n");
211  for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) {
212  m_abs_cntrl_vec[cntrl]->recordCacheTrace(cntrl, m_cache_recorder);
213  }
214  DPRINTF(RubyCacheTrace, "Cache Trace Complete\n");
215 
216  // save the current tick value
217  Tick curtick_original = curTick();
218  DPRINTF(RubyCacheTrace, "Recording current tick %ld\n", curtick_original);
219 
220  // Deschedule all prior events on the event queue, but record the tick they
221  // were scheduled at so they can be restored correctly later.
222  list<pair<Event*, Tick> > original_events;
223  while (!eventq->empty()) {
224  Event *curr_head = eventq->getHead();
225  if (curr_head->isAutoDelete()) {
226  DPRINTF(RubyCacheTrace, "Event %s auto-deletes when descheduled,"
227  " not recording\n", curr_head->name());
228  } else {
229  original_events.push_back(make_pair(curr_head, curr_head->when()));
230  }
231  eventq->deschedule(curr_head);
232  }
233 
234  // Schedule an event to start cache cooldown
235  DPRINTF(RubyCacheTrace, "Starting cache flush\n");
237  simulate();
238  DPRINTF(RubyCacheTrace, "Cache flush complete\n");
239 
240  // Deschedule any events left on the event queue.
241  while (!eventq->empty()) {
243  }
244 
245  // Restore curTick
246  setCurTick(curtick_original);
247 
248  // Restore all events that were originally on the event queue. This is
249  // done after setting curTick back to its original value so that events do
250  // not seem to be scheduled in the past.
251  while (!original_events.empty()) {
252  pair<Event*, Tick> event = original_events.back();
253  eventq->schedule(event.first, event.second);
254  original_events.pop_back();
255  }
256 
257  // No longer flushing back to memory.
258  m_cooldown_enabled = false;
259 
260  // There are several issues with continuing simulation after calling
261  // memWriteback() at the moment, that stem from taking events off the
262  // queue, simulating again, and then putting them back on, whilst
263  // pretending that no time has passed. One is that some events will have
264  // been deleted, so can't be put back. Another is that any object
265  // recording the tick something happens may end up storing a tick in the
266  // future. A simple warning here alerts the user that things may not work
267  // as expected.
268  warn_once("Ruby memory writeback is experimental. Continuing simulation "
269  "afterwards may not always work as intended.");
270 
271  // Keep the cache recorder around so that we can dump the trace if a
272  // checkpoint is immediately taken.
273 }
274 
275 void
276 RubySystem::writeCompressedTrace(uint8_t *raw_data, string filename,
277  uint64_t uncompressed_trace_size)
278 {
279  // Create the checkpoint file for the memory
280  string thefile = CheckpointIn::dir() + "/" + filename.c_str();
281 
282  int fd = creat(thefile.c_str(), 0664);
283  if (fd < 0) {
284  perror("creat");
285  fatal("Can't open memory trace file '%s'\n", filename);
286  }
287 
288  gzFile compressedMemory = gzdopen(fd, "wb");
289  if (compressedMemory == NULL)
290  fatal("Insufficient memory to allocate compression state for %s\n",
291  filename);
292 
293  if (gzwrite(compressedMemory, raw_data, uncompressed_trace_size) !=
294  uncompressed_trace_size) {
295  fatal("Write failed on memory trace file '%s'\n", filename);
296  }
297 
298  if (gzclose(compressedMemory)) {
299  fatal("Close failed on memory trace file '%s'\n", filename);
300  }
301  delete[] raw_data;
302 }
303 
304 void
306 {
307  // Store the cache-block size, so we are able to restore on systems with a
308  // different cache-block size. CacheRecorder depends on the correct
309  // cache-block size upon unserializing.
310  uint64_t block_size_bytes = getBlockSizeBytes();
311  SERIALIZE_SCALAR(block_size_bytes);
312 
313  // Check that there's a valid trace to use. If not, then memory won't be
314  // up-to-date and the simulation will probably fail when restoring from the
315  // checkpoint.
316  if (m_cache_recorder == NULL) {
317  fatal("Call memWriteback() before serialize() to create ruby trace");
318  }
319 
320  // Aggregate the trace entries together into a single array
321  uint8_t *raw_data = new uint8_t[4096];
322  uint64_t cache_trace_size = m_cache_recorder->aggregateRecords(&raw_data,
323  4096);
324  string cache_trace_file = name() + ".cache.gz";
325  writeCompressedTrace(raw_data, cache_trace_file, cache_trace_size);
326 
327  SERIALIZE_SCALAR(cache_trace_file);
328  SERIALIZE_SCALAR(cache_trace_size);
329 }
330 
331 void
333 {
334  // Delete the cache recorder if it was created in memWriteback()
335  // to checkpoint the current cache state.
336  if (m_cache_recorder) {
337  delete m_cache_recorder;
338  m_cache_recorder = NULL;
339  }
340 }
341 
342 void
343 RubySystem::readCompressedTrace(string filename, uint8_t *&raw_data,
344  uint64_t &uncompressed_trace_size)
345 {
346  // Read the trace file
347  gzFile compressedTrace;
348 
349  // trace file
350  int fd = open(filename.c_str(), O_RDONLY);
351  if (fd < 0) {
352  perror("open");
353  fatal("Unable to open trace file %s", filename);
354  }
355 
356  compressedTrace = gzdopen(fd, "rb");
357  if (compressedTrace == NULL) {
358  fatal("Insufficient memory to allocate compression state for %s\n",
359  filename);
360  }
361 
362  raw_data = new uint8_t[uncompressed_trace_size];
363  if (gzread(compressedTrace, raw_data, uncompressed_trace_size) <
364  uncompressed_trace_size) {
365  fatal("Unable to read complete trace from file %s\n", filename);
366  }
367 
368  if (gzclose(compressedTrace)) {
369  fatal("Failed to close cache trace file '%s'\n", filename);
370  }
371 }
372 
373 void
375 {
376  uint8_t *uncompressed_trace = NULL;
377 
378  // This value should be set to the checkpoint-system's block-size.
379  // Optional, as checkpoints without it can be run if the
380  // checkpoint-system's block-size == current block-size.
381  uint64_t block_size_bytes = getBlockSizeBytes();
382  UNSERIALIZE_OPT_SCALAR(block_size_bytes);
383 
384  string cache_trace_file;
385  uint64_t cache_trace_size = 0;
386 
387  UNSERIALIZE_SCALAR(cache_trace_file);
388  UNSERIALIZE_SCALAR(cache_trace_size);
389  cache_trace_file = cp.getCptDir() + "/" + cache_trace_file;
390 
391  readCompressedTrace(cache_trace_file, uncompressed_trace,
392  cache_trace_size);
393  m_warmup_enabled = true;
395 
396  // Create the cache recorder that will hang around until startup.
397  makeCacheRecorder(uncompressed_trace, cache_trace_size, block_size_bytes);
398 }
399 
400 void
402 {
404 }
405 
406 void
408 {
409 
410  // Ruby restores state from a checkpoint by resetting the clock to 0 and
411  // playing the requests that can possibly re-generate the cache state.
412  // The clock value is set to the actual checkpointed value once all the
413  // requests have been executed.
414  //
415  // This way of restoring state is pretty finicky. For example, if a
416  // Ruby component reads time before the state has been restored, it would
417  // cache this value and hence its clock would not be reset to 0, when
418  // Ruby resets the global clock. This can potentially result in a
419  // deadlock.
420  //
421  // The solution is that no Ruby component should read time before the
422  // simulation starts. And then one also needs to hope that the time
423  // Ruby finishes restoring the state is less than the time when the
424  // state was checkpointed.
425 
426  if (m_warmup_enabled) {
427  DPRINTF(RubyCacheTrace, "Starting ruby cache warmup\n");
428  // save the current tick value
429  Tick curtick_original = curTick();
430  // save the event queue head
431  Event* eventq_head = eventq->replaceHead(NULL);
432  // set curTick to 0 and reset Ruby System's clock
433  setCurTick(0);
434  resetClock();
435 
436  // Schedule an event to start cache warmup
438  simulate();
439 
440  delete m_cache_recorder;
441  m_cache_recorder = NULL;
443  if (m_systems_to_warmup == 0) {
444  m_warmup_enabled = false;
445  }
446 
447  // Restore eventq head
448  eventq->replaceHead(eventq_head);
449  // Restore curTick and Ruby System's clock
450  setCurTick(curtick_original);
451  resetClock();
452  }
453 
454  resetStats();
455 }
456 
457 void
459 {
460  if (getWarmupEnabled()) {
462  } else if (getCooldownEnabled()) {
464  }
465 }
466 
467 void
469 {
471  for (auto& network : m_networks) {
472  network->resetStats();
473  }
474 }
475 
476 bool
478 {
479  Addr address(pkt->getAddr());
480  Addr line_address = makeLineAddress(address);
481 
482  AccessPermission access_perm = AccessPermission_NotPresent;
483 
484  DPRINTF(RubySystem, "Functional Read request for %#x\n", address);
485 
486  unsigned int num_ro = 0;
487  unsigned int num_rw = 0;
488  unsigned int num_busy = 0;
489  unsigned int num_maybe_stale = 0;
490  unsigned int num_backing_store = 0;
491  unsigned int num_invalid = 0;
492 
493  // Only send functional requests within the same network.
494  assert(requestorToNetwork.count(pkt->requestorId()));
495  int request_net_id = requestorToNetwork[pkt->requestorId()];
496  assert(netCntrls.count(request_net_id));
497 
498  AbstractController *ctrl_ro = nullptr;
499  AbstractController *ctrl_rw = nullptr;
500  AbstractController *ctrl_backing_store = nullptr;
501 
502  // In this loop we count the number of controllers that have the given
503  // address in read only, read write and busy states.
504  for (auto& cntrl : netCntrls[request_net_id]) {
505  access_perm = cntrl-> getAccessPermission(line_address);
506  if (access_perm == AccessPermission_Read_Only){
507  num_ro++;
508  if (ctrl_ro == nullptr) ctrl_ro = cntrl;
509  }
510  else if (access_perm == AccessPermission_Read_Write){
511  num_rw++;
512  if (ctrl_rw == nullptr) ctrl_rw = cntrl;
513  }
514  else if (access_perm == AccessPermission_Busy)
515  num_busy++;
516  else if (access_perm == AccessPermission_Maybe_Stale)
517  num_maybe_stale++;
518  else if (access_perm == AccessPermission_Backing_Store) {
519  // See RubySlicc_Exports.sm for details, but Backing_Store is meant
520  // to represent blocks in memory *for Broadcast/Snooping protocols*,
521  // where memory has no idea whether it has an exclusive copy of data
522  // or not.
523  num_backing_store++;
524  if (ctrl_backing_store == nullptr)
525  ctrl_backing_store = cntrl;
526  }
527  else if (access_perm == AccessPermission_Invalid ||
528  access_perm == AccessPermission_NotPresent)
529  num_invalid++;
530  }
531 
532  // This if case is meant to capture what happens in a Broadcast/Snoop
533  // protocol where the block does not exist in the cache hierarchy. You
534  // only want to read from the Backing_Store memory if there is no copy in
535  // the cache hierarchy, otherwise you want to try to read the RO or RW
536  // copies existing in the cache hierarchy (covered by the else statement).
537  // The reason is because the Backing_Store memory could easily be stale, if
538  // there are copies floating around the cache hierarchy, so you want to read
539  // it only if it's not in the cache hierarchy at all.
540  int num_controllers = netCntrls[request_net_id].size();
541  if (num_invalid == (num_controllers - 1) && num_backing_store == 1) {
542  DPRINTF(RubySystem, "only copy in Backing_Store memory, read from it\n");
543  ctrl_backing_store->functionalRead(line_address, pkt);
544  return true;
545  } else if (num_ro > 0 || num_rw >= 1) {
546  if (num_rw > 1) {
547  // We iterate over the vector of abstract controllers, and return
548  // the first copy found. If we have more than one cache with block
549  // in writable permission, the first one found would be returned.
550  warn("More than one Abstract Controller with RW permission for "
551  "addr: %#x on cacheline: %#x.", address, line_address);
552  }
553  // In Broadcast/Snoop protocols, this covers if you know the block
554  // exists somewhere in the caching hierarchy, then you want to read any
555  // valid RO or RW block. In directory protocols, same thing, you want
556  // to read any valid readable copy of the block.
557  DPRINTF(RubySystem, "num_maybe_stale=%d, num_busy = %d, num_ro = %d, "
558  "num_rw = %d\n",
559  num_maybe_stale, num_busy, num_ro, num_rw);
560  // Use the copy from the controller with read/write permission (if
561  // any), otherwise use get the first read only found
562  if (ctrl_rw) {
563  ctrl_rw->functionalRead(line_address, pkt);
564  } else {
565  assert(ctrl_ro);
566  ctrl_ro->functionalRead(line_address, pkt);
567  }
568  return true;
569  } else if ((num_busy + num_maybe_stale) > 0) {
570  // No controller has a valid copy of the block, but a transient or
571  // stale state indicates a valid copy should be in transit in the
572  // network or in a message buffer waiting to be handled
573  DPRINTF(RubySystem, "Controllers functionalRead lookup "
574  "(num_maybe_stale=%d, num_busy = %d)\n",
575  num_maybe_stale, num_busy);
576  for (auto& cntrl : netCntrls[request_net_id]) {
577  if (cntrl->functionalReadBuffers(pkt))
578  return true;
579  }
580  DPRINTF(RubySystem, "Network functionalRead lookup "
581  "(num_maybe_stale=%d, num_busy = %d)\n",
582  num_maybe_stale, num_busy);
583  for (auto& network : m_networks) {
584  if (network->functionalRead(pkt))
585  return true;
586  }
587  }
588 
589  return false;
590 }
591 
592 // The function searches through all the buffers that exist in different
593 // cache, directory and memory controllers, and in the network components
594 // and writes the data portion of those that hold the address specified
595 // in the packet.
596 bool
598 {
599  Addr addr(pkt->getAddr());
600  Addr line_addr = makeLineAddress(addr);
601  AccessPermission access_perm = AccessPermission_NotPresent;
602 
603  DPRINTF(RubySystem, "Functional Write request for %#x\n", addr);
604 
605  uint32_t M5_VAR_USED num_functional_writes = 0;
606 
607  // Only send functional requests within the same network.
608  assert(requestorToNetwork.count(pkt->requestorId()));
609  int request_net_id = requestorToNetwork[pkt->requestorId()];
610  assert(netCntrls.count(request_net_id));
611 
612  for (auto& cntrl : netCntrls[request_net_id]) {
613  num_functional_writes += cntrl->functionalWriteBuffers(pkt);
614 
615  access_perm = cntrl->getAccessPermission(line_addr);
616  if (access_perm != AccessPermission_Invalid &&
617  access_perm != AccessPermission_NotPresent) {
618  num_functional_writes +=
619  cntrl->functionalWrite(line_addr, pkt);
620  }
621 
622  // Also updates requests pending in any sequencer associated
623  // with the controller
624  if (cntrl->getCPUSequencer()) {
625  num_functional_writes +=
626  cntrl->getCPUSequencer()->functionalWrite(pkt);
627  }
628  if (cntrl->getDMASequencer()) {
629  num_functional_writes +=
630  cntrl->getDMASequencer()->functionalWrite(pkt);
631  }
632  }
633 
634  for (auto& network : m_networks) {
635  num_functional_writes += network->functionalWrite(pkt);
636  }
637  DPRINTF(RubySystem, "Messages written = %u\n", num_functional_writes);
638 
639  return true;
640 }
641 
642 RubySystem *
643 RubySystemParams::create()
644 {
645  return new RubySystem(this);
646 }
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
RubySystem::m_abstract_controls
std::vector< std::map< uint32_t, AbstractController * > > m_abstract_controls
Definition: RubySystem.hh:151
warn
#define warn(...)
Definition: logging.hh:239
CacheRecorder
Definition: CacheRecorder.hh:66
RubySystem::functionalRead
bool functionalRead(Packet *ptr)
Definition: RubySystem.cc:477
CacheRecorder::aggregateRecords
uint64_t aggregateRecords(uint8_t **data, uint64_t size)
Definition: CacheRecorder.cc:171
system.hh
RubySystem::getBlockSizeBytes
static uint32_t getBlockSizeBytes()
Definition: RubySystem.hh:62
RubySystem::registerAbstractController
void registerAbstractController(AbstractController *)
Definition: RubySystem.cc:102
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:797
Packet::getAddr
Addr getAddr() const
Definition: packet.hh:754
makeLineAddress
Addr makeLineAddress(Addr addr)
Definition: Address.cc:54
Sequencer
Definition: Sequencer.hh:80
RubySystem::m_phys_mem
SimpleMemory * m_phys_mem
Definition: RubySystem.hh:136
warn_once
#define warn_once(...)
Definition: logging.hh:243
RubySystem::m_start_cycle
Cycles m_start_cycle
Definition: RubySystem.hh:142
DMASequencer.hh
CacheRecorder::enqueueNextFetchRequest
void enqueueNextFetchRequest()
Function for fetching warming up the memory and the caches.
Definition: CacheRecorder.cc:105
EventQueue::replaceHead
Event * replaceHead(Event *s)
function for replacing the head of the event queue, so that a different set of events can run without...
Definition: eventq.cc:355
RubySystem::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: RubySystem.cc:374
RubySystem::writeCompressedTrace
static void writeCompressedTrace(uint8_t *raw_data, std::string file, uint64_t uncompressed_trace_size)
Definition: RubySystem.cc:276
RubySystem::requestorToNetwork
std::unordered_map< RequestorID, unsigned > requestorToNetwork
Definition: RubySystem.hh:145
RubySystem::Params
RubySystemParams Params
Definition: RubySystem.hh:55
CacheRecorder::enqueueNextFlushRequest
void enqueueNextFlushRequest()
Function for flushing the memory contents of the caches to the main memory.
Definition: CacheRecorder.cc:83
simulate.hh
Stats::registerDumpCallback
void registerDumpCallback(const std::function< void()> &callback)
Register a callback that should be called whenever statistics are about to be dumped.
Definition: statistics.cc:589
ArmISA::fd
Bitfield< 14, 12 > fd
Definition: types.hh:159
RubySystem::m_block_size_bytes
static uint32_t m_block_size_bytes
Definition: RubySystem.hh:129
RubySystem::resetStats
void resetStats() override
Callback to reset stats.
Definition: RubySystem.cc:468
RubySystem::drainResume
void drainResume() override
Resume execution after a successful drain.
Definition: RubySystem.cc:332
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
RubySystem::RubySystem
RubySystem(const Params *p)
Definition: RubySystem.cc:74
EventQueue::getHead
Event * getHead() const
Definition: eventq.hh:851
RubySystem::registerMachineID
void registerMachineID(const MachineID &mach_id, Network *network)
Definition: RubySystem.cc:111
Packet::requestorId
RequestorID requestorId() const
Definition: packet.hh:740
RubySystem::m_cooldown_enabled
static bool m_cooldown_enabled
Definition: RubySystem.hh:135
std::vector< Sequencer * >
AbstractController
Definition: AbstractController.hh:74
RubySystem::netCntrls
std::unordered_map< unsigned, std::vector< AbstractController * > > netCntrls
Definition: RubySystem.hh:146
floorLog2
std::enable_if< std::is_integral< T >::value, int >::type floorLog2(T x)
Definition: intmath.hh:63
RubySystem::m_networks
std::vector< std::unique_ptr< Network > > m_networks
Definition: RubySystem.hh:140
RubySystem::registerRequestorIDs
void registerRequestorIDs()
Definition: RubySystem.cc:131
Event::when
Tick when() const
Get the time that the event is scheduled.
Definition: eventq.hh:503
MachineID
Definition: MachineID.hh:38
RubySystem::m_profiler
Profiler * m_profiler
Definition: RubySystem.hh:149
RubySystem::registerNetwork
void registerNetwork(Network *)
Definition: RubySystem.cc:96
ClockedObject
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
Definition: clocked_object.hh:231
RubySystem::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: RubySystem.cc:401
RubySystem::collateStats
void collateStats()
Definition: RubySystem.hh:84
RequestorID
uint16_t RequestorID
Definition: request.hh:85
RubySystem::~RubySystem
~RubySystem()
Definition: RubySystem.cc:165
cp
Definition: cprintf.cc:40
RubySystem::memWriteback
void memWriteback() override
Write back dirty buffers to memory using functional writes.
Definition: RubySystem.cc:204
Event
Definition: eventq.hh:246
Profiler
Definition: Profiler.hh:64
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
RubySystem::readCompressedTrace
static void readCompressedTrace(std::string filename, uint8_t *&raw_data, uint64_t &uncompressed_trace_size)
Definition: RubySystem.cc:343
RubySystem::m_abs_cntrl_vec
std::vector< AbstractController * > m_abs_cntrl_vec
Definition: RubySystem.hh:141
EventManager::setCurTick
void setCurTick(Tick newVal)
Definition: eventq.hh:1066
RubySystem
Definition: RubySystem.hh:52
MipsISA::event
Bitfield< 10, 5 > event
Definition: pra_constants.hh:297
statistics.hh
EventQueue::empty
bool empty() const
Returns true if no events are queued.
Definition: eventq.hh:891
RubySystem::makeCacheRecorder
void makeCacheRecorder(uint8_t *uncompressed_trace, uint64_t cache_trace_size, uint64_t block_size_bytes)
Definition: RubySystem.cc:171
RubySystem::functionalWrite
bool functionalWrite(Packet *ptr)
Definition: RubySystem.cc:597
AbstractController::functionalRead
virtual void functionalRead(const Addr &addr, PacketPtr)=0
Clocked::curCycle
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
Definition: clocked_object.hh:192
UNSERIALIZE_OPT_SCALAR
#define UNSERIALIZE_OPT_SCALAR(scalar)
Definition: serialize.hh:804
RubySystem::machineToNetwork
std::unordered_map< MachineID, unsigned > machineToNetwork
Definition: RubySystem.hh:144
simulate
GlobalSimLoopExitEvent * simulate(Tick num_cycles)
Simulate for num_cycles additional cycles.
Definition: simulate.cc:80
std::pair
STL pair class.
Definition: stl.hh:58
RubySystem.hh
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Network
Definition: Network.hh:76
RubySystem::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: RubySystem.cc:305
RubySystem::getCooldownEnabled
static bool getCooldownEnabled()
Definition: RubySystem.hh:66
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:790
RubySystem::m_memory_size_bits
static uint32_t m_memory_size_bits
Definition: RubySystem.hh:131
RubySystem::processRubyEvent
void processRubyEvent()
Definition: RubySystem.cc:458
EventQueue::schedule
void schedule(Event *event, Tick when, bool global=false)
Schedule the given event on this queue.
Definition: eventq.hh:757
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:133
RubySystem::params
const Params * params() const
Definition: RubySystem.hh:58
CheckpointIn::dir
static std::string dir()
Get the current checkout directory name.
Definition: serialize.cc:263
Network.hh
Event::isAutoDelete
bool isAutoDelete() const
The function returns true if the object is automatically deleted after the event is processed.
Definition: eventq.hh:496
RubySystem::m_randomization
static bool m_randomization
Definition: RubySystem.hh:128
RubySystem::startup
void startup() override
startup() is the final initialization call before simulation.
Definition: RubySystem.cc:407
Clocked::resetClock
void resetClock() const
Reset the object's clock using the current global tick value.
Definition: clocked_object.hh:134
std
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
Address.hh
RubySystem::getWarmupEnabled
static bool getWarmupEnabled()
Definition: RubySystem.hh:65
RubySystem::m_warmup_enabled
static bool m_warmup_enabled
Definition: RubySystem.hh:133
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
EventQueue::deschedule
void deschedule(Event *event)
Deschedule the specified event.
Definition: eventq.hh:790
addr
ip6_addr_t addr
Definition: inet.hh:423
EventManager::eventq
EventQueue * eventq
A pointer to this object's event queue.
Definition: eventq.hh:977
RubySystem::m_systems_to_warmup
static unsigned m_systems_to_warmup
Definition: RubySystem.hh:134
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:63
RubySystem::enqueueRubyEvent
void enqueueRubyEvent(Tick tick)
Definition: RubySystem.hh:103
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
std::list
STL list class.
Definition: stl.hh:51
intmath.hh
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:219
CheckpointIn
Definition: serialize.hh:67
RubySystem::m_block_size_bits
static uint32_t m_block_size_bits
Definition: RubySystem.hh:130
Event::name
virtual const std::string name() const
Definition: eventq.cc:83
MachineIDToString
std::string MachineIDToString(MachineID machine)
Definition: MachineID.hh:53
isPowerOf2
bool isPowerOf2(const T &n)
Definition: intmath.hh:102
RubySystem::m_cache_recorder
CacheRecorder * m_cache_recorder
Definition: RubySystem.hh:150
ArmISA::id
Bitfield< 33 > id
Definition: miscregs_types.hh:247
AbstractController::getMachineID
MachineID getMachineID() const
Definition: AbstractController.hh:149
simple_mem.hh
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
eventq.hh
Sequencer.hh

Generated on Wed Sep 30 2020 14:02:14 for gem5 by doxygen 1.8.17