mem: Clean up Memory Controller
[gem5.git] / src / mem / mem_interface.hh
1 /*
2 * Copyright (c) 2012-2020 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
41 /**
42 * @file
43 * MemInterface declaration
44 */
45
46 #ifndef __MEM_INTERFACE_HH__
47 #define __MEM_INTERFACE_HH__
48
49 #include <deque>
50 #include <string>
51 #include <unordered_set>
52 #include <utility>
53 #include <vector>
54
55 #include "base/statistics.hh"
56 #include "enums/AddrMap.hh"
57 #include "enums/PageManage.hh"
58 #include "mem/abstract_mem.hh"
59 #include "mem/drampower.hh"
60 #include "mem/mem_ctrl.hh"
61 #include "params/DRAMInterface.hh"
62 #include "params/MemInterface.hh"
63 #include "params/NVMInterface.hh"
64 #include "sim/eventq.hh"
65
66 /**
67 * General interface to memory device
68 * Includes functions and parameters shared across media types
69 */
70 class MemInterface : public AbstractMemory
71 {
72 protected:
73 /**
74 * A basic class to track the bank state, i.e. what row is
75 * currently open (if any), when is the bank free to accept a new
76 * column (read/write) command, when can it be precharged, and
77 * when can it be activated.
78 *
79 * The bank also keeps track of how many bytes have been accessed
80 * in the open row since it was opened.
81 */
82 class Bank
83 {
84
85 public:
86
87 static const uint32_t NO_ROW = -1;
88
89 uint32_t openRow;
90 uint8_t bank;
91 uint8_t bankgr;
92
93 Tick rdAllowedAt;
94 Tick wrAllowedAt;
95 Tick preAllowedAt;
96 Tick actAllowedAt;
97
98 uint32_t rowAccesses;
99 uint32_t bytesAccessed;
100
101 Bank() :
102 openRow(NO_ROW), bank(0), bankgr(0),
103 rdAllowedAt(0), wrAllowedAt(0), preAllowedAt(0), actAllowedAt(0),
104 rowAccesses(0), bytesAccessed(0)
105 { }
106 };
107
108 /**
109 * A pointer to the parent MemCtrl instance
110 */
111 MemCtrl* ctrl;
112
113 /**
114 * Number of commands that can issue in the defined controller
115 * command window, used to verify command bandwidth
116 */
117 unsigned int maxCommandsPerWindow;
118
119 /**
120 * Memory controller configuration initialized based on parameter
121 * values.
122 */
123 Enums::AddrMap addrMapping;
124
125 /**
126 * General device and channel characteristics
127 * The rowsPerBank is determined based on the capacity, number of
128 * ranks and banks, the burst size, and the row buffer size.
129 */
130 const uint32_t burstSize;
131 const uint32_t deviceSize;
132 const uint32_t deviceRowBufferSize;
133 const uint32_t devicesPerRank;
134 const uint32_t rowBufferSize;
135 const uint32_t burstsPerRowBuffer;
136 const uint32_t burstsPerStripe;
137 const uint32_t ranksPerChannel;
138 const uint32_t banksPerRank;
139 uint32_t rowsPerBank;
140
141 /**
142 * General timing requirements
143 */
144 const Tick M5_CLASS_VAR_USED tCK;
145 const Tick tCS;
146 const Tick tBURST;
147 const Tick tRTW;
148 const Tick tWTR;
149
150 /*
151 * @return delay between write and read commands
152 */
153 virtual Tick writeToReadDelay() const { return tBURST + tWTR; }
154
155 /*
156 * @return delay between write and read commands
157 */
158 Tick readToWriteDelay() const { return tBURST + tRTW; }
159
160 /*
161 * @return delay between accesses to different ranks
162 */
163 Tick rankToRankDelay() const { return tBURST + tCS; }
164
165
166 public:
167
168 /**
169 * Buffer sizes for read and write queues in the controller
170 * These are passed to the controller on instantiation
171 * Defining them here allows for buffers to be resized based
172 * on memory type / configuration.
173 */
174 const uint32_t readBufferSize;
175 const uint32_t writeBufferSize;
176
177 /** Set a pointer to the controller and initialize
178 * interface based on controller parameters
179 * @param _ctrl pointer to the parent controller
180 * @param command_window size of command window used to
181 * check command bandwidth
182 */
183 void setCtrl(MemCtrl* _ctrl, unsigned int command_window);
184
185 /**
186 * Get an address in a dense range which starts from 0. The input
187 * address is the physical address of the request in an address
188 * space that contains other SimObjects apart from this
189 * controller.
190 *
191 * @param addr The intput address which should be in the addrRange
192 * @return An address in the continues range [0, max)
193 */
194 Addr getCtrlAddr(Addr addr) { return range.getOffset(addr); }
195
196 /**
197 * Setup the rank based on packet received
198 *
199 * @param integer value of rank to be setup. used to index ranks vector
200 * @param are we setting up rank for read or write packet?
201 */
202 virtual void setupRank(const uint8_t rank, const bool is_read) = 0;
203
204 /**
205 * Check drain state of interface
206 *
207 * @return true if all ranks are drained and idle
208 *
209 */
210 virtual bool allRanksDrained() const = 0;
211
212 /**
213 * For FR-FCFS policy, find first command that can issue
214 * Function will be overriden by interface to select based
215 * on media characteristics, used to determine when read
216 * or write can issue.
217 *
218 * @param queue Queued requests to consider
219 * @param min_col_at Minimum tick for 'seamless' issue
220 * @return an iterator to the selected packet, else queue.end()
221 * @return the tick when the packet selected will issue
222 */
223 virtual std::pair<MemPacketQueue::iterator, Tick>
224 chooseNextFRFCFS(MemPacketQueue& queue, Tick min_col_at) const = 0;
225
226 /*
227 * Function to calulate unloaded latency
228 */
229 virtual Tick accessLatency() const = 0;
230
231 /**
232 * @return number of bytes in a burst for this interface
233 */
234 uint32_t bytesPerBurst() const { return burstSize; }
235
236 /*
237 * @return time to offset next command
238 */
239 virtual Tick commandOffset() const = 0;
240
241 /**
242 * Check if a burst operation can be issued to the interface
243 *
244 * @param Return true if RD/WR can issue
245 */
246 virtual bool burstReady(MemPacket* pkt) const = 0;
247
248 /**
249 * Determine the required delay for an access to a different rank
250 *
251 * @return required rank to rank delay
252 */
253 Tick rankDelay() const { return tCS; }
254
255 /**
256 *
257 * @return minimum additional bus turnaround required for read-to-write
258 */
259 Tick minReadToWriteDataGap() const { return std::min(tRTW, tCS); }
260
261 /**
262 *
263 * @return minimum additional bus turnaround required for write-to-read
264 */
265 Tick minWriteToReadDataGap() const { return std::min(tWTR, tCS); }
266
267 /**
268 * Address decoder to figure out physical mapping onto ranks,
269 * banks, and rows. This function is called multiple times on the same
270 * system packet if the pakcet is larger than burst of the memory. The
271 * pkt_addr is used for the offset within the packet.
272 *
273 * @param pkt The packet from the outside world
274 * @param pkt_addr The starting address of the packet
275 * @param size The size of the packet in bytes
276 * @param is_read Is the request for a read or a write to memory
277 * @param is_dram Is the request to a DRAM interface
278 * @return A MemPacket pointer with the decoded information
279 */
280 MemPacket* decodePacket(const PacketPtr pkt, Addr pkt_addr,
281 unsigned int size, bool is_read, bool is_dram);
282
283 /**
284 * Add rank to rank delay to bus timing to all banks in all ranks
285 * when access to an alternate interface is issued
286 *
287 * param cmd_at Time of current command used as starting point for
288 * addition of rank-to-rank delay
289 */
290 virtual void addRankToRankDelay(Tick cmd_at) = 0;
291
292 typedef MemInterfaceParams Params;
293 MemInterface(const Params* _p);
294 };
295
296 /**
297 * Interface to DRAM devices with media specific parameters,
298 * statistics, and functions.
299 * The DRAMInterface includes a class for individual ranks
300 * and per rank functions.
301 */
302 class DRAMInterface : public MemInterface
303 {
304 private:
305 /**
306 * Simple structure to hold the values needed to keep track of
307 * commands for DRAMPower
308 */
309 struct Command
310 {
311 Data::MemCommand::cmds type;
312 uint8_t bank;
313 Tick timeStamp;
314
315 constexpr Command(Data::MemCommand::cmds _type, uint8_t _bank,
316 Tick time_stamp)
317 : type(_type), bank(_bank), timeStamp(time_stamp)
318 { }
319 };
320
321 /**
322 * The power state captures the different operational states of
323 * the DRAM and interacts with the bus read/write state machine,
324 * and the refresh state machine.
325 *
326 * PWR_IDLE : The idle state in which all banks are closed
327 * From here can transition to: PWR_REF, PWR_ACT,
328 * PWR_PRE_PDN
329 *
330 * PWR_REF : Auto-refresh state. Will transition when refresh is
331 * complete based on power state prior to PWR_REF
332 * From here can transition to: PWR_IDLE, PWR_PRE_PDN,
333 * PWR_SREF
334 *
335 * PWR_SREF : Self-refresh state. Entered after refresh if
336 * previous state was PWR_PRE_PDN
337 * From here can transition to: PWR_IDLE
338 *
339 * PWR_PRE_PDN : Precharge power down state
340 * From here can transition to: PWR_REF, PWR_IDLE
341 *
342 * PWR_ACT : Activate state in which one or more banks are open
343 * From here can transition to: PWR_IDLE, PWR_ACT_PDN
344 *
345 * PWR_ACT_PDN : Activate power down state
346 * From here can transition to: PWR_ACT
347 */
348 enum PowerState
349 {
350 PWR_IDLE = 0,
351 PWR_REF,
352 PWR_SREF,
353 PWR_PRE_PDN,
354 PWR_ACT,
355 PWR_ACT_PDN
356 };
357
358 /**
359 * The refresh state is used to control the progress of the
360 * refresh scheduling. When normal operation is in progress the
361 * refresh state is idle. Once tREFI has elasped, a refresh event
362 * is triggered to start the following STM transitions which are
363 * used to issue a refresh and return back to normal operation
364 *
365 * REF_IDLE : IDLE state used during normal operation
366 * From here can transition to: REF_DRAIN
367 *
368 * REF_SREF_EXIT : Exiting a self-refresh; refresh event scheduled
369 * after self-refresh exit completes
370 * From here can transition to: REF_DRAIN
371 *
372 * REF_DRAIN : Drain state in which on going accesses complete.
373 * From here can transition to: REF_PD_EXIT
374 *
375 * REF_PD_EXIT : Evaluate pwrState and issue wakeup if needed
376 * Next state dependent on whether banks are open
377 * From here can transition to: REF_PRE, REF_START
378 *
379 * REF_PRE : Close (precharge) all open banks
380 * From here can transition to: REF_START
381 *
382 * REF_START : Issue refresh command and update DRAMPower stats
383 * From here can transition to: REF_RUN
384 *
385 * REF_RUN : Refresh running, waiting for tRFC to expire
386 * From here can transition to: REF_IDLE, REF_SREF_EXIT
387 */
388 enum RefreshState
389 {
390 REF_IDLE = 0,
391 REF_DRAIN,
392 REF_PD_EXIT,
393 REF_SREF_EXIT,
394 REF_PRE,
395 REF_START,
396 REF_RUN
397 };
398
399 class Rank;
400 struct RankStats : public Stats::Group
401 {
402 RankStats(DRAMInterface &dram, Rank &rank);
403
404 void regStats() override;
405 void resetStats() override;
406 void preDumpStats() override;
407
408 Rank &rank;
409
410 /*
411 * Command energies
412 */
413 Stats::Scalar actEnergy;
414 Stats::Scalar preEnergy;
415 Stats::Scalar readEnergy;
416 Stats::Scalar writeEnergy;
417 Stats::Scalar refreshEnergy;
418
419 /*
420 * Active Background Energy
421 */
422 Stats::Scalar actBackEnergy;
423
424 /*
425 * Precharge Background Energy
426 */
427 Stats::Scalar preBackEnergy;
428
429 /*
430 * Active Power-Down Energy
431 */
432 Stats::Scalar actPowerDownEnergy;
433
434 /*
435 * Precharge Power-Down Energy
436 */
437 Stats::Scalar prePowerDownEnergy;
438
439 /*
440 * self Refresh Energy
441 */
442 Stats::Scalar selfRefreshEnergy;
443
444 Stats::Scalar totalEnergy;
445 Stats::Scalar averagePower;
446
447 /**
448 * Stat to track total DRAM idle time
449 *
450 */
451 Stats::Scalar totalIdleTime;
452
453 /**
454 * Track time spent in each power state.
455 */
456 Stats::Vector pwrStateTime;
457 };
458
459 /**
460 * Rank class includes a vector of banks. Refresh and Power state
461 * machines are defined per rank. Events required to change the
462 * state of the refresh and power state machine are scheduled per
463 * rank. This class allows the implementation of rank-wise refresh
464 * and rank-wise power-down.
465 */
466 class Rank : public EventManager
467 {
468 private:
469
470 /**
471 * A reference to the parent DRAMInterface instance
472 */
473 DRAMInterface& dram;
474
475 /**
476 * Since we are taking decisions out of order, we need to keep
477 * track of what power transition is happening at what time
478 */
479 PowerState pwrStateTrans;
480
481 /**
482 * Previous low-power state, which will be re-entered after refresh.
483 */
484 PowerState pwrStatePostRefresh;
485
486 /**
487 * Track when we transitioned to the current power state
488 */
489 Tick pwrStateTick;
490
491 /**
492 * Keep track of when a refresh is due.
493 */
494 Tick refreshDueAt;
495
496 /**
497 * Function to update Power Stats
498 */
499 void updatePowerStats();
500
501 /**
502 * Schedule a power state transition in the future, and
503 * potentially override an already scheduled transition.
504 *
505 * @param pwr_state Power state to transition to
506 * @param tick Tick when transition should take place
507 */
508 void schedulePowerEvent(PowerState pwr_state, Tick tick);
509
510 public:
511
512 /**
513 * Current power state.
514 */
515 PowerState pwrState;
516
517 /**
518 * current refresh state
519 */
520 RefreshState refreshState;
521
522 /**
523 * rank is in or transitioning to power-down or self-refresh
524 */
525 bool inLowPowerState;
526
527 /**
528 * Current Rank index
529 */
530 uint8_t rank;
531
532 /**
533 * Track number of packets in read queue going to this rank
534 */
535 uint32_t readEntries;
536
537 /**
538 * Track number of packets in write queue going to this rank
539 */
540 uint32_t writeEntries;
541
542 /**
543 * Number of ACT, RD, and WR events currently scheduled
544 * Incremented when a refresh event is started as well
545 * Used to determine when a low-power state can be entered
546 */
547 uint8_t outstandingEvents;
548
549 /**
550 * delay low-power exit until this requirement is met
551 */
552 Tick wakeUpAllowedAt;
553
554 /**
555 * One DRAMPower instance per rank
556 */
557 DRAMPower power;
558
559 /**
560 * List of commands issued, to be sent to DRAMPpower at refresh
561 * and stats dump. Keep commands here since commands to different
562 * banks are added out of order. Will only pass commands up to
563 * curTick() to DRAMPower after sorting.
564 */
565 std::vector<Command> cmdList;
566
567 /**
568 * Vector of Banks. Each rank is made of several devices which in
569 * term are made from several banks.
570 */
571 std::vector<Bank> banks;
572
573 /**
574 * To track number of banks which are currently active for
575 * this rank.
576 */
577 unsigned int numBanksActive;
578
579 /** List to keep track of activate ticks */
580 std::deque<Tick> actTicks;
581
582 /**
583 * Track when we issued the last read/write burst
584 */
585 Tick lastBurstTick;
586
587 Rank(const DRAMInterfaceParams* _p, int _rank,
588 DRAMInterface& _dram);
589
590 const std::string name() const { return csprintf("%d", rank); }
591
592 /**
593 * Kick off accounting for power and refresh states and
594 * schedule initial refresh.
595 *
596 * @param ref_tick Tick for first refresh
597 */
598 void startup(Tick ref_tick);
599
600 /**
601 * Stop the refresh events.
602 */
603 void suspend();
604
605 /**
606 * Check if there is no refresh and no preparation of refresh ongoing
607 * i.e. the refresh state machine is in idle
608 *
609 * @param Return true if the rank is idle from a refresh point of view
610 */
611 bool inRefIdleState() const { return refreshState == REF_IDLE; }
612
613 /**
614 * Check if the current rank has all banks closed and is not
615 * in a low power state
616 *
617 * @param Return true if the rank is idle from a bank
618 * and power point of view
619 */
620 bool inPwrIdleState() const { return pwrState == PWR_IDLE; }
621
622 /**
623 * Trigger a self-refresh exit if there are entries enqueued
624 * Exit if there are any read entries regardless of the bus state.
625 * If we are currently issuing write commands, exit if we have any
626 * write commands enqueued as well.
627 * Could expand this in the future to analyze state of entire queue
628 * if needed.
629 *
630 * @return boolean indicating self-refresh exit should be scheduled
631 */
632 bool forceSelfRefreshExit() const;
633
634 /**
635 * Check if the command queue of current rank is idle
636 *
637 * @param Return true if the there are no commands in Q.
638 * Bus direction determines queue checked.
639 */
640 bool isQueueEmpty() const;
641
642 /**
643 * Let the rank check if it was waiting for requests to drain
644 * to allow it to transition states.
645 */
646 void checkDrainDone();
647
648 /**
649 * Push command out of cmdList queue that are scheduled at
650 * or before curTick() to DRAMPower library
651 * All commands before curTick are guaranteed to be complete
652 * and can safely be flushed.
653 */
654 void flushCmdList();
655
656 /**
657 * Computes stats just prior to dump event
658 */
659 void computeStats();
660
661 /**
662 * Reset stats on a stats event
663 */
664 void resetStats();
665
666 /**
667 * Schedule a transition to power-down (sleep)
668 *
669 * @param pwr_state Power state to transition to
670 * @param tick Absolute tick when transition should take place
671 */
672 void powerDownSleep(PowerState pwr_state, Tick tick);
673
674 /**
675 * schedule and event to wake-up from power-down or self-refresh
676 * and update bank timing parameters
677 *
678 * @param exit_delay Relative tick defining the delay required between
679 * low-power exit and the next command
680 */
681 void scheduleWakeUpEvent(Tick exit_delay);
682
683 void processWriteDoneEvent();
684 EventFunctionWrapper writeDoneEvent;
685
686 void processActivateEvent();
687 EventFunctionWrapper activateEvent;
688
689 void processPrechargeEvent();
690 EventFunctionWrapper prechargeEvent;
691
692 void processRefreshEvent();
693 EventFunctionWrapper refreshEvent;
694
695 void processPowerEvent();
696 EventFunctionWrapper powerEvent;
697
698 void processWakeUpEvent();
699 EventFunctionWrapper wakeUpEvent;
700
701 protected:
702 RankStats stats;
703 };
704
705 /**
706 * Function for sorting Command structures based on timeStamp
707 *
708 * @param a Memory Command
709 * @param next Memory Command
710 * @return true if timeStamp of Command 1 < timeStamp of Command 2
711 */
712 static bool
713 sortTime(const Command& cmd, const Command& cmd_next)
714 {
715 return cmd.timeStamp < cmd_next.timeStamp;
716 }
717
718 /**
719 * DRAM specific device characteristics
720 */
721 const uint32_t bankGroupsPerRank;
722 const bool bankGroupArch;
723
724 /**
725 * DRAM specific timing requirements
726 */
727 const Tick tCL;
728 const Tick tBURST_MIN;
729 const Tick tBURST_MAX;
730 const Tick tCCD_L_WR;
731 const Tick tCCD_L;
732 const Tick tRCD;
733 const Tick tRP;
734 const Tick tRAS;
735 const Tick tWR;
736 const Tick tRTP;
737 const Tick tRFC;
738 const Tick tREFI;
739 const Tick tRRD;
740 const Tick tRRD_L;
741 const Tick tPPD;
742 const Tick tAAD;
743 const Tick tXAW;
744 const Tick tXP;
745 const Tick tXS;
746 const Tick clkResyncDelay;
747 const bool dataClockSync;
748 const bool burstInterleave;
749 const uint8_t twoCycleActivate;
750 const uint32_t activationLimit;
751 const Tick wrToRdDlySameBG;
752 const Tick rdToWrDlySameBG;
753
754 Enums::PageManage pageMgmt;
755 /**
756 * Max column accesses (read and write) per row, before forefully
757 * closing it.
758 */
759 const uint32_t maxAccessesPerRow;
760
761 // timestamp offset
762 uint64_t timeStampOffset;
763
764 // Holds the value of the DRAM rank of burst issued
765 uint8_t activeRank;
766
767 /** Enable or disable DRAM powerdown states. */
768 bool enableDRAMPowerdown;
769
770 /** The time when stats were last reset used to calculate average power */
771 Tick lastStatsResetTick;
772
773 /**
774 * Keep track of when row activations happen, in order to enforce
775 * the maximum number of activations in the activation window. The
776 * method updates the time that the banks become available based
777 * on the current limits.
778 *
779 * @param rank_ref Reference to the rank
780 * @param bank_ref Reference to the bank
781 * @param act_tick Time when the activation takes place
782 * @param row Index of the row
783 */
784 void activateBank(Rank& rank_ref, Bank& bank_ref, Tick act_tick,
785 uint32_t row);
786
787 /**
788 * Precharge a given bank and also update when the precharge is
789 * done. This will also deal with any stats related to the
790 * accesses to the open page.
791 *
792 * @param rank_ref The rank to precharge
793 * @param bank_ref The bank to precharge
794 * @param pre_tick Time when the precharge takes place
795 * @param auto_or_preall Is this an auto-precharge or precharge all command
796 * @param trace Is this an auto precharge then do not add to trace
797 */
798 void prechargeBank(Rank& rank_ref, Bank& bank_ref,
799 Tick pre_tick, bool auto_or_preall = false,
800 bool trace = true);
801
802 struct DRAMStats : public Stats::Group
803 {
804 DRAMStats(DRAMInterface &dram);
805
806 void regStats() override;
807 void resetStats() override;
808
809 DRAMInterface &dram;
810
811 /** total number of DRAM bursts serviced */
812 Stats::Scalar readBursts;
813 Stats::Scalar writeBursts;
814
815 /** DRAM per bank stats */
816 Stats::Vector perBankRdBursts;
817 Stats::Vector perBankWrBursts;
818
819 // Latencies summed over all requests
820 Stats::Scalar totQLat;
821 Stats::Scalar totBusLat;
822 Stats::Scalar totMemAccLat;
823
824 // Average latencies per request
825 Stats::Formula avgQLat;
826 Stats::Formula avgBusLat;
827 Stats::Formula avgMemAccLat;
828
829 // Row hit count and rate
830 Stats::Scalar readRowHits;
831 Stats::Scalar writeRowHits;
832 Stats::Formula readRowHitRate;
833 Stats::Formula writeRowHitRate;
834 Stats::Histogram bytesPerActivate;
835 // Number of bytes transferred to/from DRAM
836 Stats::Scalar bytesRead;
837 Stats::Scalar bytesWritten;
838
839 // Average bandwidth
840 Stats::Formula avgRdBW;
841 Stats::Formula avgWrBW;
842 Stats::Formula peakBW;
843 // bus utilization
844 Stats::Formula busUtil;
845 Stats::Formula busUtilRead;
846 Stats::Formula busUtilWrite;
847 Stats::Formula pageHitRate;
848 };
849
850 DRAMStats stats;
851
852 /**
853 * Vector of dram ranks
854 */
855 std::vector<Rank*> ranks;
856
857 /*
858 * @return delay between write and read commands
859 */
860 Tick writeToReadDelay() const override { return tBURST + tWTR + tCL; }
861
862 /**
863 * Find which are the earliest banks ready to issue an activate
864 * for the enqueued requests. Assumes maximum of 32 banks per rank
865 * Also checks if the bank is already prepped.
866 *
867 * @param queue Queued requests to consider
868 * @param min_col_at time of seamless burst command
869 * @return One-hot encoded mask of bank indices
870 * @return boolean indicating burst can issue seamlessly, with no gaps
871 */
872 std::pair<std::vector<uint32_t>, bool>
873 minBankPrep(const MemPacketQueue& queue, Tick min_col_at) const;
874
875 /*
876 * @return time to send a burst of data without gaps
877 */
878 Tick
879 burstDelay() const
880 {
881 return (burstInterleave ? tBURST_MAX / 2 : tBURST);
882 }
883
884 public:
885 /**
886 * Initialize the DRAM interface and verify parameters
887 */
888 void init() override;
889
890 /**
891 * Iterate through dram ranks and instantiate per rank startup routine
892 */
893 void startup() override;
894
895 /**
896 * Setup the rank based on packet received
897 *
898 * @param integer value of rank to be setup. used to index ranks vector
899 * @param are we setting up rank for read or write packet?
900 */
901 void setupRank(const uint8_t rank, const bool is_read) override;
902
903 /**
904 * Iterate through dram ranks to exit self-refresh in order to drain
905 */
906 void drainRanks();
907
908 /**
909 * Return true once refresh is complete for all ranks and there are no
910 * additional commands enqueued. (only evaluated when draining)
911 * This will ensure that all banks are closed, power state is IDLE, and
912 * power stats have been updated
913 *
914 * @return true if all ranks have refreshed, with no commands enqueued
915 *
916 */
917 bool allRanksDrained() const override;
918
919 /**
920 * Iterate through DRAM ranks and suspend them
921 */
922 void suspend();
923
924 /*
925 * @return time to offset next command
926 */
927 Tick commandOffset() const override { return (tRP + tRCD); }
928
929 /*
930 * Function to calulate unloaded, closed bank access latency
931 */
932 Tick accessLatency() const override { return (tRP + tRCD + tCL); }
933
934 /**
935 * For FR-FCFS policy, find first DRAM command that can issue
936 *
937 * @param queue Queued requests to consider
938 * @param min_col_at Minimum tick for 'seamless' issue
939 * @return an iterator to the selected packet, else queue.end()
940 * @return the tick when the packet selected will issue
941 */
942 std::pair<MemPacketQueue::iterator, Tick>
943 chooseNextFRFCFS(MemPacketQueue& queue, Tick min_col_at) const override;
944
945 /**
946 * Actually do the burst - figure out the latency it
947 * will take to service the req based on bank state, channel state etc
948 * and then update those states to account for this request. Based
949 * on this, update the packet's "readyTime" and move it to the
950 * response q from where it will eventually go back to the outside
951 * world.
952 *
953 * @param mem_pkt The packet created from the outside world pkt
954 * @param next_burst_at Minimum bus timing requirement from controller
955 * @param queue Reference to the read or write queue with the packet
956 * @return pair, tick when current burst is issued and
957 * tick when next burst can issue
958 */
959 std::pair<Tick, Tick>
960 doBurstAccess(MemPacket* mem_pkt, Tick next_burst_at,
961 const std::vector<MemPacketQueue>& queue);
962
963 /**
964 * Check if a burst operation can be issued to the DRAM
965 *
966 * @param Return true if RD/WR can issue
967 * This requires the DRAM to be in the
968 * REF IDLE state
969 */
970 bool
971 burstReady(MemPacket* pkt) const override
972 {
973 return ranks[pkt->rank]->inRefIdleState();
974 }
975
976 /**
977 * This function checks if ranks are actively refreshing and
978 * therefore busy. The function also checks if ranks are in
979 * the self-refresh state, in which case, a self-refresh exit
980 * is initiated.
981 *
982 * return boolean if all ranks are in refresh and therefore busy
983 */
984 bool isBusy();
985
986 /**
987 * Add rank to rank delay to bus timing to all DRAM banks in alli ranks
988 * when access to an alternate interface is issued
989 *
990 * param cmd_at Time of current command used as starting point for
991 * addition of rank-to-rank delay
992 */
993 void addRankToRankDelay(Tick cmd_at) override;
994
995 /**
996 * Complete response process for DRAM when read burst is complete
997 * This will update the counters and check if a power down state
998 * can be entered.
999 *
1000 * @param rank Specifies rank associated with read burst
1001 */
1002 void respondEvent(uint8_t rank);
1003
1004 /**
1005 * Check the refresh state to determine if refresh needs
1006 * to be kicked back into action after a read response
1007 *
1008 * @param rank Specifies rank associated with read burst
1009 */
1010 void checkRefreshState(uint8_t rank);
1011
1012 DRAMInterface(const DRAMInterfaceParams* _p);
1013 };
1014
1015 /**
1016 * Interface to NVM devices with media specific parameters,
1017 * statistics, and functions.
1018 * The NVMInterface includes a class for individual ranks
1019 * and per rank functions.
1020 */
1021 class NVMInterface : public MemInterface
1022 {
1023 private:
1024 /**
1025 * NVM rank class simply includes a vector of banks.
1026 */
1027 class Rank : public EventManager
1028 {
1029 private:
1030
1031 /**
1032 * A reference to the parent NVMInterface instance
1033 */
1034 NVMInterface& nvm;
1035
1036 public:
1037
1038 /**
1039 * Current Rank index
1040 */
1041 uint8_t rank;
1042
1043 /**
1044 * Vector of NVM banks. Each rank is made of several banks
1045 * that can be accessed in parallel.
1046 */
1047 std::vector<Bank> banks;
1048
1049 Rank(const NVMInterfaceParams* _p, int _rank,
1050 NVMInterface& _nvm);
1051 };
1052
1053 /**
1054 * NVM specific device and channel characteristics
1055 */
1056 const uint32_t maxPendingWrites;
1057 const uint32_t maxPendingReads;
1058 const bool twoCycleRdWr;
1059
1060 /**
1061 * NVM specific timing requirements
1062 */
1063 const Tick tREAD;
1064 const Tick tWRITE;
1065 const Tick tSEND;
1066
1067 struct NVMStats : public Stats::Group
1068 {
1069 NVMStats(NVMInterface &nvm);
1070
1071 void regStats() override;
1072
1073 NVMInterface &nvm;
1074
1075 /** NVM stats */
1076 Stats::Scalar readBursts;
1077 Stats::Scalar writeBursts;
1078
1079 Stats::Vector perBankRdBursts;
1080 Stats::Vector perBankWrBursts;
1081
1082 // Latencies summed over all requests
1083 Stats::Scalar totQLat;
1084 Stats::Scalar totBusLat;
1085 Stats::Scalar totMemAccLat;
1086
1087 // Average latencies per request
1088 Stats::Formula avgQLat;
1089 Stats::Formula avgBusLat;
1090 Stats::Formula avgMemAccLat;
1091
1092 Stats::Scalar bytesRead;
1093 Stats::Scalar bytesWritten;
1094
1095 // Average bandwidth
1096 Stats::Formula avgRdBW;
1097 Stats::Formula avgWrBW;
1098 Stats::Formula peakBW;
1099 Stats::Formula busUtil;
1100 Stats::Formula busUtilRead;
1101 Stats::Formula busUtilWrite;
1102
1103 /** NVM stats */
1104 Stats::Histogram pendingReads;
1105 Stats::Histogram pendingWrites;
1106 Stats::Histogram bytesPerBank;
1107 };
1108
1109 NVMStats stats;
1110
1111 void processWriteRespondEvent();
1112 EventFunctionWrapper writeRespondEvent;
1113
1114 void processReadReadyEvent();
1115 EventFunctionWrapper readReadyEvent;
1116
1117 /**
1118 * Vector of nvm ranks
1119 */
1120 std::vector<Rank*> ranks;
1121
1122 /**
1123 * Holding queue for non-deterministic write commands, which
1124 * maintains writes that have been issued but have not completed
1125 * Stored seperately mostly to keep the code clean and help with
1126 * events scheduling.
1127 * This mimics a buffer on the media controller and therefore is
1128 * not added to the main write queue for sizing
1129 */
1130 std::list<Tick> writeRespQueue;
1131
1132 std::deque<Tick> readReadyQueue;
1133
1134 /**
1135 * Check if the write response queue is empty
1136 *
1137 * @param Return true if empty
1138 */
1139 bool writeRespQueueEmpty() const { return writeRespQueue.empty(); }
1140
1141 /**
1142 * Till when must we wait before issuing next read command?
1143 */
1144 Tick nextReadAt;
1145
1146 // keep track of reads that have issued for which data is either
1147 // not yet ready or has not yet been transferred to the ctrl
1148 uint16_t numPendingReads;
1149 uint16_t numReadDataReady;
1150
1151 public:
1152 // keep track of the number of reads that have yet to be issued
1153 uint16_t numReadsToIssue;
1154
1155 // number of writes in the writeQueue for the NVM interface
1156 uint32_t numWritesQueued;
1157
1158 /**
1159 * Initialize the NVM interface and verify parameters
1160 */
1161 void init() override;
1162
1163 /**
1164 * Setup the rank based on packet received
1165 *
1166 * @param integer value of rank to be setup. used to index ranks vector
1167 * @param are we setting up rank for read or write packet?
1168 */
1169 void setupRank(const uint8_t rank, const bool is_read) override;
1170
1171 /**
1172 * Check drain state of NVM interface
1173 *
1174 * @return true if write response queue is empty
1175 *
1176 */
1177 bool allRanksDrained() const override { return writeRespQueueEmpty(); }
1178
1179 /*
1180 * @return time to offset next command
1181 */
1182 Tick commandOffset() const override { return tBURST; }
1183
1184 /**
1185 * Check if a burst operation can be issued to the NVM
1186 *
1187 * @param Return true if RD/WR can issue
1188 * for reads, also verfy that ready count
1189 * has been updated to a non-zero value to
1190 * account for race conditions between events
1191 */
1192 bool burstReady(MemPacket* pkt) const override;
1193
1194 /**
1195 * This function checks if ranks are busy.
1196 * This state is true when either:
1197 * 1) There is no command with read data ready to transmit or
1198 * 2) The NVM inteface has reached the maximum number of outstanding
1199 * writes commands.
1200 * @param read_queue_empty There are no read queued
1201 * @param all_writes_nvm All writes in queue are for NVM interface
1202 * @return true of NVM is busy
1203 *
1204 */
1205 bool isBusy(bool read_queue_empty, bool all_writes_nvm);
1206 /**
1207 * For FR-FCFS policy, find first NVM command that can issue
1208 * default to first command to prepped region
1209 *
1210 * @param queue Queued requests to consider
1211 * @param min_col_at Minimum tick for 'seamless' issue
1212 * @return an iterator to the selected packet, else queue.end()
1213 * @return the tick when the packet selected will issue
1214 */
1215 std::pair<MemPacketQueue::iterator, Tick>
1216 chooseNextFRFCFS(MemPacketQueue& queue, Tick min_col_at) const override;
1217
1218 /**
1219 * Add rank to rank delay to bus timing to all NVM banks in alli ranks
1220 * when access to an alternate interface is issued
1221 *
1222 * param cmd_at Time of current command used as starting point for
1223 * addition of rank-to-rank delay
1224 */
1225 void addRankToRankDelay(Tick cmd_at) override;
1226
1227
1228 /**
1229 * Select read command to issue asynchronously
1230 */
1231 void chooseRead(MemPacketQueue& queue);
1232
1233 /*
1234 * Function to calulate unloaded access latency
1235 */
1236 Tick accessLatency() const override { return (tREAD + tSEND); }
1237
1238 /**
1239 * Check if the write response queue has reached defined threshold
1240 *
1241 * @param Return true if full
1242 */
1243 bool
1244 writeRespQueueFull() const
1245 {
1246 return writeRespQueue.size() == maxPendingWrites;
1247 }
1248
1249 bool
1250 readsWaitingToIssue() const
1251 {
1252 return ((numReadsToIssue != 0) &&
1253 (numPendingReads < maxPendingReads));
1254 }
1255
1256 /**
1257 * Actually do the burst and update stats.
1258 *
1259 * @param pkt The packet created from the outside world pkt
1260 * @param next_burst_at Minimum bus timing requirement from controller
1261 * @return pair, tick when current burst is issued and
1262 * tick when next burst can issue
1263 */
1264 std::pair<Tick, Tick>
1265 doBurstAccess(MemPacket* pkt, Tick next_burst_at);
1266
1267 NVMInterface(const NVMInterfaceParams* _p);
1268 };
1269
1270 #endif //__MEM_INTERFACE_HH__