Deleted Added
sdiff udiff text old ( 12637:bfc3cb9c7e6c ) new ( 12705:9668a82ead4b )
full compact
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())) {
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
1671DRAMCtrl::Rank::lowPowerEntryReady() const
1672{
1673 bool no_queued_cmds = ((memory.busStateNext == READ) && (readEntries == 0))
1674 || ((memory.busStateNext == WRITE) &&
1675 (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 }
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
1755 if (lowPowerEntryReady()) {
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.
1956 } else if (lowPowerEntryReady()) {
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
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);
1975
1976 DPRINTF(DRAMState, "Refresh done at %llu and next refresh"
1977 " at %llu\n", curTick(), refreshDueAt);
1978 }
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) {
2025 // if a refresh just occured
2026 // 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 }
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);
2151 // REF complete, decrement count
2152 --outstandingEvents;
2153
2154 DPRINTF(DRAMState, "Was refreshing for %llu ticks\n", duration);
2155 // if sleeping after refresh
2156 if (pwrState != PWR_IDLE) {
2157 assert((pwrState == PWR_PRE_PDN) || (pwrState == PWR_SREF));
2158 DPRINTF(DRAMState, "Switching to power down state after refreshing"
2159 " rank %d at %llu tick\n", rank, curTick());
2160 }
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
2168 if (!memory.nextReqEvent.scheduled()) {
2169 DPRINTF(DRAM, "Scheduling next request after refreshing rank %d\n",
2170 rank);
2171 schedule(memory.nextReqEvent, curTick());
2172 }
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);
2177
2178 // go back to REF event and close banks
2179 refreshState = REF_PRE;
2180 schedule(refreshEvent, curTick());
2181 }
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
2193 // the idle state, directly transition to a 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());
2202 // update the state in zero time and proceed below
2203 pwrState = PWR_REF;
2204 } else {
2205 // must have PRE scheduled to transition back to IDLE
2206 // and re-kick off refresh
2207 assert(prechargeEvent.scheduled());
2208 }
2209 }
2210 }
2211 }
2212
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
2217 if (pwrState == PWR_REF) {
2218 assert(refreshState == REF_PRE || refreshState == REF_PD_EXIT);
2219 DPRINTF(DRAMState, "Refreshing\n");
2220
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);
2227 } else {
2228 schedule(refreshEvent, curTick());
2229 }
2230 // Banks transitioned to IDLE, start REF
2231 refreshState = REF_START;
2232 }
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 ---