gem5  [DEVELOP-FOR-23.0]
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
hbm_ctrl.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022 The Regents of the University of California
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 
29 #include "mem/hbm_ctrl.hh"
30 
31 #include "base/trace.hh"
32 #include "debug/DRAM.hh"
33 #include "debug/Drain.hh"
34 #include "debug/MemCtrl.hh"
35 #include "debug/QOS.hh"
36 #include "mem/dram_interface.hh"
37 #include "mem/mem_interface.hh"
38 #include "sim/system.hh"
39 
40 namespace gem5
41 {
42 
43 namespace memory
44 {
45 
46 HBMCtrl::HBMCtrl(const HBMCtrlParams &p) :
47  MemCtrl(p),
48  retryRdReqPC1(false), retryWrReqPC1(false),
49  nextReqEventPC1([this] {processNextReqEvent(pc1Int, respQueuePC1,
51  name()),
52  respondEventPC1([this] {processRespondEvent(pc1Int, respQueuePC1,
53  respondEventPC1, retryRdReqPC1); }, name()),
54  pc1Int(p.dram_2)
55 {
56  DPRINTF(MemCtrl, "Setting up HBM controller\n");
57 
58  pc0Int = dynamic_cast<DRAMInterface*>(dram);
59 
60  assert(dynamic_cast<DRAMInterface*>(p.dram_2) != nullptr);
61 
64 
65  fatal_if(!pc0Int, "Memory controller must have pc0 interface");
66  fatal_if(!pc1Int, "Memory controller must have pc1 interface");
67 
68  pc0Int->setCtrl(this, commandWindow, 0);
69  pc1Int->setCtrl(this, commandWindow, 1);
70 
71  writeHighThreshold = (writeBufferSize/2 * p.write_high_thresh_perc)/100.0;
72  writeLowThreshold = (writeBufferSize/2 * p.write_low_thresh_perc)/100.0;
73 }
74 
75 void
77 {
78  MemCtrl::init();
79 }
80 
81 void
83 {
85 
87  if (isTimingMode) {
88  // shift the bus busy time sufficiently far ahead that we never
89  // have to worry about negative values when computing the time for
90  // the next request, this will add an insignificant bubble at the
91  // start of simulation
93  }
94 }
95 
96 Tick
98 {
99  Tick latency = 0;
100 
101  if (pc0Int->getAddrRange().contains(pkt->getAddr())) {
102  latency = recvAtomicLogic(pkt, pc0Int);
103  } else if (pc1Int->getAddrRange().contains(pkt->getAddr())) {
104  latency = recvAtomicLogic(pkt, pc1Int);
105  } else {
106  panic("Can't handle address range for packet %s\n", pkt->print());
107  }
108 
109  return latency;
110 }
111 
112 void
114 {
115  bool found = recvFunctionalLogic(pkt, pc0Int);
116 
117  if (!found) {
118  found = recvFunctionalLogic(pkt, pc1Int);
119  }
120 
121  if (!found) {
122  panic("Can't handle address range for packet %s\n", pkt->print());
123  }
124 }
125 
126 Tick
128 {
129  Tick latency = recvAtomic(pkt);
130 
131  if (pc0Int && pc0Int->getAddrRange().contains(pkt->getAddr())) {
132  pc0Int->getBackdoor(backdoor);
133  } else if (pc1Int && pc1Int->getAddrRange().contains(pkt->getAddr())) {
134  pc1Int->getBackdoor(backdoor);
135  }
136  else {
137  panic("Can't handle address range for packet %s\n",
138  pkt->print());
139  }
140  return latency;
141 }
142 
143 void
145  MemBackdoorPtr &backdoor)
146 {
147  auto &range = req.range();
148  if (pc0Int && pc0Int->getAddrRange().isSubset(range)) {
149  pc0Int->getBackdoor(backdoor);
150  } else if (pc1Int && pc1Int->getAddrRange().isSubset(range)) {
151  pc1Int->getBackdoor(backdoor);
152  }
153  else {
154  panic("Can't handle address range for range %s\n", range.to_string());
155  }
156 }
157 
158 bool
159 HBMCtrl::writeQueueFullPC0(unsigned int neededEntries) const
160 {
162  "Write queue limit %d, PC0 size %d, entries needed %d\n",
163  writeBufferSize/2, pc0Int->writeQueueSize, neededEntries);
164 
165  unsigned int wrsize_new = (pc0Int->writeQueueSize + neededEntries);
166  return wrsize_new > (writeBufferSize/2);
167 }
168 
169 bool
170 HBMCtrl::writeQueueFullPC1(unsigned int neededEntries) const
171 {
173  "Write queue limit %d, PC1 size %d, entries needed %d\n",
174  writeBufferSize/2, pc1Int->writeQueueSize, neededEntries);
175 
176  unsigned int wrsize_new = (pc1Int->writeQueueSize + neededEntries);
177  return wrsize_new > (writeBufferSize/2);
178 }
179 
180 bool
181 HBMCtrl::readQueueFullPC0(unsigned int neededEntries) const
182 {
184  "Read queue limit %d, PC0 size %d, entries needed %d\n",
186  neededEntries);
187 
188  unsigned int rdsize_new = pc0Int->readQueueSize + respQueue.size()
189  + neededEntries;
190  return rdsize_new > (readBufferSize/2);
191 }
192 
193 bool
194 HBMCtrl::readQueueFullPC1(unsigned int neededEntries) const
195 {
197  "Read queue limit %d, PC1 size %d, entries needed %d\n",
199  neededEntries);
200 
201  unsigned int rdsize_new = pc1Int->readQueueSize + respQueuePC1.size()
202  + neededEntries;
203  return rdsize_new > (readBufferSize/2);
204 }
205 
206 bool
208 {
209  // This is where we enter from the outside world
210  DPRINTF(MemCtrl, "recvTimingReq: request %s addr %#x size %d\n",
211  pkt->cmdString(), pkt->getAddr(), pkt->getSize());
212 
213  panic_if(pkt->cacheResponding(), "Should not see packets where cache "
214  "is responding");
215 
216  panic_if(!(pkt->isRead() || pkt->isWrite()),
217  "Should only see read and writes at memory controller\n");
218 
219  // Calc avg gap between requests
220  if (prevArrival != 0) {
222  }
223  prevArrival = curTick();
224 
225  // What type of media does this packet access?
226  bool is_pc0;
227 
228  // TODO: make the interleaving bit across pseudo channels a parameter
229  if (bits(pkt->getAddr(), 6) == 0) {
230  is_pc0 = true;
231  } else {
232  is_pc0 = false;
233  }
234 
235  // Find out how many memory packets a pkt translates to
236  // If the burst size is equal or larger than the pkt size, then a pkt
237  // translates to only one memory packet. Otherwise, a pkt translates to
238  // multiple memory packets
239  unsigned size = pkt->getSize();
240  uint32_t burst_size = pc0Int->bytesPerBurst();
241  unsigned offset = pkt->getAddr() & (burst_size - 1);
242  unsigned int pkt_count = divCeil(offset + size, burst_size);
243 
244  // run the QoS scheduler and assign a QoS priority value to the packet
245  qosSchedule({&readQueue, &writeQueue}, burst_size, pkt);
246 
247  // check local buffers and do not accept if full
248  if (pkt->isWrite()) {
249  if (is_pc0) {
250  if (writeQueueFullPC0(pkt_count)) {
251  DPRINTF(MemCtrl, "Write queue full, not accepting\n");
252  // remember that we have to retry this port
253  retryWrReq = true;
254  stats.numWrRetry++;
255  return false;
256  } else {
257  addToWriteQueue(pkt, pkt_count, pc0Int);
258  if (!nextReqEvent.scheduled()) {
259  DPRINTF(MemCtrl, "Request scheduled immediately\n");
261  }
262  stats.writeReqs++;
263  stats.bytesWrittenSys += size;
264  }
265  } else {
266  if (writeQueueFullPC1(pkt_count)) {
267  DPRINTF(MemCtrl, "Write queue full, not accepting\n");
268  // remember that we have to retry this port
269  retryWrReqPC1 = true;
270  stats.numWrRetry++;
271  return false;
272  } else {
273  addToWriteQueue(pkt, pkt_count, pc1Int);
274  if (!nextReqEventPC1.scheduled()) {
275  DPRINTF(MemCtrl, "Request scheduled immediately\n");
277  }
278  stats.writeReqs++;
279  stats.bytesWrittenSys += size;
280  }
281  }
282  } else {
283 
284  assert(pkt->isRead());
285  assert(size != 0);
286 
287  if (is_pc0) {
288  if (readQueueFullPC0(pkt_count)) {
289  DPRINTF(MemCtrl, "Read queue full, not accepting\n");
290  // remember that we have to retry this port
291  retryRdReq = true;
292  stats.numRdRetry++;
293  return false;
294  } else {
295  if (!addToReadQueue(pkt, pkt_count, pc0Int)) {
296  if (!nextReqEvent.scheduled()) {
297  DPRINTF(MemCtrl, "Request scheduled immediately\n");
299  }
300  }
301 
302  stats.readReqs++;
303  stats.bytesReadSys += size;
304  }
305  } else {
306  if (readQueueFullPC1(pkt_count)) {
307  DPRINTF(MemCtrl, "Read queue full, not accepting\n");
308  // remember that we have to retry this port
309  retryRdReqPC1 = true;
310  stats.numRdRetry++;
311  return false;
312  } else {
313  if (!addToReadQueue(pkt, pkt_count, pc1Int)) {
314  if (!nextReqEventPC1.scheduled()) {
315  DPRINTF(MemCtrl, "Request scheduled immediately\n");
317  }
318  }
319  stats.readReqs++;
320  stats.bytesReadSys += size;
321  }
322  }
323  }
324 
325  return true;
326 }
327 
328 void
330 {
331  auto it = rowBurstTicks.begin();
332  while (it != rowBurstTicks.end()) {
333  auto current_it = it++;
334  if (getBurstWindow(curTick()) > *current_it) {
335  DPRINTF(MemCtrl, "Removing burstTick for %d\n", *current_it);
336  rowBurstTicks.erase(current_it);
337  }
338  }
339 }
340 
341 void
343 {
344  auto it = colBurstTicks.begin();
345  while (it != colBurstTicks.end()) {
346  auto current_it = it++;
347  if (getBurstWindow(curTick()) > *current_it) {
348  DPRINTF(MemCtrl, "Removing burstTick for %d\n", *current_it);
349  colBurstTicks.erase(current_it);
350  }
351  }
352 }
353 
354 void
356 {
359 }
360 
361 Tick
362 HBMCtrl::verifySingleCmd(Tick cmd_tick, Tick max_cmds_per_burst, bool row_cmd)
363 {
364  // start with assumption that there is no contention on command bus
365  Tick cmd_at = cmd_tick;
366 
367  // get tick aligned to burst window
368  Tick burst_tick = getBurstWindow(cmd_tick);
369 
370  // verify that we have command bandwidth to issue the command
371  // if not, iterate over next window(s) until slot found
372 
373  if (row_cmd) {
374  while (rowBurstTicks.count(burst_tick) >= max_cmds_per_burst) {
375  DPRINTF(MemCtrl, "Contention found on row command bus at %d\n",
376  burst_tick);
377  burst_tick += commandWindow;
378  cmd_at = burst_tick;
379  }
380  DPRINTF(MemCtrl, "Now can send a row cmd_at %d\n",
381  cmd_at);
382  rowBurstTicks.insert(burst_tick);
383 
384  } else {
385  while (colBurstTicks.count(burst_tick) >= max_cmds_per_burst) {
386  DPRINTF(MemCtrl, "Contention found on col command bus at %d\n",
387  burst_tick);
388  burst_tick += commandWindow;
389  cmd_at = burst_tick;
390  }
391  DPRINTF(MemCtrl, "Now can send a col cmd_at %d\n",
392  cmd_at);
393  colBurstTicks.insert(burst_tick);
394  }
395  return cmd_at;
396 }
397 
398 Tick
399 HBMCtrl::verifyMultiCmd(Tick cmd_tick, Tick max_cmds_per_burst,
400  Tick max_multi_cmd_split)
401 {
402 
403  // start with assumption that there is no contention on command bus
404  Tick cmd_at = cmd_tick;
405 
406  // get tick aligned to burst window
407  Tick burst_tick = getBurstWindow(cmd_tick);
408 
409  // Command timing requirements are from 2nd command
410  // Start with assumption that 2nd command will issue at cmd_at and
411  // find prior slot for 1st command to issue
412  // Given a maximum latency of max_multi_cmd_split between the commands,
413  // find the burst at the maximum latency prior to cmd_at
414  Tick burst_offset = 0;
415  Tick first_cmd_offset = cmd_tick % commandWindow;
416  while (max_multi_cmd_split > (first_cmd_offset + burst_offset)) {
417  burst_offset += commandWindow;
418  }
419  // get the earliest burst aligned address for first command
420  // ensure that the time does not go negative
421  Tick first_cmd_tick = burst_tick - std::min(burst_offset, burst_tick);
422 
423  // Can required commands issue?
424  bool first_can_issue = false;
425  bool second_can_issue = false;
426  // verify that we have command bandwidth to issue the command(s)
427  while (!first_can_issue || !second_can_issue) {
428  bool same_burst = (burst_tick == first_cmd_tick);
429  auto first_cmd_count = rowBurstTicks.count(first_cmd_tick);
430  auto second_cmd_count = same_burst ?
431  first_cmd_count + 1 : rowBurstTicks.count(burst_tick);
432 
433  first_can_issue = first_cmd_count < max_cmds_per_burst;
434  second_can_issue = second_cmd_count < max_cmds_per_burst;
435 
436  if (!second_can_issue) {
437  DPRINTF(MemCtrl, "Contention (cmd2) found on command bus at %d\n",
438  burst_tick);
439  burst_tick += commandWindow;
440  cmd_at = burst_tick;
441  }
442 
443  // Verify max_multi_cmd_split isn't violated when command 2 is shifted
444  // If commands initially were issued in same burst, they are
445  // now in consecutive bursts and can still issue B2B
446  bool gap_violated = !same_burst &&
447  ((burst_tick - first_cmd_tick) > max_multi_cmd_split);
448 
449  if (!first_can_issue || (!second_can_issue && gap_violated)) {
450  DPRINTF(MemCtrl, "Contention (cmd1) found on command bus at %d\n",
451  first_cmd_tick);
452  first_cmd_tick += commandWindow;
453  }
454  }
455 
456  // Add command to burstTicks
457  rowBurstTicks.insert(burst_tick);
458  rowBurstTicks.insert(first_cmd_tick);
459 
460  return cmd_at;
461 }
462 
463 void
465 {
466 
468 
469  if (!isTimingMode && system()->isTimingMode()) {
470  // if we switched to timing mode, kick things into action,
471  // and behave as if we restored from a checkpoint
472  startup();
473  pc1Int->startup();
474  } else if (isTimingMode && !system()->isTimingMode()) {
475  // if we switch from timing mode, stop the refresh events to
476  // not cause issues with KVM
477  if (pc1Int) {
478  pc1Int->drainRanks();
479  }
480  }
481 
482  // update the mode
484 }
485 
488 {
489  AddrRangeList ranges;
490  ranges.push_back(pc0Int->getAddrRange());
491  ranges.push_back(pc1Int->getAddrRange());
492  return ranges;
493 }
494 
495 } // namespace memory
496 } // namespace gem5
gem5::memory::HBMCtrl::recvTimingReq
bool recvTimingReq(PacketPtr pkt) override
Definition: hbm_ctrl.cc:207
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::Packet::cmdString
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
Definition: packet.hh:588
gem5::memory::MemCtrl::addToReadQueue
bool addToReadQueue(PacketPtr pkt, unsigned int pkt_count, MemInterface *mem_intr)
When a new read comes in, first check if the write q has a pending request to the same address....
Definition: mem_ctrl.cc:189
gem5::memory::HBMCtrl::pc1Int
DRAMInterface * pc1Int
Definition: hbm_ctrl.hh:195
gem5::memory::MemCtrl::writeLowThreshold
uint32_t writeLowThreshold
Definition: mem_ctrl.hh:517
gem5::memory::MemInterface::readQueueSize
uint32_t readQueueSize
Read/write packets in the read/write queue for this interface qos/mem_ctrl.hh has similar counters,...
Definition: mem_interface.hh:205
gem5::memory::MemCtrl::nextReqEvent
EventFunctionWrapper nextReqEvent
Definition: mem_ctrl.hh:307
system.hh
memory
Definition: mem.h:38
gem5::memory::HBMCtrl::recvMemBackdoorReq
void recvMemBackdoorReq(const MemBackdoorReq &req, MemBackdoorPtr &_backdoor) override
Definition: hbm_ctrl.cc:144
gem5::memory::HBMCtrl::getAddrRanges
AddrRangeList getAddrRanges() override
Definition: hbm_ctrl.cc:487
gem5::memory::AbstractMemory::getAddrRange
AddrRange getAddrRange() const
Get the address range.
Definition: abstract_mem.cc:250
gem5::AddrRange::contains
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:471
gem5::memory::HBMCtrl::HBMCtrl
HBMCtrl(const HBMCtrlParams &p)
Definition: hbm_ctrl.cc:46
gem5::memory::MemCtrl
The memory controller is a single-channel memory controller capturing the most important timing const...
Definition: mem_ctrl.hh:246
gem5::memory::HBMCtrl::verifySingleCmd
Tick verifySingleCmd(Tick cmd_tick, Tick max_cmds_per_burst, bool row_cmd) override
Check for command bus contention for single cycle command.
Definition: hbm_ctrl.cc:362
gem5::Packet::cacheResponding
bool cacheResponding() const
Definition: packet.hh:659
gem5::memory::HBMCtrl::colBurstTicks
std::unordered_multiset< Tick > colBurstTicks
This is used to ensure that the column command bandwidth does not exceed the allowable media constrai...
Definition: hbm_ctrl.hh:187
gem5::Packet::isWrite
bool isWrite() const
Definition: packet.hh:594
gem5::memory::MemCtrl::writeHighThreshold
uint32_t writeHighThreshold
Definition: mem_ctrl.hh:516
gem5::memory::DRAMInterface::drainRanks
void drainRanks() override
Iterate through dram ranks to exit self-refresh in order to drain.
Definition: dram_interface.cc:991
gem5::memory::MemCtrl::startup
virtual void startup() override
startup() is the final initialization call before simulation.
Definition: mem_ctrl.cc:110
gem5::memory::MemCtrl::prevArrival
Tick prevArrival
Definition: mem_ctrl.hh:552
gem5::AddrRange::isSubset
bool isSubset(const AddrRange &r) const
Determine if this range is a subset of another range, i.e.
Definition: addr_range.hh:445
gem5::memory::MemCtrl::MemCtrl
MemCtrl(const MemCtrlParams &p)
Definition: mem_ctrl.cc:60
gem5::memory::HBMCtrl::recvFunctional
void recvFunctional(PacketPtr pkt) override
Definition: hbm_ctrl.cc:113
gem5::memory::HBMCtrl::nextReqEventPC1
EventFunctionWrapper nextReqEventPC1
NextReq and Respond events for second pseudo channel.
Definition: hbm_ctrl.hh:134
gem5::memory::qos::MemCtrl::qosSchedule
uint8_t qosSchedule(std::initializer_list< Queues * > queues_ptr, uint64_t queue_entry_size, const PacketPtr pkt)
Assign priority to a packet by executing the configured QoS policy.
Definition: mem_ctrl.hh:495
gem5::memory::MemCtrl::readBufferSize
uint32_t readBufferSize
The following are basic design parameters of the memory controller, and are initialized based on para...
Definition: mem_ctrl.hh:514
gem5::memory::MemCtrl::CtrlStats::bytesReadSys
statistics::Scalar bytesReadSys
Definition: mem_ctrl.hh:592
gem5::memory::MemInterface::readBufferSize
const uint32_t readBufferSize
Buffer sizes for read and write queues in the controller These are passed to the controller on instan...
Definition: mem_interface.hh:176
gem5::memory::MemCtrl::retryRdReq
bool retryRdReq
Remember if we have to retry a request when available.
Definition: mem_ctrl.hh:293
gem5::memory::MemCtrl::writeQueue
std::vector< MemPacketQueue > writeQueue
Definition: mem_ctrl.hh:473
gem5::memory::HBMCtrl::pruneColBurstTick
void pruneColBurstTick()
Definition: hbm_ctrl.cc:342
gem5::memory::qos::MemCtrl::schedule
uint8_t schedule(RequestorID id, uint64_t data)
Definition: mem_ctrl.cc:217
mem_interface.hh
gem5::Packet::isRead
bool isRead() const
Definition: packet.hh:593
gem5::memory::HBMCtrl::recvAtomic
Tick recvAtomic(PacketPtr pkt) override
Definition: hbm_ctrl.cc:97
gem5::memory::MemCtrl::CtrlStats::numWrRetry
statistics::Scalar numWrRetry
Definition: mem_ctrl.hh:583
gem5::VegaISA::p
Bitfield< 54 > p
Definition: pagetable.hh:70
gem5::Packet::print
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
Definition: packet.cc:368
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:210
gem5::Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::memory::DRAMInterface::commandOffset
Tick commandOffset() const override
Definition: dram_interface.hh:708
gem5::memory::HBMCtrl::pc0Int
DRAMInterface * pc0Int
Pointers to interfaces of the two pseudo channels pc0Int is same as MemCtrl::dram (it will be pointin...
Definition: hbm_ctrl.hh:194
gem5::memory::MemCtrl::stats
CtrlStats stats
Definition: mem_ctrl.hh:622
gem5::memory::HBMCtrl::respondEventPC1
EventFunctionWrapper respondEventPC1
Definition: hbm_ctrl.hh:135
gem5::memory::MemCtrl::writeBufferSize
uint32_t writeBufferSize
Definition: mem_ctrl.hh:515
gem5::memory::qos::MemCtrl::system
System * system() const
read the system pointer
Definition: mem_ctrl.hh:370
gem5::memory::MemCtrl::init
virtual void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: mem_ctrl.cc:100
gem5::memory::HBMCtrl::verifyMultiCmd
Tick verifyMultiCmd(Tick cmd_tick, Tick max_cmds_per_burst, Tick max_multi_cmd_split=0) override
Check for command bus contention for multi-cycle (2 currently) command.
Definition: hbm_ctrl.cc:399
gem5::memory::HBMCtrl::writeQueueFullPC1
bool writeQueueFullPC1(unsigned int pkt_count) const
Definition: hbm_ctrl.cc:170
gem5::memory::MemCtrl::recvFunctionalLogic
bool recvFunctionalLogic(PacketPtr pkt, MemInterface *mem_intr)
Definition: mem_ctrl.cc:1395
gem5::memory::MemCtrl::retryWrReq
bool retryWrReq
Definition: mem_ctrl.hh:294
gem5::ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:144
gem5::memory::MemInterface::writeBufferSize
const uint32_t writeBufferSize
Definition: mem_interface.hh:177
gem5::memory::MemCtrl::CtrlStats::bytesWrittenSys
statistics::Scalar bytesWrittenSys
Definition: mem_ctrl.hh:593
gem5::bits
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:76
gem5::memory::HBMCtrl::startup
virtual void startup() override
startup() is the final initialization call before simulation.
Definition: hbm_ctrl.cc:82
gem5::memory::MemCtrl::CtrlStats::writeReqs
statistics::Scalar writeReqs
Definition: mem_ctrl.hh:572
gem5::System::isTimingMode
bool isTimingMode() const
Is the system in timing mode?
Definition: system.hh:270
gem5::memory::MemCtrl::dram
MemInterface * dram
Definition: mem_ctrl.hh:504
gem5::memory::MemCtrl::isTimingMode
bool isTimingMode
Remember if the memory system is in timing mode.
Definition: mem_ctrl.hh:288
gem5::memory::MemCtrl::CtrlStats::numRdRetry
statistics::Scalar numRdRetry
Definition: mem_ctrl.hh:582
gem5::MemBackdoorReq::range
const AddrRange & range() const
Definition: backdoor.hh:140
gem5::memory::MemCtrl::respQueue
std::deque< MemPacket * > respQueue
Response queue where read packets wait after we're done working with them, but it's not time to send ...
Definition: mem_ctrl.hh:492
gem5::memory::HBMCtrl::respQueuePC1
std::deque< MemPacket * > respQueuePC1
Response queue for pkts sent to second pseudo channel The first pseudo channel uses MemCtrl::respQueu...
Definition: hbm_ctrl.hh:173
gem5::memory::HBMCtrl::drainResume
virtual void drainResume() override
Resume execution after a successful drain.
Definition: hbm_ctrl.cc:464
name
const std::string & name()
Definition: trace.cc:48
gem5::MemBackdoor
Definition: backdoor.hh:41
gem5::memory::MemCtrl::CtrlStats::totGap
statistics::Scalar totGap
Definition: mem_ctrl.hh:598
gem5::memory::MemInterface::nextBurstAt
Tick nextBurstAt
Till when the controller must wait before issuing next RD/WR burst?
Definition: mem_interface.hh:189
gem5::memory::AbstractMemory::getBackdoor
void getBackdoor(MemBackdoorPtr &bd_ptr)
Definition: abstract_mem.hh:245
gem5::memory::MemCtrl::readQueue
std::vector< MemPacketQueue > readQueue
The controller's main read and write queues, with support for QoS reordering.
Definition: mem_ctrl.hh:472
gem5::divCeil
static constexpr T divCeil(const T &a, const U &b)
Definition: intmath.hh:110
gem5::memory::HBMCtrl::pruneBurstTick
void pruneBurstTick() override
Remove commands that have already issued from rowBurstTicks and colBurstTicks.
Definition: hbm_ctrl.cc:355
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:214
gem5::memory::MemCtrl::CtrlStats::readReqs
statistics::Scalar readReqs
Definition: mem_ctrl.hh:571
gem5::memory::MemInterface::setCtrl
void setCtrl(MemCtrl *_ctrl, unsigned int command_window, uint8_t pseudo_channel=0)
Set a pointer to the controller and initialize interface based on controller parameters.
Definition: mem_interface.cc:77
gem5::memory::MemCtrl::recvAtomicLogic
Tick recvAtomicLogic(PacketPtr pkt, MemInterface *mem_intr)
Definition: mem_ctrl.cc:136
gem5::memory::HBMCtrl::readQueueFullPC0
bool readQueueFullPC0(unsigned int pkt_count) const
Check if the read queue partition of both pseudo channels has room for more entries.
Definition: hbm_ctrl.cc:181
dram_interface.hh
gem5::memory::HBMCtrl::readQueueFullPC1
bool readQueueFullPC1(unsigned int pkt_count) const
Definition: hbm_ctrl.cc:194
gem5::memory::MemCtrl::processNextReqEvent
virtual void processNextReqEvent(MemInterface *mem_intr, MemPacketQueue &resp_queue, EventFunctionWrapper &resp_event, EventFunctionWrapper &next_req_event, bool &retry_wr_req)
Bunch of things requires to setup "events" in gem5 When event "respondEvent" occurs for example,...
Definition: mem_ctrl.cc:881
gem5::memory::MemCtrl::getBurstWindow
Tick getBurstWindow(Tick cmd_tick)
Calculate burst window aligned tick.
Definition: mem_ctrl.cc:675
gem5::memory::MemCtrl::addToWriteQueue
void addToWriteQueue(PacketPtr pkt, unsigned int pkt_count, MemInterface *mem_intr)
Decode the incoming pkt, create a mem_pkt and push to the back of the write queue.
Definition: mem_ctrl.cc:304
hbm_ctrl.hh
gem5::memory::HBMCtrl::recvAtomicBackdoor
Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) override
Definition: hbm_ctrl.cc:127
trace.hh
gem5::memory::MemInterface::bytesPerBurst
uint32_t bytesPerBurst() const
Definition: mem_interface.hh:278
gem5::memory::MemCtrl::drainResume
virtual void drainResume() override
Resume execution after a successful drain.
Definition: mem_ctrl.cc:1452
std::list< AddrRange >
gem5::Packet::getAddr
Addr getAddr() const
Definition: packet.hh:807
gem5::memory::MemCtrl::commandWindow
const Tick commandWindow
Length of a command window, used to check command bandwidth.
Definition: mem_ctrl.hh:545
gem5::memory::HBMCtrl::retryWrReqPC1
bool retryWrReqPC1
Definition: hbm_ctrl.hh:80
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:236
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::MemBackdoorReq
Definition: backdoor.hh:129
gem5::memory::HBMCtrl::rowBurstTicks
std::unordered_multiset< Tick > rowBurstTicks
Holds count of row commands issued in burst window starting at defined Tick.
Definition: hbm_ctrl.hh:180
gem5::memory::HBMCtrl::init
virtual void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: hbm_ctrl.cc:76
gem5::memory::HBMCtrl::writeQueueFullPC0
bool writeQueueFullPC0(unsigned int pkt_count) const
Check if the write queue partition of both pseudo channels has room for more entries.
Definition: hbm_ctrl.cc:159
gem5::Packet::getSize
unsigned getSize() const
Definition: packet.hh:817
gem5::Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:458
gem5::memory::DRAMInterface::startup
void startup() override
Iterate through dram ranks and instantiate per rank startup routine.
Definition: dram_interface.cc:784
gem5::memory::HBMCtrl::pruneRowBurstTick
void pruneRowBurstTick()
Definition: hbm_ctrl.cc:329
gem5::memory::HBMCtrl::retryRdReqPC1
bool retryRdReqPC1
Remember if we have to retry a request for second pseudo channel.
Definition: hbm_ctrl.hh:79
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:188
gem5::memory::MemInterface::writeQueueSize
uint32_t writeQueueSize
Definition: mem_interface.hh:206

Generated on Sun Jul 30 2023 01:56:58 for gem5 by doxygen 1.8.17