dram_ctrl.hh revision 10215:52d46098c1b6
1/* 2 * Copyright (c) 2012-2014 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 */ 44 45/** 46 * @file 47 * DRAMCtrl declaration 48 */ 49 50#ifndef __MEM_DRAM_CTRL_HH__ 51#define __MEM_DRAM_CTRL_HH__ 52 53#include <deque> 54 55#include "base/statistics.hh" 56#include "enums/AddrMap.hh" 57#include "enums/MemSched.hh" 58#include "enums/PageManage.hh" 59#include "mem/abstract_mem.hh" 60#include "mem/qport.hh" 61#include "params/DRAMCtrl.hh" 62#include "sim/eventq.hh" 63 64/** 65 * The DRAM controller is a basic single-channel memory controller 66 * aiming to mimic a high-level DRAM controller and the most important 67 * timing constraints associated with the DRAM. The focus is really on 68 * modelling the impact on the system rather than the DRAM itself, 69 * hence the focus is on the controller model and not on the 70 * memory. By adhering to the correct timing constraints, ultimately 71 * there is no need for a memory model in addition to the controller 72 * model. 73 * 74 * As a basic design principle, this controller is not cycle callable, 75 * but instead uses events to decide when new decisions can be made, 76 * when resources become available, when things are to be considered 77 * done, and when to send things back. Through these simple 78 * principles, we achieve a performant model that is not 79 * cycle-accurate, but enables us to evaluate the system impact of a 80 * wide range of memory technologies, and also collect statistics 81 * about the use of the memory. 82 */ 83class DRAMCtrl : public AbstractMemory 84{ 85 86 private: 87 88 // For now, make use of a queued slave port to avoid dealing with 89 // flow control for the responses being sent back 90 class MemoryPort : public QueuedSlavePort 91 { 92 93 SlavePacketQueue queue; 94 DRAMCtrl& memory; 95 96 public: 97 98 MemoryPort(const std::string& name, DRAMCtrl& _memory); 99 100 protected: 101 102 Tick recvAtomic(PacketPtr pkt); 103 104 void recvFunctional(PacketPtr pkt); 105 106 bool recvTimingReq(PacketPtr); 107 108 virtual AddrRangeList getAddrRanges() const; 109 110 }; 111 112 /** 113 * Our incoming port, for a multi-ported controller add a crossbar 114 * in front of it 115 */ 116 MemoryPort port; 117 118 /** 119 * Remember if we have to retry a request when available. 120 */ 121 bool retryRdReq; 122 bool retryWrReq; 123 124 /** 125 * Bus state used to control the read/write switching and drive 126 * the scheduling of the next request. 127 */ 128 enum BusState { 129 READ = 0, 130 READ_TO_WRITE, 131 WRITE, 132 WRITE_TO_READ 133 }; 134 135 BusState busState; 136 137 /** List to keep track of activate ticks */ 138 std::vector<std::deque<Tick>> actTicks; 139 140 /** 141 * A basic class to track the bank state, i.e. what row is 142 * currently open (if any), when is the bank free to accept a new 143 * column (read/write) command, when can it be precharged, and 144 * when can it be activated. 145 * 146 * The bank also keeps track of how many bytes have been accessed 147 * in the open row since it was opened. 148 */ 149 class Bank 150 { 151 152 public: 153 154 static const uint32_t NO_ROW = -1; 155 156 uint32_t openRow; 157 158 Tick colAllowedAt; 159 Tick preAllowedAt; 160 Tick actAllowedAt; 161 162 uint32_t rowAccesses; 163 uint32_t bytesAccessed; 164 165 Bank() : 166 openRow(NO_ROW), colAllowedAt(0), preAllowedAt(0), actAllowedAt(0), 167 rowAccesses(0), bytesAccessed(0) 168 { } 169 }; 170 171 /** 172 * A burst helper helps organize and manage a packet that is larger than 173 * the DRAM burst size. A system packet that is larger than the burst size 174 * is split into multiple DRAM packets and all those DRAM packets point to 175 * a single burst helper such that we know when the whole packet is served. 176 */ 177 class BurstHelper { 178 179 public: 180 181 /** Number of DRAM bursts requred for a system packet **/ 182 const unsigned int burstCount; 183 184 /** Number of DRAM bursts serviced so far for a system packet **/ 185 unsigned int burstsServiced; 186 187 BurstHelper(unsigned int _burstCount) 188 : burstCount(_burstCount), burstsServiced(0) 189 { } 190 }; 191 192 /** 193 * A DRAM packet stores packets along with the timestamp of when 194 * the packet entered the queue, and also the decoded address. 195 */ 196 class DRAMPacket { 197 198 public: 199 200 /** When did request enter the controller */ 201 const Tick entryTime; 202 203 /** When will request leave the controller */ 204 Tick readyTime; 205 206 /** This comes from the outside world */ 207 const PacketPtr pkt; 208 209 const bool isRead; 210 211 /** Will be populated by address decoder */ 212 const uint8_t rank; 213 const uint8_t bank; 214 const uint16_t row; 215 216 /** 217 * Bank id is calculated considering banks in all the ranks 218 * eg: 2 ranks each with 8 banks, then bankId = 0 --> rank0, bank0 and 219 * bankId = 8 --> rank1, bank0 220 */ 221 const uint16_t bankId; 222 223 /** 224 * The starting address of the DRAM packet. 225 * This address could be unaligned to burst size boundaries. The 226 * reason is to keep the address offset so we can accurately check 227 * incoming read packets with packets in the write queue. 228 */ 229 Addr addr; 230 231 /** 232 * The size of this dram packet in bytes 233 * It is always equal or smaller than DRAM burst size 234 */ 235 unsigned int size; 236 237 /** 238 * A pointer to the BurstHelper if this DRAMPacket is a split packet 239 * If not a split packet (common case), this is set to NULL 240 */ 241 BurstHelper* burstHelper; 242 Bank& bankRef; 243 244 DRAMPacket(PacketPtr _pkt, bool is_read, uint8_t _rank, uint8_t _bank, 245 uint16_t _row, uint16_t bank_id, Addr _addr, 246 unsigned int _size, Bank& bank_ref) 247 : entryTime(curTick()), readyTime(curTick()), 248 pkt(_pkt), isRead(is_read), rank(_rank), bank(_bank), row(_row), 249 bankId(bank_id), addr(_addr), size(_size), burstHelper(NULL), 250 bankRef(bank_ref) 251 { } 252 253 }; 254 255 /** 256 * Bunch of things requires to setup "events" in gem5 257 * When event "respondEvent" occurs for example, the method 258 * processRespondEvent is called; no parameters are allowed 259 * in these methods 260 */ 261 void processNextReqEvent(); 262 EventWrapper<DRAMCtrl,&DRAMCtrl::processNextReqEvent> nextReqEvent; 263 264 void processRespondEvent(); 265 EventWrapper<DRAMCtrl, &DRAMCtrl::processRespondEvent> respondEvent; 266 267 void processActivateEvent(); 268 EventWrapper<DRAMCtrl, &DRAMCtrl::processActivateEvent> activateEvent; 269 270 void processPrechargeEvent(); 271 EventWrapper<DRAMCtrl, &DRAMCtrl::processPrechargeEvent> prechargeEvent; 272 273 void processRefreshEvent(); 274 EventWrapper<DRAMCtrl, &DRAMCtrl::processRefreshEvent> refreshEvent; 275 276 void processPowerEvent(); 277 EventWrapper<DRAMCtrl,&DRAMCtrl::processPowerEvent> powerEvent; 278 279 /** 280 * Check if the read queue has room for more entries 281 * 282 * @param pktCount The number of entries needed in the read queue 283 * @return true if read queue is full, false otherwise 284 */ 285 bool readQueueFull(unsigned int pktCount) const; 286 287 /** 288 * Check if the write queue has room for more entries 289 * 290 * @param pktCount The number of entries needed in the write queue 291 * @return true if write queue is full, false otherwise 292 */ 293 bool writeQueueFull(unsigned int pktCount) const; 294 295 /** 296 * When a new read comes in, first check if the write q has a 297 * pending request to the same address.\ If not, decode the 298 * address to populate rank/bank/row, create one or mutliple 299 * "dram_pkt", and push them to the back of the read queue.\ 300 * If this is the only 301 * read request in the system, schedule an event to start 302 * servicing it. 303 * 304 * @param pkt The request packet from the outside world 305 * @param pktCount The number of DRAM bursts the pkt 306 * translate to. If pkt size is larger then one full burst, 307 * then pktCount is greater than one. 308 */ 309 void addToReadQueue(PacketPtr pkt, unsigned int pktCount); 310 311 /** 312 * Decode the incoming pkt, create a dram_pkt and push to the 313 * back of the write queue. \If the write q length is more than 314 * the threshold specified by the user, ie the queue is beginning 315 * to get full, stop reads, and start draining writes. 316 * 317 * @param pkt The request packet from the outside world 318 * @param pktCount The number of DRAM bursts the pkt 319 * translate to. If pkt size is larger then one full burst, 320 * then pktCount is greater than one. 321 */ 322 void addToWriteQueue(PacketPtr pkt, unsigned int pktCount); 323 324 /** 325 * Actually do the DRAM access - figure out the latency it 326 * will take to service the req based on bank state, channel state etc 327 * and then update those states to account for this request.\ Based 328 * on this, update the packet's "readyTime" and move it to the 329 * response q from where it will eventually go back to the outside 330 * world. 331 * 332 * @param pkt The DRAM packet created from the outside world pkt 333 */ 334 void doDRAMAccess(DRAMPacket* dram_pkt); 335 336 /** 337 * When a packet reaches its "readyTime" in the response Q, 338 * use the "access()" method in AbstractMemory to actually 339 * create the response packet, and send it back to the outside 340 * world requestor. 341 * 342 * @param pkt The packet from the outside world 343 * @param static_latency Static latency to add before sending the packet 344 */ 345 void accessAndRespond(PacketPtr pkt, Tick static_latency); 346 347 /** 348 * Address decoder to figure out physical mapping onto ranks, 349 * banks, and rows. This function is called multiple times on the same 350 * system packet if the pakcet is larger than burst of the memory. The 351 * dramPktAddr is used for the offset within the packet. 352 * 353 * @param pkt The packet from the outside world 354 * @param dramPktAddr The starting address of the DRAM packet 355 * @param size The size of the DRAM packet in bytes 356 * @param isRead Is the request for a read or a write to DRAM 357 * @return A DRAMPacket pointer with the decoded information 358 */ 359 DRAMPacket* decodeAddr(PacketPtr pkt, Addr dramPktAddr, unsigned int size, 360 bool isRead); 361 362 /** 363 * The memory schduler/arbiter - picks which request needs to 364 * go next, based on the specified policy such as FCFS or FR-FCFS 365 * and moves it to the head of the queue. 366 */ 367 void chooseNext(std::deque<DRAMPacket*>& queue); 368 369 /** 370 * For FR-FCFS policy reorder the read/write queue depending on row buffer 371 * hits and earliest banks available in DRAM 372 */ 373 void reorderQueue(std::deque<DRAMPacket*>& queue); 374 375 /** 376 * Find which are the earliest banks ready to issue an activate 377 * for the enqueued requests. Assumes maximum of 64 banks per DIMM 378 * 379 * @param Queued requests to consider 380 * @return One-hot encoded mask of bank indices 381 */ 382 uint64_t minBankActAt(const std::deque<DRAMPacket*>& queue) const; 383 384 /** 385 * Keep track of when row activations happen, in order to enforce 386 * the maximum number of activations in the activation window. The 387 * method updates the time that the banks become available based 388 * on the current limits. 389 * 390 * @param act_tick Time when the activation takes place 391 * @param rank Index of the rank 392 * @param bank Index of the bank 393 * @param row Index of the row 394 * @param bank_ref Reference to the bank 395 */ 396 void activateBank(Tick act_tick, uint8_t rank, uint8_t bank, 397 uint16_t row, Bank& bank_ref); 398 399 /** 400 * Precharge a given bank and also update when the precharge is 401 * done. This will also deal with any stats related to the 402 * accesses to the open page. 403 * 404 * @param bank The bank to precharge 405 * @param pre_at Time when the precharge takes place 406 */ 407 void prechargeBank(Bank& bank, Tick pre_at); 408 409 /** 410 * Used for debugging to observe the contents of the queues. 411 */ 412 void printQs() const; 413 414 /** 415 * The controller's main read and write queues 416 */ 417 std::deque<DRAMPacket*> readQueue; 418 std::deque<DRAMPacket*> writeQueue; 419 420 /** 421 * Response queue where read packets wait after we're done working 422 * with them, but it's not time to send the response yet. The 423 * responses are stored seperately mostly to keep the code clean 424 * and help with events scheduling. For all logical purposes such 425 * as sizing the read queue, this and the main read queue need to 426 * be added together. 427 */ 428 std::deque<DRAMPacket*> respQueue; 429 430 /** 431 * If we need to drain, keep the drain manager around until we're 432 * done here. 433 */ 434 DrainManager *drainManager; 435 436 /** 437 * Multi-dimensional vector of banks, first dimension is ranks, 438 * second is bank 439 */ 440 std::vector<std::vector<Bank> > banks; 441 442 /** 443 * The following are basic design parameters of the memory 444 * controller, and are initialized based on parameter values. 445 * The rowsPerBank is determined based on the capacity, number of 446 * ranks and banks, the burst size, and the row buffer size. 447 */ 448 const uint32_t deviceBusWidth; 449 const uint32_t burstLength; 450 const uint32_t deviceRowBufferSize; 451 const uint32_t devicesPerRank; 452 const uint32_t burstSize; 453 const uint32_t rowBufferSize; 454 const uint32_t columnsPerRowBuffer; 455 const uint32_t ranksPerChannel; 456 const uint32_t banksPerRank; 457 const uint32_t channels; 458 uint32_t rowsPerBank; 459 const uint32_t readBufferSize; 460 const uint32_t writeBufferSize; 461 const uint32_t writeHighThreshold; 462 const uint32_t writeLowThreshold; 463 const uint32_t minWritesPerSwitch; 464 uint32_t writesThisTime; 465 uint32_t readsThisTime; 466 467 /** 468 * Basic memory timing parameters initialized based on parameter 469 * values. 470 */ 471 const Tick tWTR; 472 const Tick tRTW; 473 const Tick tBURST; 474 const Tick tRCD; 475 const Tick tCL; 476 const Tick tRP; 477 const Tick tRAS; 478 const Tick tWR; 479 const Tick tRTP; 480 const Tick tRFC; 481 const Tick tREFI; 482 const Tick tRRD; 483 const Tick tXAW; 484 const uint32_t activationLimit; 485 486 /** 487 * Memory controller configuration initialized based on parameter 488 * values. 489 */ 490 Enums::MemSched memSchedPolicy; 491 Enums::AddrMap addrMapping; 492 Enums::PageManage pageMgmt; 493 494 /** 495 * Max column accesses (read and write) per row, before forefully 496 * closing it. 497 */ 498 const uint32_t maxAccessesPerRow; 499 500 /** 501 * Pipeline latency of the controller frontend. The frontend 502 * contribution is added to writes (that complete when they are in 503 * the write buffer) and reads that are serviced the write buffer. 504 */ 505 const Tick frontendLatency; 506 507 /** 508 * Pipeline latency of the backend and PHY. Along with the 509 * frontend contribution, this latency is added to reads serviced 510 * by the DRAM. 511 */ 512 const Tick backendLatency; 513 514 /** 515 * Till when has the main data bus been spoken for already? 516 */ 517 Tick busBusyUntil; 518 519 /** 520 * Keep track of when a refresh is due. 521 */ 522 Tick refreshDueAt; 523 524 /** 525 * The refresh state is used to control the progress of the 526 * refresh scheduling. When normal operation is in progress the 527 * refresh state is idle. From there, it progresses to the refresh 528 * drain state once tREFI has passed. The refresh drain state 529 * captures the DRAM row active state, as it will stay there until 530 * all ongoing accesses complete. Thereafter all banks are 531 * precharged, and lastly, the DRAM is refreshed. 532 */ 533 enum RefreshState { 534 REF_IDLE = 0, 535 REF_DRAIN, 536 REF_PRE, 537 REF_RUN 538 }; 539 540 RefreshState refreshState; 541 542 /** 543 * The power state captures the different operational states of 544 * the DRAM and interacts with the bus read/write state machine, 545 * and the refresh state machine. In the idle state all banks are 546 * precharged. From there we either go to an auto refresh (as 547 * determined by the refresh state machine), or to a precharge 548 * power down mode. From idle the memory can also go to the active 549 * state (with one or more banks active), and in turn from there 550 * to active power down. At the moment we do not capture the deep 551 * power down and self-refresh state. 552 */ 553 enum PowerState { 554 PWR_IDLE = 0, 555 PWR_REF, 556 PWR_PRE_PDN, 557 PWR_ACT, 558 PWR_ACT_PDN 559 }; 560 561 /** 562 * Since we are taking decisions out of order, we need to keep 563 * track of what power transition is happening at what time, such 564 * that we can go back in time and change history. For example, if 565 * we precharge all banks and schedule going to the idle state, we 566 * might at a later point decide to activate a bank before the 567 * transition to idle would have taken place. 568 */ 569 PowerState pwrStateTrans; 570 571 /** 572 * Current power state. 573 */ 574 PowerState pwrState; 575 576 /** 577 * Schedule a power state transition in the future, and 578 * potentially override an already scheduled transition. 579 * 580 * @param pwr_state Power state to transition to 581 * @param tick Tick when transition should take place 582 */ 583 void schedulePowerEvent(PowerState pwr_state, Tick tick); 584 585 Tick prevArrival; 586 587 /** 588 * The soonest you have to start thinking about the next request 589 * is the longest access time that can occur before 590 * busBusyUntil. Assuming you need to precharge, open a new row, 591 * and access, it is tRP + tRCD + tCL. 592 */ 593 Tick nextReqTime; 594 595 // All statistics that the model needs to capture 596 Stats::Scalar readReqs; 597 Stats::Scalar writeReqs; 598 Stats::Scalar readBursts; 599 Stats::Scalar writeBursts; 600 Stats::Scalar bytesReadDRAM; 601 Stats::Scalar bytesReadWrQ; 602 Stats::Scalar bytesWritten; 603 Stats::Scalar bytesReadSys; 604 Stats::Scalar bytesWrittenSys; 605 Stats::Scalar servicedByWrQ; 606 Stats::Scalar mergedWrBursts; 607 Stats::Scalar neitherReadNorWrite; 608 Stats::Vector perBankRdBursts; 609 Stats::Vector perBankWrBursts; 610 Stats::Scalar numRdRetry; 611 Stats::Scalar numWrRetry; 612 Stats::Scalar totGap; 613 Stats::Vector readPktSize; 614 Stats::Vector writePktSize; 615 Stats::Vector rdQLenPdf; 616 Stats::Vector wrQLenPdf; 617 Stats::Histogram bytesPerActivate; 618 Stats::Histogram rdPerTurnAround; 619 Stats::Histogram wrPerTurnAround; 620 621 // Latencies summed over all requests 622 Stats::Scalar totQLat; 623 Stats::Scalar totMemAccLat; 624 Stats::Scalar totBusLat; 625 626 // Average latencies per request 627 Stats::Formula avgQLat; 628 Stats::Formula avgBusLat; 629 Stats::Formula avgMemAccLat; 630 631 // Average bandwidth 632 Stats::Formula avgRdBW; 633 Stats::Formula avgWrBW; 634 Stats::Formula avgRdBWSys; 635 Stats::Formula avgWrBWSys; 636 Stats::Formula peakBW; 637 Stats::Formula busUtil; 638 Stats::Formula busUtilRead; 639 Stats::Formula busUtilWrite; 640 641 // Average queue lengths 642 Stats::Average avgRdQLen; 643 Stats::Average avgWrQLen; 644 645 // Row hit count and rate 646 Stats::Scalar readRowHits; 647 Stats::Scalar writeRowHits; 648 Stats::Formula readRowHitRate; 649 Stats::Formula writeRowHitRate; 650 Stats::Formula avgGap; 651 652 // DRAM Power Calculation 653 Stats::Formula pageHitRate; 654 Stats::Vector pwrStateTime; 655 656 // Track when we transitioned to the current power state 657 Tick pwrStateTick; 658 659 // To track number of banks which are currently active 660 unsigned int numBanksActive; 661 662 /** @todo this is a temporary workaround until the 4-phase code is 663 * committed. upstream caches needs this packet until true is returned, so 664 * hold onto it for deletion until a subsequent call 665 */ 666 std::vector<PacketPtr> pendingDelete; 667 668 public: 669 670 void regStats(); 671 672 DRAMCtrl(const DRAMCtrlParams* p); 673 674 unsigned int drain(DrainManager* dm); 675 676 virtual BaseSlavePort& getSlavePort(const std::string& if_name, 677 PortID idx = InvalidPortID); 678 679 virtual void init(); 680 virtual void startup(); 681 682 protected: 683 684 Tick recvAtomic(PacketPtr pkt); 685 void recvFunctional(PacketPtr pkt); 686 bool recvTimingReq(PacketPtr pkt); 687 688}; 689 690#endif //__MEM_DRAM_CTRL_HH__ 691