dram_ctrl.cc (12637:bfc3cb9c7e6c) dram_ctrl.cc (12705:9668a82ead4b)
1/*
2 * Copyright (c) 2010-2017 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

--- 650 unchanged lines hidden (view full) ---

659
660 // at this moment should not have transitioned to a low-power state
661 assert((dram_pkt->rankRef.pwrState != PWR_SREF) &&
662 (dram_pkt->rankRef.pwrState != PWR_PRE_PDN) &&
663 (dram_pkt->rankRef.pwrState != PWR_ACT_PDN));
664
665 // track if this is the last packet before idling
666 // and that there are no outstanding commands to this rank
1/*
2 * Copyright (c) 2010-2017 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

--- 650 unchanged lines hidden (view full) ---

659
660 // at this moment should not have transitioned to a low-power state
661 assert((dram_pkt->rankRef.pwrState != PWR_SREF) &&
662 (dram_pkt->rankRef.pwrState != PWR_PRE_PDN) &&
663 (dram_pkt->rankRef.pwrState != PWR_ACT_PDN));
664
665 // track if this is the last packet before idling
666 // and that there are no outstanding commands to this rank
667 // if REF in progress, transition to LP state should not occur
668 // until REF completes
669 if ((dram_pkt->rankRef.refreshState == REF_IDLE) &&
670 (dram_pkt->rankRef.lowPowerEntryReady())) {
667 if (dram_pkt->rankRef.isQueueEmpty() &&
668 dram_pkt->rankRef.outstandingEvents == 0) {
671 // verify that there are no events scheduled
672 assert(!dram_pkt->rankRef.activateEvent.scheduled());
673 assert(!dram_pkt->rankRef.prechargeEvent.scheduled());
674
675 // if coming from active state, schedule power event to
676 // active power-down else go to precharge power-down
677 DPRINTF(DRAMState, "Rank %d sleep at tick %d; current power state is "
678 "%d\n", dram_pkt->rank, curTick(), dram_pkt->rankRef.pwrState);

--- 984 unchanged lines hidden (view full) ---

1663 // Update the stats
1664 updatePowerStats();
1665
1666 // don't automatically transition back to LP state after next REF
1667 pwrStatePostRefresh = PWR_IDLE;
1668}
1669
1670bool
669 // verify that there are no events scheduled
670 assert(!dram_pkt->rankRef.activateEvent.scheduled());
671 assert(!dram_pkt->rankRef.prechargeEvent.scheduled());
672
673 // if coming from active state, schedule power event to
674 // active power-down else go to precharge power-down
675 DPRINTF(DRAMState, "Rank %d sleep at tick %d; current power state is "
676 "%d\n", dram_pkt->rank, curTick(), dram_pkt->rankRef.pwrState);

--- 984 unchanged lines hidden (view full) ---

1661 // Update the stats
1662 updatePowerStats();
1663
1664 // don't automatically transition back to LP state after next REF
1665 pwrStatePostRefresh = PWR_IDLE;
1666}
1667
1668bool
1671DRAMCtrl::Rank::lowPowerEntryReady() const
1669DRAMCtrl::Rank::isQueueEmpty() const
1672{
1670{
1671 // check commmands in Q based on current bus direction
1673 bool no_queued_cmds = ((memory.busStateNext == READ) && (readEntries == 0))
1674 || ((memory.busStateNext == WRITE) &&
1675 (writeEntries == 0));
1672 bool no_queued_cmds = ((memory.busStateNext == READ) && (readEntries == 0))
1673 || ((memory.busStateNext == WRITE) &&
1674 (writeEntries == 0));
1676
1677 if (refreshState == REF_RUN) {
1678 // have not decremented outstandingEvents for refresh command
1679 // still check if there are no commands queued to force PD
1680 // entry after refresh completes
1681 return no_queued_cmds;
1682 } else {
1683 // ensure no commands in Q and no commands scheduled
1684 return (no_queued_cmds && (outstandingEvents == 0));
1685 }
1675 return no_queued_cmds;
1686}
1687
1688void
1689DRAMCtrl::Rank::checkDrainDone()
1690{
1691 // if this rank was waiting to drain it is now able to proceed to
1692 // precharge
1693 if (refreshState == REF_DRAIN) {

--- 53 unchanged lines hidden (view full) ---

1747 // precharge complete, decrement count
1748 --outstandingEvents;
1749
1750 // if we reached zero, then special conditions apply as we track
1751 // if all banks are precharged for the power models
1752 if (numBanksActive == 0) {
1753 // no reads to this rank in the Q and no pending
1754 // RD/WR or refresh commands
1676}
1677
1678void
1679DRAMCtrl::Rank::checkDrainDone()
1680{
1681 // if this rank was waiting to drain it is now able to proceed to
1682 // precharge
1683 if (refreshState == REF_DRAIN) {

--- 53 unchanged lines hidden (view full) ---

1737 // precharge complete, decrement count
1738 --outstandingEvents;
1739
1740 // if we reached zero, then special conditions apply as we track
1741 // if all banks are precharged for the power models
1742 if (numBanksActive == 0) {
1743 // no reads to this rank in the Q and no pending
1744 // RD/WR or refresh commands
1755 if (lowPowerEntryReady()) {
1745 if (isQueueEmpty() && outstandingEvents == 0) {
1756 // should still be in ACT state since bank still open
1757 assert(pwrState == PWR_ACT);
1758
1759 // All banks closed - switch to precharge power down state.
1760 DPRINTF(DRAMState, "Rank %d sleep at tick %d\n",
1761 rank, curTick());
1762 powerDownSleep(PWR_PRE_PDN, curTick());
1763 } else {

--- 184 unchanged lines hidden (view full) ---

1948 assert(pwrState == PWR_REF);
1949 DPRINTF(DRAMState, "Rank %d sleeping after refresh and was in "
1950 "power state %d before refreshing\n", rank,
1951 pwrStatePostRefresh);
1952 powerDownSleep(pwrState, curTick());
1953
1954 // Force PRE power-down if there are no outstanding commands
1955 // in Q after refresh.
1746 // should still be in ACT state since bank still open
1747 assert(pwrState == PWR_ACT);
1748
1749 // All banks closed - switch to precharge power down state.
1750 DPRINTF(DRAMState, "Rank %d sleep at tick %d\n",
1751 rank, curTick());
1752 powerDownSleep(PWR_PRE_PDN, curTick());
1753 } else {

--- 184 unchanged lines hidden (view full) ---

1938 assert(pwrState == PWR_REF);
1939 DPRINTF(DRAMState, "Rank %d sleeping after refresh and was in "
1940 "power state %d before refreshing\n", rank,
1941 pwrStatePostRefresh);
1942 powerDownSleep(pwrState, curTick());
1943
1944 // Force PRE power-down if there are no outstanding commands
1945 // in Q after refresh.
1956 } else if (lowPowerEntryReady()) {
1946 } else if (isQueueEmpty()) {
1947 // still have refresh event outstanding but there should
1948 // be no other events outstanding
1949 assert(outstandingEvents == 1);
1957 DPRINTF(DRAMState, "Rank %d sleeping after refresh but was NOT"
1958 " in a low power state before refreshing\n", rank);
1959 powerDownSleep(PWR_PRE_PDN, curTick());
1960
1961 } else {
1962 // move to the idle power state once the refresh is done, this
1963 // will also move the refresh state machine to the refresh
1964 // idle state
1965 schedulePowerEvent(PWR_IDLE, curTick());
1966 }
1967 }
1968
1950 DPRINTF(DRAMState, "Rank %d sleeping after refresh but was NOT"
1951 " in a low power state before refreshing\n", rank);
1952 powerDownSleep(PWR_PRE_PDN, curTick());
1953
1954 } else {
1955 // move to the idle power state once the refresh is done, this
1956 // will also move the refresh state machine to the refresh
1957 // idle state
1958 schedulePowerEvent(PWR_IDLE, curTick());
1959 }
1960 }
1961
1969 // if transitioning to self refresh do not schedule a new refresh;
1970 // when waking from self refresh, a refresh is scheduled again.
1971 if (pwrStateTrans != PWR_SREF) {
1972 // compensate for the delay in actually performing the refresh
1973 // when scheduling the next one
1974 schedule(refreshEvent, refreshDueAt - memory.tRP);
1962 // At this point, we have completed the current refresh.
1963 // In the SREF bypass case, we do not get to this state in the
1964 // refresh STM and therefore can always schedule next event.
1965 // Compensate for the delay in actually performing the refresh
1966 // when scheduling the next one
1967 schedule(refreshEvent, refreshDueAt - memory.tRP);
1975
1968
1976 DPRINTF(DRAMState, "Refresh done at %llu and next refresh"
1977 " at %llu\n", curTick(), refreshDueAt);
1978 }
1969 DPRINTF(DRAMState, "Refresh done at %llu and next refresh"
1970 " at %llu\n", curTick(), refreshDueAt);
1979 }
1980}
1981
1982void
1983DRAMCtrl::Rank::schedulePowerEvent(PowerState pwr_state, Tick tick)
1984{
1985 // respect causality
1986 assert(tick >= curTick());

--- 30 unchanged lines hidden (view full) ---

2017 // power state. In reality tCKE is needed to enter active low power.
2018 // This is neglected here.
2019 schedulePowerEvent(pwr_state, tick);
2020 //push Command to DRAMPower
2021 cmdList.push_back(Command(MemCommand::PDN_F_PRE, 0, tick));
2022 DPRINTF(DRAMPower, "%llu,PDN_F_PRE,0,%d\n", divCeil(tick,
2023 memory.tCK) - memory.timeStampOffset, rank);
2024 } else if (pwr_state == PWR_REF) {
1971 }
1972}
1973
1974void
1975DRAMCtrl::Rank::schedulePowerEvent(PowerState pwr_state, Tick tick)
1976{
1977 // respect causality
1978 assert(tick >= curTick());

--- 30 unchanged lines hidden (view full) ---

2009 // power state. In reality tCKE is needed to enter active low power.
2010 // This is neglected here.
2011 schedulePowerEvent(pwr_state, tick);
2012 //push Command to DRAMPower
2013 cmdList.push_back(Command(MemCommand::PDN_F_PRE, 0, tick));
2014 DPRINTF(DRAMPower, "%llu,PDN_F_PRE,0,%d\n", divCeil(tick,
2015 memory.tCK) - memory.timeStampOffset, rank);
2016 } else if (pwr_state == PWR_REF) {
2025 // if a refresh just occured
2017 // if a refresh just occurred
2026 // transition to PRE_PDN now that all banks are closed
2018 // transition to PRE_PDN now that all banks are closed
2027 // do not transition to SREF if commands are in Q; stay in PRE_PDN
2028 if (pwrStatePostRefresh == PWR_ACT_PDN || !lowPowerEntryReady()) {
2029 // prechage power down requires tCKE to enter. For simplicity
2030 // this is not considered.
2031 schedulePowerEvent(PWR_PRE_PDN, tick);
2032 //push Command to DRAMPower
2033 cmdList.push_back(Command(MemCommand::PDN_F_PRE, 0, tick));
2034 DPRINTF(DRAMPower, "%llu,PDN_F_PRE,0,%d\n", divCeil(tick,
2035 memory.tCK) - memory.timeStampOffset, rank);
2036 } else {
2037 // last low power State was power precharge
2038 assert(pwrStatePostRefresh == PWR_PRE_PDN);
2039 // self refresh requires time tCKESR to enter. For simplicity,
2040 // this is not considered.
2041 schedulePowerEvent(PWR_SREF, tick);
2042 // push Command to DRAMPower
2043 cmdList.push_back(Command(MemCommand::SREN, 0, tick));
2044 DPRINTF(DRAMPower, "%llu,SREN,0,%d\n", divCeil(tick,
2045 memory.tCK) - memory.timeStampOffset, rank);
2046 }
2019 // precharge power down requires tCKE to enter. For simplicity
2020 // this is not considered.
2021 schedulePowerEvent(PWR_PRE_PDN, tick);
2022 //push Command to DRAMPower
2023 cmdList.push_back(Command(MemCommand::PDN_F_PRE, 0, tick));
2024 DPRINTF(DRAMPower, "%llu,PDN_F_PRE,0,%d\n", divCeil(tick,
2025 memory.tCK) - memory.timeStampOffset, rank);
2026 } else if (pwr_state == PWR_SREF) {
2027 // should only enter SREF after PRE-PD wakeup to do a refresh
2028 assert(pwrStatePostRefresh == PWR_PRE_PDN);
2029 // self refresh requires time tCKESR to enter. For simplicity,
2030 // this is not considered.
2031 schedulePowerEvent(PWR_SREF, tick);
2032 // push Command to DRAMPower
2033 cmdList.push_back(Command(MemCommand::SREN, 0, tick));
2034 DPRINTF(DRAMPower, "%llu,SREN,0,%d\n", divCeil(tick,
2035 memory.tCK) - memory.timeStampOffset, rank);
2047 }
2048 // Ensure that we don't power-down and back up in same tick
2049 // Once we commit to PD entry, do it and wait for at least 1tCK
2050 // This could be replaced with tCKE if/when that is added to the model
2051 wakeUpAllowedAt = tick + memory.tCK;
2052
2053 // Transitioning to a low power state, set flag
2054 inLowPowerState = true;

--- 88 unchanged lines hidden (view full) ---

2143 pwrState = pwrStateTrans;
2144 pwrStateTick = curTick();
2145
2146 // if rank was refreshing, make sure to start scheduling requests again
2147 if (prev_state == PWR_REF) {
2148 // bus IDLED prior to REF
2149 // counter should be one for refresh command only
2150 assert(outstandingEvents == 1);
2036 }
2037 // Ensure that we don't power-down and back up in same tick
2038 // Once we commit to PD entry, do it and wait for at least 1tCK
2039 // This could be replaced with tCKE if/when that is added to the model
2040 wakeUpAllowedAt = tick + memory.tCK;
2041
2042 // Transitioning to a low power state, set flag
2043 inLowPowerState = true;

--- 88 unchanged lines hidden (view full) ---

2132 pwrState = pwrStateTrans;
2133 pwrStateTick = curTick();
2134
2135 // if rank was refreshing, make sure to start scheduling requests again
2136 if (prev_state == PWR_REF) {
2137 // bus IDLED prior to REF
2138 // counter should be one for refresh command only
2139 assert(outstandingEvents == 1);
2151 // REF complete, decrement count
2140 // REF complete, decrement count and go back to IDLE
2152 --outstandingEvents;
2141 --outstandingEvents;
2142 refreshState = REF_IDLE;
2153
2154 DPRINTF(DRAMState, "Was refreshing for %llu ticks\n", duration);
2143
2144 DPRINTF(DRAMState, "Was refreshing for %llu ticks\n", duration);
2155 // if sleeping after refresh
2145 // if moving back to power-down after refresh
2156 if (pwrState != PWR_IDLE) {
2146 if (pwrState != PWR_IDLE) {
2157 assert((pwrState == PWR_PRE_PDN) || (pwrState == PWR_SREF));
2147 assert(pwrState == PWR_PRE_PDN);
2158 DPRINTF(DRAMState, "Switching to power down state after refreshing"
2159 " rank %d at %llu tick\n", rank, curTick());
2160 }
2148 DPRINTF(DRAMState, "Switching to power down state after refreshing"
2149 " rank %d at %llu tick\n", rank, curTick());
2150 }
2161 if (pwrState != PWR_SREF) {
2162 // rank is not available in SREF
2163 // don't transition to IDLE in this case
2164 refreshState = REF_IDLE;
2165 }
2166 // a request event could be already scheduled by the state
2167 // machine of the other rank
2151
2152 // completed refresh event, ensure next request is scheduled
2168 if (!memory.nextReqEvent.scheduled()) {
2153 if (!memory.nextReqEvent.scheduled()) {
2169 DPRINTF(DRAM, "Scheduling next request after refreshing rank %d\n",
2170 rank);
2154 DPRINTF(DRAM, "Scheduling next request after refreshing"
2155 " rank %d\n", rank);
2171 schedule(memory.nextReqEvent, curTick());
2172 }
2156 schedule(memory.nextReqEvent, curTick());
2157 }
2173 } else if (pwrState == PWR_ACT) {
2174 if (refreshState == REF_PD_EXIT) {
2175 // kick the refresh event loop into action again
2176 assert(prev_state == PWR_ACT_PDN);
2158 }
2177
2159
2178 // go back to REF event and close banks
2179 refreshState = REF_PRE;
2180 schedule(refreshEvent, curTick());
2181 }
2160 if ((pwrState == PWR_ACT) && (refreshState == REF_PD_EXIT)) {
2161 // have exited ACT PD
2162 assert(prev_state == PWR_ACT_PDN);
2163
2164 // go back to REF event and close banks
2165 refreshState = REF_PRE;
2166 schedule(refreshEvent, curTick());
2182 } else if (pwrState == PWR_IDLE) {
2183 DPRINTF(DRAMState, "All banks precharged\n");
2184 if (prev_state == PWR_SREF) {
2185 // set refresh state to REF_SREF_EXIT, ensuring inRefIdleState
2186 // continues to return false during tXS after SREF exit
2187 // Schedule a refresh which kicks things back into action
2188 // when it finishes
2189 refreshState = REF_SREF_EXIT;
2190 schedule(refreshEvent, curTick() + memory.tXS);
2191 } else {
2192 // if we have a pending refresh, and are now moving to
2167 } else if (pwrState == PWR_IDLE) {
2168 DPRINTF(DRAMState, "All banks precharged\n");
2169 if (prev_state == PWR_SREF) {
2170 // set refresh state to REF_SREF_EXIT, ensuring inRefIdleState
2171 // continues to return false during tXS after SREF exit
2172 // Schedule a refresh which kicks things back into action
2173 // when it finishes
2174 refreshState = REF_SREF_EXIT;
2175 schedule(refreshEvent, curTick() + memory.tXS);
2176 } else {
2177 // if we have a pending refresh, and are now moving to
2193 // the idle state, directly transition to a refresh
2178 // the idle state, directly transition to, or schedule refresh
2194 if ((refreshState == REF_PRE) || (refreshState == REF_PD_EXIT)) {
2195 // ensure refresh is restarted only after final PRE command.
2196 // do not restart refresh if controller is in an intermediate
2197 // state, after PRE_PDN exit, when banks are IDLE but an
2198 // ACT is scheduled.
2199 if (!activateEvent.scheduled()) {
2200 // there should be nothing waiting at this point
2201 assert(!powerEvent.scheduled());
2179 if ((refreshState == REF_PRE) || (refreshState == REF_PD_EXIT)) {
2180 // ensure refresh is restarted only after final PRE command.
2181 // do not restart refresh if controller is in an intermediate
2182 // state, after PRE_PDN exit, when banks are IDLE but an
2183 // ACT is scheduled.
2184 if (!activateEvent.scheduled()) {
2185 // there should be nothing waiting at this point
2186 assert(!powerEvent.scheduled());
2202 // update the state in zero time and proceed below
2203 pwrState = PWR_REF;
2187 if (refreshState == REF_PD_EXIT) {
2188 // exiting PRE PD, will be in IDLE until tXP expires
2189 // and then should transition to PWR_REF state
2190 assert(prev_state == PWR_PRE_PDN);
2191 schedulePowerEvent(PWR_REF, curTick() + memory.tXP);
2192 } else if (refreshState == REF_PRE) {
2193 // can directly move to PWR_REF state and proceed below
2194 pwrState = PWR_REF;
2195 }
2204 } else {
2205 // must have PRE scheduled to transition back to IDLE
2206 // and re-kick off refresh
2207 assert(prechargeEvent.scheduled());
2208 }
2209 }
2196 } else {
2197 // must have PRE scheduled to transition back to IDLE
2198 // and re-kick off refresh
2199 assert(prechargeEvent.scheduled());
2200 }
2201 }
2210 }
2202 }
2211 }
2212
2203 }
2204
2213 // we transition to the refresh state, let the refresh state
2214 // machine know of this state update and let it deal with the
2215 // scheduling of the next power state transition as well as the
2216 // following refresh
2205 // transition to the refresh state and re-start refresh process
2206 // refresh state machine will schedule the next power state transition
2217 if (pwrState == PWR_REF) {
2207 if (pwrState == PWR_REF) {
2208 // completed final PRE for refresh or exiting power-down
2218 assert(refreshState == REF_PRE || refreshState == REF_PD_EXIT);
2209 assert(refreshState == REF_PRE || refreshState == REF_PD_EXIT);
2219 DPRINTF(DRAMState, "Refreshing\n");
2220
2210
2221 // kick the refresh event loop into action again, and that
2222 // in turn will schedule a transition to the idle power
2223 // state once the refresh is done
2224 if (refreshState == REF_PD_EXIT) {
2225 // Wait for PD exit timing to complete before issuing REF
2226 schedule(refreshEvent, curTick() + memory.tXP);
2211 // exited PRE PD for refresh, with no pending commands
2212 // bypass auto-refresh and go straight to SREF, where memory
2213 // will issue refresh immediately upon entry
2214 if (pwrStatePostRefresh == PWR_PRE_PDN && isQueueEmpty() &&
2215 (memory.drainState() != DrainState::Draining) &&
2216 (memory.drainState() != DrainState::Drained)) {
2217 DPRINTF(DRAMState, "Rank %d bypassing refresh and transitioning "
2218 "to self refresh at %11u tick\n", rank, curTick());
2219 powerDownSleep(PWR_SREF, curTick());
2220
2221 // Since refresh was bypassed, remove event by decrementing count
2222 assert(outstandingEvents == 1);
2223 --outstandingEvents;
2224
2225 // reset state back to IDLE temporarily until SREF is entered
2226 pwrState = PWR_IDLE;
2227
2228 // Not bypassing refresh for SREF entry
2227 } else {
2229 } else {
2230 DPRINTF(DRAMState, "Refreshing\n");
2231
2232 // there should be nothing waiting at this point
2233 assert(!powerEvent.scheduled());
2234
2235 // kick the refresh event loop into action again, and that
2236 // in turn will schedule a transition to the idle power
2237 // state once the refresh is done
2228 schedule(refreshEvent, curTick());
2238 schedule(refreshEvent, curTick());
2239
2240 // Banks transitioned to IDLE, start REF
2241 refreshState = REF_START;
2229 }
2242 }
2230 // Banks transitioned to IDLE, start REF
2231 refreshState = REF_START;
2232 }
2243 }
2244
2233}
2234
2235void
2236DRAMCtrl::Rank::updatePowerStats()
2237{
2238 // All commands up to refresh have completed
2239 // flush cmdList to DRAMPower
2240 flushCmdList();

--- 522 unchanged lines hidden ---
2245}
2246
2247void
2248DRAMCtrl::Rank::updatePowerStats()
2249{
2250 // All commands up to refresh have completed
2251 // flush cmdList to DRAMPower
2252 flushCmdList();

--- 522 unchanged lines hidden ---