gem5  v22.1.0.0
tlb_coalescer.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 Advanced Micro Devices, Inc.
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 met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its
16  * contributors may be used to endorse or promote products derived from this
17  * software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
33 
34 #include <cstring>
35 
38 #include "arch/generic/mmu.hh"
39 #include "base/logging.hh"
40 #include "debug/GPUTLB.hh"
41 #include "sim/process.hh"
42 
43 namespace gem5
44 {
45 
46 VegaTLBCoalescer::VegaTLBCoalescer(const VegaTLBCoalescerParams &p)
47  : ClockedObject(p),
48  TLBProbesPerCycle(p.probesPerCycle),
49  coalescingWindow(p.coalescingWindow),
50  disableCoalescing(p.disableCoalescing),
51  probeTLBEvent([this]{ processProbeTLBEvent(); },
52  "Probe the TLB below",
53  false, Event::CPU_Tick_Pri),
54  cleanupEvent([this]{ processCleanupEvent(); },
55  "Cleanup issuedTranslationsTable hashmap",
56  false, Event::Maximum_Pri),
57  tlb_level(p.tlb_level),
58  maxDownstream(p.maxDownstream),
59  numDownstream(0)
60 {
61  // create the response ports based on the number of connected ports
62  for (size_t i = 0; i < p.port_cpu_side_ports_connection_count; ++i) {
63  cpuSidePort.push_back(new CpuSidePort(csprintf("%s-port%d", name(), i),
64  this, i));
65  }
66 
67  // create the request ports based on the number of connected ports
68  for (size_t i = 0; i < p.port_mem_side_ports_connection_count; ++i) {
69  memSidePort.push_back(new MemSidePort(csprintf("%s-port%d", name(), i),
70  this, i));
71  }
72 }
73 
74 Port &
75 VegaTLBCoalescer::getPort(const std::string &if_name, PortID idx)
76 {
77  if (if_name == "cpu_side_ports") {
78  if (idx >= static_cast<PortID>(cpuSidePort.size())) {
79  panic("VegaTLBCoalescer::getPort: unknown index %d\n", idx);
80  }
81 
82  return *cpuSidePort[idx];
83  } else if (if_name == "mem_side_ports") {
84  if (idx >= static_cast<PortID>(memSidePort.size())) {
85  panic("VegaTLBCoalescer::getPort: unknown index %d\n", idx);
86  }
87 
88  return *memSidePort[idx];
89  } else {
90  panic("VegaTLBCoalescer::getPort: unknown port %s\n", if_name);
91  }
92 }
93 
94 /*
95  * This method returns true if the <incoming_pkt>
96  * can be coalesced with <coalesced_pkt> and false otherwise.
97  * A given set of rules is checked.
98  * The rules can potentially be modified based on the TLB level.
99  */
100 bool
102 {
103  if (disableCoalescing)
104  return false;
105 
106  GpuTranslationState *incoming_state =
107  safe_cast<GpuTranslationState*>(incoming_pkt->senderState);
108 
109  GpuTranslationState *coalesced_state =
110  safe_cast<GpuTranslationState*>(coalesced_pkt->senderState);
111 
112  // Rule 1: Coalesce requests only if they
113  // fall within the same virtual page
114  Addr incoming_virt_page_addr = roundDown(incoming_pkt->req->getVaddr(),
116 
117  Addr coalesced_virt_page_addr = roundDown(coalesced_pkt->req->getVaddr(),
119 
120  if (incoming_virt_page_addr != coalesced_virt_page_addr)
121  return false;
122 
123  //* Rule 2: Coalesce requests only if they
124  // share a TLB Mode, i.e. they are both read
125  // or write requests.
126  BaseMMU::Mode incoming_mode = incoming_state->tlbMode;
127  BaseMMU::Mode coalesced_mode = coalesced_state->tlbMode;
128 
129  if (incoming_mode != coalesced_mode)
130  return false;
131 
132  // when we can coalesce a packet update the reqCnt
133  // that is the number of packets represented by
134  // this coalesced packet
135  if (!incoming_state->isPrefetch)
136  coalesced_state->reqCnt.back() += incoming_state->reqCnt.back();
137 
138  return true;
139 }
140 
141 /*
142  * We need to update the physical addresses of all the translation requests
143  * that were coalesced into the one that just returned.
144  */
145 void
147 {
148  Addr virt_page_addr = roundDown(pkt->req->getVaddr(), VegaISA::PageBytes);
149 
150  DPRINTF(GPUTLB, "Update phys. addr. for %d coalesced reqs for page %#x\n",
151  issuedTranslationsTable[virt_page_addr].size(), virt_page_addr);
152 
153  GpuTranslationState *sender_state =
154  safe_cast<GpuTranslationState*>(pkt->senderState);
155 
156  // Make a copy. This gets deleted after the first is sent back on the port
157  assert(sender_state->tlbEntry);
158  VegaISA::VegaTlbEntry tlb_entry =
159  *safe_cast<VegaISA::VegaTlbEntry *>(sender_state->tlbEntry);
160  Addr first_entry_vaddr = tlb_entry.vaddr;
161  Addr first_entry_paddr = tlb_entry.paddr;
162  int page_size = tlb_entry.size();
163  bool uncacheable = tlb_entry.uncacheable();
164  int first_hit_level = sender_state->hitLevel;
165  bool is_system = pkt->req->systemReq();
166 
167  for (int i = 0; i < issuedTranslationsTable[virt_page_addr].size(); ++i) {
168  PacketPtr local_pkt = issuedTranslationsTable[virt_page_addr][i];
169  GpuTranslationState *sender_state =
170  safe_cast<GpuTranslationState*>(local_pkt->senderState);
171 
172  // we are sending the packet back, so pop the reqCnt associated
173  // with this level in the TLB hiearchy
174  if (!sender_state->isPrefetch) {
175  sender_state->reqCnt.pop_back();
176  localCycles += curCycle();
177  }
178 
179  /*
180  * Only the first packet from this coalesced request has been
181  * translated. Grab the translated phys. page addr and update the
182  * physical addresses of the remaining packets with the appropriate
183  * page offsets.
184  */
185  if (i) {
186  Addr paddr = first_entry_paddr
187  + (local_pkt->req->getVaddr() & (page_size - 1));
188  local_pkt->req->setPaddr(paddr);
189 
190  if (uncacheable)
191  local_pkt->req->setFlags(Request::UNCACHEABLE);
192 
193  // update senderState->tlbEntry, so we can insert
194  // the correct TLBEentry in the TLBs above.
195 
196  //auto p = sender_state->tc->getProcessPtr();
197  if (sender_state->tlbEntry == NULL) {
198  // not set by lower(l2) coalescer
199  sender_state->tlbEntry =
200  new VegaISA::VegaTlbEntry(1 /* VMID TODO */,
201  first_entry_vaddr,
202  first_entry_paddr,
203  tlb_entry.logBytes,
204  tlb_entry.pte);
205  }
206 
207  // update the hitLevel for all uncoalesced reqs
208  // so that each packet knows where it hit
209  // (used for statistics in the CUs)
210  sender_state->hitLevel = first_hit_level;
211  }
212 
213  // Copy PTE system bit information to coalesced requests
214  local_pkt->req->setSystemReq(is_system);
215 
216  ResponsePort *return_port = sender_state->ports.back();
217  sender_state->ports.pop_back();
218 
219  // Translation is done - Convert to a response pkt if necessary and
220  // send the translation back
221  if (local_pkt->isRequest()) {
222  local_pkt->makeTimingResponse();
223  }
224 
225  return_port->sendTimingResp(local_pkt);
226  }
227 
228  // schedule clean up for end of this cycle
229  // This is a maximum priority event and must be on
230  // the same cycle as GPUTLB cleanup event to prevent
231  // race conditions with an IssueProbeEvent caused by
232  // MemSidePort::recvReqRetry
233  cleanupQueue.push(virt_page_addr);
234 
235  if (!cleanupEvent.scheduled())
237 }
238 
239 // Receive translation requests, create a coalesced request,
240 // and send them to the TLB (TLBProbesPerCycle)
241 bool
243 {
244  // first packet of a coalesced request
245  PacketPtr first_packet = nullptr;
246  // true if we are able to do coalescing
247  bool didCoalesce = false;
248  // number of coalesced reqs for a given window
249  int coalescedReq_cnt = 0;
250 
251  GpuTranslationState *sender_state =
252  safe_cast<GpuTranslationState*>(pkt->senderState);
253 
254  bool update_stats = !sender_state->isPrefetch;
255 
256  if (coalescer->tlb_level == 1 && coalescer->mustStallCUPort(this))
257  return false;
258 
259  // push back the port to remember the path back
260  sender_state->ports.push_back(this);
261 
262  if (update_stats) {
263  // if reqCnt is empty then this packet does not represent
264  // multiple uncoalesced reqs(pkts) but just a single pkt.
265  // If it does though then the reqCnt for each level in the
266  // hierarchy accumulates the total number of reqs this packet
267  // represents
268  int req_cnt = 1;
269 
270  if (!sender_state->reqCnt.empty())
271  req_cnt = sender_state->reqCnt.back();
272 
273  sender_state->reqCnt.push_back(req_cnt);
274 
275  // update statistics
277  req_cnt = sender_state->reqCnt.back();
278  DPRINTF(GPUTLB, "receiving pkt w/ req_cnt %d\n", req_cnt);
279  coalescer->queuingCycles -= (coalescer->curCycle() * req_cnt);
282  }
283 
284  // Coalesce based on the time the packet arrives at the coalescer (here).
285  if (!sender_state->issueTime)
286  sender_state->issueTime = curTick();
287 
288  // The tick index is used as a key to the coalescerFIFO hashmap.
289  // It is shared by all candidates that fall within the
290  // given coalescingWindow.
291  Tick tick_index = sender_state->issueTime / coalescer->coalescingWindow;
292 
293  if (coalescer->coalescerFIFO.count(tick_index)) {
294  coalescedReq_cnt = coalescer->coalescerFIFO[tick_index].size();
295  }
296 
297  // see if we can coalesce the incoming pkt with another
298  // coalesced request with the same tick_index
299  for (int i = 0; i < coalescedReq_cnt; ++i) {
300  first_packet = coalescer->coalescerFIFO[tick_index][i][0];
301 
302  if (coalescer->canCoalesce(pkt, first_packet)) {
303  coalescer->coalescerFIFO[tick_index][i].push_back(pkt);
304 
305  DPRINTF(GPUTLB, "Coalesced req %i w/ tick_index %d has %d reqs\n",
306  i, tick_index,
307  coalescer->coalescerFIFO[tick_index][i].size());
308 
309  didCoalesce = true;
310  break;
311  }
312  }
313 
314  // if this is the first request for this tick_index
315  // or we did not manage to coalesce, update stats
316  // and make necessary allocations.
317  if (!coalescedReq_cnt || !didCoalesce) {
318  if (update_stats)
320 
321  std::vector<PacketPtr> new_array;
322  new_array.push_back(pkt);
323  coalescer->coalescerFIFO[tick_index].push_back(new_array);
324 
325  DPRINTF(GPUTLB, "coalescerFIFO[%d] now has %d coalesced reqs after "
326  "push\n", tick_index,
327  coalescer->coalescerFIFO[tick_index].size());
328  }
329 
330  //schedule probeTLBEvent next cycle to send the
331  //coalesced requests to the TLB
334  curTick() + coalescer->clockPeriod());
335  }
336 
337  return true;
338 }
339 
340 void
342 {
343  panic("recvReqRetry called");
344 }
345 
346 void
348 {
349 
350  GpuTranslationState *sender_state =
351  safe_cast<GpuTranslationState*>(pkt->senderState);
352 
353  bool update_stats = !sender_state->isPrefetch;
354 
355  if (update_stats)
356  coalescer->uncoalescedAccesses++;
357 
358  Addr virt_page_addr = roundDown(pkt->req->getVaddr(), VegaISA::PageBytes);
359  int map_count = coalescer->issuedTranslationsTable.count(virt_page_addr);
360 
361  if (map_count) {
362  DPRINTF(GPUTLB, "Warning! Functional access to addr %#x sees timing "
363  "req. pending\n", virt_page_addr);
364  }
365 
366  coalescer->memSidePort[0]->sendFunctional(pkt);
367 }
368 
371 {
372  // currently not checked by the requestor
373  AddrRangeList ranges;
374 
375  return ranges;
376 }
377 
378 /*
379  * a translation completed and returned
380  */
381 bool
383 {
384  coalescer->updatePhysAddresses(pkt);
385 
386  if (coalescer->tlb_level != 1)
387  return true;
388 
389 
390  coalescer->decrementNumDownstream();
391 
392  DPRINTF(GPUTLB,
393  "recvTimingReq: clscr = %p, numDownstream = %d, max = %d\n",
394  coalescer, coalescer->numDownstream, coalescer->maxDownstream);
395 
396  coalescer->unstallPorts();
397  return true;
398 }
399 
400 void
402 {
403  //we've receeived a retry. Schedule a probeTLBEvent
404  if (!coalescer->probeTLBEvent.scheduled())
405  coalescer->schedule(coalescer->probeTLBEvent,
406  curTick() + coalescer->clockPeriod());
407 }
408 
409 void
411 {
412  fatal("Memory side recvFunctional() not implemented in TLB coalescer.\n");
413 }
414 
415 /*
416  * Here we scan the coalescer FIFO and issue the max
417  * number of permitted probes to the TLB below. We
418  * permit bypassing of coalesced requests for the same
419  * tick_index.
420  *
421  * We do not access the next tick_index unless we've
422  * drained the previous one. The coalesced requests
423  * that are successfully sent are moved to the
424  * issuedTranslationsTable table (the table which keeps
425  * track of the outstanding reqs)
426  */
427 void
429 {
430  // number of TLB probes sent so far
431  int sent_probes = 0;
432 
433  // It is set to true either when the recvTiming of the TLB below
434  // returns false or when there is another outstanding request for the
435  // same virt. page.
436 
437  DPRINTF(GPUTLB, "triggered VegaTLBCoalescer %s\n", __func__);
438 
439  if ((tlb_level == 1)
440  && (availDownstreamSlots() == 0)) {
441  DPRINTF(GPUTLB, "IssueProbeEvent - no downstream slots, bail out\n");
442  return;
443  }
444 
445  for (auto iter = coalescerFIFO.begin();
446  iter != coalescerFIFO.end();) {
447  int coalescedReq_cnt = iter->second.size();
448  int i = 0;
449  int vector_index = 0;
450 
451  DPRINTF(GPUTLB, "coalescedReq_cnt is %d for tick_index %d\n",
452  coalescedReq_cnt, iter->first);
453 
454  while (i < coalescedReq_cnt) {
455  ++i;
456  PacketPtr first_packet = iter->second[vector_index][0];
457  //The request to coalescer is origanized as follows.
458  //The coalescerFIFO is a map which is indexed by coalescingWindow
459  // cycle. Only requests that falls in the same coalescingWindow
460  // considered for coalescing. Each entry of a coalescerFIFO is a
461  // vector of vectors. There is one entry for each different virtual
462  // page number and it contains vector of all request that are
463  // coalesced for the same virtual page address
464 
465  // compute virtual page address for this request
466  Addr virt_page_addr = roundDown(first_packet->req->getVaddr(),
468 
469  // is there another outstanding request for the same page addr?
470  int pending_reqs =
471  issuedTranslationsTable.count(virt_page_addr);
472 
473  if (pending_reqs) {
474  DPRINTF(GPUTLB, "Cannot issue - There are pending reqs for "
475  "page %#x\n", virt_page_addr);
476 
477  ++vector_index;
478  continue;
479  }
480 
481  // send the coalesced request for virt_page_addr
482  if (!memSidePort[0]->sendTimingReq(first_packet)) {
483  DPRINTF(GPUTLB,
484  "Failed to send TLB request for page %#x",
485  virt_page_addr);
486 
487  // No need for a retries queue since we are already
488  // buffering the coalesced request in coalescerFIFO.
489  // Arka:: No point trying to send other requests to TLB at
490  // this point since it is busy. Retries will be called later
491  // by the TLB below
492  return;
493  } else {
494 
495  if (tlb_level == 1)
497 
498  GpuTranslationState *tmp_sender_state =
499  safe_cast<GpuTranslationState*>(first_packet->senderState);
500 
501  bool update_stats = !tmp_sender_state->isPrefetch;
502 
503  if (update_stats) {
504  // req_cnt is total number of packets represented
505  // by the one we just sent counting all the way from
506  // the top of TLB hiearchy (i.e., from the CU)
507  int req_cnt = tmp_sender_state->reqCnt.back();
508  queuingCycles += (curCycle() * req_cnt);
509 
510  DPRINTF(GPUTLB, "%s sending pkt w/ req_cnt %d\n",
511  name(), req_cnt);
512 
513  // pkt_cnt is number of packets we coalesced into the one
514  // we just sent but only at this coalescer level
515  int pkt_cnt = iter->second[vector_index].size();
516  localqueuingCycles += (curCycle() * pkt_cnt);
517  }
518 
519  DPRINTF(GPUTLB, "Successfully sent TLB request for page %#x\n",
520  virt_page_addr);
521 
522  //copy coalescedReq to issuedTranslationsTable
523  issuedTranslationsTable[virt_page_addr]
524  = iter->second[vector_index];
525 
526  //erase the entry of this coalesced req
527  iter->second.erase(iter->second.begin() + vector_index);
528 
529  if (iter->second.empty())
530  assert( i == coalescedReq_cnt );
531 
532  sent_probes++;
533 
534  if (sent_probes == TLBProbesPerCycle ||
535  ((tlb_level == 1) && (!availDownstreamSlots()))) {
536  //Before returning make sure that empty vectors are taken
537  // out. Not a big issue though since a later invocation
538  // will take it out anyway.
539  if (iter->second.empty())
540  coalescerFIFO.erase(iter);
541 
542  //schedule probeTLBEvent next cycle to send the
543  //coalesced requests to the TLB
544  if (!probeTLBEvent.scheduled()) {
546  cyclesToTicks(curCycle() + Cycles(1)));
547  }
548  return;
549  }
550  }
551  }
552 
553  //if there are no more coalesced reqs for this tick_index
554  //erase the hash_map with the first iterator
555  if (iter->second.empty()) {
556  coalescerFIFO.erase(iter++);
557  } else {
558  ++iter;
559  }
560  }
561 }
562 
563 void
565 {
566  while (!cleanupQueue.empty()) {
567  Addr cleanup_addr = cleanupQueue.front();
568  cleanupQueue.pop();
569  issuedTranslationsTable.erase(cleanup_addr);
570 
571  DPRINTF(GPUTLB, "Cleanup - Delete coalescer entry with key %#x\n",
572  cleanup_addr);
573  }
574 }
575 
576 void
578 {
580 
582  .name(name() + ".uncoalesced_accesses")
583  .desc("Number of uncoalesced TLB accesses")
584  ;
585 
587  .name(name() + ".coalesced_accesses")
588  .desc("Number of coalesced TLB accesses")
589  ;
590 
592  .name(name() + ".queuing_cycles")
593  .desc("Number of cycles spent in queue")
594  ;
595 
597  .name(name() + ".local_queuing_cycles")
598  .desc("Number of cycles spent in queue for all incoming reqs")
599  ;
600 
602  .name(name() + ".local_cycles")
603  .desc("Number of cycles spent in queue for all incoming reqs")
604  ;
605 
607  .name(name() + ".local_latency")
608  .desc("Avg. latency over all incoming pkts")
609  ;
610 
611  latency
612  .name(name() + ".latency")
613  .desc("Avg. latency over all incoming pkts")
614  ;
615 
618 }
619 
620 void
622 {
623  assert(tlb_level == 1);
624  if (stalledPortsMap.count(port) != 0)
625  return; // we already know this port is stalled
626 
627  stalledPortsMap[port] = port;
628  stalledPortsQueue.push(port);
629  DPRINTF(GPUTLB,
630  "insertStalledPortIfNotMapped: port %p, mapSz = %d, qsz = %d\n",
631  port, stalledPortsMap.size(), stalledPortsQueue.size());
632 }
633 
634 bool
636 {
637  assert(tlb_level == 1);
638 
639  DPRINTF(GPUTLB, "mustStallCUPort: downstream = %d, max = %d\n",
641 
643  warn("RED ALERT - VegaTLBCoalescer::mustStallCUPort\n");
645  return true;
646  }
647  else
648  return false;
649 }
650 
651 void
653 {
654  assert(tlb_level == 1);
655  if (!stalledPorts() || availDownstreamSlots() == 0)
656  return;
657 
658  DPRINTF(GPUTLB, "unstallPorts()\n");
659  /*
660  * this check is needed because we can be called from recvTiiningResponse()
661  * or, synchronously due to having called sendRetry, from recvTimingReq()
662  */
663  if (availDownstreamSlots() == 0) // can happen if retry sent 1 downstream
664  return;
665  /*
666  * Consider this scenario
667  * 1) max downstream is reached
668  * 2) port1 tries to send a req, cant => stalledPortsQueue = [port1]
669  * 3) port2 tries to send a req, cant => stalledPortsQueue = [port1,
670  * port2]
671  * 4) a request completes and we remove port1 from both data
672  * structures & call
673  * sendRetry => stalledPortsQueue = [port2]
674  * 5) port1 sends one req downstream and a second is rejected
675  * => stalledPortsQueue = [port2, port1]
676  *
677  * so we round robin and each stalled port can send 1 req on retry
678  */
679  assert(availDownstreamSlots() == 1);
680  auto port = stalledPortsQueue.front();
681  DPRINTF(GPUTLB, "sending retry for port = %p(%s)\n", port, port->name());
682  stalledPortsQueue.pop();
683  auto iter = stalledPortsMap.find(port);
684  assert(iter != stalledPortsMap.end());
685  stalledPortsMap.erase(iter);
686  port->sendRetryReq(); // cu will synchronously call recvTimingReq
687 }
688 
689 } // namespace gem5
#define DPRINTF(x,...)
Definition: trace.hh:186
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
Tick cyclesToTicks(Cycles c) const
Tick clockPeriod() const
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:79
virtual std::string name() const
Definition: named.hh:47
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
void makeTimingResponse()
Definition: packet.hh:1077
SenderState * senderState
This packet's sender state.
Definition: packet.hh:544
RequestPtr req
A pointer to the original request.
Definition: packet.hh:376
bool isRequest() const
Definition: packet.hh:596
@ UNCACHEABLE
The request is to an uncacheable address.
Definition: request.hh:125
A ResponsePort is a specialization of a port.
Definition: port.hh:270
bool sendTimingResp(PacketPtr pkt)
Attempt to send a timing response to the request port by calling its corresponding receive function.
Definition: port.hh:370
virtual AddrRangeList getAddrRanges() const
Get a list of the non-overlapping address ranges the owner is responsible for.
virtual void recvFunctional(PacketPtr pkt)
Receive a functional request packet from the peer.
virtual bool recvTimingReq(PacketPtr pkt)
Receive a timing request from the peer.
virtual void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
virtual void recvFunctional(PacketPtr pkt)
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
statistics::Scalar localqueuingCycles
statistics::Scalar coalescedAccesses
CoalescingTable issuedTranslationsTable
void updatePhysAddresses(PacketPtr pkt)
statistics::Scalar queuingCycles
EventFunctionWrapper cleanupEvent
The cleanupEvent is scheduled after a TLBEvent triggers in order to free memory and do the required c...
std::queue< CpuSidePort * > stalledPortsQueue
statistics::Scalar uncoalescedAccesses
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
std::vector< CpuSidePort * > cpuSidePort
std::vector< MemSidePort * > memSidePort
EventFunctionWrapper probeTLBEvent
This event issues the TLB probes.
VegaTLBCoalescer(const VegaTLBCoalescerParams &p)
void insertStalledPortIfNotMapped(CpuSidePort *)
CoalescingFIFO coalescerFIFO
std::map< CpuSidePort *, CpuSidePort * > stalledPortsMap
bool canCoalesce(PacketPtr pkt1, PacketPtr pkt2)
void regStats() override
Callback to set stat parameters.
statistics::Formula localLatency
unsigned int availDownstreamSlots()
std::queue< Addr > cleanupQueue
bool mustStallCUPort(CpuSidePort *)
statistics::Scalar localCycles
unsigned int numDownstream
statistics::Formula latency
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Definition: statistics.hh:289
STL vector class.
Definition: stl.hh:37
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
Definition: intmath.hh:279
static const Priority Maximum_Pri
Maximum priority.
Definition: eventq.hh:241
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:465
void schedule(Event &event, Tick when)
Definition: eventq.hh:1019
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
Definition: eventq.hh:204
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:190
virtual void regStats()
Callback to set stat parameters.
Definition: group.cc:69
#define warn(...)
Definition: logging.hh:246
Bitfield< 7 > i
Definition: misc_types.hh:67
const Addr PageBytes
Definition: page_size.hh:42
Bitfield< 54 > p
Definition: pagetable.hh:70
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:245
uint64_t Tick
Tick count type.
Definition: types.hh:58
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
GPU TranslationState: this currently is a somewhat bastardization of the usage of SenderState,...
std::vector< ResponsePort * > ports
const std::string & name()
Definition: trace.cc:49

Generated on Wed Dec 21 2022 10:22:15 for gem5 by doxygen 1.9.1