diff options
Diffstat (limited to 'src/mem/dram_ctrl.hh')
-rw-r--r-- | src/mem/dram_ctrl.hh | 246 |
1 files changed, 197 insertions, 49 deletions
diff --git a/src/mem/dram_ctrl.hh b/src/mem/dram_ctrl.hh index b59ed3d2c..12cb0e922 100644 --- a/src/mem/dram_ctrl.hh +++ b/src/mem/dram_ctrl.hh @@ -42,6 +42,7 @@ * Neha Agarwal * Omar Naji * Matthias Jung + * Wendy Elsasser */ /** @@ -87,6 +88,10 @@ * controllers for future system architecture exploration", * Proc. ISPASS, 2014. If you use this model as part of your research * please cite the paper. + * + * The low-power functionality implements a staggered powerdown + * similar to that described in "Optimized Active and Power-Down Mode + * Refresh Control in 3D-DRAMs" by Jung et al, VLSI-SoC, 2014. */ class DRAMCtrl : public AbstractMemory { @@ -140,13 +145,14 @@ class DRAMCtrl : public AbstractMemory */ enum BusState { READ = 0, - READ_TO_WRITE, WRITE, - WRITE_TO_READ }; BusState busState; + /* bus state for next request event triggered */ + BusState busStateNext; + /** * Simple structure to hold the values needed to keep track of * commands for DRAMPower @@ -198,6 +204,82 @@ class DRAMCtrl : public AbstractMemory /** + * The power state captures the different operational states of + * the DRAM and interacts with the bus read/write state machine, + * and the refresh state machine. + * + * PWR_IDLE : The idle state in which all banks are closed + * From here can transition to: PWR_REF, PWR_ACT, + * PWR_PRE_PDN + * + * PWR_REF : Auto-refresh state. Will transition when refresh is + * complete based on power state prior to PWR_REF + * From here can transition to: PWR_IDLE, PWR_PRE_PDN, + * PWR_SREF + * + * PWR_SREF : Self-refresh state. Entered after refresh if + * previous state was PWR_PRE_PDN + * From here can transition to: PWR_IDLE + * + * PWR_PRE_PDN : Precharge power down state + * From here can transition to: PWR_REF, PWR_IDLE + * + * PWR_ACT : Activate state in which one or more banks are open + * From here can transition to: PWR_IDLE, PWR_ACT_PDN + * + * PWR_ACT_PDN : Activate power down state + * From here can transition to: PWR_ACT + */ + enum PowerState { + PWR_IDLE = 0, + PWR_REF, + PWR_SREF, + PWR_PRE_PDN, + PWR_ACT, + PWR_ACT_PDN + }; + + /** + * The refresh state is used to control the progress of the + * refresh scheduling. When normal operation is in progress the + * refresh state is idle. Once tREFI has elasped, a refresh event + * is triggered to start the following STM transitions which are + * used to issue a refresh and return back to normal operation + * + * REF_IDLE : IDLE state used during normal operation + * From here can transition to: REF_DRAIN + * + * REF_SREF_EXIT : Exiting a self-refresh; refresh event scheduled + * after self-refresh exit completes + * From here can transition to: REF_DRAIN + * + * REF_DRAIN : Drain state in which on going accesses complete. + * From here can transition to: REF_PD_EXIT + * + * REF_PD_EXIT : Evaluate pwrState and issue wakeup if needed + * Next state dependent on whether banks are open + * From here can transition to: REF_PRE, REF_START + * + * REF_PRE : Close (precharge) all open banks + * From here can transition to: REF_START + * + * REF_START : Issue refresh command and update DRAMPower stats + * From here can transition to: REF_RUN + * + * REF_RUN : Refresh running, waiting for tRFC to expire + * From here can transition to: REF_IDLE, REF_SREF_EXIT + */ + enum RefreshState { + REF_IDLE = 0, + REF_DRAIN, + REF_PD_EXIT, + REF_SREF_EXIT, + REF_PRE, + REF_START, + REF_RUN + }; + + /** * Rank class includes a vector of banks. Refresh and Power state * machines are defined per rank. Events required to change the * state of the refresh and power state machine are scheduled per @@ -210,59 +292,20 @@ class DRAMCtrl : public AbstractMemory private: /** - * The power state captures the different operational states of - * the DRAM and interacts with the bus read/write state machine, - * and the refresh state machine. In the idle state all banks are - * precharged. From there we either go to an auto refresh (as - * determined by the refresh state machine), or to a precharge - * power down mode. From idle the memory can also go to the active - * state (with one or more banks active), and in turn from there - * to active power down. At the moment we do not capture the deep - * power down and self-refresh state. - */ - enum PowerState { - PWR_IDLE = 0, - PWR_REF, - PWR_PRE_PDN, - PWR_ACT, - PWR_ACT_PDN - }; - - /** - * The refresh state is used to control the progress of the - * refresh scheduling. When normal operation is in progress the - * refresh state is idle. From there, it progresses to the refresh - * drain state once tREFI has passed. The refresh drain state - * captures the DRAM row active state, as it will stay there until - * all ongoing accesses complete. Thereafter all banks are - * precharged, and lastly, the DRAM is refreshed. - */ - enum RefreshState { - REF_IDLE = 0, - REF_DRAIN, - REF_PRE, - REF_RUN - }; - - /** * A reference to the parent DRAMCtrl instance */ DRAMCtrl& memory; /** * Since we are taking decisions out of order, we need to keep - * track of what power transition is happening at what time, such - * that we can go back in time and change history. For example, if - * we precharge all banks and schedule going to the idle state, we - * might at a later point decide to activate a bank before the - * transition to idle would have taken place. + * track of what power transition is happening at what time */ PowerState pwrStateTrans; /** - * Current power state. + * Previous low-power state, which will be re-entered after refresh. */ - PowerState pwrState; + PowerState pwrStatePostRefresh; /** * Track when we transitioned to the current power state @@ -270,11 +313,6 @@ class DRAMCtrl : public AbstractMemory Tick pwrStateTick; /** - * current refresh state - */ - RefreshState refreshState; - - /** * Keep track of when a refresh is due. */ Tick refreshDueAt; @@ -298,10 +336,31 @@ class DRAMCtrl : public AbstractMemory */ Stats::Scalar preBackEnergy; + /* + * Active Power-Down Energy + */ + Stats::Scalar actPowerDownEnergy; + + /* + * Precharge Power-Down Energy + */ + Stats::Scalar prePowerDownEnergy; + + /* + * self Refresh Energy + */ + Stats::Scalar selfRefreshEnergy; + Stats::Scalar totalEnergy; Stats::Scalar averagePower; /** + * Stat to track total DRAM idle time + * + */ + Stats::Scalar totalIdleTime; + + /** * Track time spent in each power state. */ Stats::Vector pwrStateTime; @@ -323,10 +382,47 @@ class DRAMCtrl : public AbstractMemory public: /** + * Current power state. + */ + PowerState pwrState; + + /** + * current refresh state + */ + RefreshState refreshState; + + /** + * rank is in or transitioning to power-down or self-refresh + */ + bool inLowPowerState; + + /** * Current Rank index */ uint8_t rank; + /** + * Track number of packets in read queue going to this rank + */ + uint32_t readEntries; + + /** + * Track number of packets in write queue going to this rank + */ + uint32_t writeEntries; + + /** + * Number of ACT, RD, and WR events currently scheduled + * Incremented when a refresh event is started as well + * Used to determine when a low-power state can be entered + */ + uint8_t outstandingEvents; + + /** + * delay power-down and self-refresh exit until this requirement is met + */ + Tick wakeUpAllowedAt; + /** * One DRAMPower instance per rank */ @@ -377,6 +473,10 @@ class DRAMCtrl : public AbstractMemory /** * Check if the current rank is available for scheduling. + * Rank will be unavailable if refresh is ongoing. + * This includes refresh events explicitly scheduled from the the + * controller or memory initiated events which will occur during + * self-refresh mode. * * @param Return true if the rank is idle from a refresh point of view */ @@ -392,6 +492,29 @@ class DRAMCtrl : public AbstractMemory bool inPwrIdleState() const { return pwrState == PWR_IDLE; } /** + * Trigger a self-refresh exit if there are entries enqueued + * Exit if there are any read entries regardless of the bus state. + * If we are currently issuing write commands, exit if we have any + * write commands enqueued as well. + * Could expand this in the future to analyze state of entire queue + * if needed. + * + * @return boolean indicating self-refresh exit should be scheduled + */ + bool forceSelfRefreshExit() const { + return (readEntries != 0) || + ((memory.busStateNext == WRITE) && (writeEntries != 0)); + } + + /** + * Check if the current rank is idle and should enter a low-pwer state + * + * @param Return true if the there are no read commands in Q + * and there are no outstanding events + */ + bool lowPowerEntryReady() const; + + /** * Let the rank check if it was waiting for requests to drain * to allow it to transition states. */ @@ -415,6 +538,27 @@ class DRAMCtrl : public AbstractMemory */ void computeStats(); + /** + * Schedule a transition to power-down (sleep) + * + * @param pwr_state Power state to transition to + * @param tick Absolute tick when transition should take place + */ + void powerDownSleep(PowerState pwr_state, Tick tick); + + /** + * schedule and event to wake-up from power-down or self-refresh + * and update bank timing parameters + * + * @param exit_delay Relative tick defining the delay required between + * low-power exit and the next command + */ + void scheduleWakeUpEvent(Tick exit_delay); + + void processWriteDoneEvent(); + EventWrapper<Rank, &Rank::processWriteDoneEvent> + writeDoneEvent; + void processActivateEvent(); EventWrapper<Rank, &Rank::processActivateEvent> activateEvent; @@ -431,6 +575,10 @@ class DRAMCtrl : public AbstractMemory EventWrapper<Rank, &Rank::processPowerEvent> powerEvent; + void processWakeUpEvent(); + EventWrapper<Rank, &Rank::processWakeUpEvent> + wakeUpEvent; + }; // define the process to compute stats on simulation exit |