gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
dram_ctrl.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-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) 2013 Amin Farmahini-Farahani
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  * Authors: Andreas Hansson
41  * Ani Udipi
42  * Neha Agarwal
43  * Omar Naji
44  * Wendy Elsasser
45  * Radhika Jagtap
46  */
47 
48 #include "mem/dram_ctrl.hh"
49 
50 #include "base/bitfield.hh"
51 #include "base/trace.hh"
52 #include "debug/DRAM.hh"
53 #include "debug/DRAMPower.hh"
54 #include "debug/DRAMState.hh"
55 #include "debug/Drain.hh"
56 #include "debug/QOS.hh"
57 #include "sim/system.hh"
58 
59 using namespace std;
60 using namespace Data;
61 
62 DRAMCtrl::DRAMCtrl(const DRAMCtrlParams* p) :
63  QoS::MemCtrl(p),
64  port(name() + ".port", *this), isTimingMode(false),
65  retryRdReq(false), retryWrReq(false),
66  nextReqEvent([this]{ processNextReqEvent(); }, name()),
67  respondEvent([this]{ processRespondEvent(); }, name()),
68  deviceSize(p->device_size),
69  deviceBusWidth(p->device_bus_width), burstLength(p->burst_length),
70  deviceRowBufferSize(p->device_rowbuffer_size),
71  devicesPerRank(p->devices_per_rank),
76  ranksPerChannel(p->ranks_per_channel),
77  bankGroupsPerRank(p->bank_groups_per_rank),
78  bankGroupArch(p->bank_groups_per_rank > 0),
79  banksPerRank(p->banks_per_rank), rowsPerBank(0),
80  readBufferSize(p->read_buffer_size),
81  writeBufferSize(p->write_buffer_size),
82  writeHighThreshold(writeBufferSize * p->write_high_thresh_perc / 100.0),
83  writeLowThreshold(writeBufferSize * p->write_low_thresh_perc / 100.0),
84  minWritesPerSwitch(p->min_writes_per_switch),
86  tCK(p->tCK), tRTW(p->tRTW), tCS(p->tCS), tBURST(p->tBURST),
87  tCCD_L_WR(p->tCCD_L_WR),
88  tCCD_L(p->tCCD_L), tRCD(p->tRCD), tCL(p->tCL), tRP(p->tRP), tRAS(p->tRAS),
89  tWR(p->tWR), tRTP(p->tRTP), tRFC(p->tRFC), tREFI(p->tREFI), tRRD(p->tRRD),
90  tRRD_L(p->tRRD_L), tXAW(p->tXAW), tXP(p->tXP), tXS(p->tXS),
91  activationLimit(p->activation_limit), rankToRankDly(tCS + tBURST),
92  wrToRdDly(tCL + tBURST + p->tWTR), rdToWrDly(tRTW + tBURST),
93  memSchedPolicy(p->mem_sched_policy), addrMapping(p->addr_mapping),
94  pageMgmt(p->page_policy),
95  maxAccessesPerRow(p->max_accesses_per_row),
96  frontendLatency(p->static_frontend_latency),
97  backendLatency(p->static_backend_latency),
98  nextBurstAt(0), prevArrival(0),
99  nextReqTime(0),
100  stats(*this),
102  lastStatsResetTick(0), enableDRAMPowerdown(p->enable_dram_powerdown)
103 {
104  // sanity check the ranks since we rely on bit slicing for the
105  // address decoding
106  fatal_if(!isPowerOf2(ranksPerChannel), "DRAM rank count of %d is not "
107  "allowed, must be a power of two\n", ranksPerChannel);
108 
109  fatal_if(!isPowerOf2(burstSize), "DRAM burst size %d is not allowed, "
110  "must be a power of two\n", burstSize);
111  readQueue.resize(p->qos_priorities);
112  writeQueue.resize(p->qos_priorities);
113 
114 
115  for (int i = 0; i < ranksPerChannel; i++) {
116  Rank* rank = new Rank(*this, p, i);
117  ranks.push_back(rank);
118  }
119 
120  // perform a basic check of the write thresholds
121  if (p->write_low_thresh_perc >= p->write_high_thresh_perc)
122  fatal("Write buffer low threshold %d must be smaller than the "
123  "high threshold %d\n", p->write_low_thresh_perc,
124  p->write_high_thresh_perc);
125 
126  // determine the rows per bank by looking at the total capacity
127  uint64_t capacity = ULL(1) << ceilLog2(AbstractMemory::size());
128 
129  // determine the dram actual capacity from the DRAM config in Mbytes
130  uint64_t deviceCapacity = deviceSize / (1024 * 1024) * devicesPerRank *
131  ranksPerChannel;
132 
133  // if actual DRAM size does not match memory capacity in system warn!
134  if (deviceCapacity != capacity / (1024 * 1024))
135  warn("DRAM device capacity (%d Mbytes) does not match the "
136  "address range assigned (%d Mbytes)\n", deviceCapacity,
137  capacity / (1024 * 1024));
138 
139  DPRINTF(DRAM, "Memory capacity %lld (%lld) bytes\n", capacity,
141 
142  DPRINTF(DRAM, "Row buffer size %d bytes with %d columns per row buffer\n",
144 
146 
147  // some basic sanity checks
148  if (tREFI <= tRP || tREFI <= tRFC) {
149  fatal("tREFI (%d) must be larger than tRP (%d) and tRFC (%d)\n",
150  tREFI, tRP, tRFC);
151  }
152 
153  // basic bank group architecture checks ->
154  if (bankGroupArch) {
155  // must have at least one bank per bank group
157  fatal("banks per rank (%d) must be equal to or larger than "
158  "banks groups per rank (%d)\n",
160  }
161  // must have same number of banks in each bank group
162  if ((banksPerRank % bankGroupsPerRank) != 0) {
163  fatal("Banks per rank (%d) must be evenly divisible by bank groups "
164  "per rank (%d) for equal banks per bank group\n",
165  banksPerRank, bankGroupsPerRank);
166  }
167  // tCCD_L should be greater than minimal, back-to-back burst delay
168  if (tCCD_L <= tBURST) {
169  fatal("tCCD_L (%d) should be larger than tBURST (%d) when "
170  "bank groups per rank (%d) is greater than 1\n",
171  tCCD_L, tBURST, bankGroupsPerRank);
172  }
173  // tCCD_L_WR should be greater than minimal, back-to-back burst delay
174  if (tCCD_L_WR <= tBURST) {
175  fatal("tCCD_L_WR (%d) should be larger than tBURST (%d) when "
176  "bank groups per rank (%d) is greater than 1\n",
177  tCCD_L_WR, tBURST, bankGroupsPerRank);
178  }
179  // tRRD_L is greater than minimal, same bank group ACT-to-ACT delay
180  // some datasheets might specify it equal to tRRD
181  if (tRRD_L < tRRD) {
182  fatal("tRRD_L (%d) should be larger than tRRD (%d) when "
183  "bank groups per rank (%d) is greater than 1\n",
184  tRRD_L, tRRD, bankGroupsPerRank);
185  }
186  }
187 
188 }
189 
190 void
192 {
193  MemCtrl::init();
194 
195  if (!port.isConnected()) {
196  fatal("DRAMCtrl %s is unconnected!\n", name());
197  } else {
199  }
200 
201  // a bit of sanity checks on the interleaving, save it for here to
202  // ensure that the system pointer is initialised
203  if (range.interleaved()) {
204  if (addrMapping == Enums::RoRaBaChCo) {
205  if (rowBufferSize != range.granularity()) {
206  fatal("Channel interleaving of %s doesn't match RoRaBaChCo "
207  "address map\n", name());
208  }
209  } else if (addrMapping == Enums::RoRaBaCoCh ||
210  addrMapping == Enums::RoCoRaBaCh) {
211  // for the interleavings with channel bits in the bottom,
212  // if the system uses a channel striping granularity that
213  // is larger than the DRAM burst size, then map the
214  // sequential accesses within a stripe to a number of
215  // columns in the DRAM, effectively placing some of the
216  // lower-order column bits as the least-significant bits
217  // of the address (above the ones denoting the burst size)
218  assert(columnsPerStripe >= 1);
219 
220  // channel striping has to be done at a granularity that
221  // is equal or larger to a cache line
222  if (system()->cacheLineSize() > range.granularity()) {
223  fatal("Channel interleaving of %s must be at least as large "
224  "as the cache line size\n", name());
225  }
226 
227  // ...and equal or smaller than the row-buffer size
228  if (rowBufferSize < range.granularity()) {
229  fatal("Channel interleaving of %s must be at most as large "
230  "as the row-buffer size\n", name());
231  }
232  // this is essentially the check above, so just to be sure
234  }
235  }
236 }
237 
238 void
240 {
241  // remember the memory system mode of operation
243 
244  if (isTimingMode) {
245  // timestamp offset should be in clock cycles for DRAMPower
247 
248  // update the start tick for the precharge accounting to the
249  // current tick
250  for (auto r : ranks) {
251  r->startup(curTick() + tREFI - tRP);
252  }
253 
254  // shift the bus busy time sufficiently far ahead that we never
255  // have to worry about negative values when computing the time for
256  // the next request, this will add an insignificant bubble at the
257  // start of simulation
258  nextBurstAt = curTick() + tRP + tRCD;
259  }
260 }
261 
262 Tick
264 {
265  DPRINTF(DRAM, "recvAtomic: %s 0x%x\n", pkt->cmdString(), pkt->getAddr());
266 
267  panic_if(pkt->cacheResponding(), "Should not see packets where cache "
268  "is responding");
269 
270  // do the actual memory access and turn the packet into a response
271  access(pkt);
272 
273  Tick latency = 0;
274  if (pkt->hasData()) {
275  // this value is not supposed to be accurate, just enough to
276  // keep things going, mimic a closed page
277  latency = tRP + tRCD + tCL;
278  }
279  return latency;
280 }
281 
282 bool
283 DRAMCtrl::readQueueFull(unsigned int neededEntries) const
284 {
285  DPRINTF(DRAM, "Read queue limit %d, current size %d, entries needed %d\n",
287  neededEntries);
288 
289  auto rdsize_new = totalReadQueueSize + respQueue.size() + neededEntries;
290  return rdsize_new > readBufferSize;
291 }
292 
293 bool
294 DRAMCtrl::writeQueueFull(unsigned int neededEntries) const
295 {
296  DPRINTF(DRAM, "Write queue limit %d, current size %d, entries needed %d\n",
297  writeBufferSize, totalWriteQueueSize, neededEntries);
298 
299  auto wrsize_new = (totalWriteQueueSize + neededEntries);
300  return wrsize_new > writeBufferSize;
301 }
302 
304 DRAMCtrl::decodeAddr(const PacketPtr pkt, Addr dramPktAddr, unsigned size,
305  bool isRead) const
306 {
307  // decode the address based on the address mapping scheme, with
308  // Ro, Ra, Co, Ba and Ch denoting row, rank, column, bank and
309  // channel, respectively
310  uint8_t rank;
311  uint8_t bank;
312  // use a 64-bit unsigned during the computations as the row is
313  // always the top bits, and check before creating the DRAMPacket
314  uint64_t row;
315 
316  // truncate the address to a DRAM burst, which makes it unique to
317  // a specific column, row, bank, rank and channel
318  Addr addr = dramPktAddr / burstSize;
319 
320  // we have removed the lowest order address bits that denote the
321  // position within the column
322  if (addrMapping == Enums::RoRaBaChCo || addrMapping == Enums::RoRaBaCoCh) {
323  // the lowest order bits denote the column to ensure that
324  // sequential cache lines occupy the same row
325  addr = addr / columnsPerRowBuffer;
326 
327  // after the channel bits, get the bank bits to interleave
328  // over the banks
329  bank = addr % banksPerRank;
330  addr = addr / banksPerRank;
331 
332  // after the bank, we get the rank bits which thus interleaves
333  // over the ranks
334  rank = addr % ranksPerChannel;
335  addr = addr / ranksPerChannel;
336 
337  // lastly, get the row bits, no need to remove them from addr
338  row = addr % rowsPerBank;
339  } else if (addrMapping == Enums::RoCoRaBaCh) {
340  // optimise for closed page mode and utilise maximum
341  // parallelism of the DRAM (at the cost of power)
342 
343  // take out the lower-order column bits
344  addr = addr / columnsPerStripe;
345 
346  // start with the bank bits, as this provides the maximum
347  // opportunity for parallelism between requests
348  bank = addr % banksPerRank;
349  addr = addr / banksPerRank;
350 
351  // next get the rank bits
352  rank = addr % ranksPerChannel;
353  addr = addr / ranksPerChannel;
354 
355  // next, the higher-order column bites
356  addr = addr / (columnsPerRowBuffer / columnsPerStripe);
357 
358  // lastly, get the row bits, no need to remove them from addr
359  row = addr % rowsPerBank;
360  } else
361  panic("Unknown address mapping policy chosen!");
362 
363  assert(rank < ranksPerChannel);
364  assert(bank < banksPerRank);
365  assert(row < rowsPerBank);
366  assert(row < Bank::NO_ROW);
367 
368  DPRINTF(DRAM, "Address: %lld Rank %d Bank %d Row %d\n",
369  dramPktAddr, rank, bank, row);
370 
371  // create the corresponding DRAM packet with the entry time and
372  // ready time set to the current tick, the latter will be updated
373  // later
374  uint16_t bank_id = banksPerRank * rank + bank;
375  return new DRAMPacket(pkt, isRead, rank, bank, row, bank_id, dramPktAddr,
376  size, ranks[rank]->banks[bank], *ranks[rank]);
377 }
378 
379 void
380 DRAMCtrl::addToReadQueue(PacketPtr pkt, unsigned int pktCount)
381 {
382  // only add to the read queue here. whenever the request is
383  // eventually done, set the readyTime, and call schedule()
384  assert(!pkt->isWrite());
385 
386  assert(pktCount != 0);
387 
388  // if the request size is larger than burst size, the pkt is split into
389  // multiple DRAM packets
390  // Note if the pkt starting address is not aligened to burst size, the
391  // address of first DRAM packet is kept unaliged. Subsequent DRAM packets
392  // are aligned to burst size boundaries. This is to ensure we accurately
393  // check read packets against packets in write queue.
394  const Addr base_addr = getCtrlAddr(pkt->getAddr());
395  Addr addr = base_addr;
396  unsigned pktsServicedByWrQ = 0;
397  BurstHelper* burst_helper = NULL;
398  for (int cnt = 0; cnt < pktCount; ++cnt) {
399  unsigned size = std::min((addr | (burstSize - 1)) + 1,
400  base_addr + pkt->getSize()) - addr;
401  stats.readPktSize[ceilLog2(size)]++;
402  stats.readBursts++;
404 
405  // First check write buffer to see if the data is already at
406  // the controller
407  bool foundInWrQ = false;
408  Addr burst_addr = burstAlign(addr);
409  // if the burst address is not present then there is no need
410  // looking any further
411  if (isInWriteQueue.find(burst_addr) != isInWriteQueue.end()) {
412  for (const auto& vec : writeQueue) {
413  for (const auto& p : vec) {
414  // check if the read is subsumed in the write queue
415  // packet we are looking at
416  if (p->addr <= addr &&
417  ((addr + size) <= (p->addr + p->size))) {
418 
419  foundInWrQ = true;
421  pktsServicedByWrQ++;
422  DPRINTF(DRAM,
423  "Read to addr %lld with size %d serviced by "
424  "write queue\n",
425  addr, size);
427  break;
428  }
429  }
430  }
431  }
432 
433  // If not found in the write q, make a DRAM packet and
434  // push it onto the read queue
435  if (!foundInWrQ) {
436 
437  // Make the burst helper for split packets
438  if (pktCount > 1 && burst_helper == NULL) {
439  DPRINTF(DRAM, "Read to addr %lld translates to %d "
440  "dram requests\n", pkt->getAddr(), pktCount);
441  burst_helper = new BurstHelper(pktCount);
442  }
443 
444  DRAMPacket* dram_pkt = decodeAddr(pkt, addr, size, true);
445  dram_pkt->burstHelper = burst_helper;
446 
447  assert(!readQueueFull(1));
449 
450  DPRINTF(DRAM, "Adding to read queue\n");
451 
452  readQueue[dram_pkt->qosValue()].push_back(dram_pkt);
453 
454  ++dram_pkt->rankRef.readEntries;
455 
456  // log packet
457  logRequest(MemCtrl::READ, pkt->masterId(), pkt->qosValue(),
458  dram_pkt->addr, 1);
459 
460  // Update stats
462  }
463 
464  // Starting address of next dram pkt (aligend to burstSize boundary)
465  addr = (addr | (burstSize - 1)) + 1;
466  }
467 
468  // If all packets are serviced by write queue, we send the repsonse back
469  if (pktsServicedByWrQ == pktCount) {
471  return;
472  }
473 
474  // Update how many split packets are serviced by write queue
475  if (burst_helper != NULL)
476  burst_helper->burstsServiced = pktsServicedByWrQ;
477 
478  // If we are not already scheduled to get a request out of the
479  // queue, do so now
480  if (!nextReqEvent.scheduled()) {
481  DPRINTF(DRAM, "Request scheduled immediately\n");
483  }
484 }
485 
486 void
487 DRAMCtrl::addToWriteQueue(PacketPtr pkt, unsigned int pktCount)
488 {
489  // only add to the write queue here. whenever the request is
490  // eventually done, set the readyTime, and call schedule()
491  assert(pkt->isWrite());
492 
493  // if the request size is larger than burst size, the pkt is split into
494  // multiple DRAM packets
495  const Addr base_addr = getCtrlAddr(pkt->getAddr());
496  Addr addr = base_addr;
497  for (int cnt = 0; cnt < pktCount; ++cnt) {
498  unsigned size = std::min((addr | (burstSize - 1)) + 1,
499  base_addr + pkt->getSize()) - addr;
500  stats.writePktSize[ceilLog2(size)]++;
501  stats.writeBursts++;
503 
504  // see if we can merge with an existing item in the write
505  // queue and keep track of whether we have merged or not
506  bool merged = isInWriteQueue.find(burstAlign(addr)) !=
507  isInWriteQueue.end();
508 
509  // if the item was not merged we need to create a new write
510  // and enqueue it
511  if (!merged) {
512  DRAMPacket* dram_pkt = decodeAddr(pkt, addr, size, false);
513 
516 
517  DPRINTF(DRAM, "Adding to write queue\n");
518 
519  writeQueue[dram_pkt->qosValue()].push_back(dram_pkt);
520  isInWriteQueue.insert(burstAlign(addr));
521 
522  // log packet
523  logRequest(MemCtrl::WRITE, pkt->masterId(), pkt->qosValue(),
524  dram_pkt->addr, 1);
525 
526  assert(totalWriteQueueSize == isInWriteQueue.size());
527 
528  // Update stats
530 
531  // increment write entries of the rank
532  ++dram_pkt->rankRef.writeEntries;
533  } else {
534  DPRINTF(DRAM, "Merging write burst with existing queue entry\n");
535 
536  // keep track of the fact that this burst effectively
537  // disappeared as it was merged with an existing one
539  }
540 
541  // Starting address of next dram pkt (aligend to burstSize boundary)
542  addr = (addr | (burstSize - 1)) + 1;
543  }
544 
545  // we do not wait for the writes to be send to the actual memory,
546  // but instead take responsibility for the consistency here and
547  // snoop the write queue for any upcoming reads
548  // @todo, if a pkt size is larger than burst size, we might need a
549  // different front end latency
551 
552  // If we are not already scheduled to get a request out of the
553  // queue, do so now
554  if (!nextReqEvent.scheduled()) {
555  DPRINTF(DRAM, "Request scheduled immediately\n");
557  }
558 }
559 
560 void
562 {
563 #if TRACING_ON
564  DPRINTF(DRAM, "===READ QUEUE===\n\n");
565  for (const auto& queue : readQueue) {
566  for (const auto& packet : queue) {
567  DPRINTF(DRAM, "Read %lu\n", packet->addr);
568  }
569  }
570 
571  DPRINTF(DRAM, "\n===RESP QUEUE===\n\n");
572  for (const auto& packet : respQueue) {
573  DPRINTF(DRAM, "Response %lu\n", packet->addr);
574  }
575 
576  DPRINTF(DRAM, "\n===WRITE QUEUE===\n\n");
577  for (const auto& queue : writeQueue) {
578  for (const auto& packet : queue) {
579  DPRINTF(DRAM, "Write %lu\n", packet->addr);
580  }
581  }
582 #endif // TRACING_ON
583 }
584 
585 bool
587 {
588  // This is where we enter from the outside world
589  DPRINTF(DRAM, "recvTimingReq: request %s addr %lld size %d\n",
590  pkt->cmdString(), pkt->getAddr(), pkt->getSize());
591 
592  panic_if(pkt->cacheResponding(), "Should not see packets where cache "
593  "is responding");
594 
595  panic_if(!(pkt->isRead() || pkt->isWrite()),
596  "Should only see read and writes at memory controller\n");
597 
598  // Calc avg gap between requests
599  if (prevArrival != 0) {
601  }
602  prevArrival = curTick();
603 
604 
605  // Find out how many dram packets a pkt translates to
606  // If the burst size is equal or larger than the pkt size, then a pkt
607  // translates to only one dram packet. Otherwise, a pkt translates to
608  // multiple dram packets
609  unsigned size = pkt->getSize();
610  unsigned offset = pkt->getAddr() & (burstSize - 1);
611  unsigned int dram_pkt_count = divCeil(offset + size, burstSize);
612 
613  // run the QoS scheduler and assign a QoS priority value to the packet
614  qosSchedule( { &readQueue, &writeQueue }, burstSize, pkt);
615 
616  // check local buffers and do not accept if full
617  if (pkt->isWrite()) {
618  assert(size != 0);
619  if (writeQueueFull(dram_pkt_count)) {
620  DPRINTF(DRAM, "Write queue full, not accepting\n");
621  // remember that we have to retry this port
622  retryWrReq = true;
623  stats.numWrRetry++;
624  return false;
625  } else {
626  addToWriteQueue(pkt, dram_pkt_count);
627  stats.writeReqs++;
629  }
630  } else {
631  assert(pkt->isRead());
632  assert(size != 0);
633  if (readQueueFull(dram_pkt_count)) {
634  DPRINTF(DRAM, "Read queue full, not accepting\n");
635  // remember that we have to retry this port
636  retryRdReq = true;
637  stats.numRdRetry++;
638  return false;
639  } else {
640  addToReadQueue(pkt, dram_pkt_count);
641  stats.readReqs++;
643  }
644  }
645 
646  return true;
647 }
648 
649 void
651 {
652  DPRINTF(DRAM,
653  "processRespondEvent(): Some req has reached its readyTime\n");
654 
655  DRAMPacket* dram_pkt = respQueue.front();
656 
657  // if a read has reached its ready-time, decrement the number of reads
658  // At this point the packet has been handled and there is a possibility
659  // to switch to low-power mode if no other packet is available
660  --dram_pkt->rankRef.readEntries;
661  DPRINTF(DRAM, "number of read entries for rank %d is %d\n",
662  dram_pkt->rank, dram_pkt->rankRef.readEntries);
663 
664  // counter should at least indicate one outstanding request
665  // for this read
666  assert(dram_pkt->rankRef.outstandingEvents > 0);
667  // read response received, decrement count
668  --dram_pkt->rankRef.outstandingEvents;
669 
670  // at this moment should not have transitioned to a low-power state
671  assert((dram_pkt->rankRef.pwrState != PWR_SREF) &&
672  (dram_pkt->rankRef.pwrState != PWR_PRE_PDN) &&
673  (dram_pkt->rankRef.pwrState != PWR_ACT_PDN));
674 
675  // track if this is the last packet before idling
676  // and that there are no outstanding commands to this rank
677  if (dram_pkt->rankRef.isQueueEmpty() &&
678  dram_pkt->rankRef.outstandingEvents == 0 && enableDRAMPowerdown) {
679  // verify that there are no events scheduled
680  assert(!dram_pkt->rankRef.activateEvent.scheduled());
681  assert(!dram_pkt->rankRef.prechargeEvent.scheduled());
682 
683  // if coming from active state, schedule power event to
684  // active power-down else go to precharge power-down
685  DPRINTF(DRAMState, "Rank %d sleep at tick %d; current power state is "
686  "%d\n", dram_pkt->rank, curTick(), dram_pkt->rankRef.pwrState);
687 
688  // default to ACT power-down unless already in IDLE state
689  // could be in IDLE if PRE issued before data returned
690  PowerState next_pwr_state = PWR_ACT_PDN;
691  if (dram_pkt->rankRef.pwrState == PWR_IDLE) {
692  next_pwr_state = PWR_PRE_PDN;
693  }
694 
695  dram_pkt->rankRef.powerDownSleep(next_pwr_state, curTick());
696  }
697 
698  if (dram_pkt->burstHelper) {
699  // it is a split packet
700  dram_pkt->burstHelper->burstsServiced++;
701  if (dram_pkt->burstHelper->burstsServiced ==
702  dram_pkt->burstHelper->burstCount) {
703  // we have now serviced all children packets of a system packet
704  // so we can now respond to the requester
705  // @todo we probably want to have a different front end and back
706  // end latency for split packets
708  delete dram_pkt->burstHelper;
709  dram_pkt->burstHelper = NULL;
710  }
711  } else {
712  // it is not a split packet
714  }
715 
716  delete respQueue.front();
717  respQueue.pop_front();
718 
719  if (!respQueue.empty()) {
720  assert(respQueue.front()->readyTime >= curTick());
721  assert(!respondEvent.scheduled());
722  schedule(respondEvent, respQueue.front()->readyTime);
723  } else {
724  // if there is nothing left in any queue, signal a drain
725  if (drainState() == DrainState::Draining &&
727 
728  DPRINTF(Drain, "DRAM controller done draining\n");
729  signalDrainDone();
730  }
731  }
732 
733  // We have made a location in the queue available at this point,
734  // so if there is a read that was forced to wait, retry now
735  if (retryRdReq) {
736  retryRdReq = false;
737  port.sendRetryReq();
738  }
739 }
740 
741 DRAMCtrl::DRAMPacketQueue::iterator
742 DRAMCtrl::chooseNext(DRAMPacketQueue& queue, Tick extra_col_delay)
743 {
744  // This method does the arbitration between requests.
745 
746  DRAMCtrl::DRAMPacketQueue::iterator ret = queue.end();
747 
748  if (!queue.empty()) {
749  if (queue.size() == 1) {
750  // available rank corresponds to state refresh idle
751  DRAMPacket* dram_pkt = *(queue.begin());
752  if (ranks[dram_pkt->rank]->inRefIdleState()) {
753  ret = queue.begin();
754  DPRINTF(DRAM, "Single request, going to a free rank\n");
755  } else {
756  DPRINTF(DRAM, "Single request, going to a busy rank\n");
757  }
758  } else if (memSchedPolicy == Enums::fcfs) {
759  // check if there is a packet going to a free rank
760  for (auto i = queue.begin(); i != queue.end(); ++i) {
761  DRAMPacket* dram_pkt = *i;
762  if (ranks[dram_pkt->rank]->inRefIdleState()) {
763  ret = i;
764  break;
765  }
766  }
767  } else if (memSchedPolicy == Enums::frfcfs) {
768  ret = chooseNextFRFCFS(queue, extra_col_delay);
769  } else {
770  panic("No scheduling policy chosen\n");
771  }
772  }
773  return ret;
774 }
775 
776 DRAMCtrl::DRAMPacketQueue::iterator
778 {
779  // Only determine this if needed
780  vector<uint32_t> earliest_banks(ranksPerChannel, 0);
781 
782  // Has minBankPrep been called to populate earliest_banks?
783  bool filled_earliest_banks = false;
784  // can the PRE/ACT sequence be done without impacting utlization?
785  bool hidden_bank_prep = false;
786 
787  // search for seamless row hits first, if no seamless row hit is
788  // found then determine if there are other packets that can be issued
789  // without incurring additional bus delay due to bank timing
790  // Will select closed rows first to enable more open row possibilies
791  // in future selections
792  bool found_hidden_bank = false;
793 
794  // remember if we found a row hit, not seamless, but bank prepped
795  // and ready
796  bool found_prepped_pkt = false;
797 
798  // if we have no row hit, prepped or not, and no seamless packet,
799  // just go for the earliest possible
800  bool found_earliest_pkt = false;
801 
802  auto selected_pkt_it = queue.end();
803 
804  // time we need to issue a column command to be seamless
805  const Tick min_col_at = std::max(nextBurstAt + extra_col_delay, curTick());
806 
807  for (auto i = queue.begin(); i != queue.end() ; ++i) {
808  DRAMPacket* dram_pkt = *i;
809  const Bank& bank = dram_pkt->bankRef;
810  const Tick col_allowed_at = dram_pkt->isRead() ? bank.rdAllowedAt :
811  bank.wrAllowedAt;
812 
813  DPRINTF(DRAM, "%s checking packet in bank %d\n",
814  __func__, dram_pkt->bankRef.bank);
815 
816  // check if rank is not doing a refresh and thus is available, if not,
817  // jump to the next packet
818  if (dram_pkt->rankRef.inRefIdleState()) {
819 
820  DPRINTF(DRAM,
821  "%s bank %d - Rank %d available\n", __func__,
822  dram_pkt->bankRef.bank, dram_pkt->rankRef.rank);
823 
824  // check if it is a row hit
825  if (bank.openRow == dram_pkt->row) {
826  // no additional rank-to-rank or same bank-group
827  // delays, or we switched read/write and might as well
828  // go for the row hit
829  if (col_allowed_at <= min_col_at) {
830  // FCFS within the hits, giving priority to
831  // commands that can issue seamlessly, without
832  // additional delay, such as same rank accesses
833  // and/or different bank-group accesses
834  DPRINTF(DRAM, "%s Seamless row buffer hit\n", __func__);
835  selected_pkt_it = i;
836  // no need to look through the remaining queue entries
837  break;
838  } else if (!found_hidden_bank && !found_prepped_pkt) {
839  // if we did not find a packet to a closed row that can
840  // issue the bank commands without incurring delay, and
841  // did not yet find a packet to a prepped row, remember
842  // the current one
843  selected_pkt_it = i;
844  found_prepped_pkt = true;
845  DPRINTF(DRAM, "%s Prepped row buffer hit\n", __func__);
846  }
847  } else if (!found_earliest_pkt) {
848  // if we have not initialised the bank status, do it
849  // now, and only once per scheduling decisions
850  if (!filled_earliest_banks) {
851  // determine entries with earliest bank delay
852  std::tie(earliest_banks, hidden_bank_prep) =
853  minBankPrep(queue, min_col_at);
854  filled_earliest_banks = true;
855  }
856 
857  // bank is amongst first available banks
858  // minBankPrep will give priority to packets that can
859  // issue seamlessly
860  if (bits(earliest_banks[dram_pkt->rank],
861  dram_pkt->bank, dram_pkt->bank)) {
862  found_earliest_pkt = true;
863  found_hidden_bank = hidden_bank_prep;
864 
865  // give priority to packets that can issue
866  // bank commands 'behind the scenes'
867  // any additional delay if any will be due to
868  // col-to-col command requirements
869  if (hidden_bank_prep || !found_prepped_pkt)
870  selected_pkt_it = i;
871  }
872  }
873  } else {
874  DPRINTF(DRAM, "%s bank %d - Rank %d not available\n", __func__,
875  dram_pkt->bankRef.bank, dram_pkt->rankRef.rank);
876  }
877  }
878 
879  if (selected_pkt_it == queue.end()) {
880  DPRINTF(DRAM, "%s no available ranks found\n", __func__);
881  }
882 
883  return selected_pkt_it;
884 }
885 
886 void
888 {
889  DPRINTF(DRAM, "Responding to Address %lld.. ",pkt->getAddr());
890 
891  bool needsResponse = pkt->needsResponse();
892  // do the actual memory access which also turns the packet into a
893  // response
894  access(pkt);
895 
896  // turn packet around to go back to requester if response expected
897  if (needsResponse) {
898  // access already turned the packet into a response
899  assert(pkt->isResponse());
900  // response_time consumes the static latency and is charged also
901  // with headerDelay that takes into account the delay provided by
902  // the xbar and also the payloadDelay that takes into account the
903  // number of data beats.
904  Tick response_time = curTick() + static_latency + pkt->headerDelay +
905  pkt->payloadDelay;
906  // Here we reset the timing of the packet before sending it out.
907  pkt->headerDelay = pkt->payloadDelay = 0;
908 
909  // queue the packet in the response queue to be sent out after
910  // the static latency has passed
911  port.schedTimingResp(pkt, response_time);
912  } else {
913  // @todo the packet is going to be deleted, and the DRAMPacket
914  // is still having a pointer to it
915  pendingDelete.reset(pkt);
916  }
917 
918  DPRINTF(DRAM, "Done\n");
919 
920  return;
921 }
922 
923 void
924 DRAMCtrl::activateBank(Rank& rank_ref, Bank& bank_ref,
925  Tick act_tick, uint32_t row)
926 {
927  assert(rank_ref.actTicks.size() == activationLimit);
928 
929  DPRINTF(DRAM, "Activate at tick %d\n", act_tick);
930 
931  // update the open row
932  assert(bank_ref.openRow == Bank::NO_ROW);
933  bank_ref.openRow = row;
934 
935  // start counting anew, this covers both the case when we
936  // auto-precharged, and when this access is forced to
937  // precharge
938  bank_ref.bytesAccessed = 0;
939  bank_ref.rowAccesses = 0;
940 
941  ++rank_ref.numBanksActive;
942  assert(rank_ref.numBanksActive <= banksPerRank);
943 
944  DPRINTF(DRAM, "Activate bank %d, rank %d at tick %lld, now got %d active\n",
945  bank_ref.bank, rank_ref.rank, act_tick,
946  ranks[rank_ref.rank]->numBanksActive);
947 
948  rank_ref.cmdList.push_back(Command(MemCommand::ACT, bank_ref.bank,
949  act_tick));
950 
951  DPRINTF(DRAMPower, "%llu,ACT,%d,%d\n", divCeil(act_tick, tCK) -
952  timeStampOffset, bank_ref.bank, rank_ref.rank);
953 
954  // The next access has to respect tRAS for this bank
955  bank_ref.preAllowedAt = act_tick + tRAS;
956 
957  // Respect the row-to-column command delay for both read and write cmds
958  bank_ref.rdAllowedAt = std::max(act_tick + tRCD, bank_ref.rdAllowedAt);
959  bank_ref.wrAllowedAt = std::max(act_tick + tRCD, bank_ref.wrAllowedAt);
960 
961  // start by enforcing tRRD
962  for (int i = 0; i < banksPerRank; i++) {
963  // next activate to any bank in this rank must not happen
964  // before tRRD
965  if (bankGroupArch && (bank_ref.bankgr == rank_ref.banks[i].bankgr)) {
966  // bank group architecture requires longer delays between
967  // ACT commands within the same bank group. Use tRRD_L
968  // in this case
969  rank_ref.banks[i].actAllowedAt = std::max(act_tick + tRRD_L,
970  rank_ref.banks[i].actAllowedAt);
971  } else {
972  // use shorter tRRD value when either
973  // 1) bank group architecture is not supportted
974  // 2) bank is in a different bank group
975  rank_ref.banks[i].actAllowedAt = std::max(act_tick + tRRD,
976  rank_ref.banks[i].actAllowedAt);
977  }
978  }
979 
980  // next, we deal with tXAW, if the activation limit is disabled
981  // then we directly schedule an activate power event
982  if (!rank_ref.actTicks.empty()) {
983  // sanity check
984  if (rank_ref.actTicks.back() &&
985  (act_tick - rank_ref.actTicks.back()) < tXAW) {
986  panic("Got %d activates in window %d (%llu - %llu) which "
987  "is smaller than %llu\n", activationLimit, act_tick -
988  rank_ref.actTicks.back(), act_tick,
989  rank_ref.actTicks.back(), tXAW);
990  }
991 
992  // shift the times used for the book keeping, the last element
993  // (highest index) is the oldest one and hence the lowest value
994  rank_ref.actTicks.pop_back();
995 
996  // record an new activation (in the future)
997  rank_ref.actTicks.push_front(act_tick);
998 
999  // cannot activate more than X times in time window tXAW, push the
1000  // next one (the X + 1'st activate) to be tXAW away from the
1001  // oldest in our window of X
1002  if (rank_ref.actTicks.back() &&
1003  (act_tick - rank_ref.actTicks.back()) < tXAW) {
1004  DPRINTF(DRAM, "Enforcing tXAW with X = %d, next activate "
1005  "no earlier than %llu\n", activationLimit,
1006  rank_ref.actTicks.back() + tXAW);
1007  for (int j = 0; j < banksPerRank; j++)
1008  // next activate must not happen before end of window
1009  rank_ref.banks[j].actAllowedAt =
1010  std::max(rank_ref.actTicks.back() + tXAW,
1011  rank_ref.banks[j].actAllowedAt);
1012  }
1013  }
1014 
1015  // at the point when this activate takes place, make sure we
1016  // transition to the active power state
1017  if (!rank_ref.activateEvent.scheduled())
1018  schedule(rank_ref.activateEvent, act_tick);
1019  else if (rank_ref.activateEvent.when() > act_tick)
1020  // move it sooner in time
1021  reschedule(rank_ref.activateEvent, act_tick);
1022 }
1023 
1024 void
1025 DRAMCtrl::prechargeBank(Rank& rank_ref, Bank& bank, Tick pre_at, bool trace)
1026 {
1027  // make sure the bank has an open row
1028  assert(bank.openRow != Bank::NO_ROW);
1029 
1030  // sample the bytes per activate here since we are closing
1031  // the page
1033 
1034  bank.openRow = Bank::NO_ROW;
1035 
1036  // no precharge allowed before this one
1037  bank.preAllowedAt = pre_at;
1038 
1039  Tick pre_done_at = pre_at + tRP;
1040 
1041  bank.actAllowedAt = std::max(bank.actAllowedAt, pre_done_at);
1042 
1043  assert(rank_ref.numBanksActive != 0);
1044  --rank_ref.numBanksActive;
1045 
1046  DPRINTF(DRAM, "Precharging bank %d, rank %d at tick %lld, now got "
1047  "%d active\n", bank.bank, rank_ref.rank, pre_at,
1048  rank_ref.numBanksActive);
1049 
1050  if (trace) {
1051 
1052  rank_ref.cmdList.push_back(Command(MemCommand::PRE, bank.bank,
1053  pre_at));
1054  DPRINTF(DRAMPower, "%llu,PRE,%d,%d\n", divCeil(pre_at, tCK) -
1055  timeStampOffset, bank.bank, rank_ref.rank);
1056  }
1057  // if we look at the current number of active banks we might be
1058  // tempted to think the DRAM is now idle, however this can be
1059  // undone by an activate that is scheduled to happen before we
1060  // would have reached the idle state, so schedule an event and
1061  // rather check once we actually make it to the point in time when
1062  // the (last) precharge takes place
1063  if (!rank_ref.prechargeEvent.scheduled()) {
1064  schedule(rank_ref.prechargeEvent, pre_done_at);
1065  // New event, increment count
1066  ++rank_ref.outstandingEvents;
1067  } else if (rank_ref.prechargeEvent.when() < pre_done_at) {
1068  reschedule(rank_ref.prechargeEvent, pre_done_at);
1069  }
1070 }
1071 
1072 void
1074 {
1075  DPRINTF(DRAM, "Timing access to addr %lld, rank/bank/row %d %d %d\n",
1076  dram_pkt->addr, dram_pkt->rank, dram_pkt->bank, dram_pkt->row);
1077 
1078  // get the rank
1079  Rank& rank = dram_pkt->rankRef;
1080 
1081  // are we in or transitioning to a low-power state and have not scheduled
1082  // a power-up event?
1083  // if so, wake up from power down to issue RD/WR burst
1084  if (rank.inLowPowerState) {
1085  assert(rank.pwrState != PWR_SREF);
1086  rank.scheduleWakeUpEvent(tXP);
1087  }
1088 
1089  // get the bank
1090  Bank& bank = dram_pkt->bankRef;
1091 
1092  // for the state we need to track if it is a row hit or not
1093  bool row_hit = true;
1094 
1095  // Determine the access latency and update the bank state
1096  if (bank.openRow == dram_pkt->row) {
1097  // nothing to do
1098  } else {
1099  row_hit = false;
1100 
1101  // If there is a page open, precharge it.
1102  if (bank.openRow != Bank::NO_ROW) {
1103  prechargeBank(rank, bank, std::max(bank.preAllowedAt, curTick()));
1104  }
1105 
1106  // next we need to account for the delay in activating the
1107  // page
1108  Tick act_tick = std::max(bank.actAllowedAt, curTick());
1109 
1110  // Record the activation and deal with all the global timing
1111  // constraints caused be a new activation (tRRD and tXAW)
1112  activateBank(rank, bank, act_tick, dram_pkt->row);
1113  }
1114 
1115  // respect any constraints on the command (e.g. tRCD or tCCD)
1116  const Tick col_allowed_at = dram_pkt->isRead() ?
1117  bank.rdAllowedAt : bank.wrAllowedAt;
1118 
1119  // we need to wait until the bus is available before we can issue
1120  // the command; need minimum of tBURST between commands
1121  Tick cmd_at = std::max({col_allowed_at, nextBurstAt, curTick()});
1122 
1123  // update the packet ready time
1124  dram_pkt->readyTime = cmd_at + tCL + tBURST;
1125 
1126  // update the time for the next read/write burst for each
1127  // bank (add a max with tCCD/tCCD_L/tCCD_L_WR here)
1128  Tick dly_to_rd_cmd;
1129  Tick dly_to_wr_cmd;
1130  for (int j = 0; j < ranksPerChannel; j++) {
1131  for (int i = 0; i < banksPerRank; i++) {
1132  // next burst to same bank group in this rank must not happen
1133  // before tCCD_L. Different bank group timing requirement is
1134  // tBURST; Add tCS for different ranks
1135  if (dram_pkt->rank == j) {
1136  if (bankGroupArch &&
1137  (bank.bankgr == ranks[j]->banks[i].bankgr)) {
1138  // bank group architecture requires longer delays between
1139  // RD/WR burst commands to the same bank group.
1140  // tCCD_L is default requirement for same BG timing
1141  // tCCD_L_WR is required for write-to-write
1142  // Need to also take bus turnaround delays into account
1143  dly_to_rd_cmd = dram_pkt->isRead() ?
1144  tCCD_L : std::max(tCCD_L, wrToRdDly);
1145  dly_to_wr_cmd = dram_pkt->isRead() ?
1146  std::max(tCCD_L, rdToWrDly) : tCCD_L_WR;
1147  } else {
1148  // tBURST is default requirement for diff BG timing
1149  // Need to also take bus turnaround delays into account
1150  dly_to_rd_cmd = dram_pkt->isRead() ? tBURST : wrToRdDly;
1151  dly_to_wr_cmd = dram_pkt->isRead() ? rdToWrDly : tBURST;
1152  }
1153  } else {
1154  // different rank is by default in a different bank group and
1155  // doesn't require longer tCCD or additional RTW, WTR delays
1156  // Need to account for rank-to-rank switching with tCS
1157  dly_to_wr_cmd = rankToRankDly;
1158  dly_to_rd_cmd = rankToRankDly;
1159  }
1160  ranks[j]->banks[i].rdAllowedAt = std::max(cmd_at + dly_to_rd_cmd,
1161  ranks[j]->banks[i].rdAllowedAt);
1162  ranks[j]->banks[i].wrAllowedAt = std::max(cmd_at + dly_to_wr_cmd,
1163  ranks[j]->banks[i].wrAllowedAt);
1164  }
1165  }
1166 
1167  // Save rank of current access
1168  activeRank = dram_pkt->rank;
1169 
1170  // If this is a write, we also need to respect the write recovery
1171  // time before a precharge, in the case of a read, respect the
1172  // read to precharge constraint
1173  bank.preAllowedAt = std::max(bank.preAllowedAt,
1174  dram_pkt->isRead() ? cmd_at + tRTP :
1175  dram_pkt->readyTime + tWR);
1176 
1177  // increment the bytes accessed and the accesses per row
1178  bank.bytesAccessed += burstSize;
1179  ++bank.rowAccesses;
1180 
1181  // if we reached the max, then issue with an auto-precharge
1182  bool auto_precharge = pageMgmt == Enums::close ||
1184 
1185  // if we did not hit the limit, we might still want to
1186  // auto-precharge
1187  if (!auto_precharge &&
1188  (pageMgmt == Enums::open_adaptive ||
1189  pageMgmt == Enums::close_adaptive)) {
1190  // a twist on the open and close page policies:
1191  // 1) open_adaptive page policy does not blindly keep the
1192  // page open, but close it if there are no row hits, and there
1193  // are bank conflicts in the queue
1194  // 2) close_adaptive page policy does not blindly close the
1195  // page, but closes it only if there are no row hits in the queue.
1196  // In this case, only force an auto precharge when there
1197  // are no same page hits in the queue
1198  bool got_more_hits = false;
1199  bool got_bank_conflict = false;
1200 
1201  // either look at the read queue or write queue
1202  const std::vector<DRAMPacketQueue>& queue =
1203  dram_pkt->isRead() ? readQueue : writeQueue;
1204 
1205  for (uint8_t i = 0; i < numPriorities(); ++i) {
1206  auto p = queue[i].begin();
1207  // keep on looking until we find a hit or reach the end of the queue
1208  // 1) if a hit is found, then both open and close adaptive policies keep
1209  // the page open
1210  // 2) if no hit is found, got_bank_conflict is set to true if a bank
1211  // conflict request is waiting in the queue
1212  // 3) make sure we are not considering the packet that we are
1213  // currently dealing with
1214  while (!got_more_hits && p != queue[i].end()) {
1215  if (dram_pkt != (*p)) {
1216  bool same_rank_bank = (dram_pkt->rank == (*p)->rank) &&
1217  (dram_pkt->bank == (*p)->bank);
1218 
1219  bool same_row = dram_pkt->row == (*p)->row;
1220  got_more_hits |= same_rank_bank && same_row;
1221  got_bank_conflict |= same_rank_bank && !same_row;
1222  }
1223  ++p;
1224  }
1225 
1226  if (got_more_hits)
1227  break;
1228  }
1229 
1230  // auto pre-charge when either
1231  // 1) open_adaptive policy, we have not got any more hits, and
1232  // have a bank conflict
1233  // 2) close_adaptive policy and we have not got any more hits
1234  auto_precharge = !got_more_hits &&
1235  (got_bank_conflict || pageMgmt == Enums::close_adaptive);
1236  }
1237 
1238  // DRAMPower trace command to be written
1239  std::string mem_cmd = dram_pkt->isRead() ? "RD" : "WR";
1240 
1241  // MemCommand required for DRAMPower library
1242  MemCommand::cmds command = (mem_cmd == "RD") ? MemCommand::RD :
1243  MemCommand::WR;
1244 
1245  // Update bus state to reflect when previous command was issued
1246  nextBurstAt = cmd_at + tBURST;
1247 
1248  DPRINTF(DRAM, "Access to %lld, ready at %lld next burst at %lld.\n",
1249  dram_pkt->addr, dram_pkt->readyTime, nextBurstAt);
1250 
1251  dram_pkt->rankRef.cmdList.push_back(Command(command, dram_pkt->bank,
1252  cmd_at));
1253 
1254  DPRINTF(DRAMPower, "%llu,%s,%d,%d\n", divCeil(cmd_at, tCK) -
1255  timeStampOffset, mem_cmd, dram_pkt->bank, dram_pkt->rank);
1256 
1257  // if this access should use auto-precharge, then we are
1258  // closing the row after the read/write burst
1259  if (auto_precharge) {
1260  // if auto-precharge push a PRE command at the correct tick to the
1261  // list used by DRAMPower library to calculate power
1262  prechargeBank(rank, bank, std::max(curTick(), bank.preAllowedAt));
1263 
1264  DPRINTF(DRAM, "Auto-precharged bank: %d\n", dram_pkt->bankId);
1265  }
1266 
1267  // Update the minimum timing between the requests, this is a
1268  // conservative estimate of when we have to schedule the next
1269  // request to not introduce any unecessary bubbles. In most cases
1270  // we will wake up sooner than we have to.
1271  nextReqTime = nextBurstAt - (tRP + tRCD);
1272 
1273  // Update the stats and schedule the next request
1274  if (dram_pkt->isRead()) {
1275  ++readsThisTime;
1276  if (row_hit)
1277  stats.readRowHits++;
1279  stats.perBankRdBursts[dram_pkt->bankId]++;
1280 
1281  // Update latency stats
1282  stats.totMemAccLat += dram_pkt->readyTime - dram_pkt->entryTime;
1283  stats.masterReadTotalLat[dram_pkt->masterId()] +=
1284  dram_pkt->readyTime - dram_pkt->entryTime;
1285 
1286  stats.totBusLat += tBURST;
1287  stats.totQLat += cmd_at - dram_pkt->entryTime;
1288  stats.masterReadBytes[dram_pkt->masterId()] += dram_pkt->size;
1289  } else {
1290  ++writesThisTime;
1291  if (row_hit)
1292  stats.writeRowHits++;
1294  stats.perBankWrBursts[dram_pkt->bankId]++;
1295  stats.masterWriteBytes[dram_pkt->masterId()] += dram_pkt->size;
1296  stats.masterWriteTotalLat[dram_pkt->masterId()] +=
1297  dram_pkt->readyTime - dram_pkt->entryTime;
1298  }
1299 }
1300 
1301 void
1303 {
1304  // transition is handled by QoS algorithm if enabled
1305  if (turnPolicy) {
1306  // select bus state - only done if QoS algorithms are in use
1308  }
1309 
1310  // detect bus state change
1311  bool switched_cmd_type = (busState != busStateNext);
1312  // record stats
1314 
1315  DPRINTF(DRAM, "QoS Turnarounds selected state %s %s\n",
1316  (busState==MemCtrl::READ)?"READ":"WRITE",
1317  switched_cmd_type?"[turnaround triggered]":"");
1318 
1319  if (switched_cmd_type) {
1320  if (busState == READ) {
1321  DPRINTF(DRAM,
1322  "Switching to writes after %d reads with %d reads "
1323  "waiting\n", readsThisTime, totalReadQueueSize);
1325  readsThisTime = 0;
1326  } else {
1327  DPRINTF(DRAM,
1328  "Switching to reads after %d writes with %d writes "
1329  "waiting\n", writesThisTime, totalWriteQueueSize);
1331  writesThisTime = 0;
1332  }
1333  }
1334 
1335  // updates current state
1337 
1338  // check ranks for refresh/wakeup - uses busStateNext, so done after turnaround
1339  // decisions
1340  int busyRanks = 0;
1341  for (auto r : ranks) {
1342  if (!r->inRefIdleState()) {
1343  if (r->pwrState != PWR_SREF) {
1344  // rank is busy refreshing
1345  DPRINTF(DRAMState, "Rank %d is not available\n", r->rank);
1346  busyRanks++;
1347 
1348  // let the rank know that if it was waiting to drain, it
1349  // is now done and ready to proceed
1350  r->checkDrainDone();
1351  }
1352 
1353  // check if we were in self-refresh and haven't started
1354  // to transition out
1355  if ((r->pwrState == PWR_SREF) && r->inLowPowerState) {
1356  DPRINTF(DRAMState, "Rank %d is in self-refresh\n", r->rank);
1357  // if we have commands queued to this rank and we don't have
1358  // a minimum number of active commands enqueued,
1359  // exit self-refresh
1360  if (r->forceSelfRefreshExit()) {
1361  DPRINTF(DRAMState, "rank %d was in self refresh and"
1362  " should wake up\n", r->rank);
1363  //wake up from self-refresh
1364  r->scheduleWakeUpEvent(tXS);
1365  // things are brought back into action once a refresh is
1366  // performed after self-refresh
1367  // continue with selection for other ranks
1368  }
1369  }
1370  }
1371  }
1372 
1373  if (busyRanks == ranksPerChannel) {
1374  // if all ranks are refreshing wait for them to finish
1375  // and stall this state machine without taking any further
1376  // action, and do not schedule a new nextReqEvent
1377  return;
1378  }
1379 
1380  // when we get here it is either a read or a write
1381  if (busState == READ) {
1382 
1383  // track if we should switch or not
1384  bool switch_to_writes = false;
1385 
1386  if (totalReadQueueSize == 0) {
1387  // In the case there is no read request to go next,
1388  // trigger writes if we have passed the low threshold (or
1389  // if we are draining)
1390  if (!(totalWriteQueueSize == 0) &&
1393 
1394  DPRINTF(DRAM, "Switching to writes due to read queue empty\n");
1395  switch_to_writes = true;
1396  } else {
1397  // check if we are drained
1398  // not done draining until in PWR_IDLE state
1399  // ensuring all banks are closed and
1400  // have exited low power states
1401  if (drainState() == DrainState::Draining &&
1402  respQueue.empty() && allRanksDrained()) {
1403 
1404  DPRINTF(Drain, "DRAM controller done draining\n");
1405  signalDrainDone();
1406  }
1407 
1408  // nothing to do, not even any point in scheduling an
1409  // event for the next request
1410  return;
1411  }
1412  } else {
1413 
1414  bool read_found = false;
1415  DRAMPacketQueue::iterator to_read;
1416  uint8_t prio = numPriorities();
1417 
1418  for (auto queue = readQueue.rbegin();
1419  queue != readQueue.rend(); ++queue) {
1420 
1421  prio--;
1422 
1423  DPRINTF(QOS,
1424  "DRAM controller checking READ queue [%d] priority [%d elements]\n",
1425  prio, queue->size());
1426 
1427  // Figure out which read request goes next
1428  // If we are changing command type, incorporate the minimum
1429  // bus turnaround delay which will be tCS (different rank) case
1430  to_read = chooseNext((*queue), switched_cmd_type ? tCS : 0);
1431 
1432  if (to_read != queue->end()) {
1433  // candidate read found
1434  read_found = true;
1435  break;
1436  }
1437  }
1438 
1439  // if no read to an available rank is found then return
1440  // at this point. There could be writes to the available ranks
1441  // which are above the required threshold. However, to
1442  // avoid adding more complexity to the code, return and wait
1443  // for a refresh event to kick things into action again.
1444  if (!read_found) {
1445  DPRINTF(DRAM, "No Reads Found - exiting\n");
1446  return;
1447  }
1448 
1449  auto dram_pkt = *to_read;
1450 
1451  assert(dram_pkt->rankRef.inRefIdleState());
1452 
1453  doDRAMAccess(dram_pkt);
1454 
1455  // Every respQueue which will generate an event, increment count
1456  ++dram_pkt->rankRef.outstandingEvents;
1457  // sanity check
1458  assert(dram_pkt->size <= burstSize);
1459  assert(dram_pkt->readyTime >= curTick());
1460 
1461  // log the response
1462  logResponse(MemCtrl::READ, (*to_read)->masterId(),
1463  dram_pkt->qosValue(), dram_pkt->getAddr(), 1,
1464  dram_pkt->readyTime - dram_pkt->entryTime);
1465 
1466 
1467  // Insert into response queue. It will be sent back to the
1468  // requester at its readyTime
1469  if (respQueue.empty()) {
1470  assert(!respondEvent.scheduled());
1471  schedule(respondEvent, dram_pkt->readyTime);
1472  } else {
1473  assert(respQueue.back()->readyTime <= dram_pkt->readyTime);
1474  assert(respondEvent.scheduled());
1475  }
1476 
1477  respQueue.push_back(dram_pkt);
1478 
1479  // we have so many writes that we have to transition
1481  switch_to_writes = true;
1482  }
1483 
1484  // remove the request from the queue - the iterator is no longer valid .
1485  readQueue[dram_pkt->qosValue()].erase(to_read);
1486  }
1487 
1488  // switching to writes, either because the read queue is empty
1489  // and the writes have passed the low threshold (or we are
1490  // draining), or because the writes hit the hight threshold
1491  if (switch_to_writes) {
1492  // transition to writing
1493  busStateNext = WRITE;
1494  }
1495  } else {
1496 
1497  bool write_found = false;
1498  DRAMPacketQueue::iterator to_write;
1499  uint8_t prio = numPriorities();
1500 
1501  for (auto queue = writeQueue.rbegin();
1502  queue != writeQueue.rend(); ++queue) {
1503 
1504  prio--;
1505 
1506  DPRINTF(QOS,
1507  "DRAM controller checking WRITE queue [%d] priority [%d elements]\n",
1508  prio, queue->size());
1509 
1510  // If we are changing command type, incorporate the minimum
1511  // bus turnaround delay
1512  to_write = chooseNext((*queue),
1513  switched_cmd_type ? std::min(tRTW, tCS) : 0);
1514 
1515  if (to_write != queue->end()) {
1516  write_found = true;
1517  break;
1518  }
1519  }
1520 
1521  // if there are no writes to a rank that is available to service
1522  // requests (i.e. rank is in refresh idle state) are found then
1523  // return. There could be reads to the available ranks. However, to
1524  // avoid adding more complexity to the code, return at this point and
1525  // wait for a refresh event to kick things into action again.
1526  if (!write_found) {
1527  DPRINTF(DRAM, "No Writes Found - exiting\n");
1528  return;
1529  }
1530 
1531  auto dram_pkt = *to_write;
1532 
1533  assert(dram_pkt->rankRef.inRefIdleState());
1534  // sanity check
1535  assert(dram_pkt->size <= burstSize);
1536 
1537  doDRAMAccess(dram_pkt);
1538 
1539  // removed write from queue, decrement count
1540  --dram_pkt->rankRef.writeEntries;
1541 
1542  // Schedule write done event to decrement event count
1543  // after the readyTime has been reached
1544  // Only schedule latest write event to minimize events
1545  // required; only need to ensure that final event scheduled covers
1546  // the time that writes are outstanding and bus is active
1547  // to holdoff power-down entry events
1548  if (!dram_pkt->rankRef.writeDoneEvent.scheduled()) {
1549  schedule(dram_pkt->rankRef.writeDoneEvent, dram_pkt->readyTime);
1550  // New event, increment count
1551  ++dram_pkt->rankRef.outstandingEvents;
1552 
1553  } else if (dram_pkt->rankRef.writeDoneEvent.when() <
1554  dram_pkt->readyTime) {
1555 
1556  reschedule(dram_pkt->rankRef.writeDoneEvent, dram_pkt->readyTime);
1557  }
1558 
1559  isInWriteQueue.erase(burstAlign(dram_pkt->addr));
1560 
1561  // log the response
1562  logResponse(MemCtrl::WRITE, dram_pkt->masterId(),
1563  dram_pkt->qosValue(), dram_pkt->getAddr(), 1,
1564  dram_pkt->readyTime - dram_pkt->entryTime);
1565 
1566 
1567  // remove the request from the queue - the iterator is no longer valid
1568  writeQueue[dram_pkt->qosValue()].erase(to_write);
1569 
1570  delete dram_pkt;
1571 
1572  // If we emptied the write queue, or got sufficiently below the
1573  // threshold (using the minWritesPerSwitch as the hysteresis) and
1574  // are not draining, or we have reads waiting and have done enough
1575  // writes, then switch to reads.
1576  bool below_threshold =
1578 
1579  if (totalWriteQueueSize == 0 ||
1580  (below_threshold && drainState() != DrainState::Draining) ||
1582 
1583  // turn the bus back around for reads again
1584  busStateNext = READ;
1585 
1586  // note that the we switch back to reads also in the idle
1587  // case, which eventually will check for any draining and
1588  // also pause any further scheduling if there is really
1589  // nothing to do
1590  }
1591  }
1592  // It is possible that a refresh to another rank kicks things back into
1593  // action before reaching this point.
1594  if (!nextReqEvent.scheduled())
1595  schedule(nextReqEvent, std::max(nextReqTime, curTick()));
1596 
1597  // If there is space available and we have writes waiting then let
1598  // them retry. This is done here to ensure that the retry does not
1599  // cause a nextReqEvent to be scheduled before we do so as part of
1600  // the next request processing
1602  retryWrReq = false;
1603  port.sendRetryReq();
1604  }
1605 }
1606 
1607 pair<vector<uint32_t>, bool>
1609  Tick min_col_at) const
1610 {
1611  Tick min_act_at = MaxTick;
1612  vector<uint32_t> bank_mask(ranksPerChannel, 0);
1613 
1614  // latest Tick for which ACT can occur without incurring additoinal
1615  // delay on the data bus
1616  const Tick hidden_act_max = std::max(min_col_at - tRCD, curTick());
1617 
1618  // Flag condition when burst can issue back-to-back with previous burst
1619  bool found_seamless_bank = false;
1620 
1621  // Flag condition when bank can be opened without incurring additional
1622  // delay on the data bus
1623  bool hidden_bank_prep = false;
1624 
1625  // determine if we have queued transactions targetting the
1626  // bank in question
1627  vector<bool> got_waiting(ranksPerChannel * banksPerRank, false);
1628  for (const auto& p : queue) {
1629  if (p->rankRef.inRefIdleState())
1630  got_waiting[p->bankId] = true;
1631  }
1632 
1633  // Find command with optimal bank timing
1634  // Will prioritize commands that can issue seamlessly.
1635  for (int i = 0; i < ranksPerChannel; i++) {
1636  for (int j = 0; j < banksPerRank; j++) {
1637  uint16_t bank_id = i * banksPerRank + j;
1638 
1639  // if we have waiting requests for the bank, and it is
1640  // amongst the first available, update the mask
1641  if (got_waiting[bank_id]) {
1642  // make sure this rank is not currently refreshing.
1643  assert(ranks[i]->inRefIdleState());
1644  // simplistic approximation of when the bank can issue
1645  // an activate, ignoring any rank-to-rank switching
1646  // cost in this calculation
1647  Tick act_at = ranks[i]->banks[j].openRow == Bank::NO_ROW ?
1648  std::max(ranks[i]->banks[j].actAllowedAt, curTick()) :
1649  std::max(ranks[i]->banks[j].preAllowedAt, curTick()) + tRP;
1650 
1651  // When is the earliest the R/W burst can issue?
1652  const Tick col_allowed_at = (busState == READ) ?
1653  ranks[i]->banks[j].rdAllowedAt :
1654  ranks[i]->banks[j].wrAllowedAt;
1655  Tick col_at = std::max(col_allowed_at, act_at + tRCD);
1656 
1657  // bank can issue burst back-to-back (seamlessly) with
1658  // previous burst
1659  bool new_seamless_bank = col_at <= min_col_at;
1660 
1661  // if we found a new seamless bank or we have no
1662  // seamless banks, and got a bank with an earlier
1663  // activate time, it should be added to the bit mask
1664  if (new_seamless_bank ||
1665  (!found_seamless_bank && act_at <= min_act_at)) {
1666  // if we did not have a seamless bank before, and
1667  // we do now, reset the bank mask, also reset it
1668  // if we have not yet found a seamless bank and
1669  // the activate time is smaller than what we have
1670  // seen so far
1671  if (!found_seamless_bank &&
1672  (new_seamless_bank || act_at < min_act_at)) {
1673  std::fill(bank_mask.begin(), bank_mask.end(), 0);
1674  }
1675 
1676  found_seamless_bank |= new_seamless_bank;
1677 
1678  // ACT can occur 'behind the scenes'
1679  hidden_bank_prep = act_at <= hidden_act_max;
1680 
1681  // set the bit corresponding to the available bank
1682  replaceBits(bank_mask[i], j, j, 1);
1683  min_act_at = act_at;
1684  }
1685  }
1686  }
1687  }
1688 
1689  return make_pair(bank_mask, hidden_bank_prep);
1690 }
1691 
1692 DRAMCtrl::Rank::Rank(DRAMCtrl& _memory, const DRAMCtrlParams* _p, int rank)
1693  : EventManager(&_memory), memory(_memory),
1694  pwrStateTrans(PWR_IDLE), pwrStatePostRefresh(PWR_IDLE),
1695  pwrStateTick(0), refreshDueAt(0), pwrState(PWR_IDLE),
1696  refreshState(REF_IDLE), inLowPowerState(false), rank(rank),
1697  readEntries(0), writeEntries(0), outstandingEvents(0),
1698  wakeUpAllowedAt(0), power(_p, false), banks(_p->banks_per_rank),
1699  numBanksActive(0), actTicks(_p->activation_limit, 0),
1700  writeDoneEvent([this]{ processWriteDoneEvent(); }, name()),
1701  activateEvent([this]{ processActivateEvent(); }, name()),
1702  prechargeEvent([this]{ processPrechargeEvent(); }, name()),
1703  refreshEvent([this]{ processRefreshEvent(); }, name()),
1704  powerEvent([this]{ processPowerEvent(); }, name()),
1705  wakeUpEvent([this]{ processWakeUpEvent(); }, name()),
1706  stats(_memory, *this)
1707 {
1708  for (int b = 0; b < _p->banks_per_rank; b++) {
1709  banks[b].bank = b;
1710  // GDDR addressing of banks to BG is linear.
1711  // Here we assume that all DRAM generations address bank groups as
1712  // follows:
1713  if (_p->bank_groups_per_rank > 0) {
1714  // Simply assign lower bits to bank group in order to
1715  // rotate across bank groups as banks are incremented
1716  // e.g. with 4 banks per bank group and 16 banks total:
1717  // banks 0,4,8,12 are in bank group 0
1718  // banks 1,5,9,13 are in bank group 1
1719  // banks 2,6,10,14 are in bank group 2
1720  // banks 3,7,11,15 are in bank group 3
1721  banks[b].bankgr = b % _p->bank_groups_per_rank;
1722  } else {
1723  // No bank groups; simply assign to bank number
1724  banks[b].bankgr = b;
1725  }
1726  }
1727 }
1728 
1729 void
1731 {
1732  assert(ref_tick > curTick());
1733 
1734  pwrStateTick = curTick();
1735 
1736  // kick off the refresh, and give ourselves enough time to
1737  // precharge
1738  schedule(refreshEvent, ref_tick);
1739 }
1740 
1741 void
1743 {
1745 
1746  // Update the stats
1747  updatePowerStats();
1748 
1749  // don't automatically transition back to LP state after next REF
1751 }
1752 
1753 bool
1755 {
1756  // check commmands in Q based on current bus direction
1757  bool no_queued_cmds = ((memory.busStateNext == READ) && (readEntries == 0))
1758  || ((memory.busStateNext == WRITE) &&
1759  (writeEntries == 0));
1760  return no_queued_cmds;
1761 }
1762 
1763 void
1765 {
1766  // if this rank was waiting to drain it is now able to proceed to
1767  // precharge
1768  if (refreshState == REF_DRAIN) {
1769  DPRINTF(DRAM, "Refresh drain done, now precharging\n");
1770 
1772 
1773  // hand control back to the refresh event loop
1775  }
1776 }
1777 
1778 void
1780 {
1781  // at the moment sort the list of commands and update the counters
1782  // for DRAMPower libray when doing a refresh
1783  sort(cmdList.begin(), cmdList.end(), DRAMCtrl::sortTime);
1784 
1785  auto next_iter = cmdList.begin();
1786  // push to commands to DRAMPower
1787  for ( ; next_iter != cmdList.end() ; ++next_iter) {
1788  Command cmd = *next_iter;
1789  if (cmd.timeStamp <= curTick()) {
1790  // Move all commands at or before curTick to DRAMPower
1791  power.powerlib.doCommand(cmd.type, cmd.bank,
1792  divCeil(cmd.timeStamp, memory.tCK) -
1793  memory.timeStampOffset);
1794  } else {
1795  // done - found all commands at or before curTick()
1796  // next_iter references the 1st command after curTick
1797  break;
1798  }
1799  }
1800  // reset cmdList to only contain commands after curTick
1801  // if there are no commands after curTick, updated cmdList will be empty
1802  // in this case, next_iter is cmdList.end()
1803  cmdList.assign(next_iter, cmdList.end());
1804 }
1805 
1806 void
1808 {
1809  // we should transition to the active state as soon as any bank is active
1810  if (pwrState != PWR_ACT)
1811  // note that at this point numBanksActive could be back at
1812  // zero again due to a precharge scheduled in the future
1814 }
1815 
1816 void
1818 {
1819  // counter should at least indicate one outstanding request
1820  // for this precharge
1821  assert(outstandingEvents > 0);
1822  // precharge complete, decrement count
1824 
1825  // if we reached zero, then special conditions apply as we track
1826  // if all banks are precharged for the power models
1827  if (numBanksActive == 0) {
1828  // no reads to this rank in the Q and no pending
1829  // RD/WR or refresh commands
1830  if (isQueueEmpty() && outstandingEvents == 0 &&
1831  memory.enableDRAMPowerdown) {
1832  // should still be in ACT state since bank still open
1833  assert(pwrState == PWR_ACT);
1834 
1835  // All banks closed - switch to precharge power down state.
1836  DPRINTF(DRAMState, "Rank %d sleep at tick %d\n",
1837  rank, curTick());
1839  } else {
1840  // we should transition to the idle state when the last bank
1841  // is precharged
1843  }
1844  }
1845 }
1846 
1847 void
1849 {
1850  // counter should at least indicate one outstanding request
1851  // for this write
1852  assert(outstandingEvents > 0);
1853  // Write transfer on bus has completed
1854  // decrement per rank counter
1856 }
1857 
1858 void
1860 {
1861  // when first preparing the refresh, remember when it was due
1862  if ((refreshState == REF_IDLE) || (refreshState == REF_SREF_EXIT)) {
1863  // remember when the refresh is due
1864  refreshDueAt = curTick();
1865 
1866  // proceed to drain
1868 
1869  // make nonzero while refresh is pending to ensure
1870  // power down and self-refresh are not entered
1872 
1873  DPRINTF(DRAM, "Refresh due\n");
1874  }
1875 
1876  // let any scheduled read or write to the same rank go ahead,
1877  // after which it will
1878  // hand control back to this event loop
1879  if (refreshState == REF_DRAIN) {
1880  // if a request is at the moment being handled and this request is
1881  // accessing the current rank then wait for it to finish
1882  if ((rank == memory.activeRank)
1883  && (memory.nextReqEvent.scheduled())) {
1884  // hand control over to the request loop until it is
1885  // evaluated next
1886  DPRINTF(DRAM, "Refresh awaiting draining\n");
1887 
1888  return;
1889  } else {
1891  }
1892  }
1893 
1894  // at this point, ensure that rank is not in a power-down state
1895  if (refreshState == REF_PD_EXIT) {
1896  // if rank was sleeping and we have't started exit process,
1897  // wake-up for refresh
1898  if (inLowPowerState) {
1899  DPRINTF(DRAM, "Wake Up for refresh\n");
1900  // save state and return after refresh completes
1902  return;
1903  } else {
1905  }
1906  }
1907 
1908  // at this point, ensure that all banks are precharged
1909  if (refreshState == REF_PRE) {
1910  // precharge any active bank
1911  if (numBanksActive != 0) {
1912  // at the moment, we use a precharge all even if there is
1913  // only a single bank open
1914  DPRINTF(DRAM, "Precharging all\n");
1915 
1916  // first determine when we can precharge
1917  Tick pre_at = curTick();
1918 
1919  for (auto &b : banks) {
1920  // respect both causality and any existing bank
1921  // constraints, some banks could already have a
1922  // (auto) precharge scheduled
1923  pre_at = std::max(b.preAllowedAt, pre_at);
1924  }
1925 
1926  // make sure all banks per rank are precharged, and for those that
1927  // already are, update their availability
1928  Tick act_allowed_at = pre_at + memory.tRP;
1929 
1930  for (auto &b : banks) {
1931  if (b.openRow != Bank::NO_ROW) {
1932  memory.prechargeBank(*this, b, pre_at, false);
1933  } else {
1934  b.actAllowedAt = std::max(b.actAllowedAt, act_allowed_at);
1935  b.preAllowedAt = std::max(b.preAllowedAt, pre_at);
1936  }
1937  }
1938 
1939  // precharge all banks in rank
1940  cmdList.push_back(Command(MemCommand::PREA, 0, pre_at));
1941 
1942  DPRINTF(DRAMPower, "%llu,PREA,0,%d\n",
1943  divCeil(pre_at, memory.tCK) -
1944  memory.timeStampOffset, rank);
1945  } else if ((pwrState == PWR_IDLE) && (outstandingEvents == 1)) {
1946  // Banks are closed, have transitioned to IDLE state, and
1947  // no outstanding ACT,RD/WR,Auto-PRE sequence scheduled
1948  DPRINTF(DRAM, "All banks already precharged, starting refresh\n");
1949 
1950  // go ahead and kick the power state machine into gear since
1951  // we are already idle
1953  } else {
1954  // banks state is closed but haven't transitioned pwrState to IDLE
1955  // or have outstanding ACT,RD/WR,Auto-PRE sequence scheduled
1956  // should have outstanding precharge event in this case
1957  assert(prechargeEvent.scheduled());
1958  // will start refresh when pwrState transitions to IDLE
1959  }
1960 
1961  assert(numBanksActive == 0);
1962 
1963  // wait for all banks to be precharged, at which point the
1964  // power state machine will transition to the idle state, and
1965  // automatically move to a refresh, at that point it will also
1966  // call this method to get the refresh event loop going again
1967  return;
1968  }
1969 
1970  // last but not least we perform the actual refresh
1971  if (refreshState == REF_START) {
1972  // should never get here with any banks active
1973  assert(numBanksActive == 0);
1974  assert(pwrState == PWR_REF);
1975 
1976  Tick ref_done_at = curTick() + memory.tRFC;
1977 
1978  for (auto &b : banks) {
1979  b.actAllowedAt = ref_done_at;
1980  }
1981 
1982  // at the moment this affects all ranks
1983  cmdList.push_back(Command(MemCommand::REF, 0, curTick()));
1984 
1985  // Update the stats
1986  updatePowerStats();
1987 
1988  DPRINTF(DRAMPower, "%llu,REF,0,%d\n", divCeil(curTick(), memory.tCK) -
1989  memory.timeStampOffset, rank);
1990 
1991  // Update for next refresh
1992  refreshDueAt += memory.tREFI;
1993 
1994  // make sure we did not wait so long that we cannot make up
1995  // for it
1996  if (refreshDueAt < ref_done_at) {
1997  fatal("Refresh was delayed so long we cannot catch up\n");
1998  }
1999 
2000  // Run the refresh and schedule event to transition power states
2001  // when refresh completes
2003  schedule(refreshEvent, ref_done_at);
2004  return;
2005  }
2006 
2007  if (refreshState == REF_RUN) {
2008  // should never get here with any banks active
2009  assert(numBanksActive == 0);
2010  assert(pwrState == PWR_REF);
2011 
2012  assert(!powerEvent.scheduled());
2013 
2014  if ((memory.drainState() == DrainState::Draining) ||
2015  (memory.drainState() == DrainState::Drained)) {
2016  // if draining, do not re-enter low-power mode.
2017  // simply go to IDLE and wait
2019  } else {
2020  // At the moment, we sleep when the refresh ends and wait to be
2021  // woken up again if previously in a low-power state.
2022  if (pwrStatePostRefresh != PWR_IDLE) {
2023  // power State should be power Refresh
2024  assert(pwrState == PWR_REF);
2025  DPRINTF(DRAMState, "Rank %d sleeping after refresh and was in "
2026  "power state %d before refreshing\n", rank,
2029 
2030  // Force PRE power-down if there are no outstanding commands
2031  // in Q after refresh.
2032  } else if (isQueueEmpty() && memory.enableDRAMPowerdown) {
2033  // still have refresh event outstanding but there should
2034  // be no other events outstanding
2035  assert(outstandingEvents == 1);
2036  DPRINTF(DRAMState, "Rank %d sleeping after refresh but was NOT"
2037  " in a low power state before refreshing\n", rank);
2039 
2040  } else {
2041  // move to the idle power state once the refresh is done, this
2042  // will also move the refresh state machine to the refresh
2043  // idle state
2045  }
2046  }
2047 
2048  // At this point, we have completed the current refresh.
2049  // In the SREF bypass case, we do not get to this state in the
2050  // refresh STM and therefore can always schedule next event.
2051  // Compensate for the delay in actually performing the refresh
2052  // when scheduling the next one
2054 
2055  DPRINTF(DRAMState, "Refresh done at %llu and next refresh"
2056  " at %llu\n", curTick(), refreshDueAt);
2057  }
2058 }
2059 
2060 void
2062 {
2063  // respect causality
2064  assert(tick >= curTick());
2065 
2066  if (!powerEvent.scheduled()) {
2067  DPRINTF(DRAMState, "Scheduling power event at %llu to state %d\n",
2068  tick, pwr_state);
2069 
2070  // insert the new transition
2071  pwrStateTrans = pwr_state;
2072 
2073  schedule(powerEvent, tick);
2074  } else {
2075  panic("Scheduled power event at %llu to state %d, "
2076  "with scheduled event at %llu to %d\n", tick, pwr_state,
2078  }
2079 }
2080 
2081 void
2083 {
2084  // if low power state is active low, schedule to active low power state.
2085  // in reality tCKE is needed to enter active low power. This is neglected
2086  // here and could be added in the future.
2087  if (pwr_state == PWR_ACT_PDN) {
2088  schedulePowerEvent(pwr_state, tick);
2089  // push command to DRAMPower
2090  cmdList.push_back(Command(MemCommand::PDN_F_ACT, 0, tick));
2091  DPRINTF(DRAMPower, "%llu,PDN_F_ACT,0,%d\n", divCeil(tick,
2092  memory.tCK) - memory.timeStampOffset, rank);
2093  } else if (pwr_state == PWR_PRE_PDN) {
2094  // if low power state is precharge low, schedule to precharge low
2095  // power state. In reality tCKE is needed to enter active low power.
2096  // This is neglected here.
2097  schedulePowerEvent(pwr_state, tick);
2098  //push Command to DRAMPower
2099  cmdList.push_back(Command(MemCommand::PDN_F_PRE, 0, tick));
2100  DPRINTF(DRAMPower, "%llu,PDN_F_PRE,0,%d\n", divCeil(tick,
2101  memory.tCK) - memory.timeStampOffset, rank);
2102  } else if (pwr_state == PWR_REF) {
2103  // if a refresh just occurred
2104  // transition to PRE_PDN now that all banks are closed
2105  // precharge power down requires tCKE to enter. For simplicity
2106  // this is not considered.
2108  //push Command to DRAMPower
2109  cmdList.push_back(Command(MemCommand::PDN_F_PRE, 0, tick));
2110  DPRINTF(DRAMPower, "%llu,PDN_F_PRE,0,%d\n", divCeil(tick,
2111  memory.tCK) - memory.timeStampOffset, rank);
2112  } else if (pwr_state == PWR_SREF) {
2113  // should only enter SREF after PRE-PD wakeup to do a refresh
2114  assert(pwrStatePostRefresh == PWR_PRE_PDN);
2115  // self refresh requires time tCKESR to enter. For simplicity,
2116  // this is not considered.
2118  // push Command to DRAMPower
2119  cmdList.push_back(Command(MemCommand::SREN, 0, tick));
2120  DPRINTF(DRAMPower, "%llu,SREN,0,%d\n", divCeil(tick,
2121  memory.tCK) - memory.timeStampOffset, rank);
2122  }
2123  // Ensure that we don't power-down and back up in same tick
2124  // Once we commit to PD entry, do it and wait for at least 1tCK
2125  // This could be replaced with tCKE if/when that is added to the model
2126  wakeUpAllowedAt = tick + memory.tCK;
2127 
2128  // Transitioning to a low power state, set flag
2129  inLowPowerState = true;
2130 }
2131 
2132 void
2134 {
2135  Tick wake_up_tick = std::max(curTick(), wakeUpAllowedAt);
2136 
2137  DPRINTF(DRAMState, "Scheduling wake-up for rank %d at tick %d\n",
2138  rank, wake_up_tick);
2139 
2140  // if waking for refresh, hold previous state
2141  // else reset state back to IDLE
2142  if (refreshState == REF_PD_EXIT) {
2144  } else {
2145  // don't automatically transition back to LP state after next REF
2147  }
2148 
2149  // schedule wake-up with event to ensure entry has completed before
2150  // we try to wake-up
2151  schedule(wakeUpEvent, wake_up_tick);
2152 
2153  for (auto &b : banks) {
2154  // respect both causality and any existing bank
2155  // constraints, some banks could already have a
2156  // (auto) precharge scheduled
2157  b.wrAllowedAt = std::max(wake_up_tick + exit_delay, b.wrAllowedAt);
2158  b.rdAllowedAt = std::max(wake_up_tick + exit_delay, b.rdAllowedAt);
2159  b.preAllowedAt = std::max(wake_up_tick + exit_delay, b.preAllowedAt);
2160  b.actAllowedAt = std::max(wake_up_tick + exit_delay, b.actAllowedAt);
2161  }
2162  // Transitioning out of low power state, clear flag
2163  inLowPowerState = false;
2164 
2165  // push to DRAMPower
2166  // use pwrStateTrans for cases where we have a power event scheduled
2167  // to enter low power that has not yet been processed
2168  if (pwrStateTrans == PWR_ACT_PDN) {
2169  cmdList.push_back(Command(MemCommand::PUP_ACT, 0, wake_up_tick));
2170  DPRINTF(DRAMPower, "%llu,PUP_ACT,0,%d\n", divCeil(wake_up_tick,
2171  memory.tCK) - memory.timeStampOffset, rank);
2172 
2173  } else if (pwrStateTrans == PWR_PRE_PDN) {
2174  cmdList.push_back(Command(MemCommand::PUP_PRE, 0, wake_up_tick));
2175  DPRINTF(DRAMPower, "%llu,PUP_PRE,0,%d\n", divCeil(wake_up_tick,
2176  memory.tCK) - memory.timeStampOffset, rank);
2177  } else if (pwrStateTrans == PWR_SREF) {
2178  cmdList.push_back(Command(MemCommand::SREX, 0, wake_up_tick));
2179  DPRINTF(DRAMPower, "%llu,SREX,0,%d\n", divCeil(wake_up_tick,
2180  memory.tCK) - memory.timeStampOffset, rank);
2181  }
2182 }
2183 
2184 void
2186 {
2187  // Should be in a power-down or self-refresh state
2188  assert((pwrState == PWR_ACT_PDN) || (pwrState == PWR_PRE_PDN) ||
2189  (pwrState == PWR_SREF));
2190 
2191  // Check current state to determine transition state
2192  if (pwrState == PWR_ACT_PDN) {
2193  // banks still open, transition to PWR_ACT
2195  } else {
2196  // transitioning from a precharge power-down or self-refresh state
2197  // banks are closed - transition to PWR_IDLE
2199  }
2200 }
2201 
2202 void
2204 {
2205  assert(curTick() >= pwrStateTick);
2206  // remember where we were, and for how long
2207  Tick duration = curTick() - pwrStateTick;
2208  PowerState prev_state = pwrState;
2209 
2210  // update the accounting
2211  stats.memoryStateTime[prev_state] += duration;
2212 
2213  // track to total idle time
2214  if ((prev_state == PWR_PRE_PDN) || (prev_state == PWR_ACT_PDN) ||
2215  (prev_state == PWR_SREF)) {
2216  stats.totalIdleTime += duration;
2217  }
2218 
2220  pwrStateTick = curTick();
2221 
2222  // if rank was refreshing, make sure to start scheduling requests again
2223  if (prev_state == PWR_REF) {
2224  // bus IDLED prior to REF
2225  // counter should be one for refresh command only
2226  assert(outstandingEvents == 1);
2227  // REF complete, decrement count and go back to IDLE
2230 
2231  DPRINTF(DRAMState, "Was refreshing for %llu ticks\n", duration);
2232  // if moving back to power-down after refresh
2233  if (pwrState != PWR_IDLE) {
2234  assert(pwrState == PWR_PRE_PDN);
2235  DPRINTF(DRAMState, "Switching to power down state after refreshing"
2236  " rank %d at %llu tick\n", rank, curTick());
2237  }
2238 
2239  // completed refresh event, ensure next request is scheduled
2240  if (!memory.nextReqEvent.scheduled()) {
2241  DPRINTF(DRAM, "Scheduling next request after refreshing"
2242  " rank %d\n", rank);
2243  schedule(memory.nextReqEvent, curTick());
2244  }
2245  }
2246 
2247  if ((pwrState == PWR_ACT) && (refreshState == REF_PD_EXIT)) {
2248  // have exited ACT PD
2249  assert(prev_state == PWR_ACT_PDN);
2250 
2251  // go back to REF event and close banks
2254  } else if (pwrState == PWR_IDLE) {
2255  DPRINTF(DRAMState, "All banks precharged\n");
2256  if (prev_state == PWR_SREF) {
2257  // set refresh state to REF_SREF_EXIT, ensuring inRefIdleState
2258  // continues to return false during tXS after SREF exit
2259  // Schedule a refresh which kicks things back into action
2260  // when it finishes
2262  schedule(refreshEvent, curTick() + memory.tXS);
2263  } else {
2264  // if we have a pending refresh, and are now moving to
2265  // the idle state, directly transition to, or schedule refresh
2266  if ((refreshState == REF_PRE) || (refreshState == REF_PD_EXIT)) {
2267  // ensure refresh is restarted only after final PRE command.
2268  // do not restart refresh if controller is in an intermediate
2269  // state, after PRE_PDN exit, when banks are IDLE but an
2270  // ACT is scheduled.
2271  if (!activateEvent.scheduled()) {
2272  // there should be nothing waiting at this point
2273  assert(!powerEvent.scheduled());
2274  if (refreshState == REF_PD_EXIT) {
2275  // exiting PRE PD, will be in IDLE until tXP expires
2276  // and then should transition to PWR_REF state
2277  assert(prev_state == PWR_PRE_PDN);
2279  } else if (refreshState == REF_PRE) {
2280  // can directly move to PWR_REF state and proceed below
2281  pwrState = PWR_REF;
2282  }
2283  } else {
2284  // must have PRE scheduled to transition back to IDLE
2285  // and re-kick off refresh
2286  assert(prechargeEvent.scheduled());
2287  }
2288  }
2289  }
2290  }
2291 
2292  // transition to the refresh state and re-start refresh process
2293  // refresh state machine will schedule the next power state transition
2294  if (pwrState == PWR_REF) {
2295  // completed final PRE for refresh or exiting power-down
2296  assert(refreshState == REF_PRE || refreshState == REF_PD_EXIT);
2297 
2298  // exited PRE PD for refresh, with no pending commands
2299  // bypass auto-refresh and go straight to SREF, where memory
2300  // will issue refresh immediately upon entry
2302  (memory.drainState() != DrainState::Draining) &&
2303  (memory.drainState() != DrainState::Drained) &&
2304  memory.enableDRAMPowerdown) {
2305  DPRINTF(DRAMState, "Rank %d bypassing refresh and transitioning "
2306  "to self refresh at %11u tick\n", rank, curTick());
2308 
2309  // Since refresh was bypassed, remove event by decrementing count
2310  assert(outstandingEvents == 1);
2312 
2313  // reset state back to IDLE temporarily until SREF is entered
2314  pwrState = PWR_IDLE;
2315 
2316  // Not bypassing refresh for SREF entry
2317  } else {
2318  DPRINTF(DRAMState, "Refreshing\n");
2319 
2320  // there should be nothing waiting at this point
2321  assert(!powerEvent.scheduled());
2322 
2323  // kick the refresh event loop into action again, and that
2324  // in turn will schedule a transition to the idle power
2325  // state once the refresh is done
2327 
2328  // Banks transitioned to IDLE, start REF
2330  }
2331  }
2332 
2333 }
2334 
2335 void
2337 {
2338  // All commands up to refresh have completed
2339  // flush cmdList to DRAMPower
2340  flushCmdList();
2341 
2342  // Call the function that calculates window energy at intermediate update
2343  // events like at refresh, stats dump as well as at simulation exit.
2344  // Window starts at the last time the calcWindowEnergy function was called
2345  // and is upto current time.
2346  power.powerlib.calcWindowEnergy(divCeil(curTick(), memory.tCK) -
2347  memory.timeStampOffset);
2348 
2349  // Get the energy from DRAMPower
2350  Data::MemoryPowerModel::Energy energy = power.powerlib.getEnergy();
2351 
2352  // The energy components inside the power lib are calculated over
2353  // the window so accumulate into the corresponding gem5 stat
2354  stats.actEnergy += energy.act_energy * memory.devicesPerRank;
2355  stats.preEnergy += energy.pre_energy * memory.devicesPerRank;
2356  stats.readEnergy += energy.read_energy * memory.devicesPerRank;
2357  stats.writeEnergy += energy.write_energy * memory.devicesPerRank;
2358  stats.refreshEnergy += energy.ref_energy * memory.devicesPerRank;
2359  stats.actBackEnergy += energy.act_stdby_energy * memory.devicesPerRank;
2360  stats.preBackEnergy += energy.pre_stdby_energy * memory.devicesPerRank;
2361  stats.actPowerDownEnergy += energy.f_act_pd_energy * memory.devicesPerRank;
2362  stats.prePowerDownEnergy += energy.f_pre_pd_energy * memory.devicesPerRank;
2363  stats.selfRefreshEnergy += energy.sref_energy * memory.devicesPerRank;
2364 
2365  // Accumulate window energy into the total energy.
2366  stats.totalEnergy += energy.window_energy * memory.devicesPerRank;
2367  // Average power must not be accumulated but calculated over the time
2368  // since last stats reset. SimClock::Frequency is tick period not tick
2369  // frequency.
2370  // energy (pJ) 1e-9
2371  // power (mW) = ----------- * ----------
2372  // time (tick) tick_frequency
2374  (curTick() - memory.lastStatsResetTick)) *
2375  (SimClock::Frequency / 1000000000.0);
2376 }
2377 
2378 void
2380 {
2381  DPRINTF(DRAM,"Computing stats due to a dump callback\n");
2382 
2383  // Update the stats
2384  updatePowerStats();
2385 
2386  // final update of power state times
2388  pwrStateTick = curTick();
2389 }
2390 
2391 void
2393  // The only way to clear the counters in DRAMPower is to call
2394  // calcWindowEnergy function as that then calls clearCounters. The
2395  // clearCounters method itself is private.
2396  power.powerlib.calcWindowEnergy(divCeil(curTick(), memory.tCK) -
2397  memory.timeStampOffset);
2398 
2399 }
2400 
2402  : Stats::Group(&_dram),
2403  dram(_dram),
2404 
2405  ADD_STAT(readReqs, "Number of read requests accepted"),
2406  ADD_STAT(writeReqs, "Number of write requests accepted"),
2407 
2408  ADD_STAT(readBursts,
2409  "Number of DRAM read bursts, "
2410  "including those serviced by the write queue"),
2411  ADD_STAT(writeBursts,
2412  "Number of DRAM write bursts, "
2413  "including those merged in the write queue"),
2414  ADD_STAT(servicedByWrQ,
2415  "Number of DRAM read bursts serviced by the write queue"),
2416  ADD_STAT(mergedWrBursts,
2417  "Number of DRAM write bursts merged with an existing one"),
2418 
2419  ADD_STAT(neitherReadNorWriteReqs,
2420  "Number of requests that are neither read nor write"),
2421 
2422  ADD_STAT(perBankRdBursts, "Per bank write bursts"),
2423  ADD_STAT(perBankWrBursts, "Per bank write bursts"),
2424 
2425  ADD_STAT(avgRdQLen, "Average read queue length when enqueuing"),
2426  ADD_STAT(avgWrQLen, "Average write queue length when enqueuing"),
2427 
2428  ADD_STAT(totQLat, "Total ticks spent queuing"),
2429  ADD_STAT(totBusLat, "Total ticks spent in databus transfers"),
2430  ADD_STAT(totMemAccLat,
2431  "Total ticks spent from burst creation until serviced "
2432  "by the DRAM"),
2433  ADD_STAT(avgQLat, "Average queueing delay per DRAM burst"),
2434  ADD_STAT(avgBusLat, "Average bus latency per DRAM burst"),
2435  ADD_STAT(avgMemAccLat, "Average memory access latency per DRAM burst"),
2436 
2437  ADD_STAT(numRdRetry, "Number of times read queue was full causing retry"),
2438  ADD_STAT(numWrRetry, "Number of times write queue was full causing retry"),
2439 
2440  ADD_STAT(readRowHits, "Number of row buffer hits during reads"),
2441  ADD_STAT(writeRowHits, "Number of row buffer hits during writes"),
2442  ADD_STAT(readRowHitRate, "Row buffer hit rate for reads"),
2443  ADD_STAT(writeRowHitRate, "Row buffer hit rate for writes"),
2444 
2445  ADD_STAT(readPktSize, "Read request sizes (log2)"),
2446  ADD_STAT(writePktSize, "Write request sizes (log2)"),
2447 
2448  ADD_STAT(rdQLenPdf, "What read queue length does an incoming req see"),
2449  ADD_STAT(wrQLenPdf, "What write queue length does an incoming req see"),
2450 
2451  ADD_STAT(bytesPerActivate, "Bytes accessed per row activation"),
2452 
2453  ADD_STAT(rdPerTurnAround,
2454  "Reads before turning the bus around for writes"),
2455  ADD_STAT(wrPerTurnAround,
2456  "Writes before turning the bus around for reads"),
2457 
2458  ADD_STAT(bytesReadDRAM, "Total number of bytes read from DRAM"),
2459  ADD_STAT(bytesReadWrQ, "Total number of bytes read from write queue"),
2460  ADD_STAT(bytesWritten, "Total number of bytes written to DRAM"),
2461  ADD_STAT(bytesReadSys, "Total read bytes from the system interface side"),
2462  ADD_STAT(bytesWrittenSys,
2463  "Total written bytes from the system interface side"),
2464 
2465  ADD_STAT(avgRdBW, "Average DRAM read bandwidth in MiByte/s"),
2466  ADD_STAT(avgWrBW, "Average achieved write bandwidth in MiByte/s"),
2467  ADD_STAT(avgRdBWSys, "Average system read bandwidth in MiByte/s"),
2468  ADD_STAT(avgWrBWSys, "Average system write bandwidth in MiByte/s"),
2469  ADD_STAT(peakBW, "Theoretical peak bandwidth in MiByte/s"),
2470 
2471  ADD_STAT(busUtil, "Data bus utilization in percentage"),
2472  ADD_STAT(busUtilRead, "Data bus utilization in percentage for reads"),
2473  ADD_STAT(busUtilWrite, "Data bus utilization in percentage for writes"),
2474 
2475  ADD_STAT(totGap, "Total gap between requests"),
2476  ADD_STAT(avgGap, "Average gap between requests"),
2477 
2478  ADD_STAT(masterReadBytes, "Per-master bytes read from memory"),
2479  ADD_STAT(masterWriteBytes, "Per-master bytes write to memory"),
2480  ADD_STAT(masterReadRate,
2481  "Per-master bytes read from memory rate (Bytes/sec)"),
2482  ADD_STAT(masterWriteRate,
2483  "Per-master bytes write to memory rate (Bytes/sec)"),
2484  ADD_STAT(masterReadAccesses,
2485  "Per-master read serviced memory accesses"),
2486  ADD_STAT(masterWriteAccesses,
2487  "Per-master write serviced memory accesses"),
2488  ADD_STAT(masterReadTotalLat,
2489  "Per-master read total memory access latency"),
2490  ADD_STAT(masterWriteTotalLat,
2491  "Per-master write total memory access latency"),
2492  ADD_STAT(masterReadAvgLat,
2493  "Per-master read average memory access latency"),
2494  ADD_STAT(masterWriteAvgLat,
2495  "Per-master write average memory access latency"),
2496 
2497  ADD_STAT(pageHitRate, "Row buffer hit rate, read and write combined")
2498 {
2499 }
2500 
2501 void
2503 {
2504  using namespace Stats;
2505 
2506  assert(dram._system);
2507  const auto max_masters = dram._system->maxMasters();
2508 
2511 
2512  avgRdQLen.precision(2);
2513  avgWrQLen.precision(2);
2514  avgQLat.precision(2);
2515  avgBusLat.precision(2);
2517 
2520 
2523 
2526 
2530  .flags(nozero);
2531 
2534  .flags(nozero);
2537  .flags(nozero);
2538 
2539  avgRdBW.precision(2);
2540  avgWrBW.precision(2);
2541  avgRdBWSys.precision(2);
2542  avgWrBWSys.precision(2);
2543  peakBW.precision(2);
2544  busUtil.precision(2);
2545  avgGap.precision(2);
2548 
2549 
2550  // per-master bytes read and written to memory
2552  .init(max_masters)
2553  .flags(nozero | nonan);
2554 
2556  .init(max_masters)
2557  .flags(nozero | nonan);
2558 
2559  // per-master bytes read and written to memory rate
2561  .flags(nozero | nonan)
2562  .precision(12);
2563 
2565  .init(max_masters)
2566  .flags(nozero);
2567 
2569  .init(max_masters)
2570  .flags(nozero);
2571 
2573  .init(max_masters)
2574  .flags(nozero | nonan);
2575 
2577  .flags(nonan)
2578  .precision(2);
2579 
2580 
2581  busUtilRead
2582  .precision(2);
2583 
2585  .flags(nozero | nonan)
2586  .precision(12);
2587 
2589  .init(max_masters)
2590  .flags(nozero | nonan);
2591 
2593  .flags(nonan)
2594  .precision(2);
2595 
2596  for (int i = 0; i < max_masters; i++) {
2597  const std::string master = dram._system->getMasterName(i);
2598  masterReadBytes.subname(i, master);
2599  masterReadRate.subname(i, master);
2600  masterWriteBytes.subname(i, master);
2601  masterWriteRate.subname(i, master);
2602  masterReadAccesses.subname(i, master);
2603  masterWriteAccesses.subname(i, master);
2604  masterReadTotalLat.subname(i, master);
2605  masterReadAvgLat.subname(i, master);
2606  masterWriteTotalLat.subname(i, master);
2607  masterWriteAvgLat.subname(i, master);
2608  }
2609 
2610  // Formula stats
2614 
2617 
2618  avgRdBW = (bytesReadDRAM / 1000000) / simSeconds;
2619  avgWrBW = (bytesWritten / 1000000) / simSeconds;
2620  avgRdBWSys = (bytesReadSys / 1000000) / simSeconds;
2621  avgWrBWSys = (bytesWrittenSys / 1000000) / simSeconds;
2622  peakBW = (SimClock::Frequency / dram.tBURST) * dram.burstSize / 1000000;
2623 
2624  busUtil = (avgRdBW + avgWrBW) / peakBW * 100;
2625 
2626  avgGap = totGap / (readReqs + writeReqs);
2627 
2628  busUtilRead = avgRdBW / peakBW * 100;
2629  busUtilWrite = avgWrBW / peakBW * 100;
2630 
2633 
2638 }
2639 
2640 void
2642 {
2644 }
2645 
2647  : Stats::Group(&_memory, csprintf("rank%d", _rank.rank).c_str()),
2648  rank(_rank),
2649 
2650  ADD_STAT(actEnergy, "Energy for activate commands per rank (pJ)"),
2651  ADD_STAT(preEnergy, "Energy for precharge commands per rank (pJ)"),
2652  ADD_STAT(readEnergy, "Energy for read commands per rank (pJ)"),
2653  ADD_STAT(writeEnergy, "Energy for write commands per rank (pJ)"),
2654  ADD_STAT(refreshEnergy, "Energy for refresh commands per rank (pJ)"),
2655  ADD_STAT(actBackEnergy, "Energy for active background per rank (pJ)"),
2656  ADD_STAT(preBackEnergy, "Energy for precharge background per rank (pJ)"),
2657  ADD_STAT(actPowerDownEnergy,
2658  "Energy for active power-down per rank (pJ)"),
2659  ADD_STAT(prePowerDownEnergy,
2660  "Energy for precharge power-down per rank (pJ)"),
2661  ADD_STAT(selfRefreshEnergy, "Energy for self refresh per rank (pJ)"),
2662 
2663  ADD_STAT(totalEnergy, "Total energy per rank (pJ)"),
2664  ADD_STAT(averagePower, "Core power per rank (mW)"),
2665 
2666  ADD_STAT(totalIdleTime, "Total Idle time Per DRAM Rank"),
2667  ADD_STAT(memoryStateTime, "Time in different power states")
2668 {
2669 }
2670 
2671 void
2673 {
2675 
2676  memoryStateTime.init(6);
2677  memoryStateTime.subname(0, "IDLE");
2678  memoryStateTime.subname(1, "REF");
2679  memoryStateTime.subname(2, "SREF");
2680  memoryStateTime.subname(3, "PRE_PDN");
2681  memoryStateTime.subname(4, "ACT");
2682  memoryStateTime.subname(5, "ACT_PDN");
2683 }
2684 
2685 void
2687 {
2689 
2690  rank.resetStats();
2691 }
2692 
2693 void
2695 {
2697 
2698  rank.computeStats();
2699 }
2700 
2701 void
2703 {
2704  // rely on the abstract memory
2705  functionalAccess(pkt);
2706 }
2707 
2708 Port &
2709 DRAMCtrl::getPort(const string &if_name, PortID idx)
2710 {
2711  if (if_name != "port") {
2712  return QoS::MemCtrl::getPort(if_name, idx);
2713  } else {
2714  return port;
2715  }
2716 }
2717 
2718 DrainState
2720 {
2721  // if there is anything in any of our internal queues, keep track
2722  // of that as well
2723  if (!(!totalWriteQueueSize && !totalReadQueueSize && respQueue.empty() &&
2724  allRanksDrained())) {
2725 
2726  DPRINTF(Drain, "DRAM controller not drained, write: %d, read: %d,"
2727  " resp: %d\n", totalWriteQueueSize, totalReadQueueSize,
2728  respQueue.size());
2729 
2730  // the only queue that is not drained automatically over time
2731  // is the write queue, thus kick things into action if needed
2734  }
2735 
2736  // also need to kick off events to exit self-refresh
2737  for (auto r : ranks) {
2738  // force self-refresh exit, which in turn will issue auto-refresh
2739  if (r->pwrState == PWR_SREF) {
2740  DPRINTF(DRAM,"Rank%d: Forcing self-refresh wakeup in drain\n",
2741  r->rank);
2742  r->scheduleWakeUpEvent(tXS);
2743  }
2744  }
2745 
2746  return DrainState::Draining;
2747  } else {
2748  return DrainState::Drained;
2749  }
2750 }
2751 
2752 bool
2754 {
2755  // true until proven false
2756  bool all_ranks_drained = true;
2757  for (auto r : ranks) {
2758  // then verify that the power state is IDLE ensuring all banks are
2759  // closed and rank is not in a low power state. Also verify that rank
2760  // is idle from a refresh point of view.
2761  all_ranks_drained = r->inPwrIdleState() && r->inRefIdleState() &&
2762  all_ranks_drained;
2763  }
2764  return all_ranks_drained;
2765 }
2766 
2767 void
2769 {
2770  if (!isTimingMode && system()->isTimingMode()) {
2771  // if we switched to timing mode, kick things into action,
2772  // and behave as if we restored from a checkpoint
2773  startup();
2774  } else if (isTimingMode && !system()->isTimingMode()) {
2775  // if we switch from timing mode, stop the refresh events to
2776  // not cause issues with KVM
2777  for (auto r : ranks) {
2778  r->suspend();
2779  }
2780  }
2781 
2782  // update the mode
2784 }
2785 
2786 DRAMCtrl::MemoryPort::MemoryPort(const std::string& name, DRAMCtrl& _memory)
2787  : QueuedSlavePort(name, &_memory, queue), queue(_memory, *this, true),
2788  memory(_memory)
2789 { }
2790 
2793 {
2794  AddrRangeList ranges;
2795  ranges.push_back(memory.getAddrRange());
2796  return ranges;
2797 }
2798 
2799 void
2801 {
2802  pkt->pushLabel(memory.name());
2803 
2804  if (!queue.trySatisfyFunctional(pkt)) {
2805  // Default implementation of SimpleTimingPort::recvFunctional()
2806  // calls recvAtomic() and throws away the latency; we can save a
2807  // little here by just not calculating the latency.
2808  memory.recvFunctional(pkt);
2809  }
2810 
2811  pkt->popLabel();
2812 }
2813 
2814 Tick
2816 {
2817  return memory.recvAtomic(pkt);
2818 }
2819 
2820 bool
2822 {
2823  // pass it to the memory controller
2824  return memory.recvTimingReq(pkt);
2825 }
2826 
2827 DRAMCtrl*
2828 DRAMCtrlParams::create()
2829 {
2830  return new DRAMCtrl(this);
2831 }
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
Stats::Scalar numRdRetry
Definition: dram_ctrl.hh:1076
void logResponse(BusState dir, MasterID m_id, uint8_t qos, Addr addr, uint64_t entries, double delay)
Called upon receiving a response, updates statistics and updates queues status.
Definition: mem_ctrl.cc:145
#define DPRINTF(x,...)
Definition: trace.hh:229
bool retryWrReq
Definition: dram_ctrl.hh:142
Enums::PageManage pageMgmt
Definition: dram_ctrl.hh:1006
void functionalAccess(PacketPtr pkt)
Perform an untimed memory read or write without changing anything but the memory itself.
Stats::Scalar preEnergy
Definition: dram_ctrl.hh:288
bool enableDRAMPowerdown
Enable or disable DRAM powerdown states.
Definition: dram_ctrl.hh:1149
Stats::Formula avgBusLat
Definition: dram_ctrl.hh:1073
const uint32_t writeLowThreshold
Definition: dram_ctrl.hh:967
const uint32_t activationLimit
Definition: dram_ctrl.hh:995
Ports are used to interface objects to each other.
Definition: port.hh:60
uint32_t bytesAccessed
Definition: dram_ctrl.hh:187
PowerState
The power state captures the different operational states of the DRAM and interacts with the bus read...
Definition: dram_ctrl.hh:224
Stats::Scalar mergedWrBursts
Definition: dram_ctrl.hh:1057
const Tick entryTime
When did request enter the controller.
Definition: dram_ctrl.hh:615
Stats::Scalar readBursts
Definition: dram_ctrl.hh:1054
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Definition: sim_object.cc:126
Stats::Scalar totalEnergy
Definition: dram_ctrl.hh:318
void resetStats()
Reset stats on a stats event.
Definition: dram_ctrl.cc:2392
Stats::Scalar bytesReadDRAM
Definition: dram_ctrl.hh:1093
RankStats stats
Definition: dram_ctrl.hh:582
void sendRangeChange() const
Called by the owner to send a range change.
Definition: port.hh:286
Derived & subname(off_type index, const std::string &name)
Set the subfield name for the given index, and marks this stat to print at the end of simulation...
Definition: statistics.hh:379
void prechargeBank(Rank &rank_ref, Bank &bank_ref, Tick pre_at, bool trace=true)
Precharge a given bank and also update when the precharge is done.
Definition: dram_ctrl.cc:1025
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:175
bool retryRdReq
Remember if we have to retry a request when available.
Definition: dram_ctrl.hh:141
BusState busStateNext
bus state for next request event triggered
Definition: mem_ctrl.hh:124
Stats::Scalar bytesWrittenSys
Definition: dram_ctrl.hh:1097
const std::string & name()
Definition: trace.cc:54
Stats::Formula busUtil
Definition: dram_ctrl.hh:1106
virtual AddrRangeList getAddrRanges() const
Get a list of the non-overlapping address ranges the owner is responsible for.
Definition: dram_ctrl.cc:2792
const Tick tRCD
Definition: dram_ctrl.hh:982
const Tick tWR
Definition: dram_ctrl.hh:986
Bitfield< 7 > i
std::vector< Command > cmdList
List of commands issued, to be sent to DRAMPpower at refresh and stats dump.
Definition: dram_ctrl.hh:440
std::vector< Rank * > ranks
Vector of ranks.
Definition: dram_ctrl.hh:942
std::string getMasterName(MasterID master_id)
Get the name of an object for a given request id.
Definition: system.cc:652
STL pair class.
Definition: stl.hh:61
DrainState
Object drain/handover states.
Definition: drain.hh:71
void doDRAMAccess(DRAMPacket *dram_pkt)
Actually do the DRAM access - figure out the latency it will take to service the req based on bank st...
Definition: dram_ctrl.cc:1073
EventFunctionWrapper nextReqEvent
Definition: dram_ctrl.hh:733
Tick when() const
Get the time that the event is scheduled.
Definition: eventq.hh:401
Stats::Formula avgWrBW
Definition: dram_ctrl.hh:1101
Running normally.
const Tick tRAS
Definition: dram_ctrl.hh:985
Stats::Formula busUtilRead
Definition: dram_ctrl.hh:1107
uint64_t granularity() const
Determing the interleaving granularity of the range.
Definition: addr_range.hh:257
uint64_t totalReadQueueSize
Total read request packets queue length in #packets.
Definition: mem_ctrl.hh:112
std::pair< std::vector< uint32_t >, bool > minBankPrep(const DRAMPacketQueue &queue, Tick min_col_at) const
Find which are the earliest banks ready to issue an activate for the enqueued requests.
Definition: dram_ctrl.cc:1608
A DRAM packet stores packets along with the timestamp of when the packet entered the queue...
Definition: dram_ctrl.hh:610
const FlagsType nonan
Don&#39;t print if this is NAN.
Definition: info.hh:61
uint32_t writeEntries
Track number of packets in write queue going to this rank.
Definition: dram_ctrl.hh:415
const Tick tRRD
Definition: dram_ctrl.hh:990
uint32_t openRow
Definition: dram_ctrl.hh:177
Stats::Vector perBankRdBursts
Definition: dram_ctrl.hh:1059
DRAMPacketQueue::iterator chooseNextFRFCFS(DRAMPacketQueue &queue, Tick extra_col_delay)
For FR-FCFS policy reorder the read/write queue depending on row buffer hits and earliest bursts avai...
Definition: dram_ctrl.cc:777
uint32_t readEntries
Track number of packets in read queue going to this rank.
Definition: dram_ctrl.hh:410
Tick lastStatsResetTick
The time when stats were last reset used to calculate average power.
Definition: dram_ctrl.hh:1146
MemoryPort(const std::string &name, DRAMCtrl &_memory)
Definition: dram_ctrl.cc:2786
const Tick frontendLatency
Pipeline latency of the controller frontend.
Definition: dram_ctrl.hh:1019
Stats::Vector masterReadTotalLat
Definition: dram_ctrl.hh:1126
ip6_addr_t addr
Definition: inet.hh:335
const Tick tXP
Definition: dram_ctrl.hh:993
Stats::Formula pageHitRate
Definition: dram_ctrl.hh:1134
Stats::Scalar selfRefreshEnergy
Definition: dram_ctrl.hh:316
Stats::Histogram wrPerTurnAround
Definition: dram_ctrl.hh:1091
bool cacheResponding() const
Definition: packet.hh:591
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:282
bool recvTimingReq(PacketPtr pkt)
Definition: dram_ctrl.cc:586
Stats::Formula avgWrBWSys
Definition: dram_ctrl.hh:1103
DRAMCtrl(const DRAMCtrlParams *p)
Definition: dram_ctrl.cc:62
DrainState drain() override
Notify an object that it needs to drain its state.
Definition: dram_ctrl.cc:2719
uint32_t rowAccesses
Definition: dram_ctrl.hh:186
void signalDrainDone() const
Signal that an object is drained.
Definition: drain.hh:267
MasterID masterId() const
Get the packet MasterID (interface compatibility with Packet)
Definition: dram_ctrl.hh:683
std::deque< DRAMPacket * > respQueue
Response queue where read packets wait after we&#39;re done working with them, but it&#39;s not time to send ...
Definition: dram_ctrl.hh:937
const Tick tCL
Definition: dram_ctrl.hh:983
Rank(DRAMCtrl &_memory, const DRAMCtrlParams *_p, int rank)
Definition: dram_ctrl.cc:1692
virtual void regStats()
Callback to set stat parameters.
Definition: group.cc:66
unsigned int burstsServiced
Number of DRAM bursts serviced so far for a system packet.
Definition: dram_ctrl.hh:599
Stats::Vector memoryStateTime
Track time spent in each power state.
Definition: dram_ctrl.hh:330
int ceilLog2(const T &n)
Definition: intmath.hh:135
Stats::Formula avgQLat
Definition: dram_ctrl.hh:1072
RefreshState refreshState
current refresh state
Definition: dram_ctrl.hh:395
Addr addr
The starting address of the DRAM packet.
Definition: dram_ctrl.hh:646
Bitfield< 23, 0 > offset
Definition: types.hh:154
Histogram & init(size_type size)
Set the parameters of this histogram.
Definition: statistics.hh:2644
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:586
bool writeQueueFull(unsigned int pktCount) const
Check if the write queue has room for more entries.
Definition: dram_ctrl.cc:294
uint8_t bank
Definition: dram_ctrl.hh:178
Tick refreshDueAt
Keep track of when a refresh is due.
Definition: dram_ctrl.hh:369
bool isConnected() const
Is this port currently connected to a peer?
Definition: port.hh:128
A queued port is a port that has an infinite queue for outgoing packets and thus decouples the module...
Definition: qport.hh:60
const Tick rankToRankDly
Definition: dram_ctrl.hh:996
The DRAM controller is a single-channel memory controller capturing the most important timing constra...
Definition: dram_ctrl.hh:98
Stats::Scalar totGap
Definition: dram_ctrl.hh:1110
Stats::Vector writePktSize
Definition: dram_ctrl.hh:1086
uint8_t rank
Current Rank index.
Definition: dram_ctrl.hh:405
uint8_t numPriorities() const
Gets the total number of priority levels in the QoS memory controller.
Definition: mem_ctrl.hh:350
const uint32_t burstLength
Definition: dram_ctrl.hh:952
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:475
void pushLabel(const std::string &lbl)
Push label for PrintReq (safe to call unconditionally).
Definition: packet.hh:1326
void regStats() override
Callback to set stat parameters.
Definition: dram_ctrl.cc:2672
bool isWrite() const
Definition: packet.hh:529
const uint32_t ranksPerChannel
Definition: dram_ctrl.hh:959
Tick Frequency
The simulated frequency of curTick(). (In ticks per second)
Definition: core.cc:49
bool readQueueFull(unsigned int pktCount) const
Check if the read queue has room for more entries.
Definition: dram_ctrl.cc:283
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:336
Stats::Formula avgRdBW
Definition: dram_ctrl.hh:1100
Stats::Formula simSeconds
Definition: stat_control.cc:64
bool isRead() const
Definition: packet.hh:528
DRAMStats stats
Definition: dram_ctrl.hh:1137
const std::unique_ptr< TurnaroundPolicy > turnPolicy
QoS Bus Turnaround Policy: selects the bus direction (READ/WRITE)
Definition: mem_ctrl.hh:72
const uint32_t deviceRowBufferSize
Definition: dram_ctrl.hh:953
A burst helper helps organize and manage a packet that is larger than the DRAM burst size...
Definition: dram_ctrl.hh:591
Derived & init(size_type size)
Set this vector to have the given size.
Definition: statistics.hh:1152
const uint16_t bankId
Bank id is calculated considering banks in all the ranks eg: 2 ranks each with 8 banks, then bankId = 0 –> rank0, bank0 and bankId = 8 –> rank1, bank0.
Definition: dram_ctrl.hh:638
void deschedule(Event &event)
Definition: eventq.hh:750
void computeStats()
Computes stats just prior to dump event.
Definition: dram_ctrl.cc:2379
virtual void init() override
Initialise this memory.
Definition: dram_ctrl.cc:191
uint8_t outstandingEvents
Number of ACT, RD, and WR events currently scheduled Incremented when a refresh event is started as w...
Definition: dram_ctrl.hh:422
EventFunctionWrapper activateEvent
Definition: dram_ctrl.hh:567
Stats::Scalar writeEnergy
Definition: dram_ctrl.hh:290
void startup(Tick ref_tick)
Kick off accounting for power and refresh states and schedule initial refresh.
Definition: dram_ctrl.cc:1730
bool isQueueEmpty() const
Check if the command queue of current rank is idle.
Definition: dram_ctrl.cc:1754
unsigned int numBanksActive
To track number of banks which are currently active for this rank.
Definition: dram_ctrl.hh:452
Stats::Vector perBankWrBursts
Definition: dram_ctrl.hh:1060
Stats::Formula peakBW
Definition: dram_ctrl.hh:1104
void recvFunctional(PacketPtr pkt)
Receive a functional request packet from the peer.
Definition: dram_ctrl.cc:2800
bool isTimingMode
Remember if the memory system is in timing mode.
Definition: dram_ctrl.hh:136
void processWriteDoneEvent()
Definition: dram_ctrl.cc:1848
void regStats() override
Callback to set stat parameters.
Definition: dram_ctrl.cc:2502
Stats::Scalar numWrRetry
Definition: dram_ctrl.hh:1077
Bitfield< 7 > b
A basic class to track the bank state, i.e.
Definition: dram_ctrl.hh:170
unsigned getSize() const
Definition: packet.hh:736
Addr getCtrlAddr(Addr addr)
Get an address in a dense range which starts from 0.
Definition: dram_ctrl.hh:830
const Tick MaxTick
Definition: types.hh:65
const Tick tCCD_L_WR
Definition: dram_ctrl.hh:980
const uint32_t maxAccessesPerRow
Max column accesses (read and write) per row, before forcefully closing it.
Definition: dram_ctrl.hh:1012
const uint32_t bankGroupsPerRank
Definition: dram_ctrl.hh:960
const Tick tREFI
Definition: dram_ctrl.hh:989
Tick curTick()
The current simulated tick.
Definition: core.hh:47
Tick recvAtomic(PacketPtr pkt)
Receive an atomic request packet from the peer.
Definition: dram_ctrl.cc:2815
Stats::Vector masterReadBytes
Definition: dram_ctrl.hh:1114
Enums::MemSched memSchedPolicy
Memory controller configuration initialized based on parameter values.
Definition: dram_ctrl.hh:1004
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:162
bool needsResponse() const
Definition: packet.hh:542
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:385
const Tick backendLatency
Pipeline latency of the backend and PHY.
Definition: dram_ctrl.hh:1026
EventFunctionWrapper prechargeEvent
Definition: dram_ctrl.hh:570
Stats::Vector wrQLenPdf
Definition: dram_ctrl.hh:1088
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition: packet.hh:366
void processPowerEvent()
Definition: dram_ctrl.cc:2203
Stats::Scalar servicedByWrQ
Definition: dram_ctrl.hh:1056
void schedTimingResp(PacketPtr pkt, Tick when)
Schedule the sending of a timing response.
Definition: qport.hh:92
BurstHelper * burstHelper
A pointer to the BurstHelper if this DRAMPacket is a split packet If not a split packet (common case)...
Definition: dram_ctrl.hh:658
const Tick tRP
Definition: dram_ctrl.hh:984
std::vector< Bank > banks
Vector of Banks.
Definition: dram_ctrl.hh:446
#define RD
Definition: bitfields.hh:14
uint64_t Tick
Tick count type.
Definition: types.hh:63
uint64_t power(uint32_t n, uint32_t e)
Definition: intmath.hh:40
uint8_t qosValue() const
QoS Value getter Returns 0 if QoS value was never set (constructor default).
Definition: packet.hh:701
DRAMCtrl declaration.
void qosValue(const uint8_t qv)
Set the packet QoS value (interface compatibility with Packet)
Definition: dram_ctrl.hh:671
bool isResponse() const
Definition: packet.hh:532
void popLabel()
Pop label for PrintReq (safe to call unconditionally).
Definition: packet.hh:1336
Stats::Formula avgGap
Definition: dram_ctrl.hh:1111
PowerState pwrState
Current power state.
Definition: dram_ctrl.hh:390
void checkDrainDone()
Let the rank check if it was waiting for requests to drain to allow it to transition states...
Definition: dram_ctrl.cc:1764
EventFunctionWrapper respondEvent
Definition: dram_ctrl.hh:736
Group()=delete
void replaceBits(T &val, int first, int last, B bit_val)
A convenience function to replace bits first to last of val with bit_val in place.
Definition: bitfield.hh:157
const Tick tRFC
Definition: dram_ctrl.hh:988
std::deque< Tick > actTicks
List to keep track of activate ticks.
Definition: dram_ctrl.hh:455
Stats::Vector masterWriteAccesses
Definition: dram_ctrl.hh:1123
virtual void preDumpStats()
Callback before stats are dumped.
Definition: group.cc:97
DRAMStats(DRAMCtrl &dram)
Definition: dram_ctrl.cc:2401
void access(PacketPtr pkt)
Perform an untimed memory access and update all the state (e.g.
uint64_t timeStampOffset
Definition: dram_ctrl.hh:1143
Stats::Formula readRowHitRate
Definition: dram_ctrl.hh:1082
virtual void resetStats()
Callback to reset stats.
Definition: group.cc:84
std::vector< DRAMPacketQueue > readQueue
The controller&#39;s main read and write queues, with support for QoS reordering.
Definition: dram_ctrl.hh:917
Stats::Vector rdQLenPdf
Definition: dram_ctrl.hh:1087
Addr getAddr() const
Definition: packet.hh:726
uint32_t writesThisTime
Definition: dram_ctrl.hh:969
Stats::Scalar totQLat
Definition: dram_ctrl.hh:1067
bool hasData() const
Definition: packet.hh:548
Tick recvAtomic(PacketPtr pkt)
Definition: dram_ctrl.cc:263
const Tick tRTP
Definition: dram_ctrl.hh:987
MasterID masterId() const
Definition: packet.hh:712
bool isPowerOf2(const T &n)
Definition: intmath.hh:146
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:203
Stats::Scalar writeReqs
Definition: dram_ctrl.hh:1053
Stats::Scalar readReqs
Definition: dram_ctrl.hh:1052
BusState busState
Bus state used to control the read/write switching and drive the scheduling of the next request...
Definition: mem_ctrl.hh:121
void recordTurnaroundStats()
Record statistics on turnarounds based on busStateNext and busState values.
Definition: mem_ctrl.cc:355
Stats::Scalar readEnergy
Definition: dram_ctrl.hh:289
const Tick rdToWrDly
Definition: dram_ctrl.hh:998
Stats::Formula masterReadAvgLat
Definition: dram_ctrl.hh:1130
Tick pwrStateTick
Track when we transitioned to the current power state.
Definition: dram_ctrl.hh:364
Stats::Vector masterReadAccesses
Definition: dram_ctrl.hh:1122
static bool sortTime(const Command &cmd, const Command &cmd_next)
Function for sorting Command structures based on timeStamp.
Definition: dram_ctrl.hh:1175
uint64_t totalWriteQueueSize
Total write request packets queue length in #packets.
Definition: mem_ctrl.hh:115
Stats::Scalar prePowerDownEnergy
Definition: dram_ctrl.hh:311
void resetStats() override
Callback to reset stats.
Definition: dram_ctrl.cc:2641
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Stats::Scalar bytesReadWrQ
Definition: dram_ctrl.hh:1094
Stats::Formula avgMemAccLat
Definition: dram_ctrl.hh:1074
Derived & precision(int _precision)
Set the precision and marks this stat to print at the end of simulation.
Definition: statistics.hh:324
Draining buffers pending serialization/handover.
#define ULL(N)
uint64_t constant
Definition: types.hh:50
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Definition: packet.hh:384
uint8_t bankgr
Definition: dram_ctrl.hh:179
virtual const std::string name() const
Definition: sim_object.hh:120
const uint8_t rank
Will be populated by address decoder.
Definition: dram_ctrl.hh:629
void activateBank(Rank &rank_ref, Bank &bank_ref, Tick act_tick, uint32_t row)
Keep track of when row activations happen, in order to enforce the maximum number of activations in t...
Definition: dram_ctrl.cc:924
PowerState pwrStatePostRefresh
Previous low-power state, which will be re-entered after refresh.
Definition: dram_ctrl.hh:359
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:255
RespPacketQueue queue
Definition: dram_ctrl.hh:108
const Tick tCS
Definition: dram_ctrl.hh:978
const Tick M5_CLASS_VAR_USED tCK
Basic memory timing parameters initialized based on parameter values.
Definition: dram_ctrl.hh:976
bool isRead() const
Return true if its a read packet (interface compatibility with Packet)
Definition: dram_ctrl.hh:701
Statistics container.
Definition: group.hh:85
void processRefreshEvent()
Definition: dram_ctrl.cc:1859
Tick prevArrival
Definition: dram_ctrl.hh:1033
Stats::Scalar averagePower
Definition: dram_ctrl.hh:319
const Tick tXAW
Definition: dram_ctrl.hh:992
const uint32_t row
Definition: dram_ctrl.hh:631
const unsigned int burstCount
Number of DRAM bursts requred for a system packet.
Definition: dram_ctrl.hh:596
std::unique_ptr< Packet > pendingDelete
Upstream caches need this packet until true is returned, so hold it for deletion until a subsequent c...
Definition: dram_ctrl.hh:1155
void addToWriteQueue(PacketPtr pkt, unsigned int pktCount)
Decode the incoming pkt, create a dram_pkt and push to the back of the write queue.
Definition: dram_ctrl.cc:487
static const uint32_t NO_ROW
Definition: dram_ctrl.hh:175
const uint32_t rowBufferSize
Definition: dram_ctrl.hh:956
RankStats(DRAMCtrl &memory, Rank &rank)
Definition: dram_ctrl.cc:2646
bool inRefIdleState() const
Check if there is no refresh and no preparation of refresh ongoing i.e.
Definition: dram_ctrl.hh:483
const uint32_t devicesPerRank
Definition: dram_ctrl.hh:954
MasterID maxMasters()
Get the number of masters registered in the system.
Definition: system.hh:412
uint32_t rowsPerBank
Definition: dram_ctrl.hh:963
PowerState pwrStateTrans
Since we are taking decisions out of order, we need to keep track of what power transition is happeni...
Definition: dram_ctrl.hh:354
STL deque class.
Definition: stl.hh:47
Bitfield< 24 > j
const uint32_t minWritesPerSwitch
Definition: dram_ctrl.hh:968
void suspend()
Stop the refresh events.
Definition: dram_ctrl.cc:1742
Stats::Formula masterWriteRate
Definition: dram_ctrl.hh:1119
Definition: mem_ctrl.cc:44
void schedulePowerEvent(PowerState pwr_state, Tick tick)
Schedule a power state transition in the future, and potentially override an already scheduled transi...
Definition: dram_ctrl.cc:2061
void accessAndRespond(PacketPtr pkt, Tick static_latency)
When a packet reaches its "readyTime" in the response Q, use the "access()" method in AbstractMemory ...
Definition: dram_ctrl.cc:887
const uint32_t deviceBusWidth
Definition: dram_ctrl.hh:951
const Tick tXS
Definition: dram_ctrl.hh:994
Stats::Scalar bytesReadSys
Definition: dram_ctrl.hh:1096
Stats::Formula avgRdBWSys
Definition: dram_ctrl.hh:1102
void updatePowerStats()
Function to update Power Stats.
Definition: dram_ctrl.cc:2336
Enums::PwrState pwrState() const
EventFunctionWrapper powerEvent
Definition: dram_ctrl.hh:576
void reschedule(Event &event, Tick when, bool always=false)
Definition: eventq.hh:756
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:69
AddrRange range
const uint32_t writeHighThreshold
Definition: dram_ctrl.hh:966
Enums::AddrMap addrMapping
Definition: dram_ctrl.hh:1005
Tick nextReqTime
The soonest you have to start thinking about the next request is the longest access time that can occ...
Definition: dram_ctrl.hh:1041
bool allRanksDrained() const
Return true once refresh is complete for all ranks and there are no additional commands enqueued...
Definition: dram_ctrl.cc:2753
void processPrechargeEvent()
Definition: dram_ctrl.cc:1817
void powerDownSleep(PowerState pwr_state, Tick tick)
Schedule a transition to power-down (sleep)
Definition: dram_ctrl.cc:2082
System * system() const
read the system pointer Implemented for completeness with the setter
Stats::Scalar preBackEnergy
Definition: dram_ctrl.hh:301
const Tick tRTW
Definition: dram_ctrl.hh:977
Stats::Scalar totBusLat
Definition: dram_ctrl.hh:1068
bool interleaved() const
Determine if the range is interleaved or not.
Definition: addr_range.hh:250
Stats::Average avgRdQLen
Definition: dram_ctrl.hh:1063
EventFunctionWrapper wakeUpEvent
Definition: dram_ctrl.hh:579
const std::string name() const
Definition: dram_ctrl.hh:459
void processActivateEvent()
Definition: dram_ctrl.cc:1807
DRAMPacket * decodeAddr(const PacketPtr pkt, Addr dramPktAddr, unsigned int size, bool isRead) const
Address decoder to figure out physical mapping onto ranks, banks, and rows.
Definition: dram_ctrl.cc:304
DRAMPower power
One DRAMPower instance per rank.
Definition: dram_ctrl.hh:432
void sendRetryReq()
Send a retry to the master port that previously attempted a sendTimingReq to this slave port and fail...
Definition: port.hh:380
Stats::Scalar writeRowHits
Definition: dram_ctrl.hh:1081
Stats::Scalar totalIdleTime
Stat to track total DRAM idle time.
Definition: dram_ctrl.hh:325
const Tick tCCD_L
Definition: dram_ctrl.hh:981
void logRequest(BusState dir, MasterID m_id, uint8_t qos, Addr addr, uint64_t entries)
Called upon receiving a request or updates statistics and updates queues status.
Definition: mem_ctrl.cc:88
uint64_t size() const
Get the memory size.
Tick wakeUpAllowedAt
delay power-down and self-refresh exit until this requirement is met
Definition: dram_ctrl.hh:427
Stats::Formula busUtilWrite
Definition: dram_ctrl.hh:1108
Stats::Formula writeRowHitRate
Definition: dram_ctrl.hh:1083
void resetStats() override
Callback to reset stats.
Definition: dram_ctrl.cc:2686
void processNextReqEvent()
Bunch of things requires to setup "events" in gem5 When event "respondEvent" occurs for example...
Definition: dram_ctrl.cc:1302
Stats::Scalar actEnergy
Definition: dram_ctrl.hh:287
System * _system
Pointer to the System object.
std::unordered_set< Addr > isInWriteQueue
To avoid iterating over the write queue to check for overlapping transactions, maintain a set of burs...
Definition: dram_ctrl.hh:927
const uint32_t columnsPerRowBuffer
Definition: dram_ctrl.hh:957
void recvFunctional(PacketPtr pkt)
Definition: dram_ctrl.cc:2702
Stats::Histogram bytesPerActivate
Definition: dram_ctrl.hh:1089
T divCeil(const T &a, const U &b)
Definition: intmath.hh:153
Stats::Formula masterWriteAvgLat
Definition: dram_ctrl.hh:1131
void schedule(Event &event, Tick when)
Definition: eventq.hh:744
Stats::Scalar actBackEnergy
Definition: dram_ctrl.hh:296
EventFunctionWrapper refreshEvent
Definition: dram_ctrl.hh:573
uint32_t readsThisTime
Definition: dram_ctrl.hh:970
Definition: mem.h:38
Stats::Scalar readRowHits
Definition: dram_ctrl.hh:1080
Simple structure to hold the values needed to keep track of commands for DRAMPower.
Definition: dram_ctrl.hh:150
Stats::Formula masterReadRate
Definition: dram_ctrl.hh:1118
void processWakeUpEvent()
Definition: dram_ctrl.cc:2185
const uint32_t deviceSize
The following are basic design parameters of the memory controller, and are initialized based on para...
Definition: dram_ctrl.hh:950
uint8_t activeRank
Definition: dram_ctrl.hh:1140
Stats::Average avgWrQLen
Definition: dram_ctrl.hh:1064
std::vector< DRAMPacketQueue > writeQueue
Definition: dram_ctrl.hh:918
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:237
Tick readyTime
When will request leave the controller.
Definition: dram_ctrl.hh:618
const uint32_t columnsPerStripe
Definition: dram_ctrl.hh:958
#define warn(...)
Definition: logging.hh:212
Stats::Scalar totMemAccLat
Definition: dram_ctrl.hh:1069
const uint8_t bank
Definition: dram_ctrl.hh:630
Data::MemCommand::cmds type
Definition: dram_ctrl.hh:151
void preDumpStats() override
Callback before stats are dumped.
Definition: dram_ctrl.cc:2694
bool trySatisfyFunctional(PacketPtr pkt)
Check the list of buffered packets against the supplied functional request.
Definition: packet_queue.cc:87
bool isTimingMode() const
Is the system in timing mode?
Definition: system.hh:150
Tick nextBurstAt
Till when must we wait before issuing next RD/WR burst?
Definition: dram_ctrl.hh:1031
T bits(T val, int first, int last)
Extract the bitfield from position &#39;first&#39; to &#39;last&#39; (inclusive) from &#39;val&#39; and right justify it...
Definition: bitfield.hh:72
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
Definition: packet.hh:523
void processRespondEvent()
Definition: dram_ctrl.cc:650
const uint32_t writeBufferSize
Definition: dram_ctrl.hh:965
const uint32_t burstSize
Definition: dram_ctrl.hh:955
const uint32_t banksPerRank
Definition: dram_ctrl.hh:962
const uint32_t readBufferSize
Definition: dram_ctrl.hh:964
DRAMPower is a standalone tool which calculates the power consumed by a DRAM in the system...
Definition: drampower.hh:55
const FlagsType nozero
Don&#39;t print if this is zero.
Definition: info.hh:59
Bitfield< 0 > p
const Tick tRRD_L
Definition: dram_ctrl.hh:991
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:185
virtual void drainResume() override
Resume execution after a successful drain.
Definition: dram_ctrl.cc:2768
virtual void startup() override
startup() is the final initialization call before simulation.
Definition: dram_ctrl.cc:239
Addr burstAlign(Addr addr) const
Burst-align an address.
Definition: dram_ctrl.hh:912
Stats::Vector masterWriteBytes
Definition: dram_ctrl.hh:1115
Counter value() const
Return the current value of this stat as its base type.
Definition: statistics.hh:703
Stats::Vector readPktSize
Definition: dram_ctrl.hh:1085
const Tick wrToRdDly
Definition: dram_ctrl.hh:997
void addToReadQueue(PacketPtr pkt, unsigned int pktCount)
When a new read comes in, first check if the write q has a pending request to the same address...
Definition: dram_ctrl.cc:380
Stats::Scalar actPowerDownEnergy
Definition: dram_ctrl.hh:306
void printQs() const
Used for debugging to observe the contents of the queues.
Definition: dram_ctrl.cc:561
uint8_t schedule(MasterID m_id, uint64_t data)
Definition: mem_ctrl.cc:214
unsigned int size
The size of this dram packet in bytes It is always equal or smaller than DRAM burst size...
Definition: dram_ctrl.hh:652
bool recvTimingReq(PacketPtr)
Receive a timing request from the peer.
Definition: dram_ctrl.cc:2821
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Definition: statistics.hh:1899
const bool bankGroupArch
Definition: dram_ctrl.hh:961
const FlagsType init
This Stat is Initialized.
Definition: info.hh:47
Stats::Vector masterWriteTotalLat
Definition: dram_ctrl.hh:1127
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition: dram_ctrl.cc:2709
Stats::Scalar writeBursts
Definition: dram_ctrl.hh:1055
const PacketPtr pkt
This comes from the outside world.
Definition: dram_ctrl.hh:621
void scheduleWakeUpEvent(Tick exit_delay)
schedule and event to wake-up from power-down or self-refresh and update bank timing parameters ...
Definition: dram_ctrl.cc:2133
Stats::Histogram rdPerTurnAround
Definition: dram_ctrl.hh:1090
Rank class includes a vector of banks.
Definition: dram_ctrl.hh:340
Stats::Scalar bytesWritten
Definition: dram_ctrl.hh:1095
bool inLowPowerState
rank is in or transitioning to power-down or self-refresh
Definition: dram_ctrl.hh:400
libDRAMPower powerlib
Definition: drampower.hh:96
BusState selectNextBusState()
Returns next bus direction (READ or WRITE) based on configured policy.
Definition: mem_ctrl.cc:243
MemoryPort port
Our incoming port, for a multi-ported controller add a crossbar in front of it.
Definition: dram_ctrl.hh:131
void flushCmdList()
Push command out of cmdList queue that are scheduled at or before curTick() to DRAMPower library All ...
Definition: dram_ctrl.cc:1779
const Tick tBURST
Definition: dram_ctrl.hh:979
Stats::Scalar refreshEnergy
Definition: dram_ctrl.hh:291
DRAMPacketQueue::iterator chooseNext(DRAMPacketQueue &queue, Tick extra_col_delay)
The memory schduler/arbiter - picks which request needs to go next, based on the specified policy suc...
Definition: dram_ctrl.cc:742

Generated on Fri Feb 28 2020 16:27:02 for gem5 by doxygen 1.8.13